use of com.google.devtools.build.lib.cmdline.LabelSyntaxException in project bazel by bazelbuild.
the class CppConfiguration method resolveIncludeDir.
/**
* Resolve the given include directory.
*
* <p>If it starts with %sysroot%/, that part is replaced with the actual sysroot.
*
* <p>If it starts with %workspace%/, that part is replaced with the empty string
* (essentially making it relative to the build directory).
*
* <p>If it starts with %crosstool_top%/ or is any relative path, it is
* interpreted relative to the crosstool top. The use of assumed-crosstool-relative
* specifications is considered deprecated, and all such uses should eventually
* be replaced by "%crosstool_top%/".
*
* <p>If it is of the form %package(@repository//my/package)%/folder, then it is
* interpreted as the named folder in the appropriate package. All of the normal
* package syntax is supported. The /folder part is optional.
*
* <p>It is illegal if it starts with a % and does not match any of the above
* forms to avoid accidentally silently ignoring misspelled prefixes.
*
* <p>If it is absolute, it remains unchanged.
*/
static PathFragment resolveIncludeDir(String s, PathFragment sysroot, PathFragment crosstoolTopPathFragment) throws InvalidConfigurationException {
PathFragment pathPrefix;
String pathString;
int packageEndIndex = s.indexOf(PACKAGE_END);
if (packageEndIndex != -1 && s.startsWith(PACKAGE_START)) {
String packageString = s.substring(PACKAGE_START.length(), packageEndIndex);
try {
pathPrefix = PackageIdentifier.parse(packageString).getSourceRoot();
} catch (LabelSyntaxException e) {
throw new InvalidConfigurationException("The package '" + packageString + "' is not valid");
}
int pathStartIndex = packageEndIndex + PACKAGE_END.length();
if (pathStartIndex + 1 < s.length()) {
if (s.charAt(pathStartIndex) != '/') {
throw new InvalidConfigurationException("The path in the package for '" + s + "' is not valid");
}
pathString = s.substring(pathStartIndex + 1, s.length());
} else {
pathString = "";
}
} else if (s.startsWith(SYSROOT_START)) {
if (sysroot == null) {
throw new InvalidConfigurationException("A %sysroot% prefix is only allowed if the " + "default_sysroot option is set");
}
pathPrefix = sysroot;
pathString = s.substring(SYSROOT_START.length(), s.length());
} else if (s.startsWith(WORKSPACE_START)) {
pathPrefix = PathFragment.EMPTY_FRAGMENT;
pathString = s.substring(WORKSPACE_START.length(), s.length());
} else {
pathPrefix = crosstoolTopPathFragment;
if (s.startsWith(CROSSTOOL_START)) {
pathString = s.substring(CROSSTOOL_START.length(), s.length());
} else if (s.startsWith("%")) {
throw new InvalidConfigurationException("The include path '" + s + "' has an " + "unrecognized %prefix%");
} else {
pathString = s;
}
}
PathFragment path = new PathFragment(pathString);
if (!path.isNormalized()) {
throw new InvalidConfigurationException("The include path '" + s + "' is not normalized.");
}
return pathPrefix.getRelative(path);
}
use of com.google.devtools.build.lib.cmdline.LabelSyntaxException in project bazel by bazelbuild.
the class SkylarkImportLookupFunction method labelsForAbsoluteImports.
/**
* Computes the set of Labels corresponding to a collection of PathFragments representing absolute
* import paths.
*
* @return a map from the computed {@link Label}s to the corresponding {@link PathFragment}s;
* {@code null} if any Skyframe dependencies are unavailable.
* @throws SkylarkImportFailedException
*/
@Nullable
static ImmutableMap<PathFragment, Label> labelsForAbsoluteImports(ImmutableSet<PathFragment> pathsToLookup, Environment env) throws SkylarkImportFailedException, InterruptedException {
// Import PathFragments are absolute, so there is a 1-1 mapping from corresponding Labels.
ImmutableMap.Builder<PathFragment, Label> outputMap = new ImmutableMap.Builder<>();
// The SkyKey here represents the directory containing an import PathFragment, hence there
// can in general be multiple imports per lookup.
Multimap<SkyKey, PathFragment> lookupMap = LinkedHashMultimap.create();
for (PathFragment importPath : pathsToLookup) {
PathFragment relativeImportPath = importPath.toRelative();
PackageIdentifier pkgToLookUp = PackageIdentifier.createInMainRepo(relativeImportPath.getParentDirectory());
lookupMap.put(ContainingPackageLookupValue.key(pkgToLookUp), importPath);
}
// Attempt to find a package for every directory containing an import.
Map<SkyKey, ValueOrException2<BuildFileNotFoundException, InconsistentFilesystemException>> lookupResults = env.getValuesOrThrow(lookupMap.keySet(), BuildFileNotFoundException.class, InconsistentFilesystemException.class);
if (env.valuesMissing()) {
return null;
}
try {
// Process lookup results.
for (Entry<SkyKey, ValueOrException2<BuildFileNotFoundException, InconsistentFilesystemException>> entry : lookupResults.entrySet()) {
ContainingPackageLookupValue lookupValue = (ContainingPackageLookupValue) entry.getValue().get();
if (!lookupValue.hasContainingPackage()) {
// Although multiple imports may be in the same package-less directory, we only
// report an error for the first one.
PackageIdentifier lookupKey = ((PackageIdentifier) entry.getKey().argument());
PathFragment importFile = lookupKey.getPackageFragment();
throw SkylarkImportFailedException.noBuildFile(importFile);
}
PackageIdentifier pkgIdForImport = lookupValue.getContainingPackageName();
PathFragment containingPkgPath = pkgIdForImport.getPackageFragment();
for (PathFragment importPath : lookupMap.get(entry.getKey())) {
PathFragment relativeImportPath = importPath.toRelative();
String targetNameForImport = relativeImportPath.relativeTo(containingPkgPath).toString();
try {
outputMap.put(importPath, Label.create(pkgIdForImport, targetNameForImport));
} catch (LabelSyntaxException e) {
// simple path.
throw new SkylarkImportFailedException(e);
}
}
}
} catch (BuildFileNotFoundException e) {
// Thrown when there are IO errors looking for BUILD files.
throw new SkylarkImportFailedException(e);
} catch (InconsistentFilesystemException e) {
throw new SkylarkImportFailedException(e);
}
return outputMap.build();
}
use of com.google.devtools.build.lib.cmdline.LabelSyntaxException in project bazel by bazelbuild.
the class NewRepositoryBuildFileHandler method getBuildFileValue.
private FileValue getBuildFileValue(Rule rule, Environment env) throws RepositoryFunctionException, InterruptedException {
WorkspaceAttributeMapper mapper = WorkspaceAttributeMapper.of(rule);
String buildFileAttribute;
try {
buildFileAttribute = mapper.get("build_file", Type.STRING);
} catch (EvalException e) {
throw new RepositoryFunctionException(e, Transience.PERSISTENT);
}
RootedPath rootedBuild;
if (LabelValidator.isAbsolute(buildFileAttribute)) {
try {
// Parse a label
Label label = Label.parseAbsolute(buildFileAttribute);
SkyKey pkgSkyKey = PackageLookupValue.key(label.getPackageIdentifier());
PackageLookupValue pkgLookupValue = (PackageLookupValue) env.getValue(pkgSkyKey);
if (pkgLookupValue == null) {
return null;
}
if (!pkgLookupValue.packageExists()) {
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), "Unable to load package for " + buildFileAttribute + ": not found."), Transience.PERSISTENT);
}
// And now for the file
Path packageRoot = pkgLookupValue.getRoot();
rootedBuild = RootedPath.toRootedPath(packageRoot, label.toPathFragment());
} catch (LabelSyntaxException ex) {
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), String.format("In %s the 'build_file' attribute does not specify a valid label: %s", rule, ex.getMessage())), Transience.PERSISTENT);
}
} else {
// TODO(dmarting): deprecate using a path for the build_file attribute.
PathFragment buildFile = new PathFragment(buildFileAttribute);
Path buildFileTarget = workspacePath.getRelative(buildFile);
if (!buildFileTarget.exists()) {
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), String.format("In %s the 'build_file' attribute does not specify an existing file " + "(%s does not exist)", rule, buildFileTarget)), Transience.PERSISTENT);
}
if (buildFile.isAbsolute()) {
rootedBuild = RootedPath.toRootedPath(buildFileTarget.getParentDirectory(), new PathFragment(buildFileTarget.getBaseName()));
} else {
rootedBuild = RootedPath.toRootedPath(workspacePath, buildFile);
}
}
SkyKey buildFileKey = FileValue.key(rootedBuild);
FileValue buildFileValue;
try {
// Note that this dependency is, strictly speaking, not necessary: the symlink could simply
// point to this FileValue and the symlink chasing could be done while loading the package
// but this results in a nicer error message and it's correct as long as RepositoryFunctions
// don't write to things in the file system this FileValue depends on. In theory, the latter
// is possible if the file referenced by build_file is a symlink to somewhere under the
// external/ directory, but if you do that, you are really asking for trouble.
buildFileValue = (FileValue) env.getValueOrThrow(buildFileKey, IOException.class, FileSymlinkException.class, InconsistentFilesystemException.class);
if (buildFileValue == null) {
return null;
}
} catch (IOException | FileSymlinkException | InconsistentFilesystemException e) {
throw new RepositoryFunctionException(new IOException("Cannot lookup " + buildFileAttribute + ": " + e.getMessage()), Transience.TRANSIENT);
}
return buildFileValue;
}
use of com.google.devtools.build.lib.cmdline.LabelSyntaxException in project bazel by bazelbuild.
the class RepositoryFunction method addExternalFilesDependencies.
/**
* For files that are under $OUTPUT_BASE/external, add a dependency on the corresponding rule so
* that if the WORKSPACE file changes, the File/DirectoryStateValue will be re-evaluated.
*
* <p>Note that: - We don't add a dependency on the parent directory at the package root boundary,
* so the only transitive dependencies from files inside the package roots to external files are
* through symlinks. So the upwards transitive closure of external files is small. - The only way
* other than external repositories for external source files to get into the skyframe graph in
* the first place is through symlinks outside the package roots, which we neither want to
* encourage nor optimize for since it is not common. So the set of external files is small.
*/
public static void addExternalFilesDependencies(RootedPath rootedPath, BlazeDirectories directories, Environment env) throws IOException, InterruptedException {
Path externalRepoDir = getExternalRepositoryDirectory(directories);
PathFragment repositoryPath = rootedPath.asPath().relativeTo(externalRepoDir);
if (repositoryPath.segmentCount() == 0) {
// repository path.
return;
}
String repositoryName = repositoryPath.getSegment(0);
try {
// Add a dependency to the repository rule. RepositoryDirectoryValue does add this dependency
// already but we want to catch RepositoryNotFoundException, so invoke #getRule first.
RepositoryFunction.getRule(repositoryName, env);
if (repositoryPath.segmentCount() > 1) {
// For all file under the repository directory, depends on the actual RepositoryDirectory
// function so we get invalidation when the repository is fetched.
// For the repository directory itself, we cannot depends on the RepositoryDirectoryValue
// (cycle).
env.getValue(RepositoryDirectoryValue.key(RepositoryName.create("@" + repositoryName)));
}
} catch (RepositoryFunction.RepositoryNotFoundException ex) {
// of the resolution. Therefore we are safe to ignore that Exception.
return;
} catch (RepositoryFunctionException | LabelSyntaxException ex) {
// This should never happen.
throw new IllegalStateException("Repository " + repositoryName + " cannot be resolved for path " + rootedPath, ex);
}
}
use of com.google.devtools.build.lib.cmdline.LabelSyntaxException in project bazel by bazelbuild.
the class RepositoryLoaderFunction method compute.
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException {
// This cannot be combined with {@link RepositoryDelegatorFunction}. RDF fetches the
// repository and must not have a Skyframe restart after writing it (otherwise the repository
// would be re-downloaded).
RepositoryName nameFromRule = (RepositoryName) skyKey.argument();
SkyKey repositoryKey = RepositoryDirectoryValue.key(nameFromRule);
RepositoryDirectoryValue repository = (RepositoryDirectoryValue) env.getValue(repositoryKey);
if (repository == null) {
return null;
}
SkyKey workspaceKey = WorkspaceFileValue.key(RootedPath.toRootedPath(repository.getPath(), new PathFragment("WORKSPACE")));
WorkspaceFileValue workspacePackage = (WorkspaceFileValue) env.getValue(workspaceKey);
if (workspacePackage == null) {
return null;
}
RepositoryName workspaceName;
try {
String workspaceNameStr = workspacePackage.getPackage().getWorkspaceName();
workspaceName = workspaceNameStr.isEmpty() ? RepositoryName.create("") : RepositoryName.create("@" + workspaceNameStr);
} catch (LabelSyntaxException e) {
throw new IllegalStateException(e);
}
if (!workspaceName.isDefault() && !workspaceName.strippedName().equals(Label.DEFAULT_REPOSITORY_DIRECTORY) && !nameFromRule.equals(workspaceName)) {
Path workspacePath = repository.getPath().getRelative("WORKSPACE");
env.getListener().handle(Event.warn(Location.fromFile(workspacePath), "Workspace name in " + workspacePath + " (" + workspaceName + ") does not match the " + "name given in the repository's definition (" + nameFromRule + "); this will " + "cause a build error in future versions"));
}
return new RepositoryValue(nameFromRule, repository);
}
Aggregations