Search in sources :

Example 6 with LabelTypes

use of com.google.gerrit.entities.LabelTypes in project gerrit by GerritCodeReview.

the class LabelsJson method labelsForSubmittedChange.

private Map<String, LabelWithStatus> labelsForSubmittedChange(AccountLoader accountLoader, ChangeData cd, LabelTypes labelTypes, boolean standard, boolean detailed) throws PermissionBackendException {
    Set<Account.Id> allUsers = new HashSet<>();
    if (detailed) {
        // the latest patch set (in the next loop).
        for (PatchSetApproval psa : cd.approvals().values()) {
            allUsers.add(psa.accountId());
        }
    }
    Set<String> labelNames = new HashSet<>();
    SetMultimap<Account.Id, PatchSetApproval> current = MultimapBuilder.hashKeys().hashSetValues().build();
    for (PatchSetApproval a : cd.currentApprovals()) {
        allUsers.add(a.accountId());
        Optional<LabelType> type = labelTypes.byLabel(a.labelId());
        if (type.isPresent()) {
            labelNames.add(type.get().getName());
            // Not worth the effort to distinguish between votable/non-votable for 0
            // values on closed changes, since they can't vote anyway.
            current.put(a.accountId(), a);
        }
    }
    // Since voting on merged changes is allowed all labels which apply to
    // the change must be returned. All applying labels can be retrieved from
    // the submit records, which is what initLabels does.
    // It's not possible to only compute the labels based on the approvals
    // since merged changes may not have approvals for all labels (e.g. if not
    // all labels are required for submit or if the change was auto-closed due
    // to direct push or if new labels were defined after the change was
    // merged).
    Map<String, LabelWithStatus> labels;
    labels = initLabels(accountLoader, cd, labelTypes, standard);
    // it wouldn't be included in the submit records.
    for (String name : labelNames) {
        if (!labels.containsKey(name)) {
            labels.put(name, LabelWithStatus.create(new LabelInfo(), null));
        }
    }
    labels.entrySet().stream().filter(e -> labelTypes.byLabel(e.getKey()).isPresent()).forEach(e -> setLabelValues(labelTypes.byLabel(e.getKey()).get(), e.getValue()));
    for (Account.Id accountId : allUsers) {
        Map<String, ApprovalInfo> byLabel = Maps.newHashMapWithExpectedSize(labels.size());
        Map<String, VotingRangeInfo> pvr = Collections.emptyMap();
        if (detailed) {
            pvr = getPermittedVotingRanges(permittedLabels(accountId, cd));
        }
        for (Map.Entry<String, LabelWithStatus> entry : labels.entrySet()) {
            ApprovalInfo ai = approvalInfo(accountLoader, accountId, 0, null, null, null);
            byLabel.put(entry.getKey(), ai);
            addApproval(entry.getValue().label(), ai);
        }
        for (PatchSetApproval psa : current.get(accountId)) {
            Optional<LabelType> type = labelTypes.byLabel(psa.labelId());
            if (!type.isPresent()) {
                continue;
            }
            short val = psa.value();
            ApprovalInfo info = byLabel.get(type.get().getName());
            if (info != null) {
                info.value = Integer.valueOf(val);
                info.permittedVotingRange = pvr.getOrDefault(type.get().getName(), null);
                info.setDate(psa.granted());
                info.tag = psa.tag().orElse(null);
                if (psa.postSubmit()) {
                    info.postSubmit = true;
                }
            }
            if (!standard) {
                continue;
            }
            setLabelScores(accountLoader, type.get(), labels.get(type.get().getName()), val, accountId);
        }
    }
    return labels;
}
Also used : Iterables(com.google.common.collect.Iterables) AccountLoader(com.google.gerrit.server.account.AccountLoader) PermissionBackendException(com.google.gerrit.server.permissions.PermissionBackendException) LabelInfo(com.google.gerrit.extensions.common.LabelInfo) MultimapBuilder(com.google.common.collect.MultimapBuilder) Inject(com.google.inject.Inject) HashBasedTable(com.google.common.collect.HashBasedTable) HashMap(java.util.HashMap) PermissionBackend(com.google.gerrit.server.permissions.PermissionBackend) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) PatchSetApproval(com.google.gerrit.entities.PatchSetApproval) LabelTypes(com.google.gerrit.entities.LabelTypes) Lists(com.google.common.collect.Lists) LabelValue(com.google.gerrit.entities.LabelValue) LabelType(com.google.gerrit.entities.LabelType) Map(java.util.Map) ChangeUtil(com.google.gerrit.server.ChangeUtil) LinkedHashMultimap(com.google.common.collect.LinkedHashMultimap) ApprovalInfo(com.google.gerrit.extensions.common.ApprovalInfo) ImmutableMap(com.google.common.collect.ImmutableMap) ReviewerStateInternal(com.google.gerrit.server.notedb.ReviewerStateInternal) Collection(java.util.Collection) Account(com.google.gerrit.entities.Account) Set(java.util.Set) Instant(java.time.Instant) Maps(com.google.common.collect.Maps) Ints(com.google.common.primitives.Ints) SubmitRecord(com.google.gerrit.entities.SubmitRecord) SetMultimap(com.google.common.collect.SetMultimap) Preconditions.checkState(com.google.common.base.Preconditions.checkState) VotingRangeInfo(com.google.gerrit.extensions.common.VotingRangeInfo) Collectors.toList(java.util.stream.Collectors.toList) ChangeData(com.google.gerrit.server.query.change.ChangeData) List(java.util.List) Nullable(com.google.gerrit.common.Nullable) TreeMap(java.util.TreeMap) AutoValue(com.google.auto.value.AutoValue) Optional(java.util.Optional) Table(com.google.common.collect.Table) Collections(java.util.Collections) FluentLogger(com.google.common.flogger.FluentLogger) LabelPermission(com.google.gerrit.server.permissions.LabelPermission) Singleton(com.google.inject.Singleton) Account(com.google.gerrit.entities.Account) VotingRangeInfo(com.google.gerrit.extensions.common.VotingRangeInfo) PatchSetApproval(com.google.gerrit.entities.PatchSetApproval) LabelInfo(com.google.gerrit.extensions.common.LabelInfo) ApprovalInfo(com.google.gerrit.extensions.common.ApprovalInfo) LabelType(com.google.gerrit.entities.LabelType) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) TreeMap(java.util.TreeMap) HashSet(java.util.HashSet)

