Ejemplo n.º 1
0
 private ChangeMessage message(Change c, String body) {
   String uuid;
   try {
     uuid = ChangeUtil.messageUUID(db);
   } catch (OrmException e) {
     return null;
   }
   ChangeMessage m =
       new ChangeMessage(
           new ChangeMessage.Key(c.getId(), uuid), null, TimeUtil.nowTs(), c.currentPatchSetId());
   m.setMessage(body);
   return m;
 }
Ejemplo n.º 2
0
  private void abandonOneChange(Change change)
      throws OrmException, NoSuchChangeException, IOException {
    db.changes().beginTransaction(change.getId());

    // TODO(dborowitz): support InternalUser in ChangeUpdate
    ChangeControl control =
        changeControlFactory.controlFor(change, identifiedUserFactory.create(change.getOwner()));
    ChangeUpdate update = updateFactory.create(control);
    try {
      change =
          db.changes()
              .atomicUpdate(
                  change.getId(),
                  new AtomicUpdate<Change>() {
                    @Override
                    public Change update(Change change) {
                      if (change.getStatus().isOpen()) {
                        change.setStatus(Change.Status.ABANDONED);
                        return change;
                      }
                      return null;
                    }
                  });

      if (change != null) {
        ChangeMessage msg =
            new ChangeMessage(
                new ChangeMessage.Key(change.getId(), ChangeUtil.messageUUID(db)),
                null,
                change.getLastUpdatedOn(),
                change.currentPatchSetId());
        msg.setMessage("Project was deleted.");

        // TODO(yyonas): atomic change is not propagated.
        cmUtil.addChangeMessage(db, update, msg);
        db.commit();
        indexer.index(db, change);
      }
    } finally {
      db.rollback();
    }
    update.commit();
  }
Ejemplo n.º 3
0
  private void updateChangeStatus(
      List<ChangeData> submitted, Branch.NameKey destBranch, boolean dryRun, IdentifiedUser caller)
      throws NoSuchChangeException, IntegrationException, ResourceConflictException, OrmException {
    if (!dryRun) {
      logDebug("Updating change status for {} changes", submitted.size());
    } else {
      logDebug("Checking change state for {} changes in a dry run", submitted.size());
    }
    MergeTip mergeTip = mergeTips.get(destBranch);
    for (ChangeData cd : submitted) {
      Change c = cd.change();
      CodeReviewCommit commit = commits.get(c.getId());
      CommitMergeStatus s = commit != null ? commit.getStatusCode() : null;
      if (s == null) {
        // Shouldn't ever happen, but leave the change alone. We'll pick
        // it up on the next pass.
        //
        logDebug(
            "Submitted change {} did not appear in set of new commits"
                + " produced by merge strategy",
            c.getId());
        continue;
      }

      if (!dryRun) {
        try {
          setApproval(cd, caller);
        } catch (IOException e) {
          throw new OrmException(e);
        }
      }

      String txt = s.getMessage();
      logDebug("Status of change {} ({}) on {}: {}", c.getId(), commit.name(), c.getDest(), s);
      // If mergeTip is null merge failed and mergeResultRev will not be read.
      ObjectId mergeResultRev = mergeTip != null ? mergeTip.getMergeResults().get(commit) : null;
      // The change notes must be forcefully reloaded so that the SUBMIT
      // approval that we added earlier is visible
      commit.notes().reload();
      try {
        ChangeMessage msg;
        switch (s) {
          case CLEAN_MERGE:
            if (!dryRun) {
              setMerged(c, message(c, txt + getByAccountName(commit)), mergeResultRev);
            }
            break;

          case CLEAN_REBASE:
          case CLEAN_PICK:
            if (!dryRun) {
              setMerged(
                  c,
                  message(c, txt + " as " + commit.name() + getByAccountName(commit)),
                  mergeResultRev);
            }
            break;

          case ALREADY_MERGED:
            if (!dryRun) {
              setMerged(c, null, mergeResultRev);
            }
            break;

          case PATH_CONFLICT:
          case REBASE_MERGE_CONFLICT:
          case MANUAL_RECURSIVE_MERGE:
          case CANNOT_CHERRY_PICK_ROOT:
          case NOT_FAST_FORWARD:
          case INVALID_PROJECT_CONFIGURATION:
          case INVALID_PROJECT_CONFIGURATION_PLUGIN_VALUE_NOT_PERMITTED:
          case INVALID_PROJECT_CONFIGURATION_PLUGIN_VALUE_NOT_EDITABLE:
          case INVALID_PROJECT_CONFIGURATION_PARENT_PROJECT_NOT_FOUND:
          case INVALID_PROJECT_CONFIGURATION_ROOT_PROJECT_CANNOT_HAVE_PARENT:
          case SETTING_PARENT_PROJECT_ONLY_ALLOWED_BY_ADMIN:
            setNew(commit.notes(), message(c, txt));
            throw new ResourceConflictException(
                "Cannot merge " + commit.name() + "\n" + s.getMessage());

          case MISSING_DEPENDENCY:
            logDebug("Change {} is missing dependency", c.getId());
            throw new IntegrationException("Cannot merge " + commit.name() + "\n" + s.getMessage());

          case REVISION_GONE:
            logDebug("Commit not found for change {}", c.getId());
            msg =
                new ChangeMessage(
                    new ChangeMessage.Key(c.getId(), ChangeUtil.messageUUID(db)),
                    null,
                    TimeUtil.nowTs(),
                    c.currentPatchSetId());
            msg.setMessage("Failed to read commit for this patch set");
            setNew(commit.notes(), msg);
            throw new IntegrationException(msg.getMessage());

          default:
            msg = message(c, "Unspecified merge failure: " + s.name());
            setNew(commit.notes(), msg);
            throw new IntegrationException(msg.getMessage());
        }
      } catch (OrmException | IOException err) {
        logWarn("Error updating change status for " + c.getId(), err);
      }
    }
  }
