blob: f8194c44899a5e43733db65d246a23a820ca55b7 [file] [log] [blame]
/*
* Copyright 2012-present Facebook, Inc.
*
* 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.facebook.buck.cli;
import com.facebook.buck.model.BuildFileTree;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.parser.BuildTargetParser;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.facebook.buck.parser.ParseContext;
import com.facebook.buck.parser.Parser;
import com.facebook.buck.rules.ArtifactCache;
import com.facebook.buck.util.Ansi;
import com.facebook.buck.util.ProjectFilesystem;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;
abstract class AbstractCommandRunner<T extends AbstractCommandOptions> implements CommandRunner {
protected final PrintStream stdOut;
protected final PrintStream stdErr;
protected final Ansi ansi;
protected final Console console;
private final ProjectFilesystem projectFilesystem;
private final ArtifactCache artifactCache;
protected AbstractCommandRunner(ArtifactCache artifactCache) {
this(System.out,
System.err,
new Console(System.out, System.err, new Ansi()),
new ProjectFilesystem(new File(".")),
artifactCache);
}
protected AbstractCommandRunner(PrintStream stdOut,
PrintStream stdErr,
Console console,
ProjectFilesystem projectFilesystem,
ArtifactCache artifactCache) {
this.stdOut = Preconditions.checkNotNull(stdOut);
this.stdErr = Preconditions.checkNotNull(stdErr);
this.console = Preconditions.checkNotNull(console);
this.ansi = Preconditions.checkNotNull(console.getAnsi());
this.projectFilesystem = Preconditions.checkNotNull(projectFilesystem);
this.artifactCache = Preconditions.checkNotNull(artifactCache);
}
abstract T createOptions(BuckConfig buckConfig);
private ParserAndOptions<T> createParser(BuckConfig buckConfig) {
T options = createOptions(buckConfig);
return new ParserAndOptions<T>(options);
}
@Override
public final int runCommand(BuckConfig buckConfig, String[] args) throws IOException {
ParserAndOptions<T> parserAndOptions = createParser(buckConfig);
T options = parserAndOptions.options;
CmdLineParser parser = parserAndOptions.parser;
boolean hasValidOptions = false;
try {
parser.parseArgument(args);
hasValidOptions = true;
} catch (CmdLineException e) {
System.err.println(e.getMessage());
}
if (hasValidOptions && !options.showHelp()) {
return runCommandWithOptions(options);
} else {
printUsage(parser);
return 1;
}
}
public final void printUsage(BuckConfig buckConfig) {
CmdLineParser parser = createParser(buckConfig).parser;
printUsage(parser);
}
public final void printUsage(CmdLineParser parser) {
String intro = getUsageIntro();
if (intro != null) {
System.err.println(intro);
}
parser.printUsage(System.err);
}
/**
* @return the exit code this process should exit with or
* {@link #STATUS_NO_EXIT} if it should not shut down
*/
abstract int runCommandWithOptions(T options) throws IOException;
/**
* @return may be null
*/
abstract String getUsageIntro();
public ProjectFilesystem getProjectFilesystem() {
return projectFilesystem;
}
/**
* @return Creates a parser for this command.
*/
protected Parser createParser() {
// Find all the build files so we know where package boundaries are.
BuildFileTree buildFiles = BuildFileTree.constructBuildFileTree(getProjectFilesystem());
// Create a Parser.
return new Parser(getProjectFilesystem(), getArtifactCache(), buildFiles);
}
/**
* @return A list of {@link BuildTarget}s for the input buildTargetNames.
*/
protected ImmutableList<BuildTarget> getBuildTargets(Parser parser, List<String> buildTargetNames)
throws NoSuchBuildTargetException {
Preconditions.checkNotNull(parser);
Preconditions.checkNotNull(buildTargetNames);
ImmutableList.Builder<BuildTarget> buildTargets = ImmutableList.builder();
// Parse all of the build targets specified by the user.
BuildTargetParser buildTargetParser = parser.getBuildTargetParser();
for (String buildTargetName : buildTargetNames) {
buildTargets.add(buildTargetParser.parse(buildTargetName, ParseContext.fullyQualified()));
}
return buildTargets.build();
}
public ArtifactCache getArtifactCache() {
return artifactCache;
}
private static class ParserAndOptions<T> {
private final T options;
private final CmdLineParser parser;
private ParserAndOptions(T options) {
this.options = options;
this.parser = new CmdLineParserAdditionalOptions(options);
}
}
}