Example 7 with LabelTypes

use of com.google.gerrit.entities.LabelTypes in project gerrit by GerritCodeReview.

the class ChangeInserter method updateChange.

@Override
public boolean updateChange(ChangeContext ctx) throws RestApiException, IOException, PermissionBackendException, ConfigInvalidException {
    // Use defensive copy created by ChangeControl.
    change = ctx.getChange();
    patchSetInfo = patchSetInfoFactory.get(ctx.getRevWalk(), ctx.getRevWalk().parseCommit(commitId), psId);
    ctx.getChange().setCurrentPatchSet(patchSetInfo);
    ChangeUpdate update = ctx.getUpdate(psId);
    update.setChangeId(change.getKey().get());
    update.setSubjectForCommit("Create change");
    update.setBranch(change.getDest().branch());
    try {
        update.setTopic(change.getTopic());
    } catch (ValidationException ex) {
        throw new BadRequestException(ex.getMessage());
    }
    update.setPsDescription(patchSetDescription);
    update.setPrivate(isPrivate);
    update.setWorkInProgress(workInProgress);
    if (revertOf != null) {
        update.setRevertOf(revertOf.get());
    }
    if (cherryPickOf != null) {
        update.setCherryPickOf(cherryPickOf.getCommaSeparatedChangeAndPatchSetId());
    }
    List<String> newGroups = groups;
    if (newGroups.isEmpty()) {
        newGroups = GroupCollector.getDefaultGroups(commitId);
    }
    patchSet = psUtil.insert(ctx.getRevWalk(), update, psId, commitId, newGroups, pushCert, patchSetDescription);
    /* TODO: fixStatusToMerged is used here because the tests
     * (byStatusClosed() in AbstractQueryChangesTest)
     * insert changes that are already merged,
     * and setStatus may not be used to set the Status to merged
     *
     * is it possible to make the tests use the merge code path,
     * instead of setting the status directly?
     */
    if (change.getStatus() == Change.Status.MERGED) {
        update.fixStatusToMerged(new SubmissionId(change));
    } else {
        update.setStatus(change.getStatus());
    }
    reviewerAdditions = reviewerModifier.prepare(ctx.getNotes(), ctx.getUser(), getReviewerInputs(), true);
    Optional<ReviewerModification> reviewerError = reviewerAdditions.getFailures().stream().findFirst();
    if (reviewerError.isPresent()) {
        throw new UnprocessableEntityException(reviewerError.get().result.error);
    }
    reviewerAdditions.updateChange(ctx, patchSet);
    LabelTypes labelTypes = projectState.getLabelTypes();
    approvalsUtil.addApprovalsForNewPatchSet(update, labelTypes, patchSet, ctx.getUser(), approvals);
    // TODO(dborowitz): Still necessary?
    if (!approvals.isEmpty()) {
        update.putReviewer(ctx.getAccountId(), REVIEWER);
    }
    if (message != null) {
        changeMessage = cmUtil.setChangeMessage(update, message, ChangeMessagesUtil.uploadedPatchSetTag(workInProgress));
    }
    return true;
}
Also used : UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) LabelTypes(com.google.gerrit.entities.LabelTypes) CommitValidationException(com.google.gerrit.server.git.validators.CommitValidationException) ValidationException(com.google.gerrit.server.validators.ValidationException) SubmissionId(com.google.gerrit.entities.SubmissionId) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) ReviewerModification(com.google.gerrit.server.change.ReviewerModifier.ReviewerModification) ChangeUpdate(com.google.gerrit.server.notedb.ChangeUpdate)