Ejemplo n.º 4
0
  private void setNew(ChangeNotes notes, final ChangeMessage msg)
      throws NoSuchChangeException, IOException {
    Change c = notes.getChange();

    Change change = null;
    ChangeUpdate update = null;
    try {
      db.changes().beginTransaction(c.getId());
      try {
        change =
            db.changes()
                .atomicUpdate(
                    c.getId(),
                    new AtomicUpdate<Change>() {
                      @Override
                      public Change update(Change c) {
                        if (c.getStatus().isOpen()) {
                          c.setStatus(Change.Status.NEW);
                          ChangeUtil.updated(c);
                        }
                        return c;
                      }
                    });
        ChangeControl control = changeControl(change);

        // TODO(yyonas): atomic change is not propagated.
        update = updateFactory.create(control, c.getLastUpdatedOn());
        if (msg != null) {
          cmUtil.addChangeMessage(db, update, msg);
        }
        db.commit();
      } finally {
        db.rollback();
      }
    } catch (OrmException err) {
      logWarn("Cannot record merge failure message", err);
    }
    if (update != null) {
      update.commit();
    }
    indexer.index(db, change);

    PatchSetApproval submitter = null;
    try {
      submitter = approvalsUtil.getSubmitter(db, notes, notes.getChange().currentPatchSetId());
    } catch (Exception e) {
      logError("Cannot get submitter for change " + notes.getChangeId(), e);
    }
    if (submitter != null) {
      try {
        hooks.doMergeFailedHook(
            c,
            accountCache.get(submitter.getAccountId()).getAccount(),
            db.patchSets().get(c.currentPatchSetId()),
            msg.getMessage(),
            db);
      } catch (OrmException ex) {
        logError("Cannot run hook for merge failed " + c.getId(), ex);
      }
    }
  }