Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add toolkit using directive and cli options #1768

Merged
merged 2 commits into from Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions build.sc
Expand Up @@ -394,6 +394,9 @@ trait Core extends ScalaCliSbtModule with ScalaCliPublishModule with HasTests
| def scalafmtName = "${Deps.scalafmtCli.dep.module.name.value}"
| def defaultScalafmtVersion = "${Deps.scalafmtCli.dep.version}"
|
| def toolkitOrganization = "${Deps.toolkit.dep.module.organization.value}"
| def toolkitName = "${Deps.toolkit.dep.module.name.value}"
|
| def defaultScalaVersion = "${Scala.defaultUser}"
| def defaultScala212Version = "${Scala.scala212}"
| def defaultScala213Version = "${Scala.scala213}"
Expand Down
Expand Up @@ -70,7 +70,8 @@ case object ScalaPreprocessor extends Preprocessor {
directives.ScalaNative.handler,
directives.ScalaVersion.handler,
directives.Sources.handler,
directives.Tests.handler
directives.Tests.handler,
directives.Toolkit.handler
).map(_.mapE(_.buildOptions))

val requireDirectiveHandlers: Seq[DirectiveHandler[BuildRequirements]] =
Expand Down
Expand Up @@ -3,11 +3,12 @@ package scala.build.tests
import com.eed3si9n.expecty.Expecty.expect

import java.io.IOException
import scala.build.{BuildThreads, Directories, LocalRepo}
import scala.build.{BuildThreads, Directories, LocalRepo, Position, Positioned}
import scala.build.options.{BuildOptions, InternalOptions, MaybeScalaVersion}
import scala.build.tests.util.BloopServer
import build.Ops.EitherThrowOps
import scala.build.Position
import dependency.AnyDependency

class DirectiveTests extends munit.FunSuite {

Expand Down Expand Up @@ -87,4 +88,23 @@ class DirectiveTests extends munit.FunSuite {
}
}

test("resolve toolkit dependency") {
val testInputs = TestInputs(
os.rel / "simple.sc" ->
"""//> using toolkit "latest"
|""".stripMargin
)
testInputs.withBuild(baseOptions, buildThreads, bloopConfigOpt) {
(_, _, maybeBuild) =>
val build = maybeBuild.orThrow
val dep = build.options.classPathOptions.extraDependencies.toSeq.headOption
assert(dep.nonEmpty)

val toolkitDep = dep.get.value
expect(toolkitDep.organization == "org.virtuslab")
expect(toolkitDep.name == "toolkit")
expect(toolkitDep.version == "latest.release")
}
}

}
Expand Up @@ -16,6 +16,7 @@ import scala.build.EitherCps.{either, value}
import scala.build.*
import scala.build.blooprifle.BloopRifleConfig
import scala.build.compiler.{BloopCompilerMaker, ScalaCompilerMaker, SimpleScalaCompilerMaker}
import scala.build.directives.DirectiveDescription
import scala.build.errors.{AmbiguousPlatformError, BuildException}
import scala.build.input.{Element, Inputs, ResourceDirectory}
import scala.build.interactive.Interactive
Expand All @@ -24,6 +25,7 @@ import scala.build.internal.CsLoggerUtil.*
import scala.build.internal.{Constants, FetchExternalBinary, OsLibc, Util}
import scala.build.options.ScalaVersionUtil.fileWithTtl0
import scala.build.options.{Platform, ScalacOpt, ShadowingSeq}
import scala.build.preprocessing.directives.Toolkit
import scala.build.options as bo
import scala.cli.ScalaCli
import scala.cli.commands.publish.ConfigUtil.*
Expand Down Expand Up @@ -180,6 +182,10 @@ final case class SharedOptions(
@ValueDescription("/example/path")
@Tag(tags.must)
compilationOutput: Option[String] = None,
@HelpMessage("Add toolkit to classPath")
@ValueDescription("version|latest")
@Name("toolkit")
withToolkit: Option[String] = None
) extends HasLoggingOptions {
// format: on

Expand Down Expand Up @@ -310,7 +316,7 @@ final case class SharedOptions(
SharedOptions.parseDependencies(
dependencies.dependency.map(Positioned.none),
ignoreErrors
)
) ++ SharedOptions.resolveToolkitDependency(withToolkit)
)
),
internal = bo.InternalOptions(
Expand Down Expand Up @@ -623,4 +629,7 @@ object SharedOptions {
}
}