Example 8 with LabelTypes

use of com.google.gerrit.entities.LabelTypes in project gerrit by GerritCodeReview.

the class DeleteReviewerOp method updateChange.

@Override
public boolean updateChange(ChangeContext ctx) throws AuthException, ResourceNotFoundException, PermissionBackendException, IOException {
    Account.Id reviewerId = reviewer.id();
    // Check of removing this reviewer (even if there is no vote processed by the loop below) is OK
    removeReviewerControl.checkRemoveReviewer(ctx.getNotes(), ctx.getUser(), reviewerId);
    if (!approvalsUtil.getReviewers(ctx.getNotes()).all().contains(reviewerId)) {
        throw new ResourceNotFoundException(String.format("Reviewer %s doesn't exist in the change, hence can't delete it", reviewer.getName()));
    }
    currChange = ctx.getChange();
    setPatchSet(psUtil.current(ctx.getNotes()));
    LabelTypes labelTypes = projectCache.get(ctx.getProject()).orElseThrow(illegalState(ctx.getProject())).getLabelTypes(ctx.getNotes());
    // removing a reviewer will remove all her votes
    for (LabelType lt : labelTypes.getLabelTypes()) {
        newApprovals.put(lt.getName(), (short) 0);
    }
    String ccOrReviewer = approvalsUtil.getReviewers(ctx.getNotes()).byState(ReviewerStateInternal.CC).contains(reviewerId) ? "cc" : "reviewer";
    StringBuilder msg = new StringBuilder();
    msg.append(String.format("Removed %s %s", ccOrReviewer, AccountTemplateUtil.getAccountTemplate(reviewer.id())));
    StringBuilder removedVotesMsg = new StringBuilder();
    removedVotesMsg.append(" with the following votes:\n\n");
    boolean votesRemoved = false;
    for (PatchSetApproval a : approvals(ctx, reviewerId)) {
        // Check if removing this vote is OK
        removeReviewerControl.checkRemoveReviewer(ctx.getNotes(), ctx.getUser(), a);
        if (a.patchSetId().equals(patchSet.id()) && a.value() != 0) {
            oldApprovals.put(a.label(), a.value());
            removedVotesMsg.append("* ").append(a.label()).append(formatLabelValue(a.value())).append(" by ").append(AccountTemplateUtil.getAccountTemplate(a.accountId())).append("\n");
            votesRemoved = true;
        }
    }
    if (votesRemoved) {
        msg.append(removedVotesMsg);
    } else {
        msg.append(".");
    }
    ChangeUpdate update = ctx.getUpdate(patchSet.id());
    update.removeReviewer(reviewerId);
    mailMessage = cmUtil.setChangeMessage(ctx, msg.toString(), ChangeMessagesUtil.TAG_DELETE_REVIEWER);
    return true;
}
Also used : Account(com.google.gerrit.entities.Account) LabelTypes(com.google.gerrit.entities.LabelTypes) LabelType(com.google.gerrit.entities.LabelType) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) PatchSetApproval(com.google.gerrit.entities.PatchSetApproval) ChangeUpdate(com.google.gerrit.server.notedb.ChangeUpdate)

Example 9 with LabelTypes

use of com.google.gerrit.entities.LabelTypes in project gerrit by GerritCodeReview.

the class ReviewerJson method format.

