use of com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper in project bazel by bazelbuild.
the class AndroidNdkRepositoryFunction method fetch.
@Override
public RepositoryDirectoryValue.Builder fetch(Rule rule, Path outputDirectory, BlazeDirectories directories, Environment env, Map<String, String> markerData) throws InterruptedException, RepositoryFunctionException {
Map<String, String> environ = declareEnvironmentDependencies(markerData, env, PATH_ENV_VAR_AS_LIST);
if (environ == null) {
return null;
}
prepareLocalRepositorySymlinkTree(rule, outputDirectory);
WorkspaceAttributeMapper attributes = WorkspaceAttributeMapper.of(rule);
PathFragment pathFragment;
if (attributes.isAttributeValueExplicitlySpecified("path")) {
pathFragment = getTargetPath(rule, directories.getWorkspace());
} else if (environ.get(PATH_ENV_VAR) != null) {
pathFragment = getAndroidNdkHomeEnvironmentVar(directories.getWorkspace(), environ);
} else {
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), "Either the path attribute of android_ndk_repository or the ANDROID_NDK_HOME " + " environment variable must be set."), Transience.PERSISTENT);
}
Path ndkSymlinkTreeDirectory = outputDirectory.getRelative("ndk");
try {
ndkSymlinkTreeDirectory.createDirectory();
} catch (IOException e) {
throw new RepositoryFunctionException(e, Transience.TRANSIENT);
}
Path ndkHome = directories.getOutputBase().getFileSystem().getPath(pathFragment);
if (!symlinkLocalRepositoryContents(ndkSymlinkTreeDirectory, ndkHome)) {
return null;
}
String ruleName = rule.getName();
// We need to fetch the NDK release info from the actual home to avoid cycle in the
// dependency graph (the path relative to the repository root depends on the
// repository being fetched).
NdkRelease ndkRelease = getNdkRelease(ndkHome, env);
if (env.valuesMissing()) {
return null;
}
String apiLevelString;
if (attributes.isAttributeValueExplicitlySpecified("api_level")) {
try {
apiLevelString = attributes.get("api_level", Type.INTEGER).toString();
} catch (EvalException e) {
throw new RepositoryFunctionException(e, Transience.PERSISTENT);
}
} else {
DirectoryListingValue platformsDirectoryValue = AndroidRepositoryUtils.getDirectoryListing(ndkHome, PLATFORMS_DIR, env);
if (platformsDirectoryValue == null) {
return null;
}
ImmutableSortedSet<Integer> apiLevels = AndroidRepositoryUtils.getApiLevels(platformsDirectoryValue.getDirents());
if (apiLevels.isEmpty()) {
// themselves.
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), "android_ndk_repository requires that at least one Android platform is present in " + "the Android NDK platforms directory. Please ensure that the path attribute " + "or the ANDROID_NDK_HOME environment variable points to a valid NDK."), Transience.PERSISTENT);
}
apiLevelString = apiLevels.first().toString();
}
// NDK minor revisions should be backwards compatible within a major revision, the crosstools
// we generate don't care about the minor revision.
NdkMajorRevision ndkMajorRevision;
if (!ndkRelease.isValid) {
String warningMessage = String.format("The revision of the Android NDK referenced by android_ndk_repository rule '%s' " + "could not be determined (the revision string found is '%s'). Defaulting to " + "revision %s.", ruleName, ndkRelease.rawRelease, AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getKey());
env.getListener().handle(Event.warn(warningMessage));
ndkMajorRevision = AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getValue();
} else if (!AndroidNdkCrosstools.isKnownNDKRevision(ndkRelease)) {
String warningMessage = String.format("The major revision of the Android NDK referenced by android_ndk_repository rule " + "'%s' is %s. The major revisions supported by Bazel are %s. Defaulting to " + "revision %s.", ruleName, ndkRelease.majorRevision, AndroidNdkCrosstools.KNOWN_NDK_MAJOR_REVISIONS.keySet(), AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getKey());
env.getListener().handle(Event.warn(warningMessage));
ndkMajorRevision = AndroidNdkCrosstools.LATEST_KNOWN_REVISION.getValue();
} else {
ndkMajorRevision = AndroidNdkCrosstools.KNOWN_NDK_MAJOR_REVISIONS.get(ndkRelease.majorRevision);
}
ApiLevel apiLevel = ndkMajorRevision.apiLevel(env.getListener(), ruleName, apiLevelString);
ImmutableList.Builder<CrosstoolStlPair> crosstoolsAndStls = ImmutableList.builder();
try {
String hostPlatform = AndroidNdkCrosstools.getHostPlatform(ndkRelease);
NdkPaths ndkPaths = new NdkPaths(ruleName, hostPlatform, apiLevel);
for (StlImpl stlImpl : StlImpls.get(ndkPaths)) {
CrosstoolRelease crosstoolRelease = ndkMajorRevision.crosstoolRelease(ndkPaths, stlImpl, hostPlatform);
crosstoolsAndStls.add(new CrosstoolStlPair(crosstoolRelease, stlImpl));
}
} catch (NdkCrosstoolsException e) {
throw new RepositoryFunctionException(new IOException(e), Transience.PERSISTENT);
}
String buildFile = createBuildFile(ruleName, crosstoolsAndStls.build());
writeBuildFile(outputDirectory, buildFile);
return RepositoryDirectoryValue.builder().setPath(outputDirectory);
}
use of com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper in project bazel by bazelbuild.
the class GitCloner method clone.
public static SkyValue clone(Rule rule, Path outputDirectory, ExtendedEventHandler eventHandler, Map<String, String> clientEnvironment) throws RepositoryFunctionException {
WorkspaceAttributeMapper mapper = WorkspaceAttributeMapper.of(rule);
if (mapper.isAttributeValueExplicitlySpecified("commit") == mapper.isAttributeValueExplicitlySpecified("tag")) {
throw new RepositoryFunctionException(new EvalException(rule.getLocation(), "One of either commit or tag must be defined"), Transience.PERSISTENT);
}
GitRepositoryDescriptor descriptor;
String startingPoint;
try {
if (mapper.isAttributeValueExplicitlySpecified("commit")) {
startingPoint = mapper.get("commit", Type.STRING);
} else {
startingPoint = "tags/" + mapper.get("tag", Type.STRING);
}
descriptor = new GitRepositoryDescriptor(mapper.get("remote", Type.STRING), startingPoint, mapper.get("init_submodules", Type.BOOLEAN), outputDirectory);
} catch (EvalException e) {
throw new RepositoryFunctionException(e, Transience.PERSISTENT);
}
// Setup proxy if remote is http or https
if (descriptor.remote != null && Ascii.toLowerCase(descriptor.remote).startsWith("http")) {
try {
new ProxyHelper(clientEnvironment).createProxyIfNeeded(new URL(descriptor.remote));
} catch (IOException ie) {
throw new RepositoryFunctionException(ie, Transience.TRANSIENT);
}
}
Git git = null;
try {
if (descriptor.directory.exists()) {
if (isUpToDate(descriptor)) {
return new HttpDownloadValue(descriptor.directory);
}
try {
FileSystemUtils.deleteTree(descriptor.directory);
} catch (IOException e) {
throw new RepositoryFunctionException(e, Transience.TRANSIENT);
}
}
git = Git.cloneRepository().setURI(descriptor.remote).setCredentialsProvider(new NetRCCredentialsProvider()).setDirectory(descriptor.directory.getPathFile()).setCloneSubmodules(false).setNoCheckout(true).setProgressMonitor(new GitProgressMonitor(descriptor.remote, "Cloning " + descriptor.remote, eventHandler)).call();
git.checkout().setCreateBranch(true).setName("bazel-checkout").setStartPoint(descriptor.checkout).call();
// the first level.
if (descriptor.initSubmodules && !git.submoduleInit().call().isEmpty()) {
git.submoduleUpdate().setProgressMonitor(new GitProgressMonitor(descriptor.remote, "Cloning submodules for " + descriptor.remote, eventHandler)).call();
}
} catch (InvalidRemoteException e) {
throw new RepositoryFunctionException(new IOException("Invalid Git repository URI: " + e.getMessage()), Transience.PERSISTENT);
} catch (RefNotFoundException | InvalidRefNameException e) {
throw new RepositoryFunctionException(new IOException("Invalid branch, tag, or commit: " + e.getMessage()), Transience.PERSISTENT);
} catch (GitAPIException e) {
// This is a sad attempt to actually get a useful error message out of jGit, which will bury
// the actual (useful) cause of the exception under several throws.
StringBuilder errmsg = new StringBuilder();
errmsg.append(e.getMessage());
Throwable throwable = e;
while (throwable.getCause() != null) {
throwable = throwable.getCause();
errmsg.append(" caused by " + throwable.getMessage());
}
throw new RepositoryFunctionException(new IOException("Error cloning repository: " + errmsg), Transience.PERSISTENT);
} catch (JGitInternalException e) {
// caller of the command can handle them effectively." Thanks, jgit.
throw new RepositoryFunctionException(new IOException(e.getMessage()), Transience.PERSISTENT);
} finally {
if (git != null) {
git.close();
}
}
return new HttpDownloadValue(descriptor.directory);
}
use of com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper in project bazel by bazelbuild.
the class NewHttpArchiveFunction method fetch.
@Nullable
@Override
public RepositoryDirectoryValue.Builder fetch(Rule rule, Path outputDirectory, BlazeDirectories directories, Environment env, Map<String, String> markerData) throws RepositoryFunctionException, InterruptedException {
NewRepositoryBuildFileHandler buildFileHandler = new NewRepositoryBuildFileHandler(directories.getWorkspace());
if (!buildFileHandler.prepareBuildFile(rule, env)) {
return null;
}
try {
FileSystemUtils.createDirectoryAndParents(outputDirectory);
} catch (IOException e) {
throw new RepositoryFunctionException(new IOException("Could not create directory for " + rule.getName() + ": " + e.getMessage()), Transience.TRANSIENT);
}
// Download.
Path downloadedPath = downloader.download(rule, outputDirectory, env.getListener(), clientEnvironment);
// Decompress.
Path decompressed;
WorkspaceAttributeMapper mapper = WorkspaceAttributeMapper.of(rule);
String prefix = null;
if (mapper.isAttributeValueExplicitlySpecified("strip_prefix")) {
try {
prefix = mapper.get("strip_prefix", Type.STRING);
} catch (EvalException e) {
throw new RepositoryFunctionException(e, Transience.PERSISTENT);
}
}
decompressed = DecompressorValue.decompress(DecompressorDescriptor.builder().setTargetKind(rule.getTargetKind()).setTargetName(rule.getName()).setArchivePath(downloadedPath).setRepositoryPath(outputDirectory).setPrefix(prefix).build());
// Finally, write WORKSPACE and BUILD files.
createWorkspaceFile(decompressed, rule.getTargetKind(), rule.getName());
buildFileHandler.finishBuildFile(outputDirectory);
return RepositoryDirectoryValue.builder().setPath(outputDirectory);
}
use of com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper in project bazel by bazelbuild.
the class HttpArchiveFunction method getDescriptor.
protected DecompressorDescriptor getDescriptor(Rule rule, Path downloadPath, Path outputDirectory) throws RepositoryFunctionException {
DecompressorDescriptor.Builder builder = DecompressorDescriptor.builder().setTargetKind(rule.getTargetKind()).setTargetName(rule.getName()).setArchivePath(downloadPath).setRepositoryPath(outputDirectory);
WorkspaceAttributeMapper mapper = WorkspaceAttributeMapper.of(rule);
if (mapper.isAttributeValueExplicitlySpecified("strip_prefix")) {
try {
builder.setPrefix(mapper.get("strip_prefix", Type.STRING));
} catch (EvalException e) {
throw new RepositoryFunctionException(e, Transience.PERSISTENT);
}
}
return builder.build();
}
use of com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper in project bazel by bazelbuild.
the class HttpFileFunction method getDescriptor.
@Override
protected DecompressorDescriptor getDescriptor(Rule rule, Path downloadPath, Path outputDirectory) throws RepositoryFunctionException {
WorkspaceAttributeMapper mapper = WorkspaceAttributeMapper.of(rule);
boolean executable = false;
try {
executable = (mapper.isAttributeValueExplicitlySpecified("executable") && mapper.get("executable", Type.BOOLEAN));
} catch (EvalException e) {
throw new RepositoryFunctionException(e, Transience.PERSISTENT);
}
return DecompressorDescriptor.builder().setDecompressor(FileDecompressor.INSTANCE).setTargetKind(rule.getTargetKind()).setTargetName(rule.getName()).setArchivePath(downloadPath).setRepositoryPath(outputDirectory).setExecutable(executable).build();
}
Aggregations