@@ -2531,4 +2531,193 @@ EOF
25312531 expect_log " foo.txt"
25322532}
25332533
2534+ function test_unused_deps() {
2535+ if [[ -n " ${RULES_JAVA_OVERRIDE_PATH:- } " ]]; then
2536+ cat >> MODULE.bazel << EOF
2537+ local_path_override(
2538+ module_name = "rules_java",
2539+ path = "${RULES_JAVA_OVERRIDE_PATH} ",
2540+ )
2541+ EOF
2542+ fi
2543+
2544+ # Check if rules_java has the toolchain-driven unused_deps support
2545+ # We check this by querying the attributes of java_package_configuration
2546+ # or attempting to build a package configuration target with 'unused_deps'.
2547+ # If rules_java does not have it, we skip the test.
2548+
2549+ mkdir -p pkg
2550+ cat > pkg/BUILD << EOF
2551+ load("@rules_java//java:defs.bzl", "java_package_configuration")
2552+ java_package_configuration(
2553+ name = "test_config_query",
2554+ package_specs = [":spec_query"],
2555+ unused_deps = "error",
2556+ )
2557+ package_group(
2558+ name = "spec_query",
2559+ packages = ["//pkg/..."],
2560+ )
2561+ EOF
2562+
2563+ if ! bazel query //pkg:test_config_query > /dev/null 2>&1 ; then
2564+ echo " Skipping test_unused_deps: rules_java does not support unused_deps configuration yet"
2565+ return 0
2566+ fi
2567+
2568+ # Write the common toolchain definition for main repo targets
2569+ cat << 'EOF ' > pkg/BUILD
2570+ load("@rules_java//toolchains:default_java_toolchain.bzl", "default_java_toolchain")
2571+ load("@rules_java//java:defs.bzl", "java_package_configuration")
2572+
2573+ package_group(
2574+ name = "my_package_spec",
2575+ packages = ["//pkg/..."],
2576+ )
2577+
2578+ java_package_configuration(
2579+ name = "unused_deps_error_config",
2580+ package_specs = [":my_package_spec"],
2581+ unused_deps = "error",
2582+ )
2583+
2584+ default_java_toolchain(
2585+ name = "java_toolchain",
2586+ package_configuration = [":unused_deps_error_config"],
2587+ )
2588+ EOF
2589+
2590+ # -------------------------------------------------------------
2591+ # Scenario 1: Simple Unused (Error)
2592+ # -------------------------------------------------------------
2593+ cat << 'EOF ' >> pkg/BUILD
2594+ load("@rules_java//java:java_library.bzl", "java_library")
2595+ java_library(name = "simple_unused", srcs = ["SimpleUnused.java"], deps = [":b"])
2596+ java_library(name = "b", srcs = ["B.java"])
2597+ EOF
2598+ echo " public class SimpleUnused {}" > pkg/SimpleUnused.java
2599+ echo " public class B {}" > pkg/B.java
2600+
2601+ bazel build //pkg:simple_unused \
2602+ --extra_toolchains=//pkg:java_toolchain_definition \
2603+ >& $TEST_log && fail " build succeeded, but expected it to fail due to unused dependency (Simple Unused)"
2604+
2605+ expect_log " Target '//pkg:b' is declared as a direct dependency of '//pkg:simple_unused' but is unused"
2606+
2607+ # -------------------------------------------------------------
2608+ # Scenario 2: Simple Used (Success)
2609+ # -------------------------------------------------------------
2610+ echo " public class SimpleUnused { B b; }" > pkg/SimpleUnused.java
2611+ bazel build //pkg:simple_unused \
2612+ --extra_toolchains=//pkg:java_toolchain_definition \
2613+ >& $TEST_log || fail " build failed, but expected Simple Used to succeed"
2614+
2615+ # -------------------------------------------------------------
2616+ # Scenario 3: Exported Only (Error)
2617+ # -------------------------------------------------------------
2618+ cat << 'EOF ' >> pkg/BUILD
2619+ java_library(name = "exported_only", srcs = ["ExportedOnly.java"], deps = [":exports_c"])
2620+ java_library(name = "exports_c", exports = [":c"])
2621+ java_library(name = "c", srcs = ["C.java"])
2622+ EOF
2623+ echo " public class ExportedOnly { C c; }" > pkg/ExportedOnly.java
2624+ echo " public class C {}" > pkg/C.java
2625+
2626+ bazel build //pkg:exported_only \
2627+ --extra_toolchains=//pkg:java_toolchain_definition \
2628+ >& $TEST_log && fail " build succeeded, but expected it to fail due to unused dependency (Exported Only)"
2629+
2630+ expect_log " Target '//pkg:exports_c' is declared as a direct dependency of '//pkg:exported_only' but is unused"
2631+
2632+ # -------------------------------------------------------------
2633+ # Scenario 4: Exported & Direct Used (Success)
2634+ # -------------------------------------------------------------
2635+ # Define exports_c_with_srcs that exports C but also has its own class
2636+ cat << 'EOF ' >> pkg/BUILD
2637+ java_library(name = "exported_and_direct", srcs = ["ExportedAndDirect.java"], deps = [":exports_c_with_srcs"])
2638+ java_library(name = "exports_c_with_srcs", srcs = ["B2.java"], exports = [":c"])
2639+ EOF
2640+ echo " public class B2 {}" > pkg/B2.java
2641+ echo " public class ExportedAndDirect { B2 b; C c; }" > pkg/ExportedAndDirect.java
2642+
2643+ bazel build //pkg:exported_and_direct \
2644+ --extra_toolchains=//pkg:java_toolchain_definition \
2645+ >& $TEST_log || fail " build failed, but expected Exported & Direct Used to succeed"
2646+
2647+ # -------------------------------------------------------------
2648+ # Scenario 5: Indirect Used (Error - Strict Deps violation)
2649+ # -------------------------------------------------------------
2650+ cat << 'EOF ' >> pkg/BUILD
2651+ java_library(name = "indirect_used", srcs = ["IndirectUsed.java"], deps = [":dep_no_exports"])
2652+ java_library(name = "dep_no_exports", deps = [":c"])
2653+ EOF
2654+ echo " public class IndirectUsed { C c; }" > pkg/IndirectUsed.java
2655+
2656+ bazel build //pkg:indirect_used \
2657+ --extra_toolchains=//pkg:java_toolchain_definition \
2658+ >& $TEST_log && fail " build succeeded, but expected it to fail due to strict deps violation"
2659+
2660+ # Check that it's a strict deps error, not an unused deps error
2661+ expect_log " is not visible from target '//pkg:indirect_used'"
2662+
2663+ # -------------------------------------------------------------
2664+ # Scenario 6: Non-Main Repository Target (Success)
2665+ # -------------------------------------------------------------
2666+ mkdir -p ext
2667+ cat > ext/MODULE.bazel << EOF
2668+ module(name = "ext")
2669+ bazel_dep(name = "rules_java")
2670+ EOF
2671+ if [[ -n " ${RULES_JAVA_OVERRIDE_PATH:- } " ]]; then
2672+ cat >> ext/MODULE.bazel << EOF
2673+ local_path_override(
2674+ module_name = "rules_java",
2675+ path = "${RULES_JAVA_OVERRIDE_PATH} ",
2676+ )
2677+ EOF
2678+ fi
2679+
2680+ cat > ext/BUILD << EOF
2681+ load("@rules_java//java:java_library.bzl", "java_library")
2682+ load("@rules_java//toolchains:default_java_toolchain.bzl", "default_java_toolchain")
2683+ load("@rules_java//java:defs.bzl", "java_package_configuration")
2684+
2685+ package_group(
2686+ name = "ext_package_spec",
2687+ packages = ["//..."],
2688+ )
2689+
2690+ java_package_configuration(
2691+ name = "unused_deps_error_config",
2692+ package_specs = [":ext_package_spec"],
2693+ unused_deps = "error",
2694+ )
2695+
2696+ default_java_toolchain(
2697+ name = "java_toolchain",
2698+ package_configuration = [":unused_deps_error_config"],
2699+ )
2700+
2701+ java_library(name = "ext_lib", srcs = ["Ext.java"], deps = [":ext_dep"])
2702+ java_library(name = "ext_dep", srcs = ["ExtDep.java"])
2703+ EOF
2704+
2705+ echo " public class Ext {}" > ext/Ext.java
2706+ echo " public class ExtDep {}" > ext/ExtDep.java
2707+
2708+ cat >> MODULE.bazel << EOF
2709+ bazel_dep(name = "ext")
2710+ local_path_override(
2711+ module_name = "ext",
2712+ path = "ext",
2713+ )
2714+ EOF
2715+
2716+ # Build the target in the external repo. Even though ext_dep is unused,
2717+ # it should compile successfully because unused deps checking is disabled for non-main repos.
2718+ bazel build @ext//:ext_lib \
2719+ --extra_toolchains=@ext//:java_toolchain_definition \
2720+ >& $TEST_log || fail " build of external target failed, but expected to succeed (unused check disabled for external repos)"
2721+ }
2722+
25342723run_suite " Java integration tests"
0 commit comments