Add POST /changes/{id}/revisions/{sha1}/review

Clients can post a code review scoring and comments using a JSON
REST-style API. The API accepts change specifications using either the
triplet "project~branch~change_id" or the legacy _number format, and
also accepts commit SHA-1 or legacy patch set id to identify which
patch set the comments apply too. Clients should prefer to use commit
SHA-1 to write comments, especially from automated builders where the
commit was just checked out.

Comments may include a top level cover message, updated scores for
labels (previously approval categories), and inline file comments:

  POST /changes/gerrit~master~I9589cc46b.../revisions/fe7ffc.../review
  Content-Type: application/json;charset=utf-8

  {
    "message": "Thank you for starting this project, it is useful.",

    "labels": {
      "Verified": 1,
      "Code-Review": -1
    },

    "comments": {
      "gerrit-gwtui/src/main/java/com/google/gerrit/client/rpc/RestApi.java": [
        { "line": 1, "message": "Is the copyright notice date correct?" },
        { "line": 32, "message": "Great idea, but try ..."}
      ]
    }
  }

Labels are merged with the already existing labels for the calling
user. This allows updating independent categories from unrelated
processes, such as two different build systems testing on Linux and
Mac OS X. Callers can erase a label by setting it to 0.

Label names are free-form in the JSON map, but the server still needs
to restrict labels to those declared in the approval_categories table
as it needs a category_id value to link the score to the patch set in
the database. This will change in the future as we fix more of the UI
and server code to not have this requirement.

By default the POST is rejected with a 403 Forbidden error if a label
is used in a way that is not permitted by the caller, e.g. trying to
assign Code-Review+2 will fail unless the caller has that permission.
Clients can request these permission errors to be ignored by setting
the top level property "strict_labels": false in the request:

    "strict_labels": false,
	"labels": { "Code-Review": 2 },

If a label is used without permission the value will be squashed to
the highest (or lowest) value permitted to be used by the caller. If
this value is 0, the label won't be set.

Inline file comments can also be supplied using the comments map. Keys
are file names, with lists of comment objects holding line number and
message text. All comments must be supplied during the POST. If the
user has any drafts these will be erased when the comments are stored
and published. In a future commit the web UI will be rewritten to use
this RPC and will include all draft comments anytime it publishes.
This will simplify last-minute edits of inline comments, as they can
be updated without needing to wait for drafts to save.

Drafts may optionally be published or left in draft status by setting
the drafts field to another value:

  "drafts": DELETE,   // Delete non-updated drafts (default behavior).
  "drafts": PUBLISH,  // Publish non-updated drafts now.
  "drafts": KEEP,     // Leave non-updated draft in draft status.

This commit copies a lot of code from PublishComments and refactors it
to a cleaner implementation. As soon as the web UI switches to the new
/review REST API call, PublishComments will be deleted, so no attempt
is made at sharing a common implementation.

Change-Id: Iee7b4dcaa28cfc83f585ff99e3ed705973a2788d
This commit is contained in:
Shawn O. Pearce
2012-11-17 15:28:36 -08:00
parent cc02f8908e
commit 43f7940111
9 changed files with 740 additions and 1 deletions

View File

@@ -0,0 +1,53 @@
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.change;
import com.google.gerrit.extensions.restapi.RestResource;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.project.ChangeControl;
import com.google.inject.TypeLiteral;
public class RevisionResource implements RestResource {
public static final TypeLiteral<RestView<RevisionResource>> REVISION_KIND =
new TypeLiteral<RestView<RevisionResource>>() {};
private final ChangeResource change;
private final PatchSet ps;
public RevisionResource(ChangeResource change, PatchSet ps) {
this.change = change;
this.ps = ps;
}
public ChangeControl getControl() {
return change.getControl();
}
public Change getChange() {
return getControl().getChange();
}
public PatchSet getPatchSet() {
return ps;
}
Account.Id getAuthorId() {
return ((IdentifiedUser) getControl().getCurrentUser()).getAccountId();
}
}