From 942834212c467b87e1064da46689e98512e8c2a9 Mon Sep 17 00:00:00 2001 From: Frank Portman Date: Mon, 24 Nov 2025 16:22:39 -0500 Subject: [PATCH 1/3] tmp --- scala/private/phases/phase_compile.bzl | 7 +- scala/scala_toolchain.bzl | 5 ++ test/toolchain_plugins/BUILD.bazel | 38 ++++++++++ .../CombinedPluginsTest.scala | 13 ++++ test/toolchain_plugins/GlobalPluginTest.scala | 16 ++++ test/toolchain_plugins/README.md | 73 +++++++++++++++++++ test/toolchain_plugins/SimplePluginTest.scala | 9 +++ .../test_toolchain_plugins.sh | 27 +++++++ 8 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 test/toolchain_plugins/BUILD.bazel create mode 100644 test/toolchain_plugins/CombinedPluginsTest.scala create mode 100644 test/toolchain_plugins/GlobalPluginTest.scala create mode 100644 test/toolchain_plugins/README.md create mode 100644 test/toolchain_plugins/SimplePluginTest.scala create mode 100755 test/toolchain_plugins/test_toolchain_plugins.sh diff --git a/scala/private/phases/phase_compile.bzl b/scala/private/phases/phase_compile.bzl index 185f7219d..ea39ac480 100644 --- a/scala/private/phases/phase_compile.bzl +++ b/scala/private/phases/phase_compile.bzl @@ -125,7 +125,12 @@ def _phase_compile( jars2labels = p.collect_jars.jars2labels.jars_to_labels deps_providers = p.collect_jars.deps_providers default_classpath = p.scalac_provider.default_classpath - plugins = ctx.attr.plugins + + # Merge toolchain plugins with target-specific plugins + toolchain = ctx.toolchains["//scala:toolchain_type"] + toolchain_plugins = getattr(toolchain, "plugins", []) + plugins = toolchain_plugins + ctx.attr.plugins + additional_outputs = [] scalacopts = p.scalacopts diff --git a/scala/scala_toolchain.bzl b/scala/scala_toolchain.bzl index dc8e9f907..384f0adf1 100644 --- a/scala/scala_toolchain.bzl +++ b/scala/scala_toolchain.bzl @@ -81,6 +81,7 @@ def _scala_toolchain_impl(ctx): toolchain = platform_common.ToolchainInfo( scalacopts = ctx.attr.scalacopts, + plugins = ctx.attr.plugins, dep_providers = ctx.attr.dep_providers, dependency_mode = dependency_mode, strict_deps_mode = strict_deps_mode, @@ -122,6 +123,10 @@ _scala_toolchain = rule( _scala_toolchain_impl, attrs = { "scalacopts": attr.string_list(), + "plugins": attr.label_list( + doc = "Compiler plugins to be enabled for all scala targets using this toolchain", + allow_files = [".jar"], + ), "dep_providers": attr.label_list( default = _default_dep_providers(), providers = [_DepsInfo], diff --git a/test/toolchain_plugins/BUILD.bazel b/test/toolchain_plugins/BUILD.bazel new file mode 100644 index 000000000..0d82e1e14 --- /dev/null +++ b/test/toolchain_plugins/BUILD.bazel @@ -0,0 +1,38 @@ +load("//scala:scala_toolchain.bzl", "scala_toolchain") +load("//scala:scala.bzl", "scala_library") + +# Define a custom toolchain with global plugins +scala_toolchain( + name = "global_plugin_toolchain_impl", + plugins = ["@org_typelevel_kind_projector//jar"], + visibility = ["//visibility:public"], +) + +toolchain( + name = "global_plugin_toolchain", + exec_compatible_with = [], + target_compatible_with = [], + toolchain = ":global_plugin_toolchain_impl", + toolchain_type = "//scala:toolchain_type", + visibility = ["//visibility:public"], +) + +# Test library that should use the global plugin from the toolchain +scala_library( + name = "test_global_plugin", + srcs = ["GlobalPluginTest.scala"], + # No explicit plugins attribute - should use the global plugin from toolchain +) + +# Simple test without plugin features +scala_library( + name = "test_simple", + srcs = ["SimplePluginTest.scala"], +) + +# Test library that adds additional plugins on top of global ones +scala_library( + name = "test_combined_plugins", + srcs = ["CombinedPluginsTest.scala"], + plugins = ["//test/plugins:compile_plugin"], # Additional plugin +) \ No newline at end of file diff --git a/test/toolchain_plugins/CombinedPluginsTest.scala b/test/toolchain_plugins/CombinedPluginsTest.scala new file mode 100644 index 000000000..a3200235c --- /dev/null +++ b/test/toolchain_plugins/CombinedPluginsTest.scala @@ -0,0 +1,13 @@ +package test.toolchain_plugins + +// This test uses kind-projector plugin features from toolchain +// AND additional features from the explicitly added plugin +object CombinedPluginsTest { + // Lambda syntax from kind-projector (global plugin) + type Tuple2K[F[_]] = Lambda[A => (A, A)] + + // This would also use features from the additional plugin if available + def test(): Unit = { + println("Combined plugins test compiled successfully") + } +} \ No newline at end of file diff --git a/test/toolchain_plugins/GlobalPluginTest.scala b/test/toolchain_plugins/GlobalPluginTest.scala new file mode 100644 index 000000000..a3147b47f --- /dev/null +++ b/test/toolchain_plugins/GlobalPluginTest.scala @@ -0,0 +1,16 @@ +package test.toolchain_plugins + +// This test uses kind-projector plugin features that should be available globally via the toolchain +object GlobalPluginTest { + // Using * as a type wildcard (kind-projector feature for Scala 2.12) + type EitherStr[A] = Either[String, A] + + // Test that we can use higher-kinded types + def foo[F[_]](fa: F[Int]): F[Int] = fa + + def test(): Unit = { + println("Global plugin test compiled successfully") + val either: EitherStr[Int] = Right(42) + println(s"Test value: $either") + } +} \ No newline at end of file diff --git a/test/toolchain_plugins/README.md b/test/toolchain_plugins/README.md new file mode 100644 index 000000000..8ea841856 --- /dev/null +++ b/test/toolchain_plugins/README.md @@ -0,0 +1,73 @@ +# Global Compiler Plugins via Toolchain + +This directory demonstrates how to configure global compiler plugins that apply to all Scala targets through the toolchain. + +## How to Use Global Plugins + +### 1. Define a toolchain with plugins + +In your `BUILD.bazel` or `WORKSPACE` file, define a Scala toolchain with the `plugins` attribute: + +```starlark +scala_toolchain( + name = "my_global_plugins_toolchain_impl", + plugins = [ + "@org_typelevel_kind_projector//jar", + "//path/to/another:plugin", + ], + # Other toolchain attributes... +) + +toolchain( + name = "my_global_plugins_toolchain", + toolchain = ":my_global_plugins_toolchain_impl", + toolchain_type = "//scala:toolchain_type", +) +``` + +### 2. Register the toolchain + +Register your custom toolchain in the WORKSPACE file or via Bazel's `--extra_toolchains` flag: + +```starlark +register_toolchains("//path/to:my_global_plugins_toolchain") +``` + +### 3. Use in your Scala targets + +All `scala_library`, `scala_binary`, and `scala_test` targets will automatically have access to the global plugins: + +```starlark +scala_library( + name = "my_lib", + srcs = ["MyLib.scala"], + # No need to specify plugins - they come from the toolchain +) +``` + +### 4. Adding target-specific plugins + +Targets can still specify additional plugins via the `plugins` attribute. These will be combined with the global plugins: + +```starlark +scala_library( + name = "my_lib_with_extra_plugin", + srcs = ["MyLib.scala"], + plugins = ["//my:additional_plugin"], # Combined with global plugins +) +``` + +## Benefits + +1. **Consistency**: Ensure all Scala code in your repository uses the same set of compiler plugins +2. **Maintainability**: Update plugins in one place instead of every BUILD file +3. **Flexibility**: Individual targets can still add their own plugins when needed +4. **Migration**: Gradually migrate from per-target plugins to global plugins + +## Example Use Cases + +- **Kind Projector**: Enable type lambda syntax across the entire codebase +- **Better Monadic For**: Improve for-comprehension desugaring globally +- **Silencer**: Suppress specific compiler warnings project-wide +- **Scala.js plugins**: Enable Scala.js compilation features +- **Custom linting/validation plugins**: Enforce coding standards across all targets \ No newline at end of file diff --git a/test/toolchain_plugins/SimplePluginTest.scala b/test/toolchain_plugins/SimplePluginTest.scala new file mode 100644 index 000000000..d2e0abd5c --- /dev/null +++ b/test/toolchain_plugins/SimplePluginTest.scala @@ -0,0 +1,9 @@ +package test.toolchain_plugins + +// Simple test that doesn't require any special plugin features +// This verifies the basic compilation works +object SimplePluginTest { + def test(): String = { + "Global plugin mechanism works" + } +} \ No newline at end of file diff --git a/test/toolchain_plugins/test_toolchain_plugins.sh b/test/toolchain_plugins/test_toolchain_plugins.sh new file mode 100755 index 000000000..09301c0e7 --- /dev/null +++ b/test/toolchain_plugins/test_toolchain_plugins.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Integration test for global compiler plugins via toolchain +set -e + +echo "Testing global compiler plugins via toolchain..." + +# Test 1: Build with global plugin from toolchain +echo "Test 1: Building with global plugin from toolchain" +bazel build --extra_toolchains=//test/toolchain_plugins:global_plugin_toolchain //test/toolchain_plugins:test_global_plugin + +# Test 2: Build with combined plugins (global + target-specific) +echo "Test 2: Building with combined plugins" +bazel build --extra_toolchains=//test/toolchain_plugins:global_plugin_toolchain //test/toolchain_plugins:test_combined_plugins + +# Test 3: Verify plugin is actually being used (should fail without the toolchain) +echo "Test 3: Verifying plugin requirement (should fail without toolchain)" +set +e +bazel build //test/toolchain_plugins:test_global_plugin 2>/dev/null +if [ $? -eq 0 ]; then + echo "ERROR: Build succeeded without global plugin - test failed" + exit 1 +fi +set -e +echo "Good: Build correctly failed without the global plugin" + +echo "All tests passed!" \ No newline at end of file From 1dc42ec89e91c9d69613fc786b5164336007cb0f Mon Sep 17 00:00:00 2001 From: Frank Portman Date: Mon, 24 Nov 2025 17:32:46 -0500 Subject: [PATCH 2/3] implement it --- docs/scala_toolchain_plugins.md | 146 ++++++++++++++++++ test/toolchain_plugins/BUILD.bazel | 40 ++--- .../toolchain_plugins/KindProjectorTest.scala | 6 + test/toolchain_plugins/NoPlugin.scala | 6 + test/toolchain_plugins/RequiresPlugin.scala | 7 + .../test_without_toolchain.sh | 8 + 6 files changed, 195 insertions(+), 18 deletions(-) create mode 100644 docs/scala_toolchain_plugins.md create mode 100644 test/toolchain_plugins/KindProjectorTest.scala create mode 100644 test/toolchain_plugins/NoPlugin.scala create mode 100644 test/toolchain_plugins/RequiresPlugin.scala create mode 100755 test/toolchain_plugins/test_without_toolchain.sh diff --git a/docs/scala_toolchain_plugins.md b/docs/scala_toolchain_plugins.md new file mode 100644 index 000000000..9140f9612 --- /dev/null +++ b/docs/scala_toolchain_plugins.md @@ -0,0 +1,146 @@ +# Global Compiler Plugins via Scala Toolchain + +Starting with this version, rules_scala supports configuring compiler plugins globally at the toolchain level. This allows you to enable compiler plugins for all Scala targets in your workspace without having to specify them in every BUILD file. + +## Motivation + +Previously, compiler plugins had to be specified on each individual `scala_library`, `scala_binary`, or `scala_test` target: + +```starlark +scala_library( + name = "lib1", + srcs = ["Lib1.scala"], + plugins = ["@org_typelevel_kind_projector//jar"], # Repetitive +) + +scala_library( + name = "lib2", + srcs = ["Lib2.scala"], + plugins = ["@org_typelevel_kind_projector//jar"], # Repetitive +) +``` + +With global plugins via toolchain, you can configure plugins once and have them apply everywhere. + +## Usage + +### Step 1: Define a Scala Toolchain with Plugins + +Create a custom Scala toolchain that includes the `plugins` attribute: + +```starlark +load("@io_bazel_rules_scala//scala:scala_toolchain.bzl", "scala_toolchain") + +scala_toolchain( + name = "my_scala_toolchain_impl", + plugins = [ + "@org_typelevel_kind_projector//jar", + "@com_olegpy_better_monadic_for//jar", + # Add more plugins as needed + ], + # Other toolchain configuration... + visibility = ["//visibility:public"], +) + +toolchain( + name = "my_scala_toolchain", + toolchain = ":my_scala_toolchain_impl", + toolchain_type = "@io_bazel_rules_scala//scala:toolchain_type", +) +``` + +### Step 2: Register the Toolchain + +Register your custom toolchain in your `WORKSPACE` file: + +```starlark +register_toolchains("//path/to:my_scala_toolchain") +``` + +Or use the `--extra_toolchains` flag: + +```bash +bazel build //... --extra_toolchains=//path/to:my_scala_toolchain +``` + +### Step 3: Use in Your Targets + +Now all your Scala targets automatically have access to the global plugins: + +```starlark +scala_library( + name = "my_lib", + srcs = ["MyLib.scala"], + # No plugins attribute needed - they come from the toolchain! +) +``` + +## Combining Global and Target-Specific Plugins + +Targets can still specify additional plugins via the `plugins` attribute. These will be combined with the global plugins from the toolchain: + +```starlark +scala_library( + name = "special_lib", + srcs = ["SpecialLib.scala"], + plugins = ["//my:custom_plugin"], # This is added to the global plugins +) +``` + +In this case, `special_lib` will have both the global plugins from the toolchain AND the custom plugin specified in the target. + +## Example: Enabling Kind Projector Globally + +Here's a complete example of enabling the Kind Projector compiler plugin globally for Scala 2.12: + +**BUILD.bazel** (in your workspace root or a dedicated toolchain package): +```starlark +load("@io_bazel_rules_scala//scala:scala_toolchain.bzl", "scala_toolchain") + +scala_toolchain( + name = "scala_2_12_with_kind_projector_impl", + plugins = ["@org_typelevel_kind_projector//jar"], + visibility = ["//visibility:public"], +) + +toolchain( + name = "scala_2_12_with_kind_projector", + toolchain = ":scala_2_12_with_kind_projector_impl", + toolchain_type = "@io_bazel_rules_scala//scala:toolchain_type", +) +``` + +**WORKSPACE**: +```starlark +register_toolchains("//:scala_2_12_with_kind_projector") +``` + +Now all Scala code in your workspace can use Kind Projector syntax: + +```scala +// Any scala_library can now use this without declaring the plugin +type EitherStr[A] = Either[String, A] +type StringOr[T] = Either[String, T] +``` + +## Migration Guide + +To migrate from per-target plugins to global plugins: + +1. Identify plugins used across multiple targets +2. Add them to your toolchain's `plugins` attribute +3. Remove the `plugins` attribute from individual targets +4. Test your build to ensure everything still compiles + +## Benefits + +- **Consistency**: Ensure all Scala code uses the same compiler plugins +- **Maintainability**: Update plugins in one place +- **Cleaner BUILD files**: Less boilerplate in target definitions +- **Flexibility**: Can still add target-specific plugins when needed + +## Limitations + +- Global plugins apply to ALL Scala targets using the toolchain +- If a plugin causes issues with specific targets, you may need to create multiple toolchains +- Plugin order matters - global plugins are loaded before target-specific plugins \ No newline at end of file diff --git a/test/toolchain_plugins/BUILD.bazel b/test/toolchain_plugins/BUILD.bazel index 0d82e1e14..9cd16b9b1 100644 --- a/test/toolchain_plugins/BUILD.bazel +++ b/test/toolchain_plugins/BUILD.bazel @@ -1,38 +1,42 @@ load("//scala:scala_toolchain.bzl", "scala_toolchain") load("//scala:scala.bzl", "scala_library") -# Define a custom toolchain with global plugins +# Toolchain WITH the kind-projector plugin scala_toolchain( - name = "global_plugin_toolchain_impl", + name = "with_plugin_impl", plugins = ["@org_typelevel_kind_projector//jar"], visibility = ["//visibility:public"], ) toolchain( - name = "global_plugin_toolchain", - exec_compatible_with = [], - target_compatible_with = [], - toolchain = ":global_plugin_toolchain_impl", + name = "with_plugin", + toolchain = ":with_plugin_impl", toolchain_type = "//scala:toolchain_type", visibility = ["//visibility:public"], ) -# Test library that should use the global plugin from the toolchain -scala_library( - name = "test_global_plugin", - srcs = ["GlobalPluginTest.scala"], - # No explicit plugins attribute - should use the global plugin from toolchain +# Toolchain WITHOUT the plugin (but otherwise identical) +scala_toolchain( + name = "without_plugin_impl", + # No plugins attribute + visibility = ["//visibility:public"], +) + +toolchain( + name = "without_plugin", + toolchain = ":without_plugin_impl", + toolchain_type = "//scala:toolchain_type", + visibility = ["//visibility:public"], ) -# Simple test without plugin features +# Test that requires kind-projector plugin scala_library( - name = "test_simple", - srcs = ["SimplePluginTest.scala"], + name = "requires_plugin", + srcs = ["RequiresPlugin.scala"], ) -# Test library that adds additional plugins on top of global ones +# Test that doesn't require any plugin scala_library( - name = "test_combined_plugins", - srcs = ["CombinedPluginsTest.scala"], - plugins = ["//test/plugins:compile_plugin"], # Additional plugin + name = "no_plugin_needed", + srcs = ["NoPlugin.scala"], ) \ No newline at end of file diff --git a/test/toolchain_plugins/KindProjectorTest.scala b/test/toolchain_plugins/KindProjectorTest.scala new file mode 100644 index 000000000..70cc483cd --- /dev/null +++ b/test/toolchain_plugins/KindProjectorTest.scala @@ -0,0 +1,6 @@ +package test.toolchain_plugins + +object KindProjectorTest { + // This WILL NOT compile without kind-projector plugin + def foo[F[_], A](fa: F[A]): F[Tuple2[A, ?]] = ??? +} \ No newline at end of file diff --git a/test/toolchain_plugins/NoPlugin.scala b/test/toolchain_plugins/NoPlugin.scala new file mode 100644 index 000000000..657c9a7b5 --- /dev/null +++ b/test/toolchain_plugins/NoPlugin.scala @@ -0,0 +1,6 @@ +package test.toolchain_plugins + +// Standard Scala - no plugin needed +class NoPlugin { + def hello: String = "This compiles without any plugin" +} \ No newline at end of file diff --git a/test/toolchain_plugins/RequiresPlugin.scala b/test/toolchain_plugins/RequiresPlugin.scala new file mode 100644 index 000000000..2e2a8f5d9 --- /dev/null +++ b/test/toolchain_plugins/RequiresPlugin.scala @@ -0,0 +1,7 @@ +package test.toolchain_plugins + +import scala.language.higherKinds + +// This REQUIRES kind-projector plugin - uses the * syntax +class HKT[F[_]] +class RequiresPlugin extends HKT[Either[String, *]] \ No newline at end of file diff --git a/test/toolchain_plugins/test_without_toolchain.sh b/test/toolchain_plugins/test_without_toolchain.sh new file mode 100755 index 000000000..a9afb4fcd --- /dev/null +++ b/test/toolchain_plugins/test_without_toolchain.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# Test that verifies the global plugin is actually being used + +set -e +echo "Testing that simple compilation works WITHOUT the special toolchain..." +bazel build //test/toolchain_plugins:test_simple + +echo "Test passed - simple compilation works without special toolchain" \ No newline at end of file From 39114d9d90119282fbf03c8af06be67af50c454d Mon Sep 17 00:00:00 2001 From: Frank Portman Date: Mon, 24 Nov 2025 20:01:36 -0500 Subject: [PATCH 3/3] remove junk --- docs/scala_toolchain_plugins.md | 146 ------------------ .../CombinedPluginsTest.scala | 13 -- test/toolchain_plugins/GlobalPluginTest.scala | 16 -- .../toolchain_plugins/KindProjectorTest.scala | 6 - test/toolchain_plugins/README.md | 73 --------- test/toolchain_plugins/SimplePluginTest.scala | 9 -- .../test_toolchain_plugins.sh | 27 ---- .../test_without_toolchain.sh | 8 - 8 files changed, 298 deletions(-) delete mode 100644 docs/scala_toolchain_plugins.md delete mode 100644 test/toolchain_plugins/CombinedPluginsTest.scala delete mode 100644 test/toolchain_plugins/GlobalPluginTest.scala delete mode 100644 test/toolchain_plugins/KindProjectorTest.scala delete mode 100644 test/toolchain_plugins/README.md delete mode 100644 test/toolchain_plugins/SimplePluginTest.scala delete mode 100755 test/toolchain_plugins/test_toolchain_plugins.sh delete mode 100755 test/toolchain_plugins/test_without_toolchain.sh diff --git a/docs/scala_toolchain_plugins.md b/docs/scala_toolchain_plugins.md deleted file mode 100644 index 9140f9612..000000000 --- a/docs/scala_toolchain_plugins.md +++ /dev/null @@ -1,146 +0,0 @@ -# Global Compiler Plugins via Scala Toolchain - -Starting with this version, rules_scala supports configuring compiler plugins globally at the toolchain level. This allows you to enable compiler plugins for all Scala targets in your workspace without having to specify them in every BUILD file. - -## Motivation - -Previously, compiler plugins had to be specified on each individual `scala_library`, `scala_binary`, or `scala_test` target: - -```starlark -scala_library( - name = "lib1", - srcs = ["Lib1.scala"], - plugins = ["@org_typelevel_kind_projector//jar"], # Repetitive -) - -scala_library( - name = "lib2", - srcs = ["Lib2.scala"], - plugins = ["@org_typelevel_kind_projector//jar"], # Repetitive -) -``` - -With global plugins via toolchain, you can configure plugins once and have them apply everywhere. - -## Usage - -### Step 1: Define a Scala Toolchain with Plugins - -Create a custom Scala toolchain that includes the `plugins` attribute: - -```starlark -load("@io_bazel_rules_scala//scala:scala_toolchain.bzl", "scala_toolchain") - -scala_toolchain( - name = "my_scala_toolchain_impl", - plugins = [ - "@org_typelevel_kind_projector//jar", - "@com_olegpy_better_monadic_for//jar", - # Add more plugins as needed - ], - # Other toolchain configuration... - visibility = ["//visibility:public"], -) - -toolchain( - name = "my_scala_toolchain", - toolchain = ":my_scala_toolchain_impl", - toolchain_type = "@io_bazel_rules_scala//scala:toolchain_type", -) -``` - -### Step 2: Register the Toolchain - -Register your custom toolchain in your `WORKSPACE` file: - -```starlark -register_toolchains("//path/to:my_scala_toolchain") -``` - -Or use the `--extra_toolchains` flag: - -```bash -bazel build //... --extra_toolchains=//path/to:my_scala_toolchain -``` - -### Step 3: Use in Your Targets - -Now all your Scala targets automatically have access to the global plugins: - -```starlark -scala_library( - name = "my_lib", - srcs = ["MyLib.scala"], - # No plugins attribute needed - they come from the toolchain! -) -``` - -## Combining Global and Target-Specific Plugins - -Targets can still specify additional plugins via the `plugins` attribute. These will be combined with the global plugins from the toolchain: - -```starlark -scala_library( - name = "special_lib", - srcs = ["SpecialLib.scala"], - plugins = ["//my:custom_plugin"], # This is added to the global plugins -) -``` - -In this case, `special_lib` will have both the global plugins from the toolchain AND the custom plugin specified in the target. - -## Example: Enabling Kind Projector Globally - -Here's a complete example of enabling the Kind Projector compiler plugin globally for Scala 2.12: - -**BUILD.bazel** (in your workspace root or a dedicated toolchain package): -```starlark -load("@io_bazel_rules_scala//scala:scala_toolchain.bzl", "scala_toolchain") - -scala_toolchain( - name = "scala_2_12_with_kind_projector_impl", - plugins = ["@org_typelevel_kind_projector//jar"], - visibility = ["//visibility:public"], -) - -toolchain( - name = "scala_2_12_with_kind_projector", - toolchain = ":scala_2_12_with_kind_projector_impl", - toolchain_type = "@io_bazel_rules_scala//scala:toolchain_type", -) -``` - -**WORKSPACE**: -```starlark -register_toolchains("//:scala_2_12_with_kind_projector") -``` - -Now all Scala code in your workspace can use Kind Projector syntax: - -```scala -// Any scala_library can now use this without declaring the plugin -type EitherStr[A] = Either[String, A] -type StringOr[T] = Either[String, T] -``` - -## Migration Guide - -To migrate from per-target plugins to global plugins: - -1. Identify plugins used across multiple targets -2. Add them to your toolchain's `plugins` attribute -3. Remove the `plugins` attribute from individual targets -4. Test your build to ensure everything still compiles - -## Benefits - -- **Consistency**: Ensure all Scala code uses the same compiler plugins -- **Maintainability**: Update plugins in one place -- **Cleaner BUILD files**: Less boilerplate in target definitions -- **Flexibility**: Can still add target-specific plugins when needed - -## Limitations - -- Global plugins apply to ALL Scala targets using the toolchain -- If a plugin causes issues with specific targets, you may need to create multiple toolchains -- Plugin order matters - global plugins are loaded before target-specific plugins \ No newline at end of file diff --git a/test/toolchain_plugins/CombinedPluginsTest.scala b/test/toolchain_plugins/CombinedPluginsTest.scala deleted file mode 100644 index a3200235c..000000000 --- a/test/toolchain_plugins/CombinedPluginsTest.scala +++ /dev/null @@ -1,13 +0,0 @@ -package test.toolchain_plugins - -// This test uses kind-projector plugin features from toolchain -// AND additional features from the explicitly added plugin -object CombinedPluginsTest { - // Lambda syntax from kind-projector (global plugin) - type Tuple2K[F[_]] = Lambda[A => (A, A)] - - // This would also use features from the additional plugin if available - def test(): Unit = { - println("Combined plugins test compiled successfully") - } -} \ No newline at end of file diff --git a/test/toolchain_plugins/GlobalPluginTest.scala b/test/toolchain_plugins/GlobalPluginTest.scala deleted file mode 100644 index a3147b47f..000000000 --- a/test/toolchain_plugins/GlobalPluginTest.scala +++ /dev/null @@ -1,16 +0,0 @@ -package test.toolchain_plugins - -// This test uses kind-projector plugin features that should be available globally via the toolchain -object GlobalPluginTest { - // Using * as a type wildcard (kind-projector feature for Scala 2.12) - type EitherStr[A] = Either[String, A] - - // Test that we can use higher-kinded types - def foo[F[_]](fa: F[Int]): F[Int] = fa - - def test(): Unit = { - println("Global plugin test compiled successfully") - val either: EitherStr[Int] = Right(42) - println(s"Test value: $either") - } -} \ No newline at end of file diff --git a/test/toolchain_plugins/KindProjectorTest.scala b/test/toolchain_plugins/KindProjectorTest.scala deleted file mode 100644 index 70cc483cd..000000000 --- a/test/toolchain_plugins/KindProjectorTest.scala +++ /dev/null @@ -1,6 +0,0 @@ -package test.toolchain_plugins - -object KindProjectorTest { - // This WILL NOT compile without kind-projector plugin - def foo[F[_], A](fa: F[A]): F[Tuple2[A, ?]] = ??? -} \ No newline at end of file diff --git a/test/toolchain_plugins/README.md b/test/toolchain_plugins/README.md deleted file mode 100644 index 8ea841856..000000000 --- a/test/toolchain_plugins/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Global Compiler Plugins via Toolchain - -This directory demonstrates how to configure global compiler plugins that apply to all Scala targets through the toolchain. - -## How to Use Global Plugins - -### 1. Define a toolchain with plugins - -In your `BUILD.bazel` or `WORKSPACE` file, define a Scala toolchain with the `plugins` attribute: - -```starlark -scala_toolchain( - name = "my_global_plugins_toolchain_impl", - plugins = [ - "@org_typelevel_kind_projector//jar", - "//path/to/another:plugin", - ], - # Other toolchain attributes... -) - -toolchain( - name = "my_global_plugins_toolchain", - toolchain = ":my_global_plugins_toolchain_impl", - toolchain_type = "//scala:toolchain_type", -) -``` - -### 2. Register the toolchain - -Register your custom toolchain in the WORKSPACE file or via Bazel's `--extra_toolchains` flag: - -```starlark -register_toolchains("//path/to:my_global_plugins_toolchain") -``` - -### 3. Use in your Scala targets - -All `scala_library`, `scala_binary`, and `scala_test` targets will automatically have access to the global plugins: - -```starlark -scala_library( - name = "my_lib", - srcs = ["MyLib.scala"], - # No need to specify plugins - they come from the toolchain -) -``` - -### 4. Adding target-specific plugins - -Targets can still specify additional plugins via the `plugins` attribute. These will be combined with the global plugins: - -```starlark -scala_library( - name = "my_lib_with_extra_plugin", - srcs = ["MyLib.scala"], - plugins = ["//my:additional_plugin"], # Combined with global plugins -) -``` - -## Benefits - -1. **Consistency**: Ensure all Scala code in your repository uses the same set of compiler plugins -2. **Maintainability**: Update plugins in one place instead of every BUILD file -3. **Flexibility**: Individual targets can still add their own plugins when needed -4. **Migration**: Gradually migrate from per-target plugins to global plugins - -## Example Use Cases - -- **Kind Projector**: Enable type lambda syntax across the entire codebase -- **Better Monadic For**: Improve for-comprehension desugaring globally -- **Silencer**: Suppress specific compiler warnings project-wide -- **Scala.js plugins**: Enable Scala.js compilation features -- **Custom linting/validation plugins**: Enforce coding standards across all targets \ No newline at end of file diff --git a/test/toolchain_plugins/SimplePluginTest.scala b/test/toolchain_plugins/SimplePluginTest.scala deleted file mode 100644 index d2e0abd5c..000000000 --- a/test/toolchain_plugins/SimplePluginTest.scala +++ /dev/null @@ -1,9 +0,0 @@ -package test.toolchain_plugins - -// Simple test that doesn't require any special plugin features -// This verifies the basic compilation works -object SimplePluginTest { - def test(): String = { - "Global plugin mechanism works" - } -} \ No newline at end of file diff --git a/test/toolchain_plugins/test_toolchain_plugins.sh b/test/toolchain_plugins/test_toolchain_plugins.sh deleted file mode 100755 index 09301c0e7..000000000 --- a/test/toolchain_plugins/test_toolchain_plugins.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -# Integration test for global compiler plugins via toolchain -set -e - -echo "Testing global compiler plugins via toolchain..." - -# Test 1: Build with global plugin from toolchain -echo "Test 1: Building with global plugin from toolchain" -bazel build --extra_toolchains=//test/toolchain_plugins:global_plugin_toolchain //test/toolchain_plugins:test_global_plugin - -# Test 2: Build with combined plugins (global + target-specific) -echo "Test 2: Building with combined plugins" -bazel build --extra_toolchains=//test/toolchain_plugins:global_plugin_toolchain //test/toolchain_plugins:test_combined_plugins - -# Test 3: Verify plugin is actually being used (should fail without the toolchain) -echo "Test 3: Verifying plugin requirement (should fail without toolchain)" -set +e -bazel build //test/toolchain_plugins:test_global_plugin 2>/dev/null -if [ $? -eq 0 ]; then - echo "ERROR: Build succeeded without global plugin - test failed" - exit 1 -fi -set -e -echo "Good: Build correctly failed without the global plugin" - -echo "All tests passed!" \ No newline at end of file diff --git a/test/toolchain_plugins/test_without_toolchain.sh b/test/toolchain_plugins/test_without_toolchain.sh deleted file mode 100755 index a9afb4fcd..000000000 --- a/test/toolchain_plugins/test_without_toolchain.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# Test that verifies the global plugin is actually being used - -set -e -echo "Testing that simple compilation works WITHOUT the special toolchain..." -bazel build //test/toolchain_plugins:test_simple - -echo "Test passed - simple compilation works without special toolchain" \ No newline at end of file