/*
* Copyright 2016-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.rules.args;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.MacroException;
import com.facebook.buck.model.MacroMatchResult;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.CellPathResolver;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SourcePathRuleFinder;
import com.facebook.buck.rules.Tool;
import com.facebook.buck.rules.macros.MacroHandler;
import com.facebook.buck.rules.macros.WorkerMacroExpander;
import com.facebook.buck.shell.WorkerTool;
import com.facebook.buck.util.HumanReadableException;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.hash.HashCode;
import java.nio.file.Path;
import java.util.Optional;
public class WorkerMacroArg extends MacroArg {
private final WorkerTool workerTool;
private final ImmutableList<String> startupCommand;
private final ImmutableMap<String, String> startupEnvironment;
private final BuildTarget buildTarget;
public WorkerMacroArg(
MacroHandler macroHandler,
BuildTarget target,
CellPathResolver cellNames,
BuildRuleResolver resolver,
String unexpanded)
throws MacroException {
super(macroHandler, target, cellNames, resolver, unexpanded);
for (MacroMatchResult matchResult : macroHandler.getMacroMatchResults(unexpanded)) {
if (macroHandler.getExpander(matchResult.getMacroType()) instanceof WorkerMacroExpander
&& matchResult.getStartIndex() != 0) {
throw new MacroException(
String.format("the worker macro in \"%s\" must be at the beginning", unexpanded));
}
}
// extract the BuildTargets referenced in any macros
ImmutableList.Builder<BuildTarget> targetsBuilder = new ImmutableList.Builder<>();
macroHandler.extractParseTimeDeps(
target, cellNames, unexpanded, targetsBuilder, new ImmutableSet.Builder<>());
ImmutableList<BuildTarget> targets = targetsBuilder.build();
if (targets.isEmpty()) {
throw new MacroException(
String.format(
"Unable to extract any build targets for the macros " + "used in \"%s\" of target %s",
unexpanded, target));
}
this.buildTarget = targets.get(0);
BuildRule workerTool = resolver.getRule(buildTarget);
if (!(workerTool instanceof WorkerTool)) {
throw new MacroException(
String.format(
"%s used in worker macro, \"%s\", of target %s does "
+ "not correspond to a worker_tool",
buildTarget, unexpanded, target));
}
this.workerTool = (WorkerTool) workerTool;
SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(resolver));
Tool exe = this.workerTool.getTool();
startupCommand = exe.getCommandPrefix(pathResolver);
startupEnvironment = exe.getEnvironment(pathResolver);
}
public ImmutableList<String> getStartupCommand() {
return startupCommand;
}
public ImmutableMap<String, String> getEnvironment() {
return startupEnvironment;
}
public Path getTempDir() {
return workerTool.getTempDir();
}
public String getStartupArgs(SourcePathResolver pathResolver) {
return workerTool.getArgs(pathResolver);
}
public Optional<String> getPersistentWorkerKey() {
if (workerTool.isPersistent()) {
return Optional.of(buildTarget.getCellPath().toString() + buildTarget.toString());
} else {
return Optional.empty();
}
}
public HashCode getWorkerHash() {
return workerTool.getInstanceKey();
}
public int getMaxWorkers() {
return workerTool.getMaxWorkers();
}
public String getJobArgs() {
try {
return expander.expand(target, cellNames, resolver, unexpanded).trim();
} catch (MacroException e) {
throw new HumanReadableException(e, "%s: %s", target, e.getMessage());
}
}
}