private def resolveToolkitDependency(toolkitVersion: Option[String])
: Seq[Positioned[AnyDependency]] =
toolkitVersion.toList.map(Positioned.commandLine).map(Toolkit.resolveDependency)
}
Expand Up @@ -20,4 +20,20 @@ class RunOptionsTests extends munit.FunSuite {
expect(buildOptions.notForBloopOptions.scalaPyVersion.contains(ver))
}

test("resolve toolkit dependency") {
val runOptions = RunOptions(
shared = SharedOptions(
withToolkit = Some("latest")
)
)
val buildOptions = Run.buildOptions(runOptions).value
val dep = buildOptions.classPathOptions.extraDependencies.toSeq.headOption
assert(dep.nonEmpty)

val toolkitDep = dep.get.value
expect(toolkitDep.organization == "org.virtuslab")
expect(toolkitDep.name == "toolkit")
expect(toolkitDep.version == "latest.release")
}

}
@@ -0,0 +1,47 @@
package scala.build.preprocessing.directives

import coursier.core.{Repository, Version}
import dependency.*

import scala.annotation.tailrec
import scala.build.EitherCps.{either, value}
import scala.build.directives.*
import scala.build.errors.BuildException
import scala.build.internal.Constants
import scala.build.options.{BuildOptions, ClassPathOptions, JavaOpt, Scope, ShadowingSeq}
import scala.build.{Artifacts, Logger, Positioned, options}
import scala.cli.commands.SpecificationLevel

@DirectiveGroupName("Toolkit")
@DirectiveExamples("//> using toolkit \"0.1.0\"")
@DirectiveExamples("//> using toolkit \"latest\"")
@DirectiveUsage(
"//> using toolkit _version_",
"`//> using toolkit` _version_"
)
@DirectiveDescription("Use a toolkit as dependency")
@DirectiveLevel(SpecificationLevel.SHOULD)
// format: off
final case class Toolkit(
toolkit: Option[Positioned[String]] = None
) extends HasBuildOptions {
// format: on
def buildOptions: Either[BuildException, BuildOptions] = {
val toolkitDep =
toolkit.toList.map(Toolkit.resolveDependency)
val buildOpt = BuildOptions(
classPathOptions = ClassPathOptions(
extraDependencies = ShadowingSeq.from(toolkitDep)
)
)
Right(buildOpt)
}
}

object Toolkit {
def resolveDependency(toolkitVersion: Positioned[String]) = toolkitVersion.map(version =>
val v = if version == "latest" then "latest.release" else version
dep"${Constants.toolkitOrganization}::${Constants.toolkitName}:$v"
)
val handler: DirectiveHandler[Toolkit] = DirectiveHandler.derive
}
Expand Up @@ -1057,4 +1057,19 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String])
expect(output.contains(exceptionMsg))
}
}

