blob: 9caa9e20f66dc8f8eca2e87c1db04873173b3b46 [file] [log] [blame]
// Copyright (C) 2016 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.googlesource.gerrit.plugins.automerger;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.RevisionResource;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import java.util.Map;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** Implementation behind the "Recreate Automerges" button. */
class AutomergeChangeAction
implements UiAction<RevisionResource>,
RestModifyView<RevisionResource, AutomergeChangeAction.Input> {
private static final Logger log = LoggerFactory.getLogger(AutomergeChangeAction.class);
private Provider<CurrentUser> user;
private ConfigLoader config;
private DownstreamCreator dsCreator;
@Inject
AutomergeChangeAction(
Provider<CurrentUser> user, ConfigLoader config, DownstreamCreator dsCreator) {
this.user = user;
this.config = config;
this.dsCreator = dsCreator;
}
/**
* Gets the input to the button and re-merges downstream based on the input.
*
* @param rev RevisionResource of the change whose page we are clicking the button.
* @param input A map of branch to whether or not the merge should be "-s ours".
* @return HTTP 200 on success.
* @throws IOException
* @throws RestApiException
* @throws ConfigInvalidException
* @throws StorageException
*/
@Override
public Response<Object> apply(RevisionResource rev, Input input)
throws IOException, RestApiException, StorageException, ConfigInvalidException {
Map<String, Boolean> branchMap = input.branchMap;
Change change = rev.getChange();
if (branchMap == null) {
log.debug("Branch map is empty for change {}", change.getKey().get());
return Response.none();
}
String revision = rev.getPatchSet().commitId().name();
MultipleDownstreamMergeInput mdsMergeInput = new MultipleDownstreamMergeInput();
mdsMergeInput.dsBranchMap = branchMap;
mdsMergeInput.changeNumber = change.getId().get();
mdsMergeInput.patchsetNumber = rev.getPatchSet().number();
mdsMergeInput.project = change.getProject().get();
mdsMergeInput.topic = dsCreator.getOrSetTopic(change.getId().get(), change.getTopic());
mdsMergeInput.subject = change.getSubject();
mdsMergeInput.obsoleteRevision = revision;
mdsMergeInput.currentRevision = revision;
log.debug("Multiple downstream merge input: {}", mdsMergeInput.dsBranchMap);
try {
dsCreator.createMergesAndHandleConflicts(mdsMergeInput);
} catch (ConfigInvalidException e) {
throw new ResourceConflictException(
"Automerger configuration file is invalid: " + e.getMessage());
} catch (InvalidQueryParameterException e) {
throw new ResourceConflictException(
"Topic or branch cannot have both braces and quotes: " + e.getMessage());
}
return Response.none();
}
/**
* Description for what the DOM element for the button should look like.
*
* @param resource RevisionResource of the change whose page the button is on.
* @return Description object that contains the right labels, visibility, etc.
*/
@Override
public Description getDescription(RevisionResource resource) {
String project = resource.getProject().get();
String branch = resource.getChange().getDest().shortName();
Description desc = new Description();
desc = desc.setLabel("Recreate automerges").setTitle("Recreate automerges downstream");
try {
if (config.getDownstreamBranches(branch, project).isEmpty()) {
desc = desc.setVisible(false);
} else {
desc = desc.setVisible(user.get() instanceof IdentifiedUser);
}
} catch (RestApiException | IOException | ConfigInvalidException e) {
log.error("Failed to recreate automerges for {} on {}", project, branch);
desc = desc.setVisible(false);
}
return desc;
}
static class Input {
Map<String, Boolean> branchMap;
}
}