summaryrefslogtreecommitdiffstats
path: root/extensions/PhabBugz/lib/Revision.pm
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/PhabBugz/lib/Revision.pm')
-rw-r--r--extensions/PhabBugz/lib/Revision.pm372
1 files changed, 372 insertions, 0 deletions
diff --git a/extensions/PhabBugz/lib/Revision.pm b/extensions/PhabBugz/lib/Revision.pm
new file mode 100644
index 000000000..29d665009
--- /dev/null
+++ b/extensions/PhabBugz/lib/Revision.pm
@@ -0,0 +1,372 @@
+# This Source Code Form is hasject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This Source Code Form is "Incompatible With Secondary Licenses", as
+# defined by the Mozilla Public License, v. 2.0.
+
+package Bugzilla::Extension::PhabBugz::Revision;
+
+use 5.10.1;
+use strict;
+use warnings;
+
+use Bugzilla::Bug;
+use Bugzilla::Error;
+use Bugzilla::Util qw(trim);
+use Bugzilla::Extension::PhabBugz::Util qw(
+ get_phab_bmo_ids
+ request
+);
+
+use Types::Standard -all;
+
+my $SearchResult = Dict[
+ id => Int,
+ type => Str,
+ phid => Str,
+ fields => Dict[
+ title => Str,
+ authorPHID => Str,
+ dateCreated => Int,
+ dateModified => Int,
+ policy => Dict[ view => Str, edit => Str ],
+ "bugzilla.bug-id" => Int,
+ ],
+ attachments => Dict[
+ reviewers => Dict[
+ reviewers => ArrayRef[
+ Dict[
+ reviewerPHID => Str,
+ status => Str,
+ isBlocking => Bool,
+ actorPHID => Maybe[Str],
+ ],
+ ],
+ ],
+ subscribers => Dict[
+ subscriberPHIDs => ArrayRef[Str],
+ subscriberCount => Int,
+ viewerIsSubscribed => Bool,
+ ],
+ projects => Dict[ projectPHIDs => ArrayRef[Str] ],
+ ],
+];
+
+my $NewParams = Dict[ phids => ArrayRef[Str] ];
+
+#########################
+# Initialization #
+#########################
+
+sub new {
+ my ($class, $params) = @_;
+ $NewParams->assert_valid($params);
+ my $self = _load($params);
+ $SearchResult->assert_valid($self);
+
+ return bless($self, $class);
+}
+
+sub _load {
+ my ($params) = @_;
+
+ my $data = {
+ queryKey => 'all',
+ attachments => {
+ projects => 1,
+ reviewers => 1,
+ subscribers => 1
+ },
+ constraints => $params
+ };
+
+ my $result = request('differential.revision.search', $data);
+ if (exists $result->{result}{data} && @{ $result->{result}{data} }) {
+ return $result->{result}->{data}->[0];
+ }
+
+ return $result;
+}
+
+# {
+# "data": [
+# {
+# "id": 25,
+# "type": "DREV",
+# "phid": "PHID-DREV-uozm3ggfp7e7uoqegmc3",
+# "fields": {
+# "title": "Added .arcconfig",
+# "authorPHID": "PHID-USER-4wigy3sh5fc5t74vapwm",
+# "dateCreated": 1507666113,
+# "dateModified": 1508514027,
+# "policy": {
+# "view": "public",
+# "edit": "admin"
+# },
+# "bugzilla.bug-id": "1154784"
+# },
+# "attachments": {
+# "reviewers": {
+# "reviewers": [
+# {
+# "reviewerPHID": "PHID-USER-2gjdpu7thmpjxxnp7tjq",
+# "status": "added",
+# "isBlocking": false,
+# "actorPHID": null
+# },
+# {
+# "reviewerPHID": "PHID-USER-o5dnet6dp4dkxkg5b3ox",
+# "status": "rejected",
+# "isBlocking": false,
+# "actorPHID": "PHID-USER-o5dnet6dp4dkxkg5b3ox"
+# }
+# ]
+# },
+# "subscribers": {
+# "subscriberPHIDs": [],
+# "subscriberCount": 0,
+# "viewerIsSubscribed": true
+# },
+# "projects": {
+# "projectPHIDs": []
+# }
+# }
+# }
+# ],
+# "maps": {},
+# "query": {
+# "queryKey": null
+# },
+# "cursor": {
+# "limit": 100,
+# "after": null,
+# "before": null,
+# "order": null
+# }
+# }
+
+#########################
+# Modification #
+#########################
+
+sub update {
+ my ($self) = @_;
+
+ my $data = {
+ objectIdentifier => $self->phid,
+ transactions => []
+ };
+
+ if ($self->{added_comments}) {
+ foreach my $comment (@{ $self->{added_comments} }) {
+ push(@{ $data->{transactions} }, {
+ type => 'comment',
+ value => $comment
+ });
+ }
+ }
+
+ if ($self->{set_subscribers}) {
+ push(@{ $data->{transactions} }, {
+ type => 'subscribers.set',
+ value => $self->{set_subscribers}
+ });
+ }
+
+ if ($self->{add_subscribers}) {
+ push(@{ $data->{transactions} }, {
+ type => 'subscribers.add',
+ value => $self->{add_subscribers}
+ });
+ }
+
+ if ($self->{remove_subscribers}) {
+ push(@{ $data->{transactions} }, {
+ type => 'subscribers.remove',
+ value => $self->{remove_subscribers}
+ });
+ }
+
+ if ($self->{set_reviewers}) {
+ push(@{ $data->{transactions} }, {
+ type => 'reviewers.set',
+ value => $self->{set_reviewers}
+ });
+ }
+
+ if ($self->{add_reviewers}) {
+ push(@{ $data->{transactions} }, {
+ type => 'reviewers.add',
+ value => $self->{add_reviewers}
+ });
+ }
+
+ if ($self->{remove_reviewers}) {
+ push(@{ $data->{transactions} }, {
+ type => 'reviewers.remove',
+ value => $self->{remove_reviewers}
+ });
+ }
+
+ if ($self->{set_policy}) {
+ foreach my $name ("view", "edit") {
+ next unless $self->{set_policy}->{$name};
+ push(@{ $data->{transactions} }, {
+ type => $name,
+ value => $self->{set_policy}->{$name}
+ });
+ }
+ }
+
+ my $result = request('differential.revision.edit', $data);
+
+ return $result;
+}
+
+#########################
+# Accessors #
+#########################
+
+sub id { $_[0]->{id}; }
+sub phid { $_[0]->{phid}; }
+sub title { $_[0]->{fields}->{title}; }
+sub status { $_[0]->{fields}->{status}->{value}; }
+sub creation_ts { $_[0]->{fields}->{dateCreated}; }
+sub modification_ts { $_[0]->{fields}->{dateModified}; }
+sub author_phid { $_[0]->{fields}->{authorPHID}; }
+sub bug_id { $_[0]->{fields}->{'bugzilla.bug-id'}; }
+
+sub view_policy { $_[0]->{fields}->{policy}->{view}; }
+sub edit_policy { $_[0]->{fields}->{policy}->{edit}; }
+
+sub reviewers_raw { $_[0]->{attachments}->{reviewers}->{reviewers}; }
+sub subscribers_raw { $_[0]->{attachments}->{subscribers}; }
+sub projects_raw { $_[0]->{attachments}->{projects}; }
+sub subscriber_count { $_[0]->{attachments}->{subscribers}->{subscriberCount}; }
+
+sub bug {
+ my ($self) = @_;
+ return $self->{bug} ||= Bugzilla::Bug->new({ id => $self->bug_id, cache => 1 });
+}
+
+sub author {
+ my ($self) = @_;
+ return $self->{author} if $self->{author};
+ my $users = get_phab_bmo_ids({ phids => [$self->author_phid] });
+ if (@$users) {
+ $self->{author} = new Bugzilla::User({ id => $users->[0]->{id}, cache => 1 });
+ $self->{author}->{phab_phid} = $self->author_phid;
+ return $self->{author};
+ }
+ return undef;
+}
+
+sub reviewers {
+ my ($self) = @_;
+ return $self->{reviewers} if $self->{reviewers};
+
+ my @phids;
+ foreach my $reviewer (@{ $self->reviewers_raw }) {
+ push(@phids, $reviewer->{reviewerPHID});
+ }
+
+ return [] if !@phids;
+
+ my $users = get_phab_bmo_ids({ phids => \@phids });
+
+ my @reviewers;
+ foreach my $user (@$users) {
+ my $reviewer = Bugzilla::User->new({ id => $user->{id}, cache => 1});
+ $reviewer->{phab_phid} = $user->{phid};
+ foreach my $reviewer_data (@{ $self->reviewers_raw }) {
+ if ($reviewer_data->{reviewerPHID} eq $user->{phid}) {
+ $reviewer->{phab_review_status} = $reviewer_data->{status};
+ last;
+ }
+ }
+ push(@reviewers, $reviewer);
+ }
+
+ return \@reviewers;
+}
+
+sub subscribers {
+ my ($self) = @_;
+ return $self->{subscribers} if $self->{subscribers};
+
+ my @phids;
+ foreach my $phid (@{ $self->subscribers_raw->{subscriberPHIDs} }) {
+ push(@phids, $phid);
+ }
+
+ my $users = get_phab_bmo_ids({ phids => \@phids });
+
+ return [] if !@phids;
+
+ my @subscribers;
+ foreach my $user (@$users) {
+ my $subscriber = Bugzilla::User->new({ id => $user->{id}, cache => 1});
+ $subscriber->{phab_phid} = $user->{phid};
+ push(@subscribers, $subscriber);
+ }
+
+ return \@subscribers;
+}
+
+#########################
+# Mutators #
+#########################
+
+sub add_comment {
+ my ($self, $comment) = @_;
+ $comment = trim($comment);
+ $self->{added_comments} ||= [];
+ push(@{ $self->{added_comments} }, $comment);
+}
+
+sub add_reviewer {
+ my ($self, $reviewer) = @_;
+ $self->{add_reviewers} ||= [];
+ my $reviewer_phid = blessed $reviewer ? $reviewer->phab_phid : $reviewer;
+ push(@{ $self->{add_reviewers} }, $reviewer_phid);
+}
+
+sub remove_reviewer {
+ my ($self, $reviewer) = @_;
+ $self->{remove_reviewers} ||= [];
+ my $reviewer_phid = blessed $reviewer ? $reviewer->phab_phid : $reviewer;
+ push(@{ $self->{remove_reviewers} }, $reviewer_phid);
+}
+
+sub set_reviewers {
+ my ($self, $reviewers) = @_;
+ $self->{set_reviewers} = [ map { $_->phab_phid } @$reviewers ];
+}
+
+sub add_subscriber {
+ my ($self, $subscriber) = @_;
+ $self->{add_subscribers} ||= [];
+ my $subscriber_phid = blessed $subscriber ? $subscriber->phab_phid : $subscriber;
+ push(@{ $self->{add_subscribers} }, $subscriber_phid);
+}
+
+sub remove_subscriber {
+ my ($self, $subscriber) = @_;
+ $self->{remove_subscribers} ||= [];
+ my $subscriber_phid = blessed $subscriber ? $subscriber->phab_phid : $subscriber;
+ push(@{ $self->{remove_subscribers} }, $subscriber_phid);
+}
+
+sub set_subscribers {
+ my ($self, $subscribers) = @_;
+ $self->{set_subscribers} = $subscribers;
+}
+
+sub set_policy {
+ my ($self, $name, $policy) = @_;
+ $self->{set_policy} ||= {};
+ $self->{set_policy}->{$name} = $policy;
+}
+
+1; \ No newline at end of file