use of com.google.devtools.build.lib.syntax.Mutability 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.Mutability in project bazel by bazelbuild.
the class ASTFileLookupFunction method compute.
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException {
Label fileLabel = (Label) skyKey.argument();
PathFragment filePathFragment = fileLabel.toPathFragment();
//
// Determine whether the package designated by fileLabel exists.
//
SkyKey pkgSkyKey = PackageLookupValue.key(fileLabel.getPackageIdentifier());
PackageLookupValue pkgLookupValue = null;
try {
pkgLookupValue = (PackageLookupValue) env.getValueOrThrow(pkgSkyKey, BuildFileNotFoundException.class, InconsistentFilesystemException.class);
} catch (BuildFileNotFoundException e) {
throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(e), Transience.PERSISTENT);
} catch (InconsistentFilesystemException e) {
throw new ASTLookupFunctionException(e, Transience.PERSISTENT);
}
if (pkgLookupValue == null) {
return null;
}
if (!pkgLookupValue.packageExists()) {
return ASTFileLookupValue.forBadPackage(fileLabel, pkgLookupValue.getErrorMsg());
}
//
// Determine whether the file designated by fileLabel exists.
//
Path packageRoot = pkgLookupValue.getRoot();
RootedPath rootedPath = RootedPath.toRootedPath(packageRoot, filePathFragment);
SkyKey fileSkyKey = FileValue.key(rootedPath);
FileValue fileValue = null;
try {
fileValue = (FileValue) env.getValueOrThrow(fileSkyKey, IOException.class, FileSymlinkException.class, InconsistentFilesystemException.class);
} catch (IOException | FileSymlinkException e) {
throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(e), Transience.PERSISTENT);
} catch (InconsistentFilesystemException e) {
throw new ASTLookupFunctionException(e, Transience.PERSISTENT);
}
if (fileValue == null) {
return null;
}
if (!fileValue.isFile()) {
return ASTFileLookupValue.forBadFile(fileLabel);
}
//
// Both the package and the file exist; load the file and parse it as an AST.
//
BuildFileAST ast = null;
Path path = rootedPath.asPath();
try {
long astFileSize = fileValue.getSize();
try (Mutability mutability = Mutability.create("validate")) {
ValidationEnvironment validationEnv = new ValidationEnvironment(ruleClassProvider.createSkylarkRuleClassEnvironment(fileLabel, mutability, env.getListener(), /*astFileContentHashCode=*/
null, /*importMap=*/
null).setupDynamic(Runtime.PKG_NAME, Runtime.NONE).setupDynamic(Runtime.REPOSITORY_NAME, Runtime.NONE));
ast = BuildFileAST.parseSkylarkFile(path, astFileSize, env.getListener());
ast = ast.validate(validationEnv, env.getListener());
}
} catch (IOException e) {
throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(e), Transience.TRANSIENT);
}
return ASTFileLookupValue.withFile(ast);
}
use of com.google.devtools.build.lib.syntax.Mutability in project bazel by bazelbuild.
the class WorkspaceFileFunction method compute.
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws WorkspaceFileFunctionException, InterruptedException {
WorkspaceFileKey key = (WorkspaceFileKey) skyKey.argument();
RootedPath workspaceRoot = key.getPath();
WorkspaceASTValue workspaceASTValue = (WorkspaceASTValue) env.getValue(WorkspaceASTValue.key(workspaceRoot));
if (workspaceASTValue == null) {
return null;
}
Path repoWorkspace = workspaceRoot.getRoot().getRelative(workspaceRoot.getRelativePath());
Package.Builder builder = packageFactory.newExternalPackageBuilder(repoWorkspace, ruleClassProvider.getRunfilesPrefix());
if (workspaceASTValue.getASTs().isEmpty()) {
return new WorkspaceFileValue(// resulting package
builder.build(), // list of imports
ImmutableMap.<String, Extension>of(), // list of symbol bindings
ImmutableMap.<String, Object>of(), // Workspace root
workspaceRoot, // first fragment, idx = 0
0, // last fragment
false);
}
WorkspaceFactory parser;
try (Mutability mutability = Mutability.create("workspace %s", repoWorkspace)) {
parser = new WorkspaceFactory(builder, ruleClassProvider, packageFactory.getEnvironmentExtensions(), mutability, key.getIndex() == 0, directories.getEmbeddedBinariesRoot(), directories.getWorkspace());
if (key.getIndex() > 0) {
WorkspaceFileValue prevValue = (WorkspaceFileValue) env.getValue(WorkspaceFileValue.key(key.getPath(), key.getIndex() - 1));
if (prevValue == null) {
return null;
}
if (prevValue.next() == null) {
return prevValue;
}
parser.setParent(prevValue.getPackage(), prevValue.getImportMap(), prevValue.getBindings());
}
BuildFileAST ast = workspaceASTValue.getASTs().get(key.getIndex());
PackageFunction.SkylarkImportResult importResult = PackageFunction.fetchImportsFromBuildFile(repoWorkspace, rootPackage, ast, env, null);
if (importResult == null) {
return null;
}
parser.execute(ast, importResult.importMap);
} catch (NoSuchPackageException e) {
throw new WorkspaceFileFunctionException(e, Transience.PERSISTENT);
} catch (NameConflictException e) {
throw new WorkspaceFileFunctionException(e, Transience.PERSISTENT);
}
return new WorkspaceFileValue(builder.build(), parser.getImportMap(), parser.getVariableBindings(), workspaceRoot, key.getIndex(), key.getIndex() < workspaceASTValue.getASTs().size() - 1);
}
use of com.google.devtools.build.lib.syntax.Mutability in project bazel by bazelbuild.
the class SkylarkAspectFactory method create.
@Override
public ConfiguredAspect create(ConfiguredTarget base, RuleContext ruleContext, AspectParameters parameters) throws InterruptedException {
try (Mutability mutability = Mutability.create("aspect")) {
AspectDescriptor aspectDescriptor = new AspectDescriptor(skylarkAspect.getAspectClass(), parameters);
SkylarkRuleContext skylarkRuleContext;
try {
skylarkRuleContext = new SkylarkRuleContext(ruleContext, aspectDescriptor);
} catch (EvalException e) {
ruleContext.ruleError(e.getMessage());
return null;
}
Environment env = Environment.builder(mutability).setGlobals(skylarkAspect.getFuncallEnv().getGlobals()).setEventHandler(ruleContext.getAnalysisEnvironment().getEventHandler()).build();
// so we do *not* setLoadingPhase().
Object aspectSkylarkObject;
try {
aspectSkylarkObject = skylarkAspect.getImplementation().call(ImmutableList.<Object>of(base, skylarkRuleContext), ImmutableMap.<String, Object>of(), /*ast=*/
null, env);
if (ruleContext.hasErrors()) {
return null;
} else if (!(aspectSkylarkObject instanceof SkylarkClassObject) && !(aspectSkylarkObject instanceof Iterable)) {
ruleContext.ruleError(String.format("Aspect implementation should return a struct or a list, but got %s", SkylarkType.typeOf(aspectSkylarkObject)));
return null;
}
return createAspect(aspectSkylarkObject, aspectDescriptor, ruleContext);
} catch (EvalException e) {
addAspectToStackTrace(base, e);
ruleContext.ruleError("\n" + e.print());
return null;
}
}
}
use of com.google.devtools.build.lib.syntax.Mutability in project bazel by bazelbuild.
the class SkylarkImportLookupFunction method createExtension.
/**
* Creates the Extension to be imported.
*/
private Extension createExtension(BuildFileAST ast, Label extensionLabel, Map<String, Extension> importMap, Environment env, boolean inWorkspace) throws SkylarkImportFailedException, InterruptedException {
StoredEventHandler eventHandler = new StoredEventHandler();
// TODO(bazel-team): this method overestimates the changes which can affect the
// Skylark RuleClass. For example changes to comments or unused functions can modify the hash.
// A more accurate - however much more complicated - way would be to calculate a hash based on
// the transitive closure of the accessible AST nodes.
PathFragment extensionFile = extensionLabel.toPathFragment();
try (Mutability mutability = Mutability.create("importing %s", extensionFile)) {
com.google.devtools.build.lib.syntax.Environment extensionEnv = ruleClassProvider.createSkylarkRuleClassEnvironment(extensionLabel, mutability, eventHandler, ast.getContentHashCode(), importMap).setupOverride("native", packageFactory.getNativeModule(inWorkspace));
execAndExport(ast, extensionLabel, eventHandler, extensionEnv);
Event.replayEventsOn(env.getListener(), eventHandler.getEvents());
if (eventHandler.hasErrors()) {
throw SkylarkImportFailedException.errors(extensionFile);
}
return new Extension(extensionEnv);
}
}
Aggregations