Skip to content

Commit

Permalink
Implement legacy_symbols
Browse files Browse the repository at this point in the history
In the repositories that don't have autoloads we also expose native.legacy_symbols.
Those can be used to fallback to the native symbol, whenever it's still available in Bazel.

Fallback using a top-level symbol doesn't work, because BzlCompileFunction would throw an error when it's mentioned.

legacy_symbols aren't available when autoloads are not enabled.

The feature is intended to be used with bazel_features repository, which can correctly report native symbols on all versions of Bazel.

PiperOrigin-RevId: 673741927
Change-Id: I2334030d70cbb944b92784e32a184841ea238d51
  • Loading branch information
comius authored and copybara-github committed Sep 12, 2024
1 parent be9668d commit 0f6d0d8
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import net.starlark.java.eval.GuardedValue;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkSemantics;

Expand Down Expand Up @@ -232,10 +233,14 @@ public ImmutableMap<String, Object> modifyBuildBzlEnv(
ImmutableMap<String, Object> originalEnv,
ImmutableMap<String, Object> newSymbols) {
if (isWithAutoloads) {
return modifyBuildBzlEnv(originalEnv, /* add= */ newSymbols, /* remove= */ removedSymbols);
return modifyBuildBzlEnv(
originalEnv, /* add= */ newSymbols, /* remove= */ removedSymbols, isWithAutoloads);
} else {
return modifyBuildBzlEnv(
originalEnv, /* add= */ ImmutableMap.of(), /* remove= */ partiallyRemovedSymbols);
originalEnv,
/* add= */ ImmutableMap.of(),
/* remove= */ partiallyRemovedSymbols,
isWithAutoloads);
}
}

Expand All @@ -247,7 +252,8 @@ public ImmutableMap<String, Object> modifyBuildBzlEnv(
private ImmutableMap<String, Object> modifyBuildBzlEnv(
ImmutableMap<String, Object> originalEnv,
ImmutableMap<String, Object> add,
ImmutableList<String> remove) {
ImmutableList<String> remove,
boolean isWithAutoloads) {
Map<String, Object> envBuilder = new LinkedHashMap<>(originalEnv);
Map<String, Object> nativeBindings =
convertNativeStructToMap((StarlarkInfo) envBuilder.remove("native"));
Expand All @@ -266,6 +272,30 @@ private ImmutableMap<String, Object> modifyBuildBzlEnv(
envBuilder.remove(symbol);
}
}

if (!isWithAutoloads) {
// In the repositories that don't have autoloads we also expose native.legacy_symbols.
// Those can be used to fallback to the native symbol, whenever it's still available in Bazel.
// Fallback using a top-level symbol doesn't work, because BzlCompileFunction would throw an
// error when it's mentioned.
// legacy_symbols aren't available when autoloads are not enabled. The feature is intended to
// be use with bazel_features repository, which can correctly report native symbols on all
// versions of Bazel.
ImmutableMap<String, Object> legacySymbols =
envBuilder.entrySet().stream()
.filter(entry -> AUTOLOAD_CONFIG.containsKey(entry.getKey()))
.collect(
toImmutableMap(
e -> e.getKey(),
// Drop GuardedValue - it doesn't work on non-toplevel symbols
e ->
e.getValue() instanceof GuardedValue
? ((GuardedValue) e.getValue()).getObject()
: e.getValue()));
nativeBindings.put(
"legacy_symbols", StructProvider.STRUCT.create(legacySymbols, "no native symbol '%s'"));
}

envBuilder.put(
"native", StructProvider.STRUCT.create(nativeBindings, "no native function or rule '%s'"));
return ImmutableMap.copyOf(envBuilder);
Expand Down Expand Up @@ -485,7 +515,8 @@ private static SymbolRedirect renamedSymbolRedirect(
"rules_sh",
"apple_common",
"bazel_skylib",
"bazel_tools");
"bazel_tools",
"bazel_features");

private static final ImmutableMap<String, SymbolRedirect> AUTOLOAD_CONFIG =
ImmutableMap.<String, SymbolRedirect>builder()
Expand Down
57 changes: 57 additions & 0 deletions src/test/shell/integration/load_removed_symbols_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,26 @@ local_path_override(
EOF
}


function mock_rules_java() {
rules_java_workspace="${TEST_TMPDIR}/rules_java_workspace"
mkdir -p "${rules_java_workspace}/java"
touch "${rules_java_workspace}/java/BUILD"
touch "${rules_java_workspace}/WORKSPACE"
cat > "${rules_java_workspace}/MODULE.bazel" << EOF
module(name = "rules_java")
EOF
cat >> MODULE.bazel << EOF
bazel_dep(
name = "rules_java",
)
local_path_override(
module_name = "rules_java",
path = "${rules_java_workspace}",
)
EOF
}

function disabled_test_removed_rule_loaded() {
setup_module_dot_bazel
mock_rules_android
Expand Down Expand Up @@ -413,5 +433,42 @@ EOF
bazel query --incompatible_autoload_externally=+@rules_python ':py_library' --output=build >&$TEST_log 2>&1 || fail "build failed"
}

function test_legacy_symbols() {
setup_module_dot_bazel
mock_rules_java

rules_java_workspace="${TEST_TMPDIR}/rules_java_workspace"

mkdir -p "${rules_java_workspace}/java/common"
touch "${rules_java_workspace}/java/common/BUILD"
cat > "${rules_java_workspace}/java/common/proguard_spec_info.bzl" << EOF
def _init(specs):
return {"specs": specs}
def _proguard_spec_info():
if hasattr(native, "legacy_symbols"):
if hasattr(native.legacy_symbols, "ProguardSpecProvider"):
print("Native provider")
return native.legacy_symbols.ProguardSpecProvider
print("Starlark provider")
return provider(fields = ["specs"], init = _init)[0]
ProguardSpecInfo = _proguard_spec_info()
EOF

cat > BUILD << EOF
load("@rules_java//java/common:proguard_spec_info.bzl", "ProguardSpecInfo")
EOF

bazel build --incompatible_autoload_externally=+ProguardSpecProvider :all >&$TEST_log 2>&1 || fail "build unexpectedly failed"
expect_log "Native provider"


bazel build --incompatible_autoload_externally=ProguardSpecProvider,-java_lite_proto_library,-java_import :all >&$TEST_log 2>&1 || fail "build unexpectedly failed"
expect_log "Starlark provider"
}




run_suite "load_removed_symbols"

0 comments on commit 0f6d0d8

Please sign in to comment.