diff options
Diffstat (limited to 'java/com/google/gerrit/sshd/commands/GarbageCollectionCommand.java')
-rw-r--r-- | java/com/google/gerrit/sshd/commands/GarbageCollectionCommand.java | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/java/com/google/gerrit/sshd/commands/GarbageCollectionCommand.java b/java/com/google/gerrit/sshd/commands/GarbageCollectionCommand.java new file mode 100644 index 0000000000..ecbb3733c1 --- /dev/null +++ b/java/com/google/gerrit/sshd/commands/GarbageCollectionCommand.java @@ -0,0 +1,117 @@ +// 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.sshd.commands; + +import static com.google.gerrit.common.data.GlobalCapability.MAINTAIN_SERVER; +import static com.google.gerrit.common.data.GlobalCapability.RUN_GC; +import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE; +import static java.util.stream.Collectors.toList; + +import com.google.common.collect.Lists; +import com.google.gerrit.common.data.GarbageCollectionResult; +import com.google.gerrit.extensions.annotations.RequiresAnyCapability; +import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.server.git.GarbageCollection; +import com.google.gerrit.server.project.ProjectCache; +import com.google.gerrit.server.project.ProjectState; +import com.google.gerrit.sshd.CommandMetaData; +import com.google.gerrit.sshd.SshCommand; +import com.google.inject.Inject; +import java.util.ArrayList; +import java.util.List; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; + +/** Runs the Git garbage collection. */ +@RequiresAnyCapability({RUN_GC, MAINTAIN_SERVER}) +@CommandMetaData(name = "gc", description = "Run Git garbage collection", runsAt = MASTER_OR_SLAVE) +public class GarbageCollectionCommand extends SshCommand { + + @Option(name = "--all", usage = "runs the Git garbage collection for all projects") + private boolean all; + + @Option(name = "--show-progress", usage = "progress information is shown") + private boolean showProgress; + + @Option(name = "--aggressive", usage = "run aggressive garbage collection") + private boolean aggressive; + + @Argument( + index = 0, + required = false, + multiValued = true, + metaVar = "NAME", + usage = "projects for which the Git garbage collection should be run") + private List<ProjectState> projects = new ArrayList<>(); + + @Inject private ProjectCache projectCache; + + @Inject private GarbageCollection.Factory garbageCollectionFactory; + + @Override + public void run() throws Exception { + verifyCommandLine(); + runGC(); + } + + private void verifyCommandLine() throws UnloggedFailure { + if (!all && projects.isEmpty()) { + throw die("needs projects as command arguments or --all option"); + } + if (all && !projects.isEmpty()) { + throw die("either specify projects as command arguments or use --all option"); + } + } + + private void runGC() { + List<Project.NameKey> projectNames; + if (all) { + projectNames = Lists.newArrayList(projectCache.all()); + } else { + projectNames = projects.stream().map(ProjectState::getNameKey).collect(toList()); + } + + GarbageCollectionResult result = + garbageCollectionFactory + .create() + .run(projectNames, aggressive, showProgress ? stdout : null); + if (result.hasErrors()) { + for (GarbageCollectionResult.Error e : result.getErrors()) { + String msg; + switch (e.getType()) { + case REPOSITORY_NOT_FOUND: + msg = "error: project \"" + e.getProjectName() + "\" not found"; + break; + case GC_ALREADY_SCHEDULED: + msg = + "error: garbage collection for project \"" + + e.getProjectName() + + "\" was already scheduled"; + break; + case GC_FAILED: + msg = "error: garbage collection for project \"" + e.getProjectName() + "\" failed"; + break; + default: + msg = + "error: garbage collection for project \"" + + e.getProjectName() + + "\" failed: " + + e.getType(); + } + stdout.print(msg + "\n"); + } + } + } +} |