diff options
author | Kristina Chodorow <kchodorow@google.com> | 2015-03-18 17:00:21 +0000 |
---|---|---|
committer | Han-Wen Nienhuys <hanwen@google.com> | 2015-03-20 14:26:56 +0000 |
commit | 830af4ca3ad02de3901dbbd790713753668b2b0e (patch) | |
tree | 66aa1122cc4ec7967599bcaf4afff200970e7adc /src/main/java/com | |
parent | d584f6520da8f480bdfdfdac7e7f8160102379ae (diff) |
Add on-the-fly remote repos
Adds a new rule:
new_http_archive(
name = "whatever",
url = "http://www.github.com/google/bazel-tools/my-tools.zip",
sha256 = "...",
build_file = "my/tools/objc.BUILD",
)
This will download & unzip my-tools.zip, put a WORKSPACE file in its root, and
link the provided BUILD file into its root.
--
MOS_MIGRATED_REVID=88941267
Diffstat (limited to 'src/main/java/com')
10 files changed, 402 insertions, 24 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java index 483103f8c3..988afec114 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java @@ -20,9 +20,11 @@ import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.BlazeVersionInfo; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.bazel.repository.HttpArchiveFunction; +import com.google.devtools.build.lib.bazel.repository.HttpDownloadFunction; import com.google.devtools.build.lib.bazel.repository.HttpJarFunction; import com.google.devtools.build.lib.bazel.repository.LocalRepositoryFunction; import com.google.devtools.build.lib.bazel.repository.MavenJarFunction; +import com.google.devtools.build.lib.bazel.repository.NewHttpArchiveFunction; import com.google.devtools.build.lib.bazel.repository.NewLocalRepositoryFunction; import com.google.devtools.build.lib.bazel.repository.RepositoryDelegatorFunction; import com.google.devtools.build.lib.bazel.repository.RepositoryFunction; @@ -30,6 +32,7 @@ import com.google.devtools.build.lib.bazel.rules.workspace.HttpArchiveRule; import com.google.devtools.build.lib.bazel.rules.workspace.HttpJarRule; import com.google.devtools.build.lib.bazel.rules.workspace.LocalRepositoryRule; import com.google.devtools.build.lib.bazel.rules.workspace.MavenJarRule; +import com.google.devtools.build.lib.bazel.rules.workspace.NewHttpArchiveRule; import com.google.devtools.build.lib.bazel.rules.workspace.NewLocalRepositoryRule; import com.google.devtools.build.lib.runtime.BlazeModule; import com.google.devtools.build.lib.skyframe.SkyFunctions; @@ -53,12 +56,14 @@ public class BazelRepositoryModule extends BlazeModule { private final ImmutableMap<String, RepositoryFunction> repositoryHandlers; public BazelRepositoryModule() { - repositoryHandlers = ImmutableMap.of( - LocalRepositoryRule.NAME, new LocalRepositoryFunction(), - HttpArchiveRule.NAME, new HttpArchiveFunction(), - HttpJarRule.NAME, new HttpJarFunction(), - MavenJarRule.NAME, new MavenJarFunction(), - NewLocalRepositoryRule.NAME, new NewLocalRepositoryFunction()); + repositoryHandlers = ImmutableMap.<String, RepositoryFunction>builder() + .put(LocalRepositoryRule.NAME, new LocalRepositoryFunction()) + .put(HttpArchiveRule.NAME, new HttpArchiveFunction()) + .put(HttpJarRule.NAME, new HttpJarFunction()) + .put(MavenJarRule.NAME, new MavenJarFunction()) + .put(NewHttpArchiveRule.NAME, new NewHttpArchiveFunction()) + .put(NewLocalRepositoryRule.NAME, new NewLocalRepositoryFunction()) + .build(); } @Override @@ -95,6 +100,9 @@ public class BazelRepositoryModule extends BlazeModule { // Create the delegator everything flows through. builder.put(SkyFunctions.REPOSITORY, new RepositoryDelegatorFunction(repositoryHandlers)); + + // Helper SkyFunctions. + builder.put(SkyFunctionName.computed(HttpDownloadFunction.NAME), new HttpDownloadFunction()); return builder.build(); } } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorFactory.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorFactory.java index 3660317148..d3001a40ee 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorFactory.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorFactory.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.bazel.repository; import com.google.devtools.build.lib.bazel.rules.workspace.HttpArchiveRule; import com.google.devtools.build.lib.bazel.rules.workspace.HttpJarRule; +import com.google.devtools.build.lib.bazel.rules.workspace.NewHttpArchiveRule; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; @@ -55,7 +56,8 @@ public abstract class DecompressorFactory { } } - if (targetKind.startsWith(HttpArchiveRule.NAME + " ")) { + if (targetKind.startsWith(HttpArchiveRule.NAME + " ") + || targetKind.startsWith(NewHttpArchiveRule.NAME + " ")) { if (baseName.endsWith(".zip") || baseName.endsWith(".jar")) { return new ZipDecompressor(archivePath); } else { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpDownloadFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpDownloadFunction.java new file mode 100644 index 0000000000..c16f5093ea --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/HttpDownloadFunction.java @@ -0,0 +1,131 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.bazel.repository; + +import com.google.devtools.build.lib.bazel.repository.RepositoryFunction.RepositoryFunctionException; +import com.google.devtools.build.lib.packages.AggregatingAttributeMapper; +import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.packages.Type; +import com.google.devtools.build.lib.skyframe.FileValue; +import com.google.devtools.build.lib.skyframe.RepositoryValue; +import com.google.devtools.build.lib.syntax.EvalException; +import com.google.devtools.build.lib.vfs.FileSystemUtils; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.skyframe.SkyFunction; +import com.google.devtools.build.skyframe.SkyFunctionException; +import com.google.devtools.build.skyframe.SkyFunctionName; +import com.google.devtools.build.skyframe.SkyKey; +import com.google.devtools.build.skyframe.SkyValue; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Objects; + +import javax.annotation.Nullable; + +/** + * Downloads an archive file over HTTP. + */ +public class HttpDownloadFunction implements SkyFunction { + public static final String NAME = "HTTP_DOWNLOAD"; + + @Nullable + @Override + public SkyValue compute(SkyKey skyKey, Environment env) throws RepositoryFunctionException { + HttpDescriptor descriptor = (HttpDescriptor) skyKey.argument(); + try { + FileSystemUtils.createDirectoryAndParents(descriptor.outputDirectory); + } catch (IOException e) { + throw new RepositoryFunctionException(e, SkyFunctionException.Transience.TRANSIENT); + } + FileValue repositoryValue = RepositoryFunction.getRepositoryDirectory( + descriptor.outputDirectory, env); + if (repositoryValue == null) { + System.out.println("Returning null"); + return null; + } + + Path archive; + try { + archive = new HttpDownloader(descriptor.url, descriptor.sha256, descriptor.outputDirectory) + .download(); + } catch (IOException e) { + throw new RepositoryFunctionException(new IOException("Error downloading from " + + descriptor.url + " to " + descriptor.outputDirectory + ": " + e.getMessage()), + SkyFunctionException.Transience.TRANSIENT); + } + return new RepositoryValue(archive, repositoryValue); + } + + @Nullable + @Override + public String extractTag(SkyKey skyKey) { + return null; + } + + public static SkyKey key(Rule rule, Path outputDirectory) + throws RepositoryFunction.RepositoryFunctionException { + AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule); + URL url = null; + try { + url = new URL(mapper.get("url", Type.STRING)); + } catch (MalformedURLException e) { + throw new RepositoryFunction.RepositoryFunctionException( + new EvalException(rule.getLocation(), "Error parsing URL: " + e.getMessage()), + SkyFunctionException.Transience.PERSISTENT); + } + String sha256 = mapper.get("sha256", Type.STRING); + return new SkyKey( + SkyFunctionName.computed(NAME), + new HttpDownloadFunction.HttpDescriptor(url, sha256, outputDirectory)); + } + + static final class HttpDescriptor { + private URL url; + private String sha256; + private Path outputDirectory; + + public HttpDescriptor(URL url, String sha256, Path outputDirectory) { + this.url = url; + this.sha256 = sha256; + this.outputDirectory = outputDirectory; + } + + @Override + public String toString() { + return url + " -> " + outputDirectory + " (" + sha256 + ")"; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof HttpDescriptor)) { + return false; + } + HttpDescriptor other = (HttpDescriptor) obj; + return Objects.equals(url, other.url) + && Objects.equals(sha256, other.sha256) + && Objects.equals(outputDirectory, other.outputDirectory); + } + + @Override + public int hashCode() { + return Objects.hash(url, sha256, outputDirectory); + } + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java new file mode 100644 index 0000000000..af9ad22996 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java @@ -0,0 +1,88 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.bazel.repository; + +import com.google.devtools.build.lib.bazel.rules.workspace.NewHttpArchiveRule; +import com.google.devtools.build.lib.packages.ExternalPackage; +import com.google.devtools.build.lib.packages.PackageIdentifier.RepositoryName; +import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.skyframe.RepositoryValue; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.skyframe.SkyFunction; +import com.google.devtools.build.skyframe.SkyFunctionException; +import com.google.devtools.build.skyframe.SkyFunctionName; +import com.google.devtools.build.skyframe.SkyKey; +import com.google.devtools.build.skyframe.SkyValue; + +import java.io.IOException; + +import javax.annotation.Nullable; + +/** + * Downloads an archive from a URL, decompresses it, creates a WORKSPACE file, and adds a BUILD + * file for it. + */ +public class NewHttpArchiveFunction extends HttpArchiveFunction { + + @Override + public SkyFunctionName getSkyFunctionName() { + return SkyFunctionName.computed(NewHttpArchiveRule.NAME); + } + + @Nullable + @Override + public SkyValue compute(SkyKey skyKey, SkyFunction.Environment env) + throws RepositoryFunctionException { + RepositoryName repositoryName = (RepositoryName) skyKey.argument(); + Rule rule = RepositoryFunction.getRule(repositoryName, NewHttpArchiveRule.NAME, env); + if (rule == null) { + return null; + } + + // Download. + Path outputDirectory = getOutputBase().getRelative(ExternalPackage.NAME) + .getRelative(rule.getName()); + RepositoryValue downloadedFileValue; + try { + downloadedFileValue = (RepositoryValue) env.getValueOrThrow( + HttpDownloadFunction.key(rule, outputDirectory), IOException.class); + } catch (IOException e) { + throw new RepositoryFunctionException(e, SkyFunctionException.Transience.PERSISTENT); + } + if (downloadedFileValue == null) { + return null; + } + + // Decompress. + Path decompressedDirectory; + try { + decompressedDirectory = DecompressorFactory.create( + rule.getTargetKind(), rule.getName(), downloadedFileValue.getPath()).decompress(); + } catch (DecompressorFactory.DecompressorException e) { + throw new RepositoryFunctionException( + new IOException(e.getMessage()), SkyFunctionException.Transience.TRANSIENT); + } + + // Add WORKSPACE and BUILD files. + NewLocalRepositoryFunction.createWorkspaceFile(decompressedDirectory, rule); + if (NewLocalRepositoryFunction.createBuildFile( + rule, getWorkspace(), decompressedDirectory, env) == null) { + return null; + } + + return new RepositoryValue( + decompressedDirectory, downloadedFileValue.getRepositoryDirectory()); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewLocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewLocalRepositoryFunction.java index 8f03ac4781..510d36cd60 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewLocalRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewLocalRepositoryFunction.java @@ -78,13 +78,7 @@ public class NewLocalRepositoryFunction extends RepositoryFunction { } // Add x/WORKSPACE. - try { - Path workspaceFile = repositoryDirectory.getRelative("WORKSPACE"); - FileSystemUtils.writeContent(workspaceFile, Charset.forName("UTF-8"), - "# DO NOT EDIT: automatically generated WORKSPACE file for " + rule + "\n"); - } catch (IOException e) { - throw new RepositoryFunctionException(e, Transience.TRANSIENT); - } + createWorkspaceFile(repositoryDirectory, rule); AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule); String path = mapper.get("path", Type.STRING); @@ -112,24 +106,52 @@ public class NewLocalRepositoryFunction extends RepositoryFunction { } // Link x/BUILD to <build_root>/x.BUILD. + if (createBuildFile(rule, getWorkspace(), repositoryDirectory, env) == null) { + return null; + } + + return new RepositoryValue(repositoryDirectory, directoryValue); + } + + public static void createWorkspaceFile(Path repositoryDirectory, Rule rule) + throws RepositoryFunctionException { + try { + Path workspaceFile = repositoryDirectory.getRelative("WORKSPACE"); + FileSystemUtils.writeContent(workspaceFile, Charset.forName("UTF-8"), + "# DO NOT EDIT: automatically generated WORKSPACE file for " + rule + "\n"); + } catch (IOException e) { + throw new RepositoryFunctionException(e, Transience.TRANSIENT); + } + } + + /** + * Symlinks a BUILD file from the local filesystem into the external repository's root. + * @param rule the rule that declares the build_file path. + * @param workspaceDirectory the workspace root for the build. + * @param repositoryDirectory the external repository's root directory. + * @param env the Skyframe environment. + * @return the file value of the symlink created. + * @throws RepositoryFunctionException if the BUILD file specified does not exist or cannot be + * linked. + */ + public static FileValue createBuildFile(Rule rule, Path workspaceDirectory, + Path repositoryDirectory, Environment env) + throws RepositoryFunctionException { + AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule); PathFragment buildFile = new PathFragment(mapper.get("build_file", Type.STRING)); - Path buildFileTarget = getWorkspace().getRelative(buildFile); + Path buildFileTarget = workspaceDirectory.getRelative(buildFile); if (!buildFileTarget.exists()) { throw new RepositoryFunctionException( new EvalException(rule.getLocation(), "In " + rule + " the 'build_file' attribute does not specify an existing file (" - + buildFile + " does not exist)"), + + buildFileTarget + " does not exist)"), Transience.PERSISTENT); } Path buildFilePath = repositoryDirectory.getRelative("BUILD"); - if (createSymbolicLink(buildFilePath, buildFileTarget, env) == null) { - return null; - } - - return new RepositoryValue(repositoryDirectory, directoryValue); + return createSymbolicLink(buildFilePath, buildFileTarget, env); } - private FileValue createSymbolicLink(Path from, Path to, Environment env) + private static FileValue createSymbolicLink(Path from, Path to, Environment env) throws RepositoryFunctionException { try { if (!from.exists()) { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java index 1eaf6a210d..0a43d80d6e 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java @@ -52,6 +52,7 @@ import com.google.devtools.build.lib.bazel.rules.workspace.HttpArchiveRule; import com.google.devtools.build.lib.bazel.rules.workspace.HttpJarRule; import com.google.devtools.build.lib.bazel.rules.workspace.LocalRepositoryRule; import com.google.devtools.build.lib.bazel.rules.workspace.MavenJarRule; +import com.google.devtools.build.lib.bazel.rules.workspace.NewHttpArchiveRule; import com.google.devtools.build.lib.bazel.rules.workspace.NewLocalRepositoryRule; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.PackageGroup; @@ -274,6 +275,7 @@ public class BazelRuleClassProvider { builder.addRuleDefinition(HttpJarRule.class); builder.addRuleDefinition(LocalRepositoryRule.class); builder.addRuleDefinition(MavenJarRule.class); + builder.addRuleDefinition(NewHttpArchiveRule.class); builder.addRuleDefinition(NewLocalRepositoryRule.class); builder.addConfigurationFragment(new BazelConfiguration.Loader()); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/HttpArchiveRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/HttpArchiveRule.java index a2d5a35473..5da1ae9966 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/HttpArchiveRule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/HttpArchiveRule.java @@ -42,7 +42,7 @@ public class HttpArchiveRule implements RuleDefinition { A URL to an archive file containing a Bazel repository. ${SYNOPSIS} - <p>This must be an http URL that ends with .zip. There is no support for authentication or + <p>This must be an HTTP URL that ends with .zip. There is no support for authentication or redirection.</p> <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ .add(attr("url", STRING).mandatory()) diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewHttpArchiveRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewHttpArchiveRule.java new file mode 100644 index 0000000000..131bbac910 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewHttpArchiveRule.java @@ -0,0 +1,121 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.bazel.rules.workspace; + +import static com.google.devtools.build.lib.packages.Attribute.attr; +import static com.google.devtools.build.lib.packages.Type.STRING; + +import com.google.devtools.build.lib.analysis.BlazeRule; +import com.google.devtools.build.lib.analysis.RuleDefinition; +import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; +import com.google.devtools.build.lib.packages.RuleClass; + +/** + * Rule definition for the new_http_archive rule. + */ +@BlazeRule(name = NewHttpArchiveRule.NAME, + type = RuleClass.Builder.RuleClassType.WORKSPACE, + ancestors = { WorkspaceBaseRule.class }, + factoryClass = WorkspaceConfiguredTargetFactory.class) +public class NewHttpArchiveRule implements RuleDefinition { + public static final String NAME = "new_http_archive"; + + @Override + public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) { + return builder + /* <!-- #BLAZE_RULE(new_http_archive).ATTRIBUTE(url) --> + A URL to an archive file containing a Bazel repository. + ${SYNOPSIS} + + <p>This must be an HTTP URL that ends with .zip. There is no support for authentication or + redirection.</p> + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add(attr("url", STRING).mandatory()) + /* <!-- #BLAZE_RULE(new_http_archive).ATTRIBUTE(sha256) --> + The expected SHA-256 hash of the file downloaded. + ${SYNOPSIS} + + <p>This must match the SHA-256 hash of the file downloaded.</p> + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add(attr("sha256", STRING).mandatory()) + /* <!-- #BLAZE_RULE(new_http_archive).ATTRIBUTE(build_file) --> + A file to use as a BUILD file for this directory. + ${SYNOPSIS} + + <p>This path is relative to the build's workspace. The file does not need to be named + BUILD, but can be (something like BUILD.new-repo-name may work well for distinguishing it + from the repository's actual BUILD files.</p> + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add(attr("build_file", STRING).mandatory()) + .setWorkspaceOnly() + .build(); + } +} + +/*<!-- #BLAZE_RULE (NAME = new_http_archive, TYPE = OTHER, FAMILY = General)[GENERIC_RULE] --> + +${ATTRIBUTE_SIGNATURE} + +<p>Downloads a compressed archive file, decompresses it, and creates a Bazel repository by +combining the archive with the provided BUILD file.</p> + +<p>Only Zip-formatted archives with the .zip extension are supported.</p> + +${ATTRIBUTE_DEFINITION} + +<h4 id="new_http_archive_examples">Examples</h4> + +<p>Suppose the current repository contains the source code for a chat program, rooted at the + directory <i>~/chat-app</i>. It needs to depend on an SSL library which is available from + <i>http://example.com/openssl.zip</i>. This .zip file contains the following directory + structure:</p> + +<pre class="code"> +src/ + openssl.cc + openssl.h +</pre> + +<p>In the local repository, the user creates a <i>ssl.BUILD</i> file which contains the following +target definition:</p> + +<pre class="code"> +cc_library( + name = "openssl-lib", + srcs = ["src/openssl.cc"], + hdrs = ["src/openssl.h"], +) +</pre> + +<p>Targets in the <i>~/chat-app</i> repository can depend on this target if the following lines are + added to <i>~/chat-app/WORKSPACE</i>:</p> + +<pre class="code"> +new_http_archive( + name = "my-ssl", + url = "http://example.com/openssl.zip", + sha256 = "03a58ac630e59778f328af4bcc4acb4f80208ed4", + build_file = "ssl.BUILD", +) + +bind( + name = "openssl", + actual = "@my-ssl//:openssl-lib", +) +</pre> + +<p>See <a href="#bind_examples">Bind</a> for how to use bound targets.</p> + +<!-- #END_BLAZE_RULE -->*/ diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewLocalRepositoryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewLocalRepositoryRule.java index 96438fed8d..f8f8b85baf 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewLocalRepositoryRule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewLocalRepositoryRule.java @@ -48,7 +48,7 @@ public class NewLocalRepositoryRule implements RuleDefinition { A file to use as a BUILD file for this directory. ${SYNOPSIS} - <p>This path must be relative to the build's workspace. The file does not need to be named + <p>This path is relative to the build's workspace. The file does not need to be named BUILD, but can be (something like BUILD.new-repo-name may work well for distinguishing it from the repository's actual BUILD files.</p> <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryValue.java index 3183953e77..8272e6726a 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryValue.java @@ -47,6 +47,10 @@ public class RepositoryValue implements SkyValue { return path; } + public FileValue getRepositoryDirectory() { + return details; + } + @Override public boolean equals(Object other) { if (this == other) { |