use of com.google.devtools.build.lib.syntax.BaseFunction in project bazel by bazelbuild.
the class SkylarkRepositoryFunction method fetch.
@Nullable
@Override
public RepositoryDirectoryValue.Builder fetch(Rule rule, Path outputDirectory, BlazeDirectories directories, Environment env, Map<String, String> markerData) throws RepositoryFunctionException, InterruptedException {
BaseFunction function = rule.getRuleClassObject().getConfiguredTargetFunction();
if (declareEnvironmentDependencies(markerData, env, getEnviron(rule)) == null) {
return null;
}
try (Mutability mutability = Mutability.create("skylark repository")) {
com.google.devtools.build.lib.syntax.Environment buildEnv = com.google.devtools.build.lib.syntax.Environment.builder(mutability).setGlobals(rule.getRuleClassObject().getRuleDefinitionEnvironment().getGlobals()).setEventHandler(env.getListener()).build();
SkylarkRepositoryContext skylarkRepositoryContext = new SkylarkRepositoryContext(rule, outputDirectory, env, clientEnvironment, httpDownloader, markerData);
// This has side-effect, we don't care about the output.
// Also we do a lot of stuff in there, maybe blocking operations and we should certainly make
// it possible to return null and not block but it doesn't seem to be easy with Skylark
// structure as it is.
Object retValue = function.call(ImmutableList.<Object>of(skylarkRepositoryContext), ImmutableMap.<String, Object>of(), null, buildEnv);
if (retValue != Runtime.NONE) {
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), "Call to repository rule " + rule.getName() + " returned a non-None value, None expected."), Transience.PERSISTENT);
}
} catch (EvalException e) {
if (e.getCause() instanceof SkylarkRepositoryMissingDependencyException) {
// A dependency is missing, cleanup and returns null
try {
if (outputDirectory.exists()) {
FileSystemUtils.deleteTree(outputDirectory);
}
} catch (IOException e1) {
throw new RepositoryFunctionException(e1, Transience.TRANSIENT);
}
return null;
}
throw new RepositoryFunctionException(e, Transience.TRANSIENT);
}
if (!outputDirectory.isDirectory()) {
throw new RepositoryFunctionException(new IOException(rule + " must create a directory"), Transience.TRANSIENT);
}
if (!outputDirectory.getRelative("WORKSPACE").exists()) {
createWorkspaceFile(outputDirectory, rule.getTargetKind(), rule.getName());
}
return RepositoryDirectoryValue.builder().setPath(outputDirectory);
}
use of com.google.devtools.build.lib.syntax.BaseFunction in project bazel by bazelbuild.
the class PackageFactory method buildPkgEnv.
private void buildPkgEnv(Environment pkgEnv, PackageContext context, RuleFactory ruleFactory) {
// TODO(bazel-team): remove the naked functions that are redundant with the nativeModule,
// or if not possible, at least make them straight copies from the native module variant.
// or better, use a common Environment.Frame for these common bindings
// (that shares a backing ImmutableMap for the bindings?)
pkgEnv.setup("native", nativeModule).setup("distribs", newDistribsFunction.apply(context)).setup("glob", newGlobFunction.apply(context, /*async=*/
false)).setup("mocksubinclude", newMockSubincludeFunction.apply(context)).setup("licenses", newLicensesFunction.apply(context)).setup("exports_files", newExportsFilesFunction.apply()).setup("package_group", newPackageGroupFunction.apply()).setup("package", newPackageFunction(packageArguments)).setup("environment_group", newEnvironmentGroupFunction.apply(context));
for (String ruleClass : ruleFactory.getRuleClassNames()) {
BaseFunction ruleFunction = newRuleFunction(ruleFactory, ruleClass);
pkgEnv.setup(ruleClass, ruleFunction);
}
for (EnvironmentExtension extension : environmentExtensions) {
extension.update(pkgEnv);
}
}
use of com.google.devtools.build.lib.syntax.BaseFunction in project bazel by bazelbuild.
the class PackageFactory method newPackageFunction.
/**
* Returns a function-value implementing "package" in the specified package
* context.
*/
private static BaseFunction newPackageFunction(final ImmutableMap<String, PackageArgument<?>> packageArguments) {
// Flatten the map of argument name of PackageArgument specifier in two co-indexed arrays:
// one for the argument names, to create a FunctionSignature when we create the function,
// one of the PackageArgument specifiers, over which to iterate at every function invocation
// at the same time that we iterate over the function arguments.
final int numArgs = packageArguments.size();
final String[] argumentNames = new String[numArgs];
final PackageArgument<?>[] argumentSpecifiers = new PackageArgument<?>[numArgs];
int i = 0;
for (Map.Entry<String, PackageArgument<?>> entry : packageArguments.entrySet()) {
argumentNames[i] = entry.getKey();
argumentSpecifiers[i++] = entry.getValue();
}
return new BaseFunction("package", FunctionSignature.namedOnly(0, argumentNames)) {
@Override
public Object call(Object[] arguments, FuncallExpression ast, Environment env) throws EvalException {
Package.Builder pkgBuilder = getContext(env, ast).pkgBuilder;
// Validate parameter list
if (pkgBuilder.isPackageFunctionUsed()) {
throw new EvalException(ast.getLocation(), "'package' can only be used once per BUILD file");
}
pkgBuilder.setPackageFunctionUsed();
// Parse params
boolean foundParameter = false;
for (int i = 0; i < numArgs; i++) {
Object value = arguments[i];
if (value != null) {
foundParameter = true;
argumentSpecifiers[i].convertAndProcess(pkgBuilder, ast.getLocation(), value);
}
}
if (!foundParameter) {
throw new EvalException(ast.getLocation(), "at least one argument must be given to the 'package' function");
}
return Runtime.NONE;
}
};
}
use of com.google.devtools.build.lib.syntax.BaseFunction in project bazel by bazelbuild.
the class WorkspaceFactory method addWorkspaceFunctions.
private void addWorkspaceFunctions(Environment workspaceEnv, StoredEventHandler localReporter) {
try {
workspaceEnv.setup("workspace", newWorkspaceFunction.apply(allowOverride, ruleFactory));
for (Map.Entry<String, BaseFunction> function : workspaceFunctions.entrySet()) {
workspaceEnv.update(function.getKey(), function.getValue());
}
if (installDir != null) {
workspaceEnv.update("__embedded_dir__", installDir.getPathString());
}
if (workspaceDir != null) {
workspaceEnv.update("__workspace_dir__", workspaceDir.getPathString());
}
File jreDirectory = new File(System.getProperty("java.home"));
workspaceEnv.update("DEFAULT_SERVER_JAVABASE", jreDirectory.getParentFile().toString());
for (EnvironmentExtension extension : environmentExtensions) {
extension.updateWorkspace(workspaceEnv);
}
workspaceEnv.setupDynamic(PackageFactory.PKG_CONTEXT, new PackageFactory.PackageContext(builder, null, localReporter, AttributeContainer.ATTRIBUTE_CONTAINER_FACTORY));
} catch (EvalException e) {
throw new AssertionError(e);
}
}
use of com.google.devtools.build.lib.syntax.BaseFunction in project bazel by bazelbuild.
the class WorkspaceFactory method createWorkspaceFunctions.
private static ImmutableMap<String, BaseFunction> createWorkspaceFunctions(boolean allowOverride, RuleFactory ruleFactory) {
ImmutableMap.Builder<String, BaseFunction> mapBuilder = ImmutableMap.builder();
mapBuilder.put(BIND, newBindFunction(ruleFactory));
for (String ruleClass : ruleFactory.getRuleClassNames()) {
if (!ruleClass.equals(BIND)) {
BaseFunction ruleFunction = newRuleFunction(ruleFactory, ruleClass, allowOverride);
mapBuilder.put(ruleClass, ruleFunction);
}
}
return mapBuilder.build();
}
Aggregations