@Nullable
  @Override
  public SkyValue compute(SkyKey skyKey, SkyFunction.Environment env)
      throws RepositoryFunctionException {
    RepositoryName repositoryName = (RepositoryName) skyKey.argument();
    Rule rule = getRule(repositoryName, NewHttpArchiveRule.NAME, env);
    if (rule == null) {
      return null;
    }
    Path outputDirectory = getExternalRepositoryDirectory().getRelative(rule.getName());
    try {
      FileSystemUtils.createDirectoryAndParents(outputDirectory);
    } catch (IOException e) {
      throw new RepositoryFunctionException(
          new IOException(
              "Could not create directory for " + rule.getName() + ": " + e.getMessage()),
          Transience.TRANSIENT);
    }
    FileValue repositoryDirectory = getRepositoryDirectory(outputDirectory, env);
    if (repositoryDirectory == null) {
      return null;
    }

    // Download.
    HttpDownloadValue downloadedFileValue;
    try {
      downloadedFileValue =
          (HttpDownloadValue)
              env.getValueOrThrow(
                  HttpDownloadFunction.key(rule, outputDirectory), IOException.class);
    } catch (IOException e) {
      throw new RepositoryFunctionException(e, Transience.PERSISTENT);
    }
    if (downloadedFileValue == null) {
      return null;
    }

    // Decompress.
    DecompressorValue decompressed;
    try {
      decompressed =
          (DecompressorValue)
              env.getValueOrThrow(
                  DecompressorValue.key(
                      rule.getTargetKind(),
                      rule.getName(),
                      downloadedFileValue.getPath(),
                      outputDirectory),
                  IOException.class);
      if (decompressed == null) {
        return null;
      }
    } catch (IOException e) {
      throw new RepositoryFunctionException(new IOException(e.getMessage()), Transience.TRANSIENT);
    }

    // Add WORKSPACE and BUILD files.
    createWorkspaceFile(decompressed.getDirectory(), rule);
    return symlinkBuildFile(rule, getWorkspace(), repositoryDirectory, env);
  }
  @Override
  public SkyValue fetch(Rule rule, Path outputDirectory, Environment env)
      throws SkyFunctionException {
    prepareLocalRepositorySymlinkTree(rule, outputDirectory);
    PathFragment pathFragment = getTargetPath(rule, getWorkspace());

    if (!symlinkLocalRepositoryContents(
        outputDirectory, getOutputBase().getFileSystem().getPath(pathFragment))) {
      return null;
    }

    AttributeMap attributes = NonconfigurableAttributeMapper.of(rule);
    String buildToolsVersion = attributes.get("build_tools_version", Type.STRING);
    Integer apiLevel = attributes.get("api_level", Type.INTEGER);

    String template = getStringResource("android_sdk_repository_template.txt");

    String buildFile =
        template
            .replaceAll("%repository_name%", rule.getName())
            .replaceAll("%build_tools_version%", buildToolsVersion)
            .replaceAll("%api_level%", apiLevel.toString());

    writeBuildFile(outputDirectory, buildFile);
    return RepositoryDirectoryValue.create(outputDirectory);
  }
 /** Adds the given rule to the stack trace of the exception (if there is one). */
 private static void addRuleToStackTrace(EvalException ex, Rule rule, BaseFunction ruleImpl) {
   if (ex instanceof EvalExceptionWithStackTrace) {
     ((EvalExceptionWithStackTrace) ex)
         .registerPhantomFuncall(
             String.format("%s(name = '%s')", rule.getRuleClass(), rule.getName()),
             rule.getLocation(),
             ruleImpl);
   }
 }
 protected void createDirectory(Path path, Rule rule) throws RepositoryFunctionException {
   try {
     FileSystemUtils.createDirectoryAndParents(path);
   } catch (IOException e) {
     throw new RepositoryFunctionException(
         new IOException(
             "Could not create directory for " + rule.getName() + ": " + e.getMessage()),
         Transience.TRANSIENT);
   }
 }
        @Nullable
        @Override
        public Map<String, Label> apply(Rule rule) {
          ImmutableMap.Builder<String, Label> result = ImmutableMap.builder();
          for (String tool : TOOLS) {
            result.put(
                "android/" + tool,
                Label.parseAbsoluteUnchecked("@" + rule.getName() + "//tools/android:" + tool));
          }

          return result.build();
        }
Example #6
0
 protected SkyValue compute(Environment env, Rule rule) throws RepositoryFunctionException {
   // The output directory is always under .external-repository (to stay out of the way of
   // artifacts from this repository) and uses the rule's name to avoid conflicts with other
   // remote repository rules. For example, suppose you had the following WORKSPACE file:
   //
   // http_archive(name = "png", url = "http://example.com/downloads/png.tar.gz", sha256 = "...")
   //
   // This would download png.tar.gz to .external-repository/png/png.tar.gz.
   Path outputDirectory = getExternalRepositoryDirectory().getRelative(rule.getName());
   FileValue directoryValue = createDirectory(outputDirectory, env);
   if (directoryValue == null) {
     return null;
   }
   AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule);
   URL url = null;
   try {
     url = new URL(mapper.get("url", Type.STRING));
   } catch (MalformedURLException e) {
     throw new RepositoryFunctionException(
         new EvalException(rule.getLocation(), "Error parsing URL: " + e.getMessage()),
         Transience.PERSISTENT);
   }
   String sha256 = mapper.get("sha256", Type.STRING);
   HttpDownloader downloader = new HttpDownloader(url, sha256, outputDirectory);
   try {
     Path archiveFile = downloader.download();
     outputDirectory =
         DecompressorFactory.create(
                 rule.getTargetKind(), rule.getName(), archiveFile, outputDirectory)
             .decompress();
   } catch (IOException e) {
     // Assumes all IO errors transient.
     throw new RepositoryFunctionException(e, Transience.TRANSIENT);
   } catch (DecompressorException e) {
     throw new RepositoryFunctionException(new IOException(e.getMessage()), Transience.TRANSIENT);
   }
   return new RepositoryValue(outputDirectory, directoryValue);
 }
  protected FileValue prepareLocalRepositorySymlinkTree(Rule rule, Environment env)
      throws RepositoryFunctionException {
    Path repositoryDirectory = getExternalRepositoryDirectory().getRelative(rule.getName());
    try {
      FileSystemUtils.deleteTree(repositoryDirectory);
      FileSystemUtils.createDirectoryAndParents(repositoryDirectory);
    } catch (IOException e) {
      throw new RepositoryFunctionException(e, Transience.TRANSIENT);
    }
    FileValue directoryValue = getRepositoryDirectory(repositoryDirectory, env);

    if (directoryValue == null) {
      return null;
    }

    // Add x/WORKSPACE.
    createWorkspaceFile(repositoryDirectory, rule);
    return directoryValue;
  }
 public void testRuleProperties() throws Exception {
   assertEquals(rule.getName(), mapper.getName());
   assertEquals(rule.getLabel(), mapper.getLabel());
 }