forked from bazelbuild/bazel
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from meteorcloudy/bzlmod-repo
Fetching repositories from bzlmod generated repo info
- Loading branch information
Showing
24 changed files
with
983 additions
and
11 deletions.
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
src/main/java/com/google/devtools/build/lib/bazel/bzlmod/repo/BUILD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
load("@rules_java//java:defs.bzl", "java_library") | ||
|
||
package( | ||
default_visibility = ["//src:__subpackages__"], | ||
) | ||
|
||
java_library( | ||
name = "repo_rule_value", | ||
srcs = [ | ||
"BzlmodRepoRuleValue.java", | ||
], | ||
deps = [ | ||
"//src/main/java/com/google/devtools/build/lib/concurrent", | ||
"//src/main/java/com/google/devtools/build/lib/packages", | ||
"//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec", | ||
"//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", | ||
"//third_party:guava", | ||
], | ||
) | ||
|
||
java_library( | ||
name = "repo_info_values", | ||
srcs = [ | ||
"BazelModuleRepoInfoValue.java", | ||
"ModuleRuleRepoInfoValue.java", | ||
"RepositoryInfo.java", | ||
], | ||
deps = [ | ||
"//src/main/java/com/google/devtools/build/lib/concurrent", | ||
"//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", | ||
"//third_party:guava", | ||
], | ||
) | ||
|
||
java_library( | ||
name = "repo_info_functions", | ||
srcs = [ | ||
"BazelModuleRepoInfoFunction.java", | ||
"ModuleRuleRepoInfoFunction.java", | ||
"LockFileParser.java", | ||
], | ||
deps = [ | ||
":repo_info_values", | ||
"//src/main/java/com/google/devtools/build/lib/actions:file_metadata", | ||
"//src/main/java/com/google/devtools/build/lib/pkgcache", | ||
"//src/main/java/com/google/devtools/build/lib/skyframe:precomputed_value", | ||
"//src/main/java/com/google/devtools/build/lib/vfs", | ||
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", | ||
"//src/main/java/com/google/devtools/build/skyframe", | ||
"//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", | ||
"//third_party:gson", | ||
"//third_party:guava", | ||
], | ||
) | ||
|
||
java_library( | ||
name = "repo_rule_creator", | ||
srcs = ["BzlmodRepoRuleCreator.java"], | ||
deps = [ | ||
"//src/main/java/com/google/devtools/build/lib/events", | ||
"//src/main/java/com/google/devtools/build/lib/packages", | ||
"//src/main/java/net/starlark/java/eval", | ||
], | ||
) |
72 changes: 72 additions & 0 deletions
72
...ain/java/com/google/devtools/build/lib/bazel/bzlmod/repo/BazelModuleRepoInfoFunction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package com.google.devtools.build.lib.bazel.bzlmod.repo; | ||
|
||
import com.google.common.base.Preconditions; | ||
import com.google.common.collect.ImmutableList; | ||
import com.google.devtools.build.lib.actions.FileValue; | ||
import com.google.devtools.build.lib.pkgcache.PathPackageLocator; | ||
import com.google.devtools.build.lib.skyframe.PrecomputedValue; | ||
import com.google.devtools.build.lib.vfs.FileSystemUtils; | ||
import com.google.devtools.build.lib.vfs.Path; | ||
import com.google.devtools.build.lib.vfs.PathFragment; | ||
import com.google.devtools.build.lib.vfs.Root; | ||
import com.google.devtools.build.lib.vfs.RootedPath; | ||
import com.google.devtools.build.skyframe.SkyFunction; | ||
import com.google.devtools.build.skyframe.SkyFunctionException; | ||
import com.google.devtools.build.skyframe.SkyFunctionException.Transience; | ||
import com.google.devtools.build.skyframe.SkyKey; | ||
import com.google.devtools.build.skyframe.SkyValue; | ||
|
||
import java.io.IOException; | ||
|
||
import javax.annotation.Nullable; | ||
|
||
public class BazelModuleRepoInfoFunction implements SkyFunction { | ||
|
||
@Nullable | ||
@Override | ||
public SkyValue compute(SkyKey skyKey, Environment env) | ||
throws SkyFunctionException, InterruptedException { | ||
Preconditions.checkArgument(skyKey == BazelModuleRepoInfoValue.key()); | ||
PathPackageLocator packageLocator = PrecomputedValue.PATH_PACKAGE_LOCATOR.get(env); | ||
ImmutableList<Root> packagePath = packageLocator.getPathEntries(); | ||
|
||
// In Bazel, there should be only one workspace root. | ||
Root workspaceRoot = packagePath.get(0); | ||
RootedPath lockFile = RootedPath.toRootedPath(workspaceRoot, | ||
PathFragment.create("native_module_repos.json")); | ||
|
||
FileValue fileValue = (FileValue) env.getValue(FileValue.key(lockFile)); | ||
if (env.valuesMissing()) { | ||
return null; | ||
} | ||
|
||
if (!fileValue.exists() || !fileValue.isFile()) { | ||
throw new ResolvedBazelModuleRepositoriesFunctionException( | ||
new IOException("Expect lock file native_module_repos.json to exist at workspace root."), | ||
Transience.TRANSIENT); | ||
} | ||
|
||
Path lockFilePath = lockFile.asPath(); | ||
byte[] bytes; | ||
try { | ||
bytes = FileSystemUtils.readWithKnownFileSize(lockFilePath, lockFilePath.getFileSize()); | ||
} catch (IOException ex) { | ||
throw new ResolvedBazelModuleRepositoriesFunctionException(ex, Transience.TRANSIENT); | ||
} | ||
|
||
return new BazelModuleRepoInfoValue( | ||
LockFileParser.loadRepositoryInfos(new String(bytes))); | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public String extractTag(SkyKey skyKey) { | ||
return null; | ||
} | ||
|
||
private static final class ResolvedBazelModuleRepositoriesFunctionException extends SkyFunctionException { | ||
ResolvedBazelModuleRepositoriesFunctionException(IOException e, Transience transience) { | ||
super(e, transience); | ||
} | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
src/main/java/com/google/devtools/build/lib/bazel/bzlmod/repo/BazelModuleRepoInfoValue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.google.devtools.build.lib.bazel.bzlmod.repo; | ||
|
||
import com.google.common.collect.ImmutableMap; | ||
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; | ||
import com.google.devtools.build.skyframe.SkyFunctionName; | ||
import com.google.devtools.build.skyframe.SkyKey; | ||
import com.google.devtools.build.skyframe.SkyValue; | ||
|
||
// TODO(pcloudy): implement the actual SkyFunction for this | ||
public class BazelModuleRepoInfoValue implements SkyValue { | ||
public static final SkyFunctionName BAZEL_MODULE_REPO_INFO = | ||
SkyFunctionName.createHermetic("BAZEL_MODULE_REPO_INFO"); | ||
|
||
@Immutable | ||
public static class BazelModuleRepoInfoKey implements SkyKey { | ||
private static final BazelModuleRepoInfoKey KEY = new BazelModuleRepoInfoKey(); | ||
|
||
private BazelModuleRepoInfoKey() {} | ||
|
||
@Override | ||
public SkyFunctionName functionName() { | ||
return BAZEL_MODULE_REPO_INFO; | ||
} | ||
} | ||
|
||
public static BazelModuleRepoInfoKey key() { | ||
return BazelModuleRepoInfoKey.KEY; | ||
} | ||
|
||
private final ImmutableMap<String, RepositoryInfo> repositories; | ||
|
||
public BazelModuleRepoInfoValue(ImmutableMap<String, RepositoryInfo> repositories) { | ||
this.repositories = repositories; | ||
} | ||
|
||
public RepositoryInfo getRepository(String repositoryName) { | ||
return repositories.getOrDefault(repositoryName, null); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/com/google/devtools/build/lib/bazel/bzlmod/repo/BzlmodRepoRuleCreator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.google.devtools.build.lib.bazel.bzlmod.repo; | ||
|
||
import com.google.devtools.build.lib.events.EventHandler; | ||
import com.google.devtools.build.lib.packages.Package; | ||
import com.google.devtools.build.lib.packages.Rule; | ||
import com.google.devtools.build.lib.packages.RuleFactory.InvalidRuleException; | ||
|
||
import net.starlark.java.eval.StarlarkSemantics; | ||
|
||
import java.util.Map; | ||
|
||
public interface BzlmodRepoRuleCreator { | ||
Rule createRule(Package.Builder pkg, StarlarkSemantics semantics, Map<String, Object> kwargs, EventHandler handler) | ||
throws InterruptedException, InvalidRuleException; | ||
} |
99 changes: 99 additions & 0 deletions
99
src/main/java/com/google/devtools/build/lib/bazel/bzlmod/repo/BzlmodRepoRuleValue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package com.google.devtools.build.lib.bazel.bzlmod.repo; | ||
|
||
import com.google.common.collect.Interner; | ||
import com.google.devtools.build.lib.concurrent.BlazeInterners; | ||
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; | ||
import com.google.devtools.build.lib.packages.Rule; | ||
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; | ||
import com.google.devtools.build.skyframe.SkyFunctionName; | ||
import com.google.devtools.build.skyframe.SkyKey; | ||
import com.google.devtools.build.skyframe.SkyValue; | ||
|
||
import java.util.Objects; | ||
|
||
public class BzlmodRepoRuleValue implements SkyValue { | ||
public static final SkyFunctionName BZLMOD_REPO_RULE = | ||
SkyFunctionName.createHermetic("BZLMOD_REPO_RULE"); | ||
|
||
private final Rule rule; | ||
|
||
public BzlmodRepoRuleValue(Rule rule) { | ||
this.rule = rule; | ||
} | ||
|
||
public Rule getRule() { | ||
return rule; | ||
} | ||
|
||
public static BzlmodRepoRuleKey key(String repositoryName, boolean forModuleRuleResolution) { | ||
return BzlmodRepoRuleKey.create(repositoryName, forModuleRuleResolution); | ||
} | ||
|
||
/** Represents an unsuccessful repository lookup. */ | ||
public static final class RepoRuleNotFoundValue extends BzlmodRepoRuleValue { | ||
private RepoRuleNotFoundValue() { | ||
super(null); | ||
} | ||
|
||
@Override | ||
public Rule getRule() { | ||
throw new IllegalStateException(); | ||
} | ||
} | ||
|
||
public static final RepoRuleNotFoundValue REPO_RULE_NOT_FOUND_VALUE = new RepoRuleNotFoundValue(); | ||
|
||
/** Argument for the SkyKey to request a BzlmodRepoRuleValue. */ | ||
@Immutable | ||
@AutoCodec | ||
public static class BzlmodRepoRuleKey implements SkyKey { | ||
private static final Interner<BzlmodRepoRuleValue.BzlmodRepoRuleKey> interner = BlazeInterners.newWeakInterner(); | ||
|
||
private final String repositoryName; | ||
private final boolean forModuleRuleResolution; | ||
|
||
private BzlmodRepoRuleKey(String repositoryName, boolean forModuleRuleResolution) { | ||
this.repositoryName = repositoryName; | ||
this.forModuleRuleResolution = forModuleRuleResolution; | ||
} | ||
|
||
@AutoCodec.VisibleForSerialization | ||
@AutoCodec.Instantiator | ||
static BzlmodRepoRuleValue.BzlmodRepoRuleKey create( | ||
String repositoryName, boolean forModuleRuleResolution) { | ||
return interner.intern( | ||
new BzlmodRepoRuleValue.BzlmodRepoRuleKey(repositoryName, forModuleRuleResolution)); | ||
} | ||
|
||
public String getRepositoryName() { | ||
return repositoryName; | ||
} | ||
|
||
public boolean isForModuleRuleResolution() { | ||
return forModuleRuleResolution; | ||
} | ||
|
||
@Override | ||
public SkyFunctionName functionName() { | ||
return BZLMOD_REPO_RULE; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} | ||
if (!(obj instanceof BzlmodRepoRuleValue.BzlmodRepoRuleKey)) { | ||
return false; | ||
} | ||
BzlmodRepoRuleValue.BzlmodRepoRuleKey other = (BzlmodRepoRuleValue.BzlmodRepoRuleKey) obj; | ||
return this.repositoryName.equals(other.repositoryName) | ||
&& this.forModuleRuleResolution == other.forModuleRuleResolution; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(BzlmodRepoRuleKey.class, repositoryName, forModuleRuleResolution); | ||
} | ||
} | ||
} |
75 changes: 75 additions & 0 deletions
75
src/main/java/com/google/devtools/build/lib/bazel/bzlmod/repo/LockFileParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package com.google.devtools.build.lib.bazel.bzlmod.repo; | ||
|
||
import com.google.common.collect.ImmutableList; | ||
import com.google.common.collect.ImmutableMap; | ||
import com.google.devtools.build.lib.bazel.bzlmod.repo.RepositoryInfo.Builder; | ||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
import com.google.gson.JsonParser; | ||
import com.google.gson.JsonPrimitive; | ||
|
||
import java.util.Map.Entry; | ||
|
||
public abstract class LockFileParser { | ||
private static Object convertToJavaObject(JsonElement element) { | ||
if (element.isJsonNull()) { | ||
return null; | ||
} | ||
if (element.isJsonPrimitive()) { | ||
JsonPrimitive value = element.getAsJsonPrimitive(); | ||
if (value.isBoolean()) { | ||
return value.getAsBoolean(); | ||
} else if (value.isString()) { | ||
return value.getAsString(); | ||
} else if (value.isNumber()) { | ||
return value.getAsInt(); | ||
} | ||
} else if (element.isJsonArray()) { | ||
ImmutableList.Builder<Object> builder = ImmutableList.builder(); | ||
for (JsonElement e : element.getAsJsonArray()) { | ||
builder.add(convertToJavaObject(e)); | ||
} | ||
return builder.build(); | ||
} else if (element.isJsonObject()) { | ||
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder(); | ||
for (Entry<String, JsonElement> entry : element.getAsJsonObject().entrySet()) { | ||
builder.put(entry.getKey(), convertToJavaObject(entry.getValue())); | ||
} | ||
return builder.build(); | ||
} | ||
throw new IllegalArgumentException("Wrong element type"); | ||
} | ||
|
||
static ImmutableMap<String, RepositoryInfo> loadRepositoryInfos(String content) { | ||
JsonParser parser = new JsonParser(); | ||
JsonElement json = parser.parse(content); | ||
|
||
ImmutableMap.Builder<String, RepositoryInfo> repositoryInfos = ImmutableMap.builder(); | ||
|
||
for (JsonElement repoElement: json.getAsJsonObject().get("repositories").getAsJsonArray()) { | ||
JsonObject repo = repoElement.getAsJsonObject(); | ||
|
||
ImmutableMap.Builder<String, Object> attributesBuilder = ImmutableMap.builder(); | ||
if (repo.get("rule_class").getAsString().contains("%")) { | ||
attributesBuilder.put("visibility", ImmutableList.of()); | ||
} | ||
for (Entry<String, JsonElement> entry : repo.get("attributes").getAsJsonObject().entrySet()) { | ||
attributesBuilder.put(entry.getKey(), convertToJavaObject(entry.getValue())); | ||
} | ||
|
||
RepositoryInfo.Builder builder = new Builder(); | ||
String name = "@" + repo.get("name").getAsString(); | ||
RepositoryInfo repositoryInfo = builder.setName(name) | ||
.setRuleClass(repo.get("rule_class").getAsString()) | ||
.setAttributes(attributesBuilder.build()) | ||
.setRepoDeps((ImmutableList) convertToJavaObject(repo.get("repo_deps"))) | ||
.setRepoMappings((ImmutableMap<String, String>) convertToJavaObject(repo.get("repo_mappings"))) | ||
.setVendorDir(repo.get("vendor_dir").getAsString()) | ||
.build(); | ||
|
||
repositoryInfos.put(name, repositoryInfo); | ||
} | ||
|
||
return repositoryInfos.build(); | ||
} | ||
} |
Oops, something went wrong.