Later, a submission could need to add extra listeners to the BatchUpdate. Support that directly in BatchUpdate. Change-Id: I4d03b91451aeae0d3fd6e20b7bc99a6f39b1f580
132 lines
5.1 KiB
Java
132 lines
5.1 KiB
Java
// Copyright (C) 2011 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.submit;
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.ImmutableSet;
|
|
import com.google.gerrit.entities.BranchNameKey;
|
|
import com.google.gerrit.entities.Project;
|
|
import com.google.gerrit.exceptions.StorageException;
|
|
import com.google.gerrit.extensions.restapi.RestApiException;
|
|
import com.google.gerrit.server.git.CodeReviewCommit;
|
|
import com.google.gerrit.server.project.NoSuchProjectException;
|
|
import com.google.gerrit.server.submit.MergeOpRepoManager.OpenRepo;
|
|
import com.google.gerrit.server.update.BatchUpdate;
|
|
import com.google.gerrit.server.update.UpdateException;
|
|
import com.google.inject.Inject;
|
|
import com.google.inject.Singleton;
|
|
import java.io.IOException;
|
|
import java.util.LinkedHashSet;
|
|
import java.util.Map;
|
|
import org.eclipse.jgit.transport.ReceiveCommand;
|
|
|
|
public class SubmoduleOp {
|
|
|
|
@Singleton
|
|
public static class Factory {
|
|
private final SubscriptionGraph.Factory subscriptionGraphFactory;
|
|
private final SubmoduleCommits.Factory submoduleCommitsFactory;
|
|
|
|
@Inject
|
|
Factory(
|
|
SubscriptionGraph.Factory subscriptionGraphFactory,
|
|
SubmoduleCommits.Factory submoduleCommitsFactory) {
|
|
this.subscriptionGraphFactory = subscriptionGraphFactory;
|
|
this.submoduleCommitsFactory = submoduleCommitsFactory;
|
|
}
|
|
|
|
public SubmoduleOp create(
|
|
Map<BranchNameKey, ReceiveCommand> updatedBranches, MergeOpRepoManager orm)
|
|
throws SubmoduleConflictException {
|
|
return new SubmoduleOp(
|
|
updatedBranches,
|
|
orm,
|
|
subscriptionGraphFactory.compute(updatedBranches.keySet(), orm),
|
|
submoduleCommitsFactory.create(orm));
|
|
}
|
|
}
|
|
|
|
private final Map<BranchNameKey, ReceiveCommand> updatedBranches;
|
|
private final MergeOpRepoManager orm;
|
|
private final SubscriptionGraph subscriptionGraph;
|
|
private final SubmoduleCommits submoduleCommits;
|
|
private final UpdateOrderCalculator updateOrderCalculator;
|
|
|
|
private SubmoduleOp(
|
|
Map<BranchNameKey, ReceiveCommand> updatedBranches,
|
|
MergeOpRepoManager orm,
|
|
SubscriptionGraph subscriptionGraph,
|
|
SubmoduleCommits submoduleCommits) {
|
|
this.updatedBranches = updatedBranches;
|
|
this.orm = orm;
|
|
this.subscriptionGraph = subscriptionGraph;
|
|
this.submoduleCommits = submoduleCommits;
|
|
this.updateOrderCalculator = new UpdateOrderCalculator(subscriptionGraph);
|
|
}
|
|
|
|
public void updateSuperProjects(boolean dryrun) throws RestApiException {
|
|
ImmutableSet<Project.NameKey> projects = updateOrderCalculator.getProjectsInOrder();
|
|
if (projects == null) {
|
|
return;
|
|
}
|
|
|
|
if (dryrun) {
|
|
// On dryrun, the refs hasn't been updated.
|
|
// force the new tips on submoduleCommits
|
|
forceRefTips(updatedBranches, submoduleCommits);
|
|
}
|
|
|
|
LinkedHashSet<Project.NameKey> superProjects = new LinkedHashSet<>();
|
|
try {
|
|
GitlinkOp.Factory gitlinkOpFactory =
|
|
new GitlinkOp.Factory(submoduleCommits, subscriptionGraph);
|
|
for (Project.NameKey project : projects) {
|
|
// only need superprojects
|
|
if (subscriptionGraph.isAffectedSuperProject(project)) {
|
|
superProjects.add(project);
|
|
// get a new BatchUpdate for the super project
|
|
OpenRepo or = orm.getRepo(project);
|
|
for (BranchNameKey branch : subscriptionGraph.getAffectedSuperBranches(project)) {
|
|
or.getUpdate().addRepoOnlyOp(gitlinkOpFactory.create(branch));
|
|
}
|
|
}
|
|
}
|
|
BatchUpdate.execute(orm.batchUpdates(superProjects), ImmutableList.of(), dryrun);
|
|
} catch (UpdateException | IOException | NoSuchProjectException e) {
|
|
throw new StorageException("Cannot update gitlinks", e);
|
|
}
|
|
}
|
|
|
|
private void forceRefTips(
|
|
Map<BranchNameKey, ReceiveCommand> updatedBranches, SubmoduleCommits submoduleCommits) {
|
|
// This is dryrun, all commands succeeded (no need to filter success).
|
|
for (Map.Entry<BranchNameKey, ReceiveCommand> updateBranch : updatedBranches.entrySet()) {
|
|
try {
|
|
ReceiveCommand command = updateBranch.getValue();
|
|
if (command.getType() == ReceiveCommand.Type.DELETE) {
|
|
continue;
|
|
}
|
|
|
|
BranchNameKey branchNameKey = updateBranch.getKey();
|
|
OpenRepo openRepo = orm.getRepo(branchNameKey.project());
|
|
CodeReviewCommit fakeTip = openRepo.rw.parseCommit(command.getNewId());
|
|
submoduleCommits.addBranchTip(branchNameKey, fakeTip);
|
|
} catch (NoSuchProjectException | IOException e) {
|
|
throw new StorageException("Cannot find branch tip target in dryrun", e);
|
|
}
|
|
}
|
|
}
|
|
}
|