diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5df59e4b8..0a868b0d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,7 @@ jobs: run: | cargo install mdbook --no-default-features --features search --vers "^0.4" --locked cargo install mdbook-variables --vers "^0.2" --locked + cargo install mdbook-admonish --vers "^1" --locked export PATH="$PATH:$HOME/.cargo/bin" mdbook --version diff --git a/book.toml b/book.toml index 804a93995..ec81f5aee 100644 --- a/book.toml +++ b/book.toml @@ -3,11 +3,11 @@ authors = ["Eugene Yokota"] language = "en" multilingual = false src = "src/reference" -title = "The book of sbt" +title = "The Book of sbt" [output.html] theme = "theme" -additional-css = ["src/reference/custom-2024.css"] +additional-css = ["src/reference/custom-2024.css", "src/reference/mdbook-admonish.css"] cname = "www.scala-sbt.org" [preprocessor.variables] @@ -15,4 +15,8 @@ cname = "www.scala-sbt.org" [preprocessor.variables.variables] sbt_version = "2.0.0-alpha7" sbt_runner_version = "1.9.8" -scala3ExampleVersion = "3.3.1" +scala3_example_version = "3.3.1" + +[preprocessor.admonish] +command = "mdbook-admonish" +assets_version = "3.0.2" # do not edit: managed by `mdbook-admonish install` diff --git a/src/reference/00-Getting-Started/03-Directories.md b/src/reference/00-Getting-Started/03-Directories.md deleted file mode 100644 index e6f4809cd..000000000 --- a/src/reference/00-Getting-Started/03-Directories.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -out: Directories.html ---- - - [ByExample]: sbt-by-example.html - [Setup]: Setup.html - [Organizing-Build]: Organizing-Build.html - -Directory structure -------------------- - -This page assumes you've [installed sbt][Setup] and seen -[sbt by example][ByExample]. - -### Base directory - -In sbt's terminology, the "base directory" is the directory containing -the project. So if you created a project `hello` containing -`/tmp/foo-build/build.sbt` as in the [sbt by example][ByExample], -`/tmp/foo-build` is your base directory. - -### Source code - -sbt uses the same directory structure as -[Maven](https://maven.apache.org/) for source files by default (all paths -are relative to the base directory): - -``` -src/ - main/ - resources/ - - scala/ -
- scala-2.12/ -
- java/ -
- test/ - resources - - scala/ - - scala-2.12/ - - java/ - -``` - -Other directories in `src/` will be ignored. Additionally, all hidden -directories will be ignored. - -Source code can be placed in the project's base directory as -`hello/app.scala`, which may be OK for small projects, -though for normal projects people tend to keep the projects in -the `src/main/` directory to keep things neat. -The fact that you can place `*.scala` source code in the base directory might seem like -an odd trick, but this fact becomes relevant [later][Organizing-Build]. - -### sbt build definition files - -The build definition is described in `build.sbt` (actually any files named `*.sbt`) in the project's base directory. - -``` -build.sbt -``` - -### Build support files - -In addition to `build.sbt`, `project` directory can contain `.scala` files -that define helper objects and one-off plugins. -See [organizing the build][Organizing-Build] for more. - -``` -build.sbt -project/ - Dependencies.scala -``` - -You may see `.sbt` files inside `project/` but they are not equivalent to -`.sbt` files in the project's base directory. Explaining this will -come [later][Organizing-Build], since you'll need some background information first. - -### Build products - -Generated files (compiled classes, packaged jars, managed files, caches, -and documentation) will be written to the `target` directory by default. - -### Configuring version control - -Your `.gitignore` (or equivalent for other version control systems) should -contain: - -``` -target/ -``` - -Note that this deliberately has a trailing `/` (to match only directories) -and it deliberately has no leading `/` (to match `project/target/` in -addition to plain `target/`). diff --git a/src/reference/README.md b/src/reference/README.md index afe44a3c8..71514ec25 100644 --- a/src/reference/README.md +++ b/src/reference/README.md @@ -1,5 +1,11 @@ -The book of sbt -=============== +The Book of sbt (Draft) +======================= + +```admonish warning +This is a draft documentation of sbt 2.x that is yet to be released. +While the general concept translates to sbt 1.x, +details of both 2.x and this doc are subject to change. +``` ![sbt logo](files/sbt-logo.svg) @@ -11,7 +17,7 @@ makes JAR packages, and publishes them to [Maven Central](https://central.sonaty JVM community's package registry. ```scala -scalaVersion := "{{scala3ExampleVersion}}" +scalaVersion := "{{scala3_example_version}}" ``` You just need one line of `build.sbt` to get started with Scala. diff --git a/src/reference/SUMMARY.md b/src/reference/SUMMARY.md index 82e218655..aa7d572b8 100644 --- a/src/reference/SUMMARY.md +++ b/src/reference/SUMMARY.md @@ -2,13 +2,18 @@ [Introduction](README.md) -# Quick Start - -- [Installing sbt runner](Setup.md) -- [sbt by example](sbt-by-example.md) - ----- - -# Appendix - -- [Setup notes](setup-notes.md) +- [Quick Start]() + - [Installing sbt runner](Setup.md) + - [sbt by example](sbt-by-example.md) +- [Getting Started](guide/index.md) + - [Why sbt exists](guide/why-sbt-exists.md) + - [Creating a new build](guide/sbt-new.md) + - [sbt components](guide/sbt-components.md) + - [Working with an existing build](guide/running.md) + - [Build definition basics](guide/build-definition-basics.md) + - [Library dependency basics](guide/library-dependency-basics.md) + - [Build layout](guide/build-layout.md) + - [sbt with IDEs](guide/IDE.md) +- [sbt Reference]() +- [Appendix]() + - [Setup notes](setup-notes.md) diff --git a/src/reference/00-Getting-Started/01-Setup/00.md b/src/reference/guide/01-Setup/00.md similarity index 100% rename from src/reference/00-Getting-Started/01-Setup/00.md rename to src/reference/guide/01-Setup/00.md diff --git a/src/reference/00-Getting-Started/01-Setup/a.md b/src/reference/guide/01-Setup/a.md similarity index 100% rename from src/reference/00-Getting-Started/01-Setup/a.md rename to src/reference/guide/01-Setup/a.md diff --git a/src/reference/00-Getting-Started/01-Setup/b.md b/src/reference/guide/01-Setup/b.md similarity index 100% rename from src/reference/00-Getting-Started/01-Setup/b.md rename to src/reference/guide/01-Setup/b.md diff --git a/src/reference/00-Getting-Started/01-Setup/c.md b/src/reference/guide/01-Setup/c.md similarity index 100% rename from src/reference/00-Getting-Started/01-Setup/c.md rename to src/reference/guide/01-Setup/c.md diff --git a/src/reference/00-Getting-Started/04-Running.md b/src/reference/guide/04-Running.md similarity index 100% rename from src/reference/00-Getting-Started/04-Running.md rename to src/reference/guide/04-Running.md diff --git a/src/reference/00-Getting-Started/05-Basic-Def.md b/src/reference/guide/05-Basic-Def.md similarity index 93% rename from src/reference/00-Getting-Started/05-Basic-Def.md rename to src/reference/guide/05-Basic-Def.md index 80ebcddca..bee8e01d8 100644 --- a/src/reference/00-Getting-Started/05-Basic-Def.md +++ b/src/reference/guide/05-Basic-Def.md @@ -38,26 +38,6 @@ the `sbt` launcher will download it for you. If this file is not present, the `sbt` launcher will choose an arbitrary version, which is discouraged because it makes your build non-portable. -### What is a build definition? - -A *build definition* is defined in `build.sbt`, -and it consists of a set of projects (of type [`Project`](../api/sbt/Project.html)). -Because the term *project* can be ambiguous, -we often call it a *subproject* in this guide. - -For instance, in `build.sbt` you define -the subproject located in the current directory like this: - -@@snip [build.sbt]($root$/src/sbt-test/ref/basic/build.sbt) {} - -Each subproject is configured by key-value pairs. - -For example, one key is `name` and it maps to a string value, the name of -your subproject. -The key-value pairs are listed under the `.settings(...)` method as follows: - -@@snip [build.sbt]($root$/src/sbt-test/ref/basic/build.sbt) {} - ### How build.sbt defines settings `build.sbt` defines subprojects, which holds a sequence of key-value pairs diff --git a/src/reference/00-Getting-Started/05B-Multi-Project.md b/src/reference/guide/05B-Multi-Project.md similarity index 100% rename from src/reference/00-Getting-Started/05B-Multi-Project.md rename to src/reference/guide/05B-Multi-Project.md diff --git a/src/reference/00-Getting-Started/06-Task-Graph.md b/src/reference/guide/06-Task-Graph.md similarity index 100% rename from src/reference/00-Getting-Started/06-Task-Graph.md rename to src/reference/guide/06-Task-Graph.md diff --git a/src/reference/00-Getting-Started/07A-Scopes.md b/src/reference/guide/07A-Scopes.md similarity index 100% rename from src/reference/00-Getting-Started/07A-Scopes.md rename to src/reference/guide/07A-Scopes.md diff --git a/src/reference/00-Getting-Started/07B-Appending-Values.md b/src/reference/guide/07B-Appending-Values.md similarity index 100% rename from src/reference/00-Getting-Started/07B-Appending-Values.md rename to src/reference/guide/07B-Appending-Values.md diff --git a/src/reference/00-Getting-Started/07C-Scope-Delegation.md b/src/reference/guide/07C-Scope-Delegation.md similarity index 100% rename from src/reference/00-Getting-Started/07C-Scope-Delegation.md rename to src/reference/guide/07C-Scope-Delegation.md diff --git a/src/reference/00-Getting-Started/08-Library-Dependencies.md b/src/reference/guide/08-Library-Dependencies.md similarity index 100% rename from src/reference/00-Getting-Started/08-Library-Dependencies.md rename to src/reference/guide/08-Library-Dependencies.md diff --git a/src/reference/00-Getting-Started/10-Using-Plugins.md b/src/reference/guide/10-Using-Plugins.md similarity index 100% rename from src/reference/00-Getting-Started/10-Using-Plugins.md rename to src/reference/guide/10-Using-Plugins.md diff --git a/src/reference/00-Getting-Started/11-Custom-Settings.md b/src/reference/guide/11-Custom-Settings.md similarity index 100% rename from src/reference/00-Getting-Started/11-Custom-Settings.md rename to src/reference/guide/11-Custom-Settings.md diff --git a/src/reference/00-Getting-Started/12-Organizing-Build.md b/src/reference/guide/12-Organizing-Build.md similarity index 100% rename from src/reference/00-Getting-Started/12-Organizing-Build.md rename to src/reference/guide/12-Organizing-Build.md diff --git a/src/reference/00-Getting-Started/13-Summary.md b/src/reference/guide/13-Summary.md similarity index 100% rename from src/reference/00-Getting-Started/13-Summary.md rename to src/reference/guide/13-Summary.md diff --git a/src/reference/00-Getting-Started/04B-IDE.md b/src/reference/guide/IDE.md similarity index 90% rename from src/reference/00-Getting-Started/04B-IDE.md rename to src/reference/guide/IDE.md index 46467bc0e..0533a0044 100644 --- a/src/reference/00-Getting-Started/04B-IDE.md +++ b/src/reference/guide/IDE.md @@ -1,6 +1,3 @@ ---- -out: IDE.html ---- [metals]: https://scalameta.org/metals/ [intellij]: https://www.jetbrains.com/idea/ @@ -14,8 +11,8 @@ out: IDE.html [nvim-metals]: https://github.com/scalameta/nvim-metals [lsp.lua]: https://github.com/scalameta/nvim-metals/discussions/39#discussion-82302 -IDE Integration ---------------- +sbt with IDEs +============= While it's possible to code Scala with just an editor and sbt, most programmers today use an Integrated Development Environment, or IDE for short. @@ -37,12 +34,12 @@ Metals in turn supports different _build servers_ including sbt via the [Build S To use Metals on VS Code: 1. Install Metals from Extensions tab:
- ![Metals](files/metals0.png) + ![Metals](../files/metals0.png) 2. Open a directory containing a `build.sbt` file. 3. From the menubar, run View > Command Palette... (`Cmd-Shift-P` on macOS) "Metals: Switch build server", and select "sbt"
- ![Metals](files/metals2.png) + ![Metals](../files/metals2.png) 4. Once the import process is complete, open a Scala file to see that code completion works:
- ![Metals](files/metals3.png) + ![Metals](../files/metals3.png) Use the following setting to opt-out some of the subprojects from BSP. @@ -56,10 +53,10 @@ the actual building work. #### Interactive debugging on VS Code 1. Metals supports interactive debugging by setting break points in the code:
- ![Metals](files/metals4.png) + ![Metals](../files/metals4.png) 2. Interactive debugging can be started by right-clicking on an unit test, and selecting "Debug Test." When the test hits a break point, you can inspect the values of the variables:
- ![Metals](files/metals5.png) + ![Metals](../files/metals5.png) See [Debugging][vscode-debugging] page on VS Code documentation for more details on how to navigate an interactive debugging session. @@ -68,7 +65,7 @@ See [Debugging][vscode-debugging] page on VS Code documentation for more details While Metals uses sbt as the build server, we can also log into the same sbt session using a thin client. - From Terminal section, type in `sbt --client`
- ![Metals](files/metals6.png) + ![Metals](../files/metals6.png) This lets you log into the sbt session Metals has started. In there you can call `testOnly` and other tasks with the code already compiled. @@ -83,9 +80,9 @@ This is a more traditional approach that might be more reliable than using BSP a To import a build to IntelliJ IDEA: 1. Install Scala plugin on the Plugins tab:
- ![IntelliJ](files/intellij1.png) + ![IntelliJ](../files/intellij1.png) 2. From Projects, open a directory containing a `build.sbt` file.
- ![IntelliJ](files/intellij2.png) + ![IntelliJ](../files/intellij2.png) 3. Once the import process is complete, open a Scala file to see that code completion works. IntelliJ Scala plugin uses its own lightweight compilation engine to detect errors, which is fast but sometimes incorrect. Per [compiler-based highlighting][intellij-scala-plugin-2021-2], IntelliJ can be configured to use the Scala compiler for error highlighting. @@ -93,11 +90,11 @@ IntelliJ Scala plugin uses its own lightweight compilation engine to detect erro #### Interactive debugging with IntelliJ IDEA 1. IntelliJ supports interactive debugging by setting break points in the code:
- ![IntelliJ](files/intellij4.png) + ![IntelliJ](../files/intellij4.png) 2. Interactive debugging can be started by right-clicking on an unit test, and selecting "Debug '<test name>'."   Alternatively, you can click the green "run" icon on the left part of the editor near the unit test. When the test hits a break point, you can inspect the values of the variables:
- ![IntelliJ](files/intellij5.png) + ![IntelliJ](../files/intellij5.png) See [Debug Code][intellij-debugging] page on IntelliJ documentation for more details on how to navigate an interactive debugging session. @@ -147,16 +144,16 @@ To use sbt as build server on IntelliJ: 1. Install Scala plugin on the Plugins tab. 2. To use the BSP approach, do not use Open button on the Project tab:
- ![IntelliJ](files/intellij7.png) + ![IntelliJ](../files/intellij7.png) 3. From menubar, click New > "Project From Existing Sources", or Find Action (`Cmd-Shift-P` on macOS) and type "Existing" to find "Import Project From Existing Sources":
- ![IntelliJ](files/intellij8.png) + ![IntelliJ](../files/intellij8.png) 4. Open a `build.sbt` file. Select **BSP** when prompted:
- ![IntelliJ](files/intellij9.png) + ![IntelliJ](../files/intellij9.png) 5. Select **sbt (recommended)** as the tool to import the BSP workspace:
- ![IntelliJ](files/intellij10.png) + ![IntelliJ](../files/intellij10.png) 6. Once the import process is complete, open a Scala file to see that code completion works:
- ![IntelliJ](files/intellij11.png) + ![IntelliJ](../files/intellij11.png) Use the following setting to opt-out some of the subprojects from BSP. @@ -165,7 +162,7 @@ bspEnabled := false ``` - Open Preferences, search BSP and check "build automatically on file save", and uncheck "export sbt projects to Bloop before import":
- ![IntelliJ](files/intellij12.png) + ![IntelliJ](../files/intellij12.png) When you make changes to the code and save them (`Cmd-S` on macOS), IntelliJ will invoke sbt to do the actual building work. @@ -177,7 +174,7 @@ See also Igal Tabachnik's [Using BSP effectively in IntelliJ and Scala](https:// We can also log into the existing sbt session using the thin client. - From Terminal section, type in `sbt --client` - ![IntelliJ](files/intellij6.png) + ![IntelliJ](../files/intellij6.png) This lets you log into the sbt session IntelliJ has started. In there you can call `testOnly` and other tasks with the code already compiled. @@ -204,40 +201,40 @@ Per `lsp.lua`, `g:metals_status` should be displayed on the status line, which c 2. Run `:MetalsInstall` when prompted. 3. Run `:MetalsStartServer`. 4. If the status line is set up, you should see something like "Connecting to sbt" or "Indexing."
- + 5. Code completion works when you're in Insert mode, and you can tab through the candidates:
- + - A build is triggered upon saving changes, and compilation errors are displayed inline:
- + #### Go to definition 1. You can jump to definition of the symbol under cursor by using `gD` (exact keybinding can be customized):
- + 2. Use `Ctrl-O` to return to the old buffer. #### Hover - To display the type information of the symbol under cursor, like hovering, use `K` in Normal mode:
- + #### Listing diagnostics 1. To list all compilation errors and warnings, use `aa`:
- + 2. Since this is in the standard quickfix list, you can use the command such as `:cnext` and `:cprev` to nagivate through the errors and warnings. 3. To list just the errors, use `ae`. #### Interactive debugging with Neovim 1. Thanks to nvim-dap, Neovim supports interactive debugging. Set break points in the code using `dt`:
- + 2. Nagivate to a unit test, confirm that it's built by hovering (`K`), and then "debug continue" (`dc`) to start a debugger. Choose "1: RunOrTest" when prompted. 3. When the test hits a break point, you can inspect the values of the variables by debug hovering (`dK`):
- + 4. "debug continue" (`dc`) again to end the session. See [nvim-metals][nvim-metals] regarding further details. @@ -248,6 +245,6 @@ We can also log into the existing sbt session using the thin client. 1. In a new vim window type `:terminal` to start the built-in terminal. 2. Type in `sbt --client`
- + Even though it's inside Neovim, tab completion etc works fine inside. diff --git a/src/reference/guide/build-definition-basics.md b/src/reference/guide/build-definition-basics.md new file mode 100644 index 000000000..8c864e88e --- /dev/null +++ b/src/reference/guide/build-definition-basics.md @@ -0,0 +1,115 @@ +Build definition basics +======================= + +This page discusses the `build.sbt` build definition. + +### What is a build definition? + +A *build definition* is defined in `build.sbt`, +and it consists of a set of projects (of type [`Project`](../api/sbt/Project.html)). +Because the term *project* can be ambiguous, +we often call it a *subproject* in this guide. + +For instance, in `build.sbt` you define +the subproject located in the current directory like this: + +```scala +{{#include ../../../src/sbt-test/ref/bare/build.sbt}} +``` + +or more explicitly: + +```scala +{{#include ../../../src/sbt-test/ref/basic/build.sbt}} +``` + +Each subproject is configured by key-value pairs. +For example, one key is `name` and it maps to a string value, the name of +your subproject. +The key-value pairs are listed under the `.settings(...)` method. + +build.sbt DSL +------------- + +`build.sbt` defines subprojects using a DSL called build.sbt DSL, which is based on Scala. +Initially you can use build.sbt DSL, like a YAML file, declaring just `scalaVersion` and `libraryDependencies`, +but it can supports more features to keep the build definition organized as the build grows larger. + +### Typed setting expression + +Let's take a closer look at the `build.sbt` DSL: + +```scala +organization := "com.example" +^^^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^^^^^^ +key operator (setting/task) body +``` + +Each entry is called a *setting expression*. +Some among them are also called task expressions. +We will see more on the difference later in this page. + +A setting expression consists of three parts: + +1. Left-hand side is a *key*. +2. *Operator*, which in this case is `:=` +3. Right-hand side is called the *body*, or the *setting/task body*. + +On the left-hand side, `name`, `version`, and `scalaVersion` are *keys*. +A key is an instance of +[`SettingKey[A]`](../../api/sbt/SettingKey.html), +[`TaskKey[A]`](../../api/sbt/TaskKey.html), or +[`InputKey[A]`](../../api/sbt/InputKey.html) where `A` is the +expected value type. + +Because key `name` is typed to `SettingKey[String]`, +the `:=` operator on `name` is also typed specifically to `String`. +If you use the wrong value type, the build definition will not compile: + +```scala +name := 42 // will not compile +``` + +### `val`s and `lazy val`s + +To avoid repeating the same information, like the version number for a library, +`build.sbt` may be interspersed with `val`s, `lazy val`s, and `def`s. + +```scala +val toolkitV = "0.2.0" +val toolkit = "org.scala-lang" %% "toolkit" % toolkitV +val toolkitTest = "org.scala-lang" %% "toolkit-test" % toolkitV + +scalaVersion := "{{scala3_example_version}}" +libraryDependencies += toolkit +libraryDependencies += (toolkitTest % Test) +``` + +In the above, `val` defines a variable, which are initialized from the top to bottom. +This means that `toolkitV` must be defined before it is referenced. + +Here's a bad example: + +```scala +// bad example +val toolkit = "org.scala-lang" %% "toolkit" % toolkitV // uninitialized reference! +val toolkitTest = "org.scala-lang" %% "toolkit-test" % toolkitV // uninitialized reference! +val toolkitV = "0.2.0" +``` + +sbt will fail to load with `java.lang.ExceptionInInitializerError` cased by a `NullPointerException` if your build.sbt contains an uninitialized forward reference. +One way to let the compiler fix this is to define the variables as `lazy`: + +```scala +lazy val toolkit = "org.scala-lang" %% "toolkit" % toolkitV +lazy val toolkitTest = "org.scala-lang" %% "toolkit-test" % toolkitV +lazy val toolkitV = "0.2.0" +``` + +Some frown upon gratuitous `lazy val`s, but Scala 3 lazy vals are efficient, +and we think it makes the build definition more robust for copy-pasting. + +```admonish note +Top-level objects and classes are not allowed in `build.sbt`. +Those should go in the `project/` directory as Scala source files. +``` diff --git a/src/reference/guide/build-layout.md b/src/reference/guide/build-layout.md new file mode 100644 index 000000000..890801061 --- /dev/null +++ b/src/reference/guide/build-layout.md @@ -0,0 +1,112 @@ + + [ByExample]: sbt-by-example.html + [Setup]: Setup.html + [Organizing-Build]: Organizing-Build.html + +Build layout +============ + +sbt uses conventions for file placement to make it easy to dive into a new sbt build: + +``` +. +├── build.sbt +├── project/ +│ ├── build.properties +│ ├── Dependencies.scala +│ └── plugins.sbt +├── src/ +│ ├── main/ +│ │ ├── java/ +│ │ ├── resources/ +│ │ ├── scala/ +│ │ └── scala-2.13/ +│ └── test/ +│ ├── java/ +│ ├── resources/ +│ ├── scala/ +│ └── scala-2.13/ +├── subproject-core/ +│ └── src/ +│ ├── main/ +│ └── test/ +├─── subproject-util/ +│ └── src/ +│ ├── main/ +│ └── test/ +└── target/ +``` + +- The local root directory `.` is the starting point of your build. +- In sbt's terminology, the *base directory* is the directory containing the subproject. In the above, `.`, `subproject-core`, and `subproject-util` are base directories. +- The build definition is described in `build.sbt` (actually any files named `*.sbt`) in the local root directory. +- The sbt version is tracked in `project/build.properties`. +- Generated files (compiled classes, packaged jars, managed files, caches, +and documentation) will be written to the `target` directory by default. + +### Build support files + +In addition to `build.sbt`, `project` directory can contain `.scala` files +that define helper objects and one-off plugins. +See [organizing the build][Organizing-Build] for more. + +``` +. +├── build.sbt +├── project/ +│ ├── build.properties +│ ├── Dependencies.scala +│ └── plugins.sbt +.... +``` + +You may see `.sbt` files inside `project/` but they are not equivalent to +`.sbt` files in the project's base directory. Explaining this will +come [later][Organizing-Build], since you'll need some background information first. + +### Source code + +sbt uses the same directory structure as +[Maven](https://maven.apache.org/) for source files by default (all paths +are relative to the base directory): + +``` +.... +├── src/ +│ ├── main/ +│ │ ├── java/
+│ │ ├── resources/ +│ │ ├── scala/
+│ │ └── scala-2.13/
+│ └── test/ +│ ├── java/ +│ ├── resources/ +│ ├── scala/ +│ └── scala-2.13/ +.... +``` + +Other directories in `src/` will be ignored. Additionally, all hidden +directories will be ignored. + +Source code can be placed in the project's base directory as +`hello/app.scala`, which may be OK for small projects, +though for normal projects people tend to keep the projects in +the `src/main/` directory to keep things neat. +The fact that you can place `*.scala` source code in the base directory might seem like +an odd trick, but this fact becomes relevant [later][Organizing-Build]. + +### Configuring version control + +Your `.gitignore` (or equivalent for other version control systems) should +contain: + +``` +target/ +``` + +Note that this deliberately has a trailing `/` (to match only directories) +and it deliberately has no leading `/` (to match `project/target/` in +addition to plain `target/`). + +sbt automates building, testing, and deployment of your subprojects from information in the build definition. diff --git a/src/reference/00-Getting-Started/00.md b/src/reference/guide/index.md similarity index 56% rename from src/reference/00-Getting-Started/00.md rename to src/reference/guide/index.md index 4419c57c4..c28b9b0fa 100644 --- a/src/reference/00-Getting-Started/00.md +++ b/src/reference/guide/index.md @@ -1,7 +1,3 @@ ---- -out: Getting-Started.html ---- - [Basic-Def]: Basic-Def.html [Scopes]: Scopes.html [Task-Graph]: Task-Graph.html @@ -18,13 +14,3 @@ The Getting Started Guide covers the concepts you need to know to create and maintain an sbt build definition. It is *highly recommended* to read the Getting Started Guide! - -If you are in a huge hurry, the most important conceptual background can -be found in [build definition][Basic-Def], [scopes][Scopes], and -[task graph][Task-Graph]. But we don't promise that -it's a good idea to skip the other pages in the guide. - -It's best to read in order, as later pages in the Getting Started Guide -build on concepts introduced earlier. - -Thanks for trying out sbt and *have fun*! diff --git a/src/reference/guide/library-dependency-basics.md b/src/reference/guide/library-dependency-basics.md new file mode 100644 index 000000000..f83e890a1 --- /dev/null +++ b/src/reference/guide/library-dependency-basics.md @@ -0,0 +1,89 @@ +Library dependency basics +========================= + +This page explains the basics of library dependency management using sbt. + +sbt uses [Coursier](https://get-coursier.io/) to implement managed +dependencies, so if you're familiar with package managers like Coursier, +npm, PIP, etc you won't have much trouble. + +The `libraryDependencies` key +----------------------------- + +Declaring a dependency looks like this, where `groupId`, `artifactId`, and +`revision` are strings: + +```scala +libraryDependencies += groupID % artifactID % revision +``` + +or like this, where `configuration` can be a string or a `Configuration` value (such as `Test`): + +```scala +libraryDependencies += groupID % artifactID % revision % configuration +``` + +When you run: + +``` +> compile +``` + +sbt will automatically resolve the dependencies and download the JAR files. + +### Getting the right Scala version with `%%` + +If you use `organization %% moduleName % version` rather than +`organization % moduleName % version` (the difference is the double `%%` after +the `organization`), sbt will add your project's binary Scala version to the artifact +name. This is just a shortcut. You could write this without the `%%`: + +```scala +libraryDependencies += "org.scala-lang" % "toolkit_3" % "0.2.0" +``` + +Assuming the `scalaVersion` for your build is 3.x, the following is +identical (note the double `%%` after `"toolkit"`): + +```scala +libraryDependencies += "org.scala-lang" %% "toolkit" % "0.2.0" +``` + +The idea is that many dependencies are compiled for multiple Scala +versions, and you'd like to get the one that matches your project +to ensure binary compatibility. + +Tracking dependencies in one place +---------------------------------- + +`.scala` files under `project` becomes part of the build definition, +which we can use to track dependencies in one place by +creating a file named `project/Dependencies.scala`. + + +```scala +// place this file at project/Dependencies.scala + +import sbt.* + +object Dependencies: + // versions + lazy val toolkitV = "0.2.0" + + // libraries + val toolkit = "org.scala-lang" %% "toolkit" % toolkitV + val toolkitTest = "org.scala-lang" %% "toolkit-test" % toolkitV +end Dependencies +``` + +The `Dependencies` object will be available in `build.sbt`. +To make it easier to use the `val`s defined in it, import `Dependencies.*` in your build.sbt file. + +```scala +import Dependencies.* + +scalaVersion := "{{scala3_example_version}}" +name := "something" +libraryDependencies += toolkit +libraryDependencies += toolkitTest % Test +``` diff --git a/src/reference/guide/running.md b/src/reference/guide/running.md new file mode 100644 index 000000000..2f62cf7ea --- /dev/null +++ b/src/reference/guide/running.md @@ -0,0 +1,184 @@ + [sbt-components]: ./sbt-components.md + +Working with an existing build +============================== + +This page describes how to use sbt once you have set up your project. +This page assumes you've read [sbt components][sbt-components]. + +If you pull a repository that uses sbt, it's fairly easy to get started. +First, get the package from GitHub, or some other repository. + +```bash +$ git clone https://github.com/scalanlp/breeze.git +$ cd breeze +``` + +### sbt shell with sbtn + +As mentioned in [sbt components][sbt-components], start an sbt shell: + +``` +$ sbt --client +``` + +This should display something like the following: + +```bash +$ sbt --client +[info] entering *experimental* thin client - BEEP WHIRR +[info] server was not detected. starting an instance +[info] welcome to sbt 1.5.5 (Azul Systems, Inc. Java 1.8.0_352) +[info] loading global plugins from /Users/eed3si9n/.sbt/1.0/plugins +[info] loading settings for project breeze-build from plugins.sbt ... +[info] loading project definition from /private/tmp/breeze/project +Downloading https://repo1.maven.org/maven2/org/scalanlp/sbt-breeze-expand-codegen_2.12_1.0/0.2.1/sbt-breeze-expand-codegen-0.2.1.pom +.... +[info] sbt server started at local:///Users/eed3si9n/.sbt/1.0/server/dd982e07e85c7de1b618/sock +[info] terminate the server with `shutdown` +[info] disconnect from the server with `exit` +sbt:breeze-parent> +``` + +projects command +---------------- + +Let's explore the build by listing out the subprojects with `projects` command: + +``` +sbt:breeze-parent> projects +[info] In file:/private/tmp/breeze/ +[info] benchmark +[info] macros +[info] math +[info] natives +[info] * root +[info] viz +``` + +This shows that this build has 6 subprojects, including the current subproject called `root`. + +tasks command +------------- + +Similarly, we can list the tasks availble to this build using `tasks` command: + +``` +sbt:breeze-parent> tasks + +This is a list of tasks defined for the current project. +It does not list the scopes the tasks are defined in; use the 'inspect' command for that. +Tasks produce values. Use the 'show' command to run the task and print the resulting value. + + bgRun Start an application's default main class as a background job + bgRunMain Start a provided main class as a background job + clean Deletes files produced by the build, such as generated sources, compiled classes, and task caches. + compile Compiles sources. + console Starts the Scala interpreter with the project classes on the classpath. + consoleProject Starts the Scala interpreter with the sbt and the build definition on the classpath and useful imports. + consoleQuick Starts the Scala interpreter with the project dependencies on the classpath. + copyResources Copies resources to the output directory. + doc Generates API documentation. + package Produces the main artifact, such as a binary jar. This is typically an alias for the task that actually does the packaging. + packageBin Produces a main artifact, such as a binary jar. + packageDoc Produces a documentation artifact, such as a jar containing API documentation. + packageSrc Produces a source artifact, such as a jar containing sources and resources. + publish Publishes artifacts to a repository. + publishLocal Publishes artifacts to the local Ivy repository. + publishM2 Publishes artifacts to the local Maven repository. + run Runs a main class, passing along arguments provided on the command line. + runMain Runs the main class selected by the first argument, passing the remaining arguments to the main method. + test Executes all tests. + testOnly Executes the tests provided as arguments or all tests if no arguments are provided. + testQuick Executes the tests that either failed before, were not run or whose transitive dependencies changed, among those provided as arguments. + update Resolves and optionally retrieves dependencies, producing a report. + +More tasks may be viewed by increasing verbosity. See 'help tasks' +``` + +### compile + +The `compile` tasks compiles the sources, after resolving and downloading the library dependendies. + +``` +> compile +``` + +This should display something like the following: + +``` +sbt:breeze-parent> compile +[info] compiling 341 Scala sources and 1 Java source to /private/tmp/breeze/math/target/scala-3.1.3/classes ... + | => math / Compile / compileIncremental 51s +``` + +### run + +The `run` task runs the main class for the subproject. +In the sbt shell, type `math/run`: + +``` +> math/run +``` + +`math/run` means `run` task, scoped to `math` subproject. +This should display something like the following: + +``` +sbt:breeze-parent> math/run +[info] Scala version: 3.1.3 true +.... + +Multiple main classes detected. Select one to run: + [1] breeze.optimize.linear.NNLS + [2] breeze.optimize.proximal.NonlinearMinimizer + [3] breeze.optimize.proximal.QuadraticMinimizer + [4] breeze.util.UpdateSerializedObjects + +Enter number: +``` + +Enter `1` at the prompt. + +### testQuick + +The `testQuick` task tests either the tests that failed before, were not run, or whose transitive dependencies changed. + +``` +> math/testQuick +``` + +This should display something like the following: + +``` +sbt:breeze-parent> math/testQuick +[info] FeatureVectorTest: +[info] - axpy fv dv (1 second, 106 milliseconds) +[info] - axpy fv vb (9 milliseconds) +[info] - DM mult (19 milliseconds) +[info] - CSC mult (32 milliseconds) +[info] - DM trans mult (4 milliseconds) +.... +[info] Run completed in 58 seconds, 183 milliseconds. +[info] Total number of tests run: 1285 +[info] Suites: completed 168, aborted 0 +[info] Tests: succeeded 1285, failed 0, canceled 0, ignored 0, pending 0 +[info] All tests passed. +[success] Total time: 130 s (02:10), completed Feb 19, 2024 +``` + +Watch (tilde) command +--------------------- + +To speed up your edit-compile-test cycle, you can ask sbt to +automatically recompile or run tests whenever you save a source file. + +Make a command run when one or more source files change by prefixing the +command with `~`. For example, in sbt shell try: + +``` +> ~testQuick +``` + +Press enter to stop watching for changes. +You can use the `~` prefix with either sbt shell or batch mode. diff --git a/src/reference/guide/sbt-components.md b/src/reference/guide/sbt-components.md new file mode 100644 index 000000000..911e090b5 --- /dev/null +++ b/src/reference/guide/sbt-components.md @@ -0,0 +1,118 @@ +sbt components +============== + +sbt runner +---------- + +An sbt build is executed using the `sbt` runner, also called "sbt-the-shell-script" to distinguish from other components. Important thing to note is that sbt runner is designed to run **any version** of sbt. + +### Specifying sbt version with project/build.properties + +The sbt runner executes a subcomponent called sbt launcher, which reads `project/build.properties` to determine the sbt version for the build, and downloads the artifacts if needed: + +``` +sbt.version={{sbt_version}} +``` + +This means that: + +- Anyone who checkouts your build would get the same sbt version, regardless of *sbt runner* they may have installed on their machines. +- The change of sbt version can be tracked in a version control system, like git. + +### sbtn (`sbt --client`) + +sbtn (native thin client) is a subcomponent of the sbt runner, called when you pass `--client` flag to the sbt runner, and is used to send commands to the sbt server. It is called sbtn because it is compiled to native code using GraalVM native-image. The protocol between sbtn and sbt server is stable enough that it should work between **most recent versions** of sbt. + +sbt server +---------- + +The sbt server is the actual build tool whose version is specified using `project/build.properties`. The sbt server acts as a cashier to take commands from sbtn and editors. + +### Coursier + +The sbt server runs [Couriser][coursier] as a subcomponent to resolve Scala libary, Scala compiler, and any other library dependencies your build needs. + +### Zinc + +Zinc is the incremental compiler for Scala, developed and maintained by sbt project. +An often overlooked aspect of Zinc is that Zinc provides a stable API to invoke **any modern versions** of Scala compiler. Combined with the fact that Coursier can resolve any Scala versions, by installing the sbt runner, you can invoke any modern versions of Scala just by writing a single line `build.sbt`: + +```scala +scalaVersion := "{{scala3_example_version}}" +``` + +### BSP server + +The sbt server supports [Build Server Protocol (BSP)](https://build-server-protocol.github.io/) to list build targets, build them, etc. +This allows IDEs like IntelliJ and Metals to communicate with a running sbt server programmatically. + +Connecting with sbt server +-------------------------- + +Let's look at three ways of connecting to the sbt server. + +### sbt shell using sbtn + +Run `sbt --client` in the working directory of your build: + +```bash +sbt --client +``` + +This should display something like the following: + +```bash +$ sbt --client +[info] server was not detected. starting an instance +[info] welcome to sbt 2.0.0-alpha7 (Azul Systems, Inc. Java 1.8.0_352) +[info] loading project definition from /private/tmp/bar/project +[info] loading settings for project bar from build.sbt ... +[info] set current project to bar (in build file:/private/tmp/bar/) +[info] sbt server started at local:///Users/eed3si9n/.sbt/2.0.0-alpha7/server/d0ac1409c0117a949d47/sock +[info] started sbt server +[info] terminate the server with `shutdown` +[info] disconnect from the server with `exit` +sbt:bar> +``` + +Running sbt with no command line arguments starts sbt shell. sbt shell has a command prompt (with tab completion and history!). + +For example, you could type `compile` at the sbt shell: + +```bash +sbt:bar> compile +``` + +To `compile` again, press up arrow and then enter. + +To leave sbt shell, type `exit` or use `Ctrl-D` (Unix) or `Ctrl-Z` (Windows). + +### Batch mode using sbtn + +You can also run sbt in batch mode: + +```bash +sbt --client compile +sbt --client testOnly TestA +``` + +```bash +$ sbt --client compile +> compile +``` + +### Shutting down sbt server + +Run the following to shutdown all sbt servers on your machine: + +```bash +sbt shutdownall +``` + +Or the following to shutdown just the current one: + +```bash +sbt --client shutdown +``` + + [coursier]: https://get-coursier.io/ diff --git a/src/reference/guide/sbt-new.md b/src/reference/guide/sbt-new.md new file mode 100644 index 000000000..da513ecfb --- /dev/null +++ b/src/reference/guide/sbt-new.md @@ -0,0 +1,117 @@ +Creating a new build +==================== + +To start a new build with `sbt`, use `sbt new`. + +```bash +$ mkdir /tmp/foo +$ cd /tmp/foo +$ sbt new + +Welcome to sbt new! +Here are some templates to get started: + a) scala/toolkit.local - Scala Toolkit (beta) by Scala Center and VirtusLab + b) typelevel/toolkit.local - Toolkit to start building Typelevel apps + c) sbt/cross-platform.local - A cross-JVM/JS/Native project + d) scala/scala3.g8 - Scala 3 seed template + e) scala/scala-seed.g8 - Scala 2 seed template + f) playframework/play-scala-seed.g8 - A Play project in Scala + g) playframework/play-java-seed.g8 - A Play project in Java + i) softwaremill/tapir.g8 - A tapir project using Netty + m) scala-js/vite.g8 - A Scala.JS + Vite project + n) holdenk/sparkProjectTemplate.g8 - A Scala Spark project + o) spotify/scio.g8 - A Scio project + p) disneystreaming/smithy4s.g8 - A Smithy4s project + q) quit +Select a template: +``` + +If you select "a", you will be prompted by more questions: + +```bash +Select a template: a +Scala version (default: 3.3.0): +Scala Toolkit version (default: 0.2.0): +``` + +Hit return key to select the default values. + +``` +[info] Updated file /private/tmp/bar/project/build.properties: set sbt.version to 1.9.8 +[info] welcome to sbt 1.9.8 (Azul Systems, Inc. Java 1.8.0_352) +.... +[info] set current project to bar (in build file:/private/tmp/foo/) +[info] sbt server started at local:///Users/eed3si9n/.sbt/1.0/server/d0ac1409c0117a949d47/sock +[info] started sbt server +sbt:bar> exit +[info] shutting down sbt server +``` + +Here are the files that are created by this template: + +```bash +. +├── build.sbt +├── project +│ └── build.properties +├── src +│ ├── main +│ │ └── scala +│ │ └── example +│ │ └── Main.scala +│ └── test +│ └── scala +│ └── example +│ └── ExampleSuite.scala +└── target +``` + +Let's take a look at the `build.sbt` file: + +```scala +val toolkitV = "0.2.0" +val toolkit = "org.scala-lang" %% "toolkit" % toolkitV +val toolkitTest = "org.scala-lang" %% "toolkit-test" % toolkitV + +scalaVersion := "3.3.0" +libraryDependencies += toolkit +libraryDependencies += (toolkitTest % Test) +``` + +This is called a **build definition**, and it contains the information sbt needs to compile your project. This is written in `.sbt` format, a subset of Scala language. + +Here's what's in `src/main/scala/example/Main.scala`: + +```scala +package example + +@main def main(args: String*): Unit = + println(s"Hello ${args.mkString}") +``` + +This is a Hello world template. We can run it from the sbt shell by starting `sbt --client` and typing `run ` inside the shell: + +``` +$ sbt --client +[info] entering *experimental* thin client - BEEP WHIRR +[info] server was not detected. starting an instance +.... +info] terminate the server with `shutdown` +[info] disconnect from the server with `exit` +sbt:bar> run Raj +[info] running example.main Raj +Hello Raj +[success] Total time: 0 s, completed Feb 18, 2024 2:38:10 PM +``` + +### Giter8 templates + +In addition to a few `.local` templates, `sbt new` integrates with [Giter8](https://www.foundweekends.org/giter8/), +and open templating system that uses GitHub to host templates. For example, `scala/scala3.g8` is maintained by the Scala team to create a new Scala 3 build: + +``` +$ /tmp +$ sbt new scala/scala3.g8 +``` + +[Giter8 wiki](https://github.com/foundweekends/giter8/wiki/giter8-templates) lists over 100 templates that can jump start your new build. diff --git a/src/reference/guide/why-sbt-exists.md b/src/reference/guide/why-sbt-exists.md new file mode 100644 index 000000000..67a60d054 --- /dev/null +++ b/src/reference/guide/why-sbt-exists.md @@ -0,0 +1,55 @@ +Why sbt exists +============== + +Preliminaries +------------- + +In Scala, a library or a executable programs used be compiled using the Scala compiler, `scalac`, or so it is documented in [Scala 3 Book](https://docs.scala-lang.org/scala3/book/taste-hello-world.html) at first: + +```scala +@main def hello() = println("Hello, World!") +``` + +```bash +$ scalac hello.scala +$ scala hello +Hello, World! +``` + +This process gets tedious and slow if we were to invoke `scalac` directly since we'd have to pass all the Scala source file names. + +Furthermore, most non-trivial programs will likely have library dependencies, and will therefore also depend transitively on their dependencies. +This is doubly compilicated for Scala ecosystem because we have Scala 2.12, 2.13 ecosystem, Scala 3.x ecosystem, JVM, JS, and Native platforms. + +Rather than working with JAR files and `scalac`, we can avoid the manual toil by introducing a higher-level subproject abstraction and by using a build tool. + +sbt +--- + +*sbt* is a simple build tool created for Scala and Java. +It lets us declare subprojects and their various dependencies and custom tasks to ensure that we'll always get a fast, repeatable build. + +To accomplish this goal, sbt does several things: + +- The version of sbt itself is tracked in `project/build.properties`. +- Defines a domain-specific language (DSL) called **build.sbt DSL** that can declare Scala version and other subproject information in `build.sbt`. +- Uses Coursier to fetch subprojects dependencies and their dependencies. +- Invokes Zinc to incrementally compile Scala and Java sources. +- Automatically runs tasks in parallel whenever possible. +- Defines conventions on how packages are published to Maven repositories to interoperate with the wider JVM ecosystem. + +To a large extent, sbt normalizes the commands needed to build a given program or library. + +Why build.sbt DSL? +------------------ + +build.sbt DSL makes sbt a unique build tool, +as opposed to other tools that use configuration file formats like YAML, TOML, and XML. +Originally developed around 2010 ~ 2013, `build.sbt` can start almost like a YAML file, declaring just `scalaVersion` and `libraryDependencies`, +but it can supports more features to keep the build definition organized as the build grows larger: + +- To avoid repeating the same information, like the version number for a library, `build.sbt` can declare variables using `val`. +- Uses Scala language constructs like `if` to define settings and tasks, when needed. +- Statically typed settings and tasks, to catch typos and type errors before the build starts. The type also helps passing data from one task from another. +- Provides **structured concurrency** via `Initialized[Task[A]]`. The DSL uses *direct style* `.value` syntax to concisely define task graphs. +- Enpowers the community to extend sbt with plugins that provide custom tasks or language extensions like Scala.JS. diff --git a/src/reference/mdbook-admonish.css b/src/reference/mdbook-admonish.css new file mode 100644 index 000000000..45aeff051 --- /dev/null +++ b/src/reference/mdbook-admonish.css @@ -0,0 +1,348 @@ +@charset "UTF-8"; +:is(.admonition) { + display: flow-root; + margin: 1.5625em 0; + padding: 0 1.2rem; + color: var(--fg); + page-break-inside: avoid; + background-color: var(--bg); + border: 0 solid black; + border-inline-start-width: 0.4rem; + border-radius: 0.2rem; + box-shadow: 0 0.2rem 1rem rgba(0, 0, 0, 0.05), 0 0 0.1rem rgba(0, 0, 0, 0.1); +} +@media print { + :is(.admonition) { + box-shadow: none; + } +} +:is(.admonition) > * { + box-sizing: border-box; +} +:is(.admonition) :is(.admonition) { + margin-top: 1em; + margin-bottom: 1em; +} +:is(.admonition) > .tabbed-set:only-child { + margin-top: 0; +} +html :is(.admonition) > :last-child { + margin-bottom: 1.2rem; +} + +a.admonition-anchor-link { + display: none; + position: absolute; + left: -1.2rem; + padding-right: 1rem; +} +a.admonition-anchor-link:link, a.admonition-anchor-link:visited { + color: var(--fg); +} +a.admonition-anchor-link:link:hover, a.admonition-anchor-link:visited:hover { + text-decoration: none; +} +a.admonition-anchor-link::before { + content: "§"; +} + +:is(.admonition-title, summary.admonition-title) { + position: relative; + min-height: 4rem; + margin-block: 0; + margin-inline: -1.6rem -1.2rem; + padding-block: 0.8rem; + padding-inline: 4.4rem 1.2rem; + font-weight: 700; + background-color: rgba(68, 138, 255, 0.1); + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + display: flex; +} +:is(.admonition-title, summary.admonition-title) p { + margin: 0; +} +html :is(.admonition-title, summary.admonition-title):last-child { + margin-bottom: 0; +} +:is(.admonition-title, summary.admonition-title)::before { + position: absolute; + top: 0.625em; + inset-inline-start: 1.6rem; + width: 2rem; + height: 2rem; + background-color: #448aff; + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + mask-image: url('data:image/svg+xml;charset=utf-8,'); + -webkit-mask-image: url('data:image/svg+xml;charset=utf-8,'); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-size: contain; + content: ""; +} +:is(.admonition-title, summary.admonition-title):hover a.admonition-anchor-link { + display: initial; +} + +details.admonition > summary.admonition-title::after { + position: absolute; + top: 0.625em; + inset-inline-end: 1.6rem; + height: 2rem; + width: 2rem; + background-color: currentcolor; + mask-image: var(--md-details-icon); + -webkit-mask-image: var(--md-details-icon); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-size: contain; + content: ""; + transform: rotate(0deg); + transition: transform 0.25s; +} +details[open].admonition > summary.admonition-title::after { + transform: rotate(90deg); +} + +:root { + --md-details-icon: url("data:image/svg+xml;charset=utf-8,"); +} + +:root { + --md-admonition-icon--admonish-note: url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--admonish-abstract: url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--admonish-info: url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--admonish-tip: url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--admonish-success: url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--admonish-question: url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--admonish-warning: url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--admonish-failure: url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--admonish-danger: url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--admonish-bug: url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--admonish-example: url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--admonish-quote: url("data:image/svg+xml;charset=utf-8,"); +} + +:is(.admonition):is(.admonish-note) { + border-color: #448aff; +} + +:is(.admonish-note) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(68, 138, 255, 0.1); +} +:is(.admonish-note) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #448aff; + mask-image: var(--md-admonition-icon--admonish-note); + -webkit-mask-image: var(--md-admonition-icon--admonish-note); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.admonish-abstract, .admonish-summary, .admonish-tldr) { + border-color: #00b0ff; +} + +:is(.admonish-abstract, .admonish-summary, .admonish-tldr) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(0, 176, 255, 0.1); +} +:is(.admonish-abstract, .admonish-summary, .admonish-tldr) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #00b0ff; + mask-image: var(--md-admonition-icon--admonish-abstract); + -webkit-mask-image: var(--md-admonition-icon--admonish-abstract); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.admonish-info, .admonish-todo) { + border-color: #00b8d4; +} + +:is(.admonish-info, .admonish-todo) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(0, 184, 212, 0.1); +} +:is(.admonish-info, .admonish-todo) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #00b8d4; + mask-image: var(--md-admonition-icon--admonish-info); + -webkit-mask-image: var(--md-admonition-icon--admonish-info); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.admonish-tip, .admonish-hint, .admonish-important) { + border-color: #00bfa5; +} + +:is(.admonish-tip, .admonish-hint, .admonish-important) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(0, 191, 165, 0.1); +} +:is(.admonish-tip, .admonish-hint, .admonish-important) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #00bfa5; + mask-image: var(--md-admonition-icon--admonish-tip); + -webkit-mask-image: var(--md-admonition-icon--admonish-tip); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.admonish-success, .admonish-check, .admonish-done) { + border-color: #00c853; +} + +:is(.admonish-success, .admonish-check, .admonish-done) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(0, 200, 83, 0.1); +} +:is(.admonish-success, .admonish-check, .admonish-done) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #00c853; + mask-image: var(--md-admonition-icon--admonish-success); + -webkit-mask-image: var(--md-admonition-icon--admonish-success); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.admonish-question, .admonish-help, .admonish-faq) { + border-color: #64dd17; +} + +:is(.admonish-question, .admonish-help, .admonish-faq) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(100, 221, 23, 0.1); +} +:is(.admonish-question, .admonish-help, .admonish-faq) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #64dd17; + mask-image: var(--md-admonition-icon--admonish-question); + -webkit-mask-image: var(--md-admonition-icon--admonish-question); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.admonish-warning, .admonish-caution, .admonish-attention) { + border-color: #ff9100; +} + +:is(.admonish-warning, .admonish-caution, .admonish-attention) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(255, 145, 0, 0.1); +} +:is(.admonish-warning, .admonish-caution, .admonish-attention) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #ff9100; + mask-image: var(--md-admonition-icon--admonish-warning); + -webkit-mask-image: var(--md-admonition-icon--admonish-warning); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.admonish-failure, .admonish-fail, .admonish-missing) { + border-color: #ff5252; +} + +:is(.admonish-failure, .admonish-fail, .admonish-missing) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(255, 82, 82, 0.1); +} +:is(.admonish-failure, .admonish-fail, .admonish-missing) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #ff5252; + mask-image: var(--md-admonition-icon--admonish-failure); + -webkit-mask-image: var(--md-admonition-icon--admonish-failure); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.admonish-danger, .admonish-error) { + border-color: #ff1744; +} + +:is(.admonish-danger, .admonish-error) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(255, 23, 68, 0.1); +} +:is(.admonish-danger, .admonish-error) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #ff1744; + mask-image: var(--md-admonition-icon--admonish-danger); + -webkit-mask-image: var(--md-admonition-icon--admonish-danger); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.admonish-bug) { + border-color: #f50057; +} + +:is(.admonish-bug) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(245, 0, 87, 0.1); +} +:is(.admonish-bug) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #f50057; + mask-image: var(--md-admonition-icon--admonish-bug); + -webkit-mask-image: var(--md-admonition-icon--admonish-bug); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.admonish-example) { + border-color: #7c4dff; +} + +:is(.admonish-example) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(124, 77, 255, 0.1); +} +:is(.admonish-example) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #7c4dff; + mask-image: var(--md-admonition-icon--admonish-example); + -webkit-mask-image: var(--md-admonition-icon--admonish-example); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.admonish-quote, .admonish-cite) { + border-color: #9e9e9e; +} + +:is(.admonish-quote, .admonish-cite) > :is(.admonition-title, summary.admonition-title) { + background-color: rgba(158, 158, 158, 0.1); +} +:is(.admonish-quote, .admonish-cite) > :is(.admonition-title, summary.admonition-title)::before { + background-color: #9e9e9e; + mask-image: var(--md-admonition-icon--admonish-quote); + -webkit-mask-image: var(--md-admonition-icon--admonish-quote); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +.navy :is(.admonition) { + background-color: var(--sidebar-bg); +} + +.ayu :is(.admonition), +.coal :is(.admonition) { + background-color: var(--theme-hover); +} + +.rust :is(.admonition) { + background-color: var(--sidebar-bg); + color: var(--sidebar-fg); +} +.rust .admonition-anchor-link:link, .rust .admonition-anchor-link:visited { + color: var(--sidebar-fg); +} diff --git a/src/reference/setup-notes.md b/src/reference/setup-notes.md index 889c647f9..da2cdd130 100644 --- a/src/reference/setup-notes.md +++ b/src/reference/setup-notes.md @@ -19,9 +19,9 @@ OS specific setup $ brew install sbt ``` -:::warning +```admonish warning Homebrew maintainers have added a dependency to JDK 13 because they want to use more brew dependencies ([brew#50649](https://github.com/Homebrew/homebrew-core/issues/50649)). This causes sbt to use JDK 13 even when `java` available on PATH is JDK 8 or 11. To prevent `sbt` from running on JDK 13, install [jEnv](https://www.jenv.be/) or switch to using [SDKMAN](https://sdkman.io/). -::: +``` ### Windows diff --git a/src/sbt-test/ref/bare/build.sbt b/src/sbt-test/ref/bare/build.sbt new file mode 100644 index 000000000..c802dd0b3 --- /dev/null +++ b/src/sbt-test/ref/bare/build.sbt @@ -0,0 +1,2 @@ +scalaVersion := "3.3.1" +name := "Hello" \ No newline at end of file diff --git a/src/sbt-test/ref/bare/test b/src/sbt-test/ref/bare/test new file mode 100644 index 000000000..4e3db8162 --- /dev/null +++ b/src/sbt-test/ref/bare/test @@ -0,0 +1 @@ +> about diff --git a/src/sbt-test/ref/basic/build.sbt b/src/sbt-test/ref/basic/build.sbt index b9253709b..f61d16a14 100644 --- a/src/sbt-test/ref/basic/build.sbt +++ b/src/sbt-test/ref/basic/build.sbt @@ -1,5 +1,5 @@ lazy val root = (project in file(".")) .settings( + scalaVersion := "3.3.1", name := "Hello", - scalaVersion := "2.12.7" )