Search in sources :

Example 1 with WorkspaceAttributeMapper

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);
}
Also used : RootedPath(com.google.devtools.build.lib.vfs.RootedPath) ToolPath(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.ToolPath) Path(com.google.devtools.build.lib.vfs.Path) NdkRelease(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkRelease) ImmutableList(com.google.common.collect.ImmutableList) StlImpl(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.StlImpl) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) EvalException(com.google.devtools.build.lib.syntax.EvalException) IOException(java.io.IOException) NdkPaths(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkPaths) DirectoryListingValue(com.google.devtools.build.lib.skyframe.DirectoryListingValue) NdkMajorRevision(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkMajorRevision) ApiLevel(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.ApiLevel) CrosstoolRelease(com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease) WorkspaceAttributeMapper(com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper) NdkCrosstoolsException(com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.AndroidNdkCrosstools.NdkCrosstoolsException)

Example 2 with WorkspaceAttributeMapper

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);
}
Also used : ProxyHelper(com.google.devtools.build.lib.bazel.repository.downloader.ProxyHelper) EvalException(com.google.devtools.build.lib.syntax.EvalException) IOException(java.io.IOException) URL(java.net.URL) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) Git(org.eclipse.jgit.api.Git) RefNotFoundException(org.eclipse.jgit.api.errors.RefNotFoundException) InvalidRefNameException(org.eclipse.jgit.api.errors.InvalidRefNameException) InvalidRemoteException(org.eclipse.jgit.api.errors.InvalidRemoteException) JGitInternalException(org.eclipse.jgit.api.errors.JGitInternalException) NetRCCredentialsProvider(org.eclipse.jgit.transport.NetRCCredentialsProvider) WorkspaceAttributeMapper(com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper) RepositoryFunctionException(com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException)

Example 3 with WorkspaceAttributeMapper

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);
}
Also used : Path(com.google.devtools.build.lib.vfs.Path) IOException(java.io.IOException) EvalException(com.google.devtools.build.lib.syntax.EvalException) NewRepositoryBuildFileHandler(com.google.devtools.build.lib.rules.repository.NewRepositoryBuildFileHandler) WorkspaceAttributeMapper(com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper) Nullable(javax.annotation.Nullable)

Example 4 with WorkspaceAttributeMapper

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();
}
Also used : EvalException(com.google.devtools.build.lib.syntax.EvalException) WorkspaceAttributeMapper(com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper)

Example 5 with WorkspaceAttributeMapper

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();
}
Also used : EvalException(com.google.devtools.build.lib.syntax.EvalException) WorkspaceAttributeMapper(com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper)

Aggregations

WorkspaceAttributeMapper (com.google.devtools.build.lib.rules.repository.WorkspaceAttributeMapper)9 EvalException (com.google.devtools.build.lib.syntax.EvalException)9 IOException (java.io.IOException)6 Path (com.google.devtools.build.lib.vfs.Path)4 RepositoryFunctionException (com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException)3 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)3 RootedPath (com.google.devtools.build.lib.vfs.RootedPath)3 Nullable (javax.annotation.Nullable)3 DirectoryListingValue (com.google.devtools.build.lib.skyframe.DirectoryListingValue)2 URL (java.net.URL)2 Predicate (com.google.common.base.Predicate)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 BlazeDirectories (com.google.devtools.build.lib.analysis.BlazeDirectories)1 ProxyHelper (com.google.devtools.build.lib.bazel.repository.downloader.ProxyHelper)1 NdkCrosstoolsException (com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.AndroidNdkCrosstools.NdkCrosstoolsException)1 ApiLevel (com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.ApiLevel)1 NdkMajorRevision (com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkMajorRevision)1 NdkPaths (com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkPaths)1 NdkRelease (com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.NdkRelease)1