From 2353b2cea3ab47312ad10837a3df455cac1cd0d7 Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Tue, 15 Apr 2025 10:53:14 +0200 Subject: [PATCH 1/2] Move `DirectiveUtils` to the `directives` module --- .../build/preprocessing/DirectivesPreprocessor.scala | 2 +- .../main/scala/scala/cli/commands/fix/BuiltInRules.scala | 6 +++--- .../build/preprocessing/directives/Directives.scala} | 9 ++++----- .../main/scala/scala/cli/doc/GenerateReferenceDoc.scala | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) rename modules/{build/src/main/scala/scala/build/preprocessing/directives/DirectivesPreprocessingUtils.scala => directives/src/main/scala/scala/build/preprocessing/directives/Directives.scala} (87%) diff --git a/modules/build/src/main/scala/scala/build/preprocessing/DirectivesPreprocessor.scala b/modules/build/src/main/scala/scala/build/preprocessing/DirectivesPreprocessor.scala index 15bde02c3b..7f715af654 100644 --- a/modules/build/src/main/scala/scala/build/preprocessing/DirectivesPreprocessor.scala +++ b/modules/build/src/main/scala/scala/build/preprocessing/DirectivesPreprocessor.scala @@ -23,7 +23,7 @@ import scala.build.options.{ SuppressWarningOptions, WithBuildRequirements } -import scala.build.preprocessing.directives.DirectivesPreprocessingUtils.* +import scala.build.preprocessing.directives.Directives.* import scala.build.preprocessing.directives.PartiallyProcessedDirectives.* import scala.build.preprocessing.directives.* diff --git a/modules/cli/src/main/scala/scala/cli/commands/fix/BuiltInRules.scala b/modules/cli/src/main/scala/scala/cli/commands/fix/BuiltInRules.scala index ae88854602..3510734bec 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/fix/BuiltInRules.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/fix/BuiltInRules.scala @@ -20,12 +20,12 @@ import scala.collection.immutable.HashMap import scala.util.chaining.scalaUtilChainingOps object BuiltInRules extends CommandHelpers { - private lazy val targetDirectivesKeysSet = DirectivesPreprocessingUtils.requireDirectiveHandlers + private lazy val targetDirectivesKeysSet = Directives.requireDirectiveHandlers .flatMap(_.keys.flatMap(_.nameAliases)).toSet - private lazy val usingDirectivesKeysGrouped = DirectivesPreprocessingUtils.usingDirectiveHandlers + private lazy val usingDirectivesKeysGrouped = Directives.usingDirectiveHandlers .flatMap(_.keys) private lazy val usingDirectivesWithTestPrefixKeysGrouped = - DirectivesPreprocessingUtils.usingDirectiveWithReqsHandlers + Directives.usingDirectiveWithReqsHandlers .flatMap(_.keys) private lazy val directiveTestPrefix = "test." diff --git a/modules/build/src/main/scala/scala/build/preprocessing/directives/DirectivesPreprocessingUtils.scala b/modules/directives/src/main/scala/scala/build/preprocessing/directives/Directives.scala similarity index 87% rename from modules/build/src/main/scala/scala/build/preprocessing/directives/DirectivesPreprocessingUtils.scala rename to modules/directives/src/main/scala/scala/build/preprocessing/directives/Directives.scala index e3ed9ba4da..e95c8f96c9 100644 --- a/modules/build/src/main/scala/scala/build/preprocessing/directives/DirectivesPreprocessingUtils.scala +++ b/modules/directives/src/main/scala/scala/build/preprocessing/directives/Directives.scala @@ -5,13 +5,12 @@ import scala.build.directives.{ HasBuildOptionsWithRequirements, HasBuildRequirements } -import scala.build.errors.{BuildException, UnusedDirectiveError} import scala.build.options.{BuildOptions, BuildRequirements, WithBuildRequirements} import scala.build.preprocessing.directives -object DirectivesPreprocessingUtils { +object Directives { val usingDirectiveHandlers: Seq[DirectiveHandler[BuildOptions]] = - Seq[DirectiveHandler[_ <: HasBuildOptions]]( + Seq[DirectiveHandler[? <: HasBuildOptions]]( directives.Benchmarking.handler, directives.BuildInfo.handler, directives.ComputeVersion.handler, @@ -37,7 +36,7 @@ object DirectivesPreprocessingUtils { val usingDirectiveWithReqsHandlers : Seq[DirectiveHandler[List[WithBuildRequirements[BuildOptions]]]] = - Seq[DirectiveHandler[_ <: HasBuildOptionsWithRequirements]]( + Seq[DirectiveHandler[? <: HasBuildOptionsWithRequirements]]( directives.CustomJar.handler, directives.Dependency.handler, directives.JavaOptions.handler, @@ -49,7 +48,7 @@ object DirectivesPreprocessingUtils { ).map(_.mapE(_.buildOptionsWithRequirements)) val requireDirectiveHandlers: Seq[DirectiveHandler[BuildRequirements]] = - Seq[DirectiveHandler[_ <: HasBuildRequirements]]( + Seq[DirectiveHandler[? <: HasBuildRequirements]]( directives.RequirePlatform.handler, directives.RequireScalaVersion.handler, directives.RequireScalaVersionBounds.handler, diff --git a/modules/generate-reference-doc/src/main/scala/scala/cli/doc/GenerateReferenceDoc.scala b/modules/generate-reference-doc/src/main/scala/scala/cli/doc/GenerateReferenceDoc.scala index 28a4c6ea5c..6de61417b4 100644 --- a/modules/generate-reference-doc/src/main/scala/scala/cli/doc/GenerateReferenceDoc.scala +++ b/modules/generate-reference-doc/src/main/scala/scala/cli/doc/GenerateReferenceDoc.scala @@ -16,7 +16,7 @@ import scala.build.internal.Constants import scala.build.internals.EnvVar import scala.build.options.{BuildOptions, BuildRequirements, WithBuildRequirements} import scala.build.preprocessing.directives.DirectiveHandler -import scala.build.preprocessing.directives.DirectivesPreprocessingUtils.* +import scala.build.preprocessing.directives.Directives.* import scala.cli.commands.{ScalaCommand, SpecificationLevel, tags} import scala.cli.doc.ReferenceDocUtils.* import scala.cli.util.ArgHelpers.* From 8a3ead646aa9deb4e9f14971a99684353a9565e1 Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Tue, 15 Apr 2025 13:41:50 +0200 Subject: [PATCH 2/2] Add API for getting data about `using` directives' definitions --- .../directives/DirectiveHandler.scala | 42 +++++++++++-------- .../preprocessing/directives/Directives.scala | 7 ++++ .../directives/DirectivesTest.scala | 19 +++++++++ 3 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 modules/directives/src/test/scala/scala/build/preprocessing/directives/DirectivesTest.scala diff --git a/modules/directives/src/main/scala/scala/build/preprocessing/directives/DirectiveHandler.scala b/modules/directives/src/main/scala/scala/build/preprocessing/directives/DirectiveHandler.scala index 40d782cb3c..caa8c85e60 100644 --- a/modules/directives/src/main/scala/scala/build/preprocessing/directives/DirectiveHandler.scala +++ b/modules/directives/src/main/scala/scala/build/preprocessing/directives/DirectiveHandler.scala @@ -46,35 +46,41 @@ trait DirectiveHandler[+T] { self => def map[U](f: T => U): DirectiveHandler[U] = new DirectiveHandler[U] { - def name = self.name - def usage = self.usage - override def usageMd = self.usageMd - def description = self.description - override def descriptionMd = self.descriptionMd - override def examples = self.examples + def name: String = self.name + def usage: String = self.usage + override def usageMd: String = self.usageMd + def description: String = self.description + override def descriptionMd: String = self.descriptionMd + override def examples: Seq[String] = self.examples - def scalaSpecificationLevel = self.scalaSpecificationLevel + def scalaSpecificationLevel: SpecificationLevel = self.scalaSpecificationLevel - def keys = self.keys + def keys: Seq[Key] = self.keys - def handleValues(scopedDirective: ScopedDirective, logger: Logger) = + def handleValues( + scopedDirective: ScopedDirective, + logger: Logger + ): Either[BuildException, ProcessedDirective[U]] = self.handleValues(scopedDirective, logger) .map(_.map(f)) } def mapE[U](f: T => Either[BuildException, U]): DirectiveHandler[U] = new DirectiveHandler[U] { - def name = self.name - def usage = self.usage - override def usageMd = self.usageMd - def description = self.description - override def descriptionMd = self.descriptionMd - override def examples = self.examples + def name: String = self.name + def usage: String = self.usage + override def usageMd: String = self.usageMd + def description: String = self.description + override def descriptionMd: String = self.descriptionMd + override def examples: Seq[String] = self.examples - def scalaSpecificationLevel = self.scalaSpecificationLevel + def scalaSpecificationLevel: SpecificationLevel = self.scalaSpecificationLevel - def keys = self.keys + def keys: Seq[Key] = self.keys - def handleValues(scopedDirective: ScopedDirective, logger: Logger) = + def handleValues( + scopedDirective: ScopedDirective, + logger: Logger + ): Either[BuildException, ProcessedDirective[U]] = self.handleValues(scopedDirective, logger).flatMap(_.mapE(f)) } diff --git a/modules/directives/src/main/scala/scala/build/preprocessing/directives/Directives.scala b/modules/directives/src/main/scala/scala/build/preprocessing/directives/Directives.scala index e95c8f96c9..fc5347fccc 100644 --- a/modules/directives/src/main/scala/scala/build/preprocessing/directives/Directives.scala +++ b/modules/directives/src/main/scala/scala/build/preprocessing/directives/Directives.scala @@ -54,4 +54,11 @@ object Directives { directives.RequireScalaVersionBounds.handler, directives.RequireScope.handler ).map(_.mapE(_.buildRequirements)) + + def allDirectiveHandlers: Seq[DirectiveHandler[BuildRequirements | BuildOptions]] = + usingDirectiveHandlers ++ requireDirectiveHandlers + + def getDirectiveHandler(key: String): Option[DirectiveHandler[BuildRequirements | BuildOptions]] = + allDirectiveHandlers.find(_.keys.exists(_.nameAliases.contains(key))) + } diff --git a/modules/directives/src/test/scala/scala/build/preprocessing/directives/DirectivesTest.scala b/modules/directives/src/test/scala/scala/build/preprocessing/directives/DirectivesTest.scala new file mode 100644 index 0000000000..66696b1b1f --- /dev/null +++ b/modules/directives/src/test/scala/scala/build/preprocessing/directives/DirectivesTest.scala @@ -0,0 +1,19 @@ +package scala.build.preprocessing.directives + +import com.eed3si9n.expecty.Expecty.expect + +class DirectivesTest extends munit.FunSuite { + test("get directive handler by key") { + val key = "python" + val handler = Directives.getDirectiveHandler(key).get + expect(handler.keys.flatMap(_.nameAliases).contains(key)) + expect(handler.isExperimental) + expect(handler.name == "Python") + expect(handler.description.nonEmpty) + expect(handler.descriptionMd.nonEmpty) + expect(handler.usage.nonEmpty) + expect(handler.usageMd.nonEmpty) + expect(handler.examples.nonEmpty) + } + +}