test("should add toolkit to classpath") {
val inputs = TestInputs(
os.rel / "Hello.scala" ->
s"""object Hello extends App {
| println(os.pwd) // os lib should be added to classpath by toolkit
|}""".stripMargin
)
inputs.fromRoot { root =>
val output = os.proc(TestUtil.cli, ".", "--toolkit", "0.1.4")
.call(cwd = root).out.trim()

expect(output == root.toString())
}
}
}
1 change: 1 addition & 0 deletions project/deps.sc
Expand Up @@ -177,6 +177,7 @@ object Deps {
def svm = ivy"org.graalvm.nativeimage:svm:$graalVmVersion"
def swoval = ivy"com.swoval:file-tree-views:2.1.9"
def testInterface = ivy"org.scala-sbt:test-interface:1.0"
def toolkit = ivy"org.virtuslab:toolkit:0.1.0"
def usingDirectives = ivy"org.virtuslab:using_directives:0.0.10"
// Lives at https://github.com/scala-cli/no-crc32-zip-input-stream, see #865
// This provides a ZipInputStream that doesn't verify CRC32 checksums, that users
Expand Down
6 changes: 6 additions & 0 deletions website/docs/reference/cli-options.md
Expand Up @@ -1408,6 +1408,12 @@ Aliases: `--compile-out`, `--compile-output`, `-d`, `--destination`, `--output-d

Copy compilation results to output directory using either relative or absolute path

### `--with-toolkit`

Aliases: `--toolkit`

Add toolkit to classPath

## Snippet options

Available in commands:
Expand Down
11 changes: 11 additions & 0 deletions website/docs/reference/directives.md
Expand Up @@ -324,6 +324,17 @@ Set the test framework
#### Examples
`//> using testFramework "utest.runner.Framework"`

### Toolkit

Use a toolkit as dependency

`//> using toolkit` _version_

#### Examples
`//> using toolkit "0.1.0"`

`//> using toolkit "latest"`


## target directives

Expand Down
8 changes: 8 additions & 0 deletions website/docs/reference/scala-command/cli-options.md
Expand Up @@ -962,6 +962,14 @@ Aliases: `--compile-out`, `--compile-output`, `-d`, `--destination`, `--output-d

Copy compilation results to output directory using either relative or absolute path

### `--with-toolkit`

Aliases: `--toolkit`

`IMPLEMENTATION specific` per Scala Runner specification

Add toolkit to classPath

## Snippet options

Available in commands:
Expand Down
11 changes: 11 additions & 0 deletions website/docs/reference/scala-command/directives.md
Expand Up @@ -254,3 +254,14 @@ Set the test framework
#### Examples
`//> using testFramework "utest.runner.Framework"`

### Toolkit

Use a toolkit as dependency

`//> using toolkit` _version_

#### Examples
`//> using toolkit "0.1.0"`

`//> using toolkit "latest"`

54 changes: 54 additions & 0 deletions website/docs/reference/scala-command/runner-specification.md
Expand Up @@ -544,6 +544,12 @@ Aliases: `--help-fmt` ,`--fmt-help` ,`--scalafmt-help`



**--with-toolkit**

Add toolkit to classPath

Aliases: `--toolkit`

</details>

---
Expand Down Expand Up @@ -1051,6 +1057,12 @@ Aliases: `--help-fmt` ,`--fmt-help` ,`--scalafmt-help`



**--with-toolkit**

Add toolkit to classPath

Aliases: `--toolkit`

</details>

---
Expand Down Expand Up @@ -1560,6 +1572,12 @@ Aliases: `--help-fmt` ,`--fmt-help` ,`--scalafmt-help`



**--with-toolkit**

Add toolkit to classPath

Aliases: `--toolkit`

**--java-prop-option**

Add java properties. Note that options equal `-Dproperty=value` are assumed to be java properties and don't require to be passed after `--java-prop`.
Expand Down Expand Up @@ -2099,6 +2117,12 @@ Aliases: `--help-fmt` ,`--fmt-help` ,`--scalafmt-help`



**--with-toolkit**

Add toolkit to classPath

Aliases: `--toolkit`

**--java-prop-option**

Add java properties. Note that options equal `-Dproperty=value` are assumed to be java properties and don't require to be passed after `--java-prop`.
Expand Down Expand Up @@ -2660,6 +2684,12 @@ Aliases: `--help-fmt` ,`--fmt-help` ,`--scalafmt-help`



**--with-toolkit**

Add toolkit to classPath

Aliases: `--toolkit`

**--java-prop-option**

Add java properties. Note that options equal `-Dproperty=value` are assumed to be java properties and don't require to be passed after `--java-prop`.
Expand Down Expand Up @@ -3171,6 +3201,12 @@ Aliases: `--help-fmt` ,`--fmt-help` ,`--scalafmt-help`



**--with-toolkit**

Add toolkit to classPath

Aliases: `--toolkit`

**--respect-project-filters**

Use project filters defined in the configuration. Turned on by default, use `--respect-project-filters:false` to disable it.
Expand Down Expand Up @@ -3748,6 +3784,12 @@ Aliases: `--help-fmt` ,`--fmt-help` ,`--scalafmt-help`



**--with-toolkit**

Add toolkit to classPath

Aliases: `--toolkit`

**--java-prop-option**

Add java properties. Note that options equal `-Dproperty=value` are assumed to be java properties and don't require to be passed after `--java-prop`.
Expand Down Expand Up @@ -4322,6 +4364,12 @@ Aliases: `--help-fmt` ,`--fmt-help` ,`--scalafmt-help`



**--with-toolkit**

Add toolkit to classPath

Aliases: `--toolkit`

**--json-options**

Command-line options JSON file
Expand Down Expand Up @@ -5123,6 +5171,12 @@ Aliases: `--help-fmt` ,`--fmt-help` ,`--scalafmt-help`



**--with-toolkit**

Add toolkit to classPath

Aliases: `--toolkit`

**--bsp-directory**

Custom BSP configuration location
Expand Down