diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ArchiveOverride.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ArchiveOverride.java index 9d7796386336da..dd38b4408f9509 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ArchiveOverride.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ArchiveOverride.java @@ -26,6 +26,7 @@ public static ArchiveOverride create(ImmutableList urls, ImmutableList patches, int patchStrip) { + return new AutoValue_GitOverride(remote, commit, patches, patchStrip); + } + + public abstract String getRemote(); + public abstract String getCommit(); + public abstract ImmutableList getPatches(); + public abstract int getPatchStrip(); + + @Override + public RepoSpec getRepoSpec(String repoName) { + ImmutableMap.Builder attrBuilder = ImmutableMap.builder(); + attrBuilder.put("name", repoName) + .put("remote", getRemote()) + .put("commit", getCommit()) + .put("patches", getPatches()) + .put("patch_args", ImmutableList.of("-p" + getPatchStrip())); + return new RepoSpec(GIT_REPOSITORY_RULE_CLASS, attrBuilder.build()); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java index ca9b2fb3725e2a..78712de6977543 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java @@ -14,6 +14,7 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; +import net.starlark.java.eval.StarlarkInt; public class ModuleFileGlobals implements ModuleFileGlobalsApi { @@ -56,13 +57,16 @@ public void overrideDep(String name, StarlarkOverrideApi override) } @Override - public StarlarkOverrideApi singleVersionOverride(String version, String registry) { - return SingleVersionOverride.create(version, registry); + public StarlarkOverrideApi singleVersionOverride(String version, String registry, + Iterable patches, StarlarkInt patchStrip) throws EvalException { + return SingleVersionOverride.create(version, registry, + ImmutableList.copyOf((Iterable) patches), + patchStrip.toInt("single_version_override.patch_strip")); } @Override public StarlarkOverrideApi archiveOverride(Object urls, String integrity, - String stripPrefix) { + String stripPrefix, Iterable patches, StarlarkInt patchStrip) throws EvalException { ImmutableList.Builder urlList = new ImmutableList.Builder<>(); if (urls instanceof String) { urlList.add((String) urls); @@ -71,8 +75,17 @@ public StarlarkOverrideApi archiveOverride(Object urls, String integrity, urlList.add(urlString); } } - // TODO: add patch file support here as well - return ArchiveOverride.create(urlList.build(), ImmutableList.of(), integrity, stripPrefix, 0); + return ArchiveOverride.create( + urlList.build(), ImmutableList.copyOf((Iterable) patches), integrity, stripPrefix, + patchStrip.toInt("archive_override.patch_strip")); + } + + @Override + public StarlarkOverrideApi gitOverride(String remote, String commit, Iterable patches, + StarlarkInt patchStrip) throws EvalException { + return GitOverride.create( + remote, commit, ImmutableList.copyOf((Iterable) patches), + patchStrip.toInt("git_override.patch_strip")); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunction.java index a41d3915be0781..c5c80eb98a5979 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionFunction.java @@ -59,7 +59,8 @@ public SkyValue compute(SkyKey skyKey, Environment env) collectDeps(ModuleKey.create(discovery.getRootModuleName(), ""), newDepGraph, referenced); ImmutableMap finalDepGraph = ImmutableMap.copyOf(Maps.filterKeys(newDepGraph, referenced::contains)); - return SelectionValue.create(discovery.getRootModuleName(), finalDepGraph); + return SelectionValue.create( + discovery.getRootModuleName(), finalDepGraph, discovery.getOverrides()); } private void collectDeps( diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionValue.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionValue.java index 8a7eb197c4d2ff..87500fb57fd6ad 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionValue.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SelectionValue.java @@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.skyframe.SkyFunctions; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import com.google.devtools.build.lib.starlarkbuildapi.repository.StarlarkOverrideApi; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; @@ -14,12 +15,15 @@ public abstract class SelectionValue implements SkyValue { public static final SkyKey KEY = () -> SkyFunctions.SELECTION; public static SelectionValue create(String rootModuleName, - ImmutableMap depGraph) { - return new AutoValue_SelectionValue(rootModuleName, depGraph); + ImmutableMap depGraph, + ImmutableMap overrides) { + return new AutoValue_SelectionValue(rootModuleName, depGraph, overrides); } public abstract String getRootModuleName(); public abstract ImmutableMap getDepGraph(); + public abstract ImmutableMap getOverrides(); + } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SingleVersionOverride.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SingleVersionOverride.java index 0868752f0ad19e..0721d0bbd5b720 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SingleVersionOverride.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/SingleVersionOverride.java @@ -1,16 +1,22 @@ package com.google.devtools.build.lib.bazel.bzlmod; import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; @AutoValue public abstract class SingleVersionOverride implements RegistryOverride { - public static SingleVersionOverride create(String version, String registry) { - return new AutoValue_SingleVersionOverride(version, registry); + public static SingleVersionOverride create(String version, String registry, + ImmutableList patches, int patchStrip) { + return new AutoValue_SingleVersionOverride(version, registry, patches, patchStrip); } public abstract String getVersion(); @Override public abstract String getRegistry(); + + public abstract ImmutableList getPatches(); + + public abstract int getPatchStrip(); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/repo/RepoSpecsFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/repo/RepoSpecsFunction.java index 6b953ca57d1dc9..1e1282525285e2 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/repo/RepoSpecsFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/repo/RepoSpecsFunction.java @@ -2,6 +2,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.bazel.bzlmod.Module; import com.google.devtools.build.lib.bazel.bzlmod.ModuleFileValue; @@ -9,6 +10,7 @@ import com.google.devtools.build.lib.bazel.bzlmod.NonRegistryOverride; import com.google.devtools.build.lib.bazel.bzlmod.RegistryOverride; import com.google.devtools.build.lib.bazel.bzlmod.SelectionValue; +import com.google.devtools.build.lib.bazel.bzlmod.SingleVersionOverride; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.skyframe.PrecomputedValue; import com.google.devtools.build.lib.starlarkbuildapi.repository.StarlarkOverrideApi; @@ -30,6 +32,7 @@ import javax.annotation.Nullable; public class RepoSpecsFunction implements SkyFunction { + @Nullable @Override public SkyValue compute(SkyKey skyKey, Environment env) @@ -95,6 +98,10 @@ private SkyValue computeForBazelModule(Environment env) } else { repoSpec = module.getRegistry().getRepoSpec(moduleKey, repoName, env.getListener()); } + // We may need to apply an extra set of patches here when the module has a single version + // override with patches. + repoSpec = maybeAppendAdditionalPatches(repoSpec, moduleKey, + selectionValue.getOverrides().get(moduleKey.getName())); repositories.put(repoName, repoSpec); } catch (IOException e) { throw new RepoSpecsFunctionException(e, Transience.PERSISTENT); @@ -103,6 +110,36 @@ private SkyValue computeForBazelModule(Environment env) return new RepoSpecsValue(repositories.build()); } + private RepoSpec maybeAppendAdditionalPatches(RepoSpec repoSpec, ModuleKey moduleKey, + StarlarkOverrideApi override) + throws RepoSpecsFunctionException { + if (!(override instanceof SingleVersionOverride)) { + return repoSpec; + } + SingleVersionOverride singleVersion = (SingleVersionOverride) override; + if (singleVersion.getPatches().isEmpty()) { + return repoSpec; + } + if (!ImmutableList.of("-p" + singleVersion.getPatchStrip()) + .equals(repoSpec.getAttributes().get("patch_args"))) { + // The registry specifies a different patch_strip than the single version override. We + // can only throw an exception here. + throw new RepoSpecsFunctionException(new IOException(String.format( + "Module %s has a single_version_override which specifies a different patch_strip" + + " (%d) than the registry (%s)", + moduleKey.toString(), singleVersion.getPatchStrip(), + repoSpec.getAttributes().get("patch_args"))), Transience.PERSISTENT); + } + // Append the patches from the override. + ImmutableList newPatches = ImmutableList.copyOf(Iterables.concat( + (ImmutableList) repoSpec.getAttributes().get("patches"), + singleVersion.getPatches())); + HashMap newAttrs = new HashMap<>(repoSpec.getAttributes().size()); + newAttrs.putAll(repoSpec.getAttributes()); + newAttrs.put("patches", newPatches); + return new RepoSpec(repoSpec.getRuleClass(), ImmutableMap.copyOf(newAttrs)); + } + @Nullable private SkyValue computeForModuleRule(Environment env) throws SkyFunctionException, InterruptedException { diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/repository/ModuleFileGlobalsApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/repository/ModuleFileGlobalsApi.java index 9f4f5fccb33f54..fe07faa6e6b116 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/repository/ModuleFileGlobalsApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/repository/ModuleFileGlobalsApi.java @@ -21,6 +21,7 @@ import net.starlark.java.annot.StarlarkMethod; import net.starlark.java.eval.Dict; import net.starlark.java.eval.EvalException; +import net.starlark.java.eval.StarlarkInt; /** * A collection of global Starlark build API functions that apply to WORKSPACE files. @@ -48,7 +49,8 @@ public interface ModuleFileGlobalsApi kwargs) throws EvalException, InterruptedException; + void module(String name, String version, Dict kwargs) + throws EvalException, InterruptedException; @StarlarkMethod( name = "bazel_dep", @@ -108,9 +110,21 @@ void overrideDep(String name, StarlarkOverrideApi override) named = true, positional = false, defaultValue = "''"), - // TODO: patch_files, patch_strip + @Param( + name = "patches", + doc = "TODO", + named = true, + positional = false, + defaultValue = "[]"), + @Param( + name = "patch_strip", + doc = "TODO", + named = true, + positional = false, + defaultValue = "0"), }) - StarlarkOverrideApi singleVersionOverride(String version, String registry); + StarlarkOverrideApi singleVersionOverride(String version, String registry, Iterable patches, + StarlarkInt patchStrip) throws EvalException; @StarlarkMethod( name = "archive_override", @@ -137,10 +151,53 @@ void overrideDep(String name, StarlarkOverrideApi override) named = true, positional = false, defaultValue = "''"), - // TODO: patch_files, patch_strip + @Param( + name = "patches", + doc = "TODO", + named = true, + positional = false, + defaultValue = "[]"), + @Param( + name = "patch_strip", + doc = "TODO", + named = true, + positional = false, + defaultValue = "0"), + }) + StarlarkOverrideApi archiveOverride(Object urls, String integrity, String stripPrefix, + Iterable patches, StarlarkInt patchStrip) + throws EvalException, ModuleFileFunctionExceptionT; + + @StarlarkMethod( + name = "git_override", + doc = "TODO", + parameters = { + @Param( + name = "remote", + doc = "TODO", + named = true, + positional = false), + @Param( + name = "commit", + doc = "TODO", + named = true, + positional = false, + defaultValue = "''"), + @Param( + name = "patches", + doc = "TODO", + named = true, + positional = false, + defaultValue = "[]"), + @Param( + name = "patch_strip", + doc = "TODO", + named = true, + positional = false, + defaultValue = "0"), }) - StarlarkOverrideApi archiveOverride(Object urls, String integrity, String stripPrefix) - throws ModuleFileFunctionExceptionT; + StarlarkOverrideApi gitOverride(String remote, String commit, Iterable patches, + StarlarkInt patchStrip) throws EvalException, ModuleFileFunctionExceptionT; @StarlarkMethod( name = "local_path_override",