-
Notifications
You must be signed in to change notification settings - Fork 191
Issue 1747 docs cross compilation #2323
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,144 @@ | ||||||
| --- | ||||||
| id: cross-compilation | ||||||
| title: Cross compilation setups | ||||||
| --- | ||||||
|
|
||||||
| Cross-building the same codebase with Scala 2.13 and Scala 3.3+ is common, but | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a personal preference for cross-building rather than cross-compilation as it puts less emphasis on the compile phase - let's just make sure we use the same term in the header and the body |
||||||
| it collides with how Scalafix resolves rules and compiler options. A rule or | ||||||
| `--scalac-options` flag that only works on Scala 2 can crash Scalafix when the | ||||||
| Scala 3 compilation unit is processed, and vice versa. Until Scalafix grows | ||||||
| conditional configuration, the safest way to avoid those failures is to split | ||||||
|
Comment on lines
+9
to
+10
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no plan to do conditional configuration so the "Until" can be misleading. IMHO, documentation should be about what's available. |
||||||
| your configuration per Scala version and let the build tool wire the right file. | ||||||
|
|
||||||
| ## Why separate configs are required today | ||||||
|
|
||||||
| * Scala 2 only flags such as `-Ywarn-unused-import` or SemanticDB options using | ||||||
| `-P:semanticdb` are rejected by Scala 3. | ||||||
|
Comment on lines
+15
to
+16
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is that impacting the configuration file? That looks like a build tool concern to me. |
||||||
| * Some built-in or custom rules depend on compiler symbols that only exist on | ||||||
| one major version. | ||||||
| * The CLI currently ingests a single `.scalafix.conf`; there is no per-target | ||||||
| override like sbt’s `CrossVersion`. | ||||||
|
|
||||||
| ## File layout suggestion | ||||||
|
|
||||||
| Keep shared defaults in one file and let version-specific files `include` it via | ||||||
| the HOCON `include` syntax. One convenient layout is: | ||||||
|
|
||||||
| ``` | ||||||
| . | ||||||
| ├── project/ | ||||||
| │ └── build config… | ||||||
|
Comment on lines
+29
to
+30
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Irrelevant? also, |
||||||
| └── scalafix/ | ||||||
| ├── common.conf | ||||||
| ├── scala2.conf | ||||||
| └── scala3.conf | ||||||
| ``` | ||||||
|
|
||||||
| `common.conf` | ||||||
| ```scala | ||||||
| rules = [ | ||||||
| DisableSyntax, | ||||||
| OrganizeImports | ||||||
| ] | ||||||
|
|
||||||
| DisableSyntax { | ||||||
| noFinalize = true | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| `scala2.conf` | ||||||
| ```scala | ||||||
| include "common.conf" | ||||||
|
|
||||||
| rules += RemoveUnused | ||||||
|
|
||||||
| // Scala 2 only compilers flags or rule settings | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned elsewhere, we should focus on compatibility (it's not necessarily about compiler flags but it can be new language features - although that's mostly for community rules, that you don't mention)
Suggested change
|
||||||
| RemoveUnused { | ||||||
| imports = true | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| `scala3.conf` | ||||||
| ```scala | ||||||
| include "common.conf" | ||||||
|
|
||||||
| rules += LeakingImplicitClassVal | ||||||
|
|
||||||
| // Scala 3 specific tweaks go here | ||||||
| OrganizeImports { | ||||||
| groupedImports = Keep | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ### Multiple include files | ||||||
|
|
||||||
| You may split out even more granular snippets (for example `linting.conf`, | ||||||
| `rewrites.conf`) and include them from both `scala2.conf` and `scala3.conf`. The | ||||||
| HOCON syntax supports nested includes, so feel free to create the hierarchy that | ||||||
| matches your team conventions. | ||||||
|
|
||||||
| ## Selecting the right config in sbt | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't sbt and CLI be at the same header level? |
||||||
|
|
||||||
| Point `scalafixConfig` at the version-specific file, typically inside a helper | ||||||
| setting applied to all cross-built projects: | ||||||
|
|
||||||
| ```scala | ||||||
| import scalafix.sbt.ScalafixPlugin.autoImport._ | ||||||
|
|
||||||
| lazy val commonSettings = Seq( | ||||||
| scalafixConfig := { | ||||||
| val base = (ThisBuild / baseDirectory).value / "scalafix" | ||||||
| val file = | ||||||
| CrossVersion.partialVersion(scalaVersion.value) match { | ||||||
| case Some((3, _)) => base / "scala3.conf" | ||||||
| case _ => base / "scala2.conf" | ||||||
| } | ||||||
| Some(file) | ||||||
| } | ||||||
| ) | ||||||
|
|
||||||
| lazy val core = project | ||||||
| .settings(commonSettings) | ||||||
| .settings( | ||||||
| scalaVersion := "3.3.3", | ||||||
| crossScalaVersions := Seq("2.13.14", "3.3.3") | ||||||
| ) | ||||||
| ``` | ||||||
|
|
||||||
| For builds that already differentiate per configuration (`Compile`, `Test`, | ||||||
| `IntegrationTest`), you can set `Compile / scalafixConfig` and | ||||||
| `Test / scalafixConfig` separately if the inputs diverge. | ||||||
|
|
||||||
| ### Command-line usage | ||||||
|
|
||||||
| When invoking the CLI directly, pass the desired config with `--config`: | ||||||
|
|
||||||
| ``` | ||||||
| scalafix --config scalafix/scala2.conf --rules RemoveUnused | ||||||
| scalafix --config scalafix/scala3.conf --rules LeakingImplicitClassVal | ||||||
|
Comment on lines
+117
to
+118
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why pass the rules explicitly since part of the doc is about shoing that we can have a different default set within the configuration? |
||||||
| ``` | ||||||
|
|
||||||
| Your CI job can loop over each target Scala version, selecting the matching | ||||||
| config before running `scalafix --check`. | ||||||
|
|
||||||
| ## Recommendations and current limitations | ||||||
|
|
||||||
| * Keep rules that truly work on both versions inside `common.conf`. | ||||||
| * Isolate risky scalac options (`-Wunused`, `-Ywarn-unused-import`, `-P:semanticdb`) | ||||||
| inside each version-specific file or sbt setting. | ||||||
|
Comment on lines
+127
to
+128
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as above - scalac-options are not part of the config so I don't understand that part |
||||||
| * Document in the repository README which rules run on which Scala version to | ||||||
| reduce confusion for new contributors. | ||||||
|
|
||||||
| ### Looking ahead | ||||||
|
|
||||||
| Issue [#1747](https://github.com/scalacenter/scalafix/issues/1747) tracks better | ||||||
| ergonomics for cross compilation. Potential improvements include: | ||||||
|
|
||||||
| * Conditional configuration blocks directly inside `.scalafix.conf` (for example | ||||||
| `if scalaVersion.startsWith("3.")`). | ||||||
| * First-class support for including multiple files via CLI flags. | ||||||
| * Allowing rule selection based on the detected input Scala dialect. | ||||||
|
|
||||||
| Until those land, the include-based layout above is the recommended, battle-tested | ||||||
| approach. | ||||||
|
|
||||||
|
Comment on lines
+132
to
+144
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we should advertize potential improvements in the docs, as it's unclear if there is a need for it, especially as 2.x is on its way out and scalafix is kept updated but no-one is actively adding features to it. As a matter of fact, I was hoping to close #1747 with this doc update. |
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -443,6 +443,23 @@ cs launch scalafix:0.13.0 -- --version # Should say 0.13.0 | |
|
|
||
| ``` | ||
|
|
||
| ### Multiple values for CLI flags | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is merged, you can rebase against main |
||
|
|
||
| Some Scalafix CLI flags accept more than one value (for example `--rules`, | ||
| `--files`, or compiler options). Pass each value by repeating the flag instead | ||
| of trying to comma-separate or space-separate them. For instance, when you need | ||
| to forward several scalac options you would write: | ||
|
|
||
| ``` | ||
| scalafix \ | ||
| --rules RemoveUnused \ | ||
| --scalac-options -Wunused:imports \ | ||
| --scalac-options -Wvalue-discard | ||
| ``` | ||
|
|
||
| The CLI treats those repeated occurrences as a list, so both compiler options | ||
| are forwarded to each Scalafix invocation. | ||
|
|
||
| ## Support in other build tools | ||
|
|
||
| Scalafix is supported in other build tools via externally maintained plugins: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should reference that from the side bar
scalafix/website/sidebars.json
Line 3 in 831c146