- Expose inner Initialize on DynamicDepsInitialize (val inner) in Settings.scala
- Add DynamicDepsInitialize case in INode.scala transform; delegate to inner init
- Include ScopeFilter.scala scalafmt changes
The .all() wrapper is nested inside the task body (Apply), so
setting.init.dynamicDependencies was always Nil. Aggregate
dynamicDependencies from child inits so the lint sees them.
- Add Initialize.dynamicDependencies (Seq[Any]) in util-collection to carry
(AttributeKey, ScopeFilter) from .all() without changing static dependency graph.
- Add DynamicDepsInitialize wrapper and Def.withDynamicDependencies; use them
in SettingKeyAll.all and TaskKeyAll.all when the init is a KeyedInitialize.
- In LintUnused, collect init.dynamicDependencies from all settings, expand
via ScopeFilter.expandDynamicDeps (build ScopeFilter.Data from structure,
apply each filter to get scopes, add ScopedKey(scope, key) to used).
- Add ScopeFilter.dataFromStructure and expandDynamicDeps with try/catch
so bad filters or structure do not break the lint.
**Problem**
Forked console currently pulls in full Zinc, which includes JLine.
**Solution**
This implements a lighter-weight, full Java ForkConsoleMain,
which no longer depends on JLine.
**Problem**
ScalaTest's `AsyncFunSuite` invokes the test framework's event handler **asynchronously**. sbt's `TestFramework` was collecting events in a **`ListBuffer`**, which is not thread-safe. With multiple suites (e.g. `IgnoreBugTestA` and `IgnoreBugTestB`), concurrent `handle()` calls could corrupt the buffer, so events from the second suite were lost or merged incorrectly and the summary showed wrong suite/test counts.
**Solution**
Replaced the event buffer in `sbt.TestFramework`'s `EventHandler` with a **thread-safe** collection: **`CopyOnWriteArrayList`** (from `java.util.concurrent`). Event handling now uses:
- `CopyOnWriteArrayList[Event]` for `results`
- `results.add(e)` in the handler
- `results.asScala.toList` when building `TestEvent` / `SuiteResult` (via `scala.jdk.CollectionConverters._`)
This preserves ordering and ensures all suites' events are reported correctly when using async styles like `AsyncFunSuite` with `test`/`ignore`.
When usePipelining is enabled and compilation has errors, CancellationException
was being thrown and showing confusing stack traces to users. This fix catches
the exception in ConcurrentRestrictions.take() and converts it to Incomplete,
which is properly handled by the task execution framework without showing stack
traces.
- Added CancellationException import
- Wrapped jservice.take().get() in try-catch
- Convert CancellationException to Incomplete to prevent stack traces
- Added scripted test to verify the fix
Fixes#7973
When a dependency declares a version range (e.g. Ivy [1.3.1,2.3] or comma-separated "1.3.1,2.3" as used by Coursier), and the resolver picks a version inside that range, sbt was still reporting an eviction warning. The chosen version satisfies the range, so it should not be reported as an eviction.
Example (from #6244): oauth2-oidc-sdk and nimbus-jose-jwt both depend on net.minidev:json-smart with range [1.3.1,2.3]. Resolution selects 2.3, which is within the range. Before this fix, sbt reported an eviction for json-smart even though 2.3 satisfies [1.3.1,2.3].
When in an sbt 2.x project directory, the script used to delegate to sbtn
before checking --script-version, so 'sbt --script-version' ran sbtn and
failed. Now we print the script version and exit before the native client
branch.
Build-level references (ThisBuild, BuildRef) should not participate
in aggregation. Only project-level references should aggregate.
Previously, when querying `ThisBuild/version`, the aggregation logic
would resolve ThisBuild to a BuildRef, then convert it to the root
project's ProjectRef, causing it to incorrectly use the root project's
aggregate definitions.
The fix uses pattern matching to distinguish BuildReference from other
reference types, returning None (no aggregation) for build-level scopes.
Fixessbt/sbt#5349
**Problem**
Apparently sbt can fail when it doesn't have rm,
which can happen "when building relocatable RPM's and building an OS image in a chroot."
**Solution**
It was suggested that we require coreutils.
- BuildServerProtocol: for Result.Inc(cause), return StatusCode.Error for any
non-InterruptedException (was throwing for non-CompileFailed, causing JSON-RPC
error instead of BspCompileResult with statusCode Error)
- BuildServerTest: add test 'buildTarget/compile - returns StatusCode.Error
when compilation fails' (introduce compile error, compile via BSP, assert
statusCode == Error)
**Problem**
Setting `Global / autoStartServer := false` in global.sbt triggers a
spurious lintUnused warning, even though the setting is correctly used
by sbt's server startup logic.
**Solution**
Add `autoStartServer` to the `excludeLintKeys` set in LintUnused.scala,
similar to other server-related settings like `serverConnectionType` and
`serverIdleTimeout`. This prevents the warning while maintaining the
functionality of the setting.
**Problem**
1. forked console is missing user code from the classpath.
2. forked console still blocks the server.
**Solution**
1. This includes proper products and classpaths to the console.
2. This also implements client-side run for console.
Commit 92b0564dc (fix for #8632) changed `csrSameVersions` so that Scala 2.13+ only aligned `scala-library` and `scala3-library`. This removed `scala-compiler` and `scala-reflect` from version
unification, so transitive dependencies pulling in an older `scala-compiler` (e.g. 2.13.15 via `refined_2.13`) were no longer evicted to match `scalaVersion` (e.g. 2.13.18).
**Problem**
The configuration name translation in logging was incorrect. When a
configuration like MultiJvm (id="MultiJvm", name="multi-jvm") was
displayed, it showed "Multi-jvm" instead of "MultiJvm" because the
display logic was guessing the identifier by capitalizing the ivy
config name.
**Solution**
This fix:
- Adds configNameToIdent reverse mapping in ConfigIndex to look up
the correct Configuration.id from the ivy config name
- Adds toConfigIdent method in KeyIndex trait for display lookup
- Updates Scope.display to accept a config name lookup function
- Updates showLoadingKey and showContextKey to use the index lookup
Fixes#5211
Generated-by: Claude
Implements cooperative idle server cleanup for `sbtn` (issue #8610). When a client disconnects from an sbt server, that server notifies all
other registered servers to shut down if they've been idle long enough and have no connected clients. This prevents accumulation of idle
background JVMs across projects.
fixes#8610
**Problem**
When platform is set, it incorrectly adds the platform suffix to implicit Scala library dependencies even though they explicitly set platform to jvm. This causes resolution errors.
**Solution**
Modified addPlatformSuffix to prioritize explicit platform settings on dependencies. If a dependency has an explicit platform, use that instead of the project platform. The project platform should only apply to dependencies without an explicit platform.
Fixes#8665
Generated-by: Claude Sonnet 4.5
When an AutoPlugin adds a project at the build root via extraProjects,
avoid creating a second root from the build definition so both do not
share the same target directory. Treat extraProjects root as 'root
already defined' and exclude the build-defined root from initialProjects
when both would be at the same base.
According to the issue, `.sbtopts` entries are appended after
CLI args in sbt 1.12.x, so `.sbtopts` JVM memory settings (e.g., `-Xmx2g`) override CLI `--mem`,
causing invalid JVM settings.
- Add ivylessPublishMavenToFile and ivylessPublishMavenToUrl for Maven layout
- Handle MavenCache and MavenRepo in ivylessPublishTask (file + HTTP)
- Add credentialFor for realm+host credential matching per Publishing docs
- Consume HTTP response body on success to avoid connection leak
- Add scripted tests: ivyless-publish-maven, ivyless-publish-maven-http
When using the aggregated key parser, a key is now valid if it exists in `data` for that scope **or** it's an aggregate key and every key it aggregates to exists in `data`. So `(root, scripted)` is accepted when the root aggregates a project that defines `scripted`, and running `scripted` at root runs it on that project as before.
Implements ivyless publish task as part of #7639 (drop Ivy dependency).
Fixes#8639.
- Add ivylessPublish for URLRepository: HTTP PUT with optional Basic auth,
same layout as ivyless publishLocal (artifacts + ivy.xml + checksums).
- Add ivylessPublishToFile for FileRepository: write to local path for
testing without HTTP server.
- Add ivylessPublishTask: when useIvy is false, use ivyless path for
URLRepository or FileRepository; otherwise use Ivy.
- Wire publish in Defaults to LibraryManagement.ivylessPublishTask
(tagged Publish, Network).
- Add scripted test dependency-management/ivyless-publish using
Resolver.file to verify ivyless publish produces identical layout.
Credentials supported via allCredentials (Basic auth for PUT).
When a project depended on another project that was built with a different Scala binary version (e.g. 2.12 vs 2.13), compilation could fail with "not found: value X" because resolution was asking for the wrong artifact.
This change updates how we build the `ModuleID` for inter-project dependencies in `projectDependenciesTask`: we now request the dependency’s Scala binary version (e.g. `bar_2.12`) instead of the current project’s, so the resolver can find the right artifact. We keep existing behavior for `Disabled` and `Constant` cross-version, and add a small safeguard in the default case when the dependency’s Scala version differs from the current project’s.
**Consuming BOMs**
- You can declare a BOM with `.pomOnly()` and versionless deps with `"*"`:
- `libraryDependencies += ("com.fasterxml.jackson" % "jackson-bom" % "2.21.0").pomOnly()`
- `libraryDependencies += "com.fasterxml.jackson.core" % "jackson-core" % "*"`
- BOMs are passed to Coursier via `Resolve.addBom()`; version `"*"` is resolved from the BOM.
**makePom**
- POM-only dependencies are emitted under `<dependencyManagement><dependencies>...</dependencies></dependencyManagement>` with `<type>pom</type>` and `<scope>import</scope>`.
- Dependencies with version `"*"` are emitted without a `<version>` element so Maven uses the BOM-managed version.
**Ivy / publishLocal emulation**
- When publishing to Ivy (e.g. `publishLocal`), BOM-resolved versions (deps that had `"*"`) are written into the published `ivy.xml` as forced dependencies (`force="true"`), so consumers that depend on this module get those versions.
**Problem**
1. Write a scripted test that runs sbt in that test.
2. sbt writes `sbt.version` under `project/build.properties`, which acts as a test filter.
3. The test setup is implicitly altered.
**Solution**
Before writing `build.properties`, sbt checks whether the base directory is inside a scripted test directory (path contains `sbt-test`). If so, it skips writing so the test setup is not altered.
Add a rootProject convenience macro that expands to a Project with base "."
and the enclosing val name as id. Allows writing `val root = rootProject`
instead of `val root = (project in file("."))` for a stable root project id.
**Problem**
Some scripted tests are failing due to the fact that -bin-SNAPSHOT
isn't being recognized.
**Solution**
This fixes sbtApiVersion to recognize BinCompatV.
When input lacks 'jsonrpc' field (e.g. {}), call System.exit(1) instead
of throwing IllegalArgumentException. Avoids noisy stack traces in
CI from WorkerExchangeTest's intentional bad-input tests.
Resolving ThisProject to ProjectRef(uri, p.id) created a self-reference
in the aggregate (and dependency) list. BuildUtil.checkCycles runs
topological sort on this relation and throws Cyclic when it sees the
self-loop.
Treat ThisProject as no-op: resolve to Vector.empty so the build loads
without error. aggregate(ThisProject) / dependsOn(ThisProject) is
effectively a no-op (self is already included).
Fixes#3616 - Scope's resolveProjectBuild and resolveProjectRef
mishandle ThisProject.
Previously, using ThisProject in aggregate() or dependsOn() would
cause a runtime error: 'Cannot resolve ThisProject w/o the current
project'.
This change adds proper handling for ThisProject in Load.scala:
- In checkAll: Skip validation for ThisProject (refers to self)
- In resolveProjects: Resolve ThisProject to ProjectRef(uri, p.id)
Problem
When a user defines an alias with a name that matches an existing task or setting key (e.g., `alias c = compile` when a custom task `c` exists), the alias silently wins and shadows the task.
Solution
Detect conflicts at alias creation time and fail with an error message:
```
Alias 'c' conflicts with a task or setting key of the same name. Use a different alias name to avoid ambiguity.
```
**Problem**
When multiple clients connect to the same sbt server, they all share the same "current project" state. When one client switches projects with `project X`, all other clients see that change.
**Solution**
Store per-channel project cursors in State attributes. Each client maintains its own cursor that tracks which project it has selected.