**Problem**
1. The ivyless publish task had ivyModule.value and publisher.value calls
inside match/case fallback branches. sbt's macro hoists ALL .value calls
from ALL match branches as task dependencies regardless of runtime path,
causing failures when useIvy=false even for supported repo types.
2. publishM2 used publishOrSkip which errors when useIvy=false, but M2
targets MavenCache which the ivyless path already supports.
**Solution**
1. Remove hoisted .value calls from fallback branches in ivylessPublishTask.
Replace with direct sys.error calls since these branches handle truly
unsupported repo types.
2. Add ivylessPublishM2Task using Def.ifS that publishes to MavenCache
via ivylessPublishMavenToFile when useIvy=false.
Generated-by: Claude claude-opus-4-6
**Problem**
The evicted task directly uses ivyModule.value to get a module descriptor.
This creates an unnecessary dependency on Ivy for eviction warnings.
**Solution**
Use dependencyResolution.value.moduleDescriptor() which works with both
Ivy and Coursier resolvers, removing the direct Ivy coupling from the
eviction checking path.
Generated-by: Claude claude-opus-4-6
Summary
- Adds support for passing JVM arguments inline to `run`, `runMain`, `bgRun`, `bgRunMain`, and `fgRun`/`fgRunMain` using `--` as a delimiter
- Syntax: `run <jvmArgs> -- <appArgs>` (e.g., `run -Xmx2G -Dapp.mode=debug -- arg1 arg2`)
- Fully backward compatible — without `--`, all arguments are treated as app args as before
- When `fork` is `false`, a warning is logged that JVM arguments will be ignored
- **Remove `ivyModule` from `updateTask0`**: Replace `IvySbt#Module` with `moduleSettings` + `DependencyResolution.moduleDescriptor()`, eliminating the Ivy dependency in the update path.
- **Replace direct Ivy usage in `Load.scala` and `TemplateCommandUtil`**: Use Coursier's `DependencyResolution` API for plugin bootstrapping and template resolution instead of constructing `IvySbt` instances directly.
- **Break `lm-coursier`'s dependency on `lm-ivy`**: Remove `IvySbt#Module` pattern match from `CoursierDependencyResolution`, replace `IBiblioResolver` usage in `Resolvers` with reflection, and switch build dependencies from `lmIvy` to `lmCore`.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Fixes nondeterministic ordering in `ScopeFilter`-backed `.all(...)` aggregation.
`SettingKeyAll.all` and `TaskKeyAll.all` previously iterated a `Set[Scope]` using `toSeq`, which made returned values order-dependent on hash iteration. This PR keeps `.all(...)` deterministic and preserves explicit project ordering when a filter provides it (for example, `inProjects(c, a, b)`).
When a test fails with ClassNotFoundException/IllegalAccessError, sbt
suggests a set command to change classLoaderLayeringStrategy. If the
project name contains hyphens (e.g. bug-report), the suggested command
was syntactically invalid because it parses as subtraction in Scala.
Quote project IDs using Util.quoteIfNotScalaId so the suggested
commands are valid when copy-pasted.
Fixes#5803
* Fix#4979: apply -debug (and other level options) at startup so loading shows debug log
- Parse log level from configuration.arguments in StandardMain.initialState
- Pass initialLevel to GlobalLogging.initial so console appender uses it from first log
- Set Keys.logLevel and BasicKeys.explicitGlobalLogLevels in initial state when level option present
- Add initialLevel parameter to GlobalLogging.initial (default Level.Info) for backward compatibility
- Add InitialLogLevelSpec tests for logLevelFromArguments
- Add docs/fix-4979-manual-verification.md for manual reproduction
- Add UpdateReportCache case class wrapping UpdateReportLite with stats/stamps
- Implement toCache/fromCache for conversion between UpdateReport and cache
- Add readFrom/writeTo for CacheStore persistence with backward compatibility
- Add fromLiteFull to JsonUtil for full reconstruction from lite format
- Update LibraryManagement to use new persistence API
- Add benchmark comparing full vs lite deserialization
- Add unit tests for persistence correctness
- Add scripted test for cache round-trip verification
- CompileDebugLogger wraps logger to prefix debug messages with [projectId]
- projectIdFromScope derives id from task scope (avoids HashWriter on ResolvedProject)
- Wire CompileDebugLogger into compileIncrementalTaskImpl and compileJavaTask
- Add CompileDebugLoggerSpec unit test and i408-debug-invalidation-prefix scripted test
sbt 2.x allows `dependsOn(...)` between subprojects with mismatched
Scala versions without any warning or error. This can lead to confusing
classpath issues at compile or runtime, especially now that Scala 3.8+
has dropped backward TASTy compatibility with 2.13.
Per review feedback, move the Scala version mismatch check from
compileTask to projectDependenciesTask, where PR #8681 already handles
Scala version mixing logic. This provides earlier detection and keeps
the validation co-located with cross-version resolution.
Generated-by: Copilot
Closes#4399
- Add subscribeToAll to InitializeOption (protocol); default true for backward compatibility.
- CommandExchange: send broadcast notifyEvent/logMessage only to channels with subscribeToAll.
- TestServer: support subscribeToAll parameter for tests; AbstractServerTest: subscribeToAllForTest.
- ClientSubscriptionTest: assert default client receives build/logMessage when command runs.
- Scripted test server/client-subscription: run show name to exercise server client path.
Treat explicit plugin toggles as last-call-wins for the same plugin.
This avoids contradictory include/exclude states when disablePlugins(X) is followed by
enablePlugins(X) (and vice versa), aligning behavior with normal override expectations.
Apply the same semantics to ProjectMatrix and add regression coverage:
- unit tests in main/src/test/scala/ProjectSpec.scala
- scripted test in sbt-app/src/sbt-test/project/i1926-disable-enable-plugin
Fixes#4310
Per review, the OOM comes from the version parser - token(StringBasic)
on the right side of || has no examples constraint. Move
.examples(knownVersions*) from the inner number parser to wrap the
entire || expression, so both alternatives are bounded.
When Test / autoScalaLibrary := false, build the non-fork test classloader
without the ScalaInstance layer: use Flat strategy and project classpath
only (rawCP), so tests do not see sbt's scala-library and avoid
NoSuchMethodError / version mismatch (e.g. scala/scala build).
- ClassLoaders.testTask: read autoScalaLibrary; when false use Flat and
rawCP-only fullCP, and do not add si.libraryJars to exclude.
- Add scripted test tests/autoScalaLibrary-test-loader that runs test
with Test / autoScalaLibrary := false.
**Problem**
`testFull` can select an aggregate-only key before a directly defined root key.
In issue #8772 this causes root project tests to be skipped, so a failing root test can pass unexpectedly.
**Solution**
Prefer directly defined keys in `Act.select`, and only fall back to aggregate-only candidates when no direct key exists.
Add scripted regression test `tests/i8772-root-project-testfull` and keep `project/extra-projects-key-aggregate` behavior intact.
Change the behavior when a cached task's output type contains
java.io.File: instead of silently skipping the cache, throw a
compile-time error with a message recommending xsbti.VirtualFileRef,
xsbti.HashedVirtualFileRef, or xsbti.VirtualFile, and linking to the
caching documentation.
Internal sbt tasks that return File types are wrapped with
Def.uncached to opt out of caching.
Fixes https://github.com/sbt/sbt/issues/8762
Generated-by: GitHub Copilot (Claude)
* [2.x] fix: Reject java.io.File as cached task output type
Use @transient on File-returning keys in Keys.scala instead of
wrapping tasks with Def.uncached in Defaults.scala. This ensures
build users who rewire these tasks also get caching skipped
automatically.
- Add @transient to 19 File-returning taskKey definitions in Keys.scala
- Revert Def.uncached wrappers from Defaults.scala
- Error at compile time when File is used as cached task output type
- Update error message to recommend @transient and link to docs
- Update scripted tests to use @transient approach
Fixes#8762
Generated-by: GitHub Copilot (Claude Opus 4.6)
**Problem**
`scalaOrganization` was ignored during compiler bridge resolution because `ZincLmUtil.getDefaultBridgeModule` hard-coded `ScalaArtifacts.Organization` (`org.scala-lang`).
**Solution**
Add a `scalaOrganization` parameter to `ZincLmUtil` methods, and passing `scalaOrganization` value to those methods.
Generated-by: Claude Opus 4.6
When `semanticdbEnabled := true` is set on Scala 2.x projects, the
`doc` task fails because `${CSR_CACHE}` placeholders in scalacOptions
(specifically the `-Xplugin:` path for the semanticdb compiler plugin)
are not resolved before being passed to Scaladoc.
This fix resolves virtual file references (containing $) in
scalacOptions before passing them to the Scaladoc bridge, matching
what zinc's MixedAnalyzingCompiler already does for compilation
(see sbt/zinc#1545).
Fixessbt/sbt#8740
Generated-by: GitHub Copilot (Claude Opus 4.6)
Allow settings to delegate when the user specifies an explicit scope
(config or task axis), so that e.g. Compile/console/fork resolves
when console/fork is defined in a delegated scope. Tasks continue to
not delegate (getDirect only) so non-existent scopes like Compile/update
still fail as in 2.0.0.
**Problem**
Adopting Scala 3.8 on sbt 2.x has created confusing errors with scala-library mismatch,
popping up as undefined summon.
**Solution**
Removing the Provided scope seems to work.
- CacheUrlConversion: normalize paths for comparison (forward slashes)
and strip leading slash on Windows file URIs so cache matching works.
- Apply scalafmt to touched files.
- Add CacheUrlConversion in lm-coursier internal to convert cache file
paths back to original repository URLs (single place for logic).
- CoursierDependencyResolution delegates to CacheUrlConversion.
- DependencyLockManager.createFromUpdateReport now accepts optional
cacheDir; when an artifact has a file URL it either converts via
cache dir (Coursier layout) or fails with a clear message.
- dependencyLock task passes csrCacheDirectory so lock file gets
portable HTTPS URLs instead of machine-specific cache paths.
Expectation 1: Lock file contains original Maven Central (or repo) URLs.
Expectation 2: If conversion is not possible, lock creation fails.
**Problem**
When the user runs testOnly with an explicit suite name (e.g. testOnly com.example.MySuite),
ScalaTest suites annotated with @DoNotDiscover were not run because sbt always passed
explicitlySpecified=false to the test framework.
**Solution**
In Tests.processOptions, when the user has specified test filters (orderedFilters.nonEmpty),
mark the filtered tests as explicitlySpecified=true with SuiteSelector so frameworks
can run @DoNotDiscover suites when explicitly requested.
- this should also work for global plugins once they are fixed in sbt 2.x
- add `missingOk` support in classifier resolution to enable failure-tolerant artifact retrieval
**Problem**
When `last` output includes ANSI escape sequences (e.g. colored `[error]` lines), `lastGrep <pattern>` was matching against the raw string. The pattern could fail to match because it was compared to text like `\u001B[31merror\u001B[0m` instead of `error`, or matching was inconsistent.
**Solution**
- Strip ANSI from each line before running the regex, using `EscHelpers.stripColorsAndMoves` from `sbt.internal.util`.
- **`Output.lastGrep`** (keys and file overloads): lines from the last run are stripped, then the pattern is applied to the stripped text; matching and printed lines are based on visible text.
- **`Output.grep`**: each line is stripped before `showMatches(pattern)` so the pattern is applied only to visible content.
**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.
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
- 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