public ReviewerInfo format(ReviewerInfo out, Account.Id reviewerAccountId, ChangeData cd, Iterable<PatchSetApproval> approvals) throws PermissionBackendException {
    LabelTypes labelTypes = cd.getLabelTypes();
    out.approvals = new TreeMap<>(labelTypes.nameComparator());
    for (PatchSetApproval ca : approvals) {
        Optional<LabelType> at = labelTypes.byLabel(ca.labelId());
        at.ifPresent(lt -> out.approvals.put(lt.getName(), formatValue(ca.value())));
    }
    // Add dummy approvals for all permitted labels for the user even if they
    // do not exist in the DB.
    PatchSet ps = cd.currentPatchSet();
    if (ps != null) {
        PermissionBackend.ForChange perm = permissionBackend.absentUser(reviewerAccountId).change(cd);
        for (SubmitRecord rec : cd.submitRecords(SubmitRuleOptions.defaults())) {
            if (rec.labels == null) {
                continue;
            }
            for (SubmitRecord.Label label : rec.labels) {
                String name = label.label;
                Optional<LabelType> type = labelTypes.byLabel(name);
                if (out.approvals.containsKey(name) || !type.isPresent()) {
                    continue;
                }
                if (perm.test(new LabelPermission(type.get()))) {
                    out.approvals.put(name, formatValue((short) 0));
                }
            }
        }
    }
    if (out.approvals.isEmpty()) {
        out.approvals = null;
    }
    return out;
}
Also used : SubmitRecord(com.google.gerrit.entities.SubmitRecord) LabelTypes(com.google.gerrit.entities.LabelTypes) PermissionBackend(com.google.gerrit.server.permissions.PermissionBackend) LabelType(com.google.gerrit.entities.LabelType) PatchSet(com.google.gerrit.entities.PatchSet) PatchSetApproval(com.google.gerrit.entities.PatchSetApproval) LabelPermission(com.google.gerrit.server.permissions.LabelPermission)

Example 10 with LabelTypes

use of com.google.gerrit.entities.LabelTypes in project gerrit by GerritCodeReview.

the class LabelNormalizer method normalize.

/**
 * Returns copies of approvals normalized to the defined ranges for the label type. Approvals for
 * unknown labels are not included in the output
 *
 * @param notes change notes containing the given approvals.
 * @param approvals list of approvals.
 */
public Result normalize(ChangeNotes notes, Collection<PatchSetApproval> approvals) {
    List<PatchSetApproval> unchanged = Lists.newArrayListWithCapacity(approvals.size());
    List<PatchSetApproval> updated = Lists.newArrayListWithCapacity(approvals.size());
    List<PatchSetApproval> deleted = Lists.newArrayListWithCapacity(approvals.size());
    LabelTypes labelTypes = projectCache.get(notes.getProjectName()).orElseThrow(illegalState(notes.getProjectName())).getLabelTypes(notes);
    for (PatchSetApproval psa : approvals) {
        Change.Id changeId = psa.key().patchSetId().changeId();
        checkArgument(changeId.equals(notes.getChangeId()), "Approval %s does not match change %s", psa.key(), notes.getChange().getKey());
        if (psa.isLegacySubmit()) {
            unchanged.add(psa);
            continue;
        }
        Optional<LabelType> label = labelTypes.byLabel(psa.labelId());
        if (!label.isPresent()) {
            deleted.add(psa);
            continue;
        }
        PatchSetApproval copy = applyTypeFloor(label.get(), psa);
        if (copy.value() != psa.value()) {
            updated.add(copy);
        } else {
            unchanged.add(psa);
        }
    }
    return Result.create(unchanged, updated, deleted);
}
Also used : LabelTypes(com.google.gerrit.entities.LabelTypes) LabelType(com.google.gerrit.entities.LabelType) Change(com.google.gerrit.entities.Change) PatchSetApproval(com.google.gerrit.entities.PatchSetApproval)

Aggregations

LabelTypes (com.google.gerrit.entities.LabelTypes)16 LabelType (com.google.gerrit.entities.LabelType)11 PatchSetApproval (com.google.gerrit.entities.PatchSetApproval)8 Map (java.util.Map)6 Account (com.google.gerrit.entities.Account)5 PatchSet (com.google.gerrit.entities.PatchSet)5 PermissionBackend (com.google.gerrit.server.permissions.PermissionBackend)5 ChangeData (com.google.gerrit.server.query.change.ChangeData)5 HashMap (java.util.HashMap)5 LabelPermission (com.google.gerrit.server.permissions.LabelPermission)4 HashSet (java.util.HashSet)4 LinkedHashMap (java.util.LinkedHashMap)4 ImmutableMap (com.google.common.collect.ImmutableMap)3 Lists (com.google.common.collect.Lists)3 Maps (com.google.common.collect.Maps)3 FluentLogger (com.google.common.flogger.FluentLogger)3 Nullable (com.google.gerrit.common.Nullable)3 Change (com.google.gerrit.entities.Change)3 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)3 UnprocessableEntityException (com.google.gerrit.extensions.restapi.UnprocessableEntityException)3