Commit Graph

17984 Commits

Author SHA1 Message Date
Dream d145d443a4
Merge 385c5c7578 into 840887820c 2026-04-13 11:44:37 +00:00
eureka928 385c5c7578
[2.x] fix: Make consoleProject bindings non-null in Scala 3
**Problem**
After #9073, `consoleProject` starts a Scala 3 REPL successfully, but
`currentState`, `extracted`, and `cpHelpers` show as `null` in the
REPL. Reviewer eed3si9n reported this on the PR.

Root cause: the Scala 3 REPL's `dotty.tools.repl.AbstractFileClassLoader`
ends up defining a fresh copy of `sbt.internal.ConsoleProjectBindings`
(and the other sbt classes referenced by the bindings) from the sbt
module jars on `unit.classpath`, instead of delegating to sbt's own
class loader via parent-first delegation. The two `Class` objects are
distinct, so setting static fields on sbt's copy has no effect on the
one the REPL compiles against. A strongly typed cast would additionally
hit `LinkageError: loader constraint violation` on `sbt.State`.

**Solution**
Strip every jar shipping sbt core code from the runtime class loader
used by the `consoleProject` REPL. The jars are detected by content —
any jar that contains `sbt/State.class`, `sbt/Extracted.class`,
`sbt/internal/ConsoleProjectBindings$.class`, or `sbt/internal/Load$.class`
is considered an sbt module jar and filtered out.

The full classpath is still passed to `Console` below, so the REPL's
compile-time classpath (from the `-classpath` flag) is unchanged and
the DSL types typecheck as before. Only the runtime URLClassLoader is
affected, forcing `sbt.*` class references inside the REPL to resolve
via parent delegation and reach sbt's own singleton copies.

**Test**
Update `project/scala3-console-project` to write a marker file from the
REPL's `initialCommands` via
`Files.writeString(path, currentState.toString.length.toString + ...)`.
If any binding is null, the `toString` throws an NPE, the REPL swallows
it, the marker is never written, and `$ exists` fails. The test now
verifies the REPL actually sees non-null bindings, not just that
`consoleProject` starts successfully.
2026-04-13 13:44:25 +02:00
bitloi 840887820c
[2.x] fix: Fix FileAlreadyExistsException in packageDirectory (#9047)
**Problem**
Intermittent java.nio.file.FileAlreadyExistsException when publishing
classes.sbtdir.zip during action-cache packaging under parallel tasks
(#9043). Copying from a temp directory straight into the final path races
on the fixed destination name.

**Solution**
Stage the built zip next to the destination with a unique temp file, then
replace the final path via Files.move with REPLACE_EXISTING and ATOMIC_MOVE,
falling back to a non-atomic move when needed. Add a concurrent
packageDirectory test.

Closes #9043

Generated-by: Cursor (AI-assisted)
2026-04-13 04:30:45 -04:00
bitloi 936a7e1ffb
[2.x] fix: clear compiler bridge zinc cache on reboot dev (#9057)
Reboot dev now removes zinc/org.scala-sbt under the resolved global zinc
directory (same layout as ZincComponentManager secondary cache).

Closes #5735
2026-04-13 04:28:43 -04:00
eugene yokota 25dd9b7363
[2.x] fix: Fixes client-side run status (#9081)
**Problem**
In sbt 2.x, if we execute a run task from the shell,
and if the program fails, it ends up taking down the entire shell
because client-side run rethrows, which is not desirable
for the sbt shell.

**Solution**
1. Omit printing out success for ClientJobParams, which is the runinfo.
2. Print out success or error on the client-side for shell usage case.
2026-04-13 00:41:35 -04:00
eureka928 1285562c76
[2.x] test: Un-pend project/consoleProject scripted test
**Problem**
CI reports "Pending test passed" for `project/consoleProject` on Java 25
after the consoleProject Scala 3 fix. The test was previously marked
pending because `consoleProject` did not work with Scala 3 (#7722) — now
it does, so scripted flags the pending file as unexpectedly passing.

**Solution**
Rename `pending` to `test` so scripted runs it as a regular test.
2026-04-13 06:04:33 +02:00
eureka928 673789111b
[2.x] fix: Fix consoleProject for Scala 3
**Problem**
`consoleProject` does not work with Scala 3 because the compiler bridge
does not implement REPL binding injection (scala/scala3#5069).
The bindings `currentState`, `extracted`, and `cpHelpers` are never
injected into the REPL session, causing `Not found` errors.

**Solution**
Work around the missing binding support by storing the three runtime
objects in a static holder (`ConsoleProjectBindings`) before launching
the REPL, and generating `val` definitions via `initialCommands` that
read from the holder. The original `bindings` are still passed to
`Console` to preserve Scala 2 backward compatibility.

Fixes sbt/sbt#7722
2026-04-13 05:28:50 +02:00
BitToby 05cd00e135
[2.x] fix: stack traces suppressed in thin client batch mode (#9058)
In sbt 2.x, running batch commands through the thin client (sbtn) suppresses stack traces for all tasks because the server's shell command unconditionally sets state.interactive = true. This causes LogManager.defaultTraceLevel to return -1 (suppressed) even when the client explicitly signals non-interactive (batch) mode via Attach(interactive=false).

This fixes the shell command to check the originating NetworkChannel's interactive flag before setting state.interactive, so thin client batch commands correctly get Int.MaxValue trace level and display full stack traces.
2026-04-12 18:24:30 -04:00
kenji yoshida c52ce78d77
[2.x] Update .gitattributes for contraband files (#9076) 2026-04-12 13:51:06 -04:00
Dream 512d2d460c
[2.x] fix: Add description and url to PomGenerator output (#9069)
**Problem**
PomGenerator (introduced in #8873) was missing <description> and <url>
elements that the old Ivy-based MakePom included. Setting `description`
and `homepage` in build.sbt had no effect on the generated pom.xml.

**Solution**
Add makeDescription and makeHomePage helpers to PomGenerator, matching
the behavior of MakePom. Add test assertions for both fields.

Fixes #9054
2026-04-12 01:59:02 -04:00
kenji yoshida 852505f9f7
[2.x] ci: Remove -Ymacro-expand option (#9072) 2026-04-12 01:57:41 -04:00
kenji yoshida c47fc6bbd8
[2.x] fix: Delete src/main/resources/log4j2.xml (#9071) 2026-04-12 01:57:00 -04:00
kenji yoshida d46ba8bfc9
[2.x] ci: Add -source-links option (#9063) 2026-04-12 01:56:17 -04:00
kenji yoshida b156871557
[2.x] ci: Delete unused code in project/Dependencies.scala (#9070) 2026-04-12 01:55:18 -04:00
kenji yoshida d86587ad54
[2.x] hide JDK warnings if JDK 26 or later (#9068) 2026-04-11 21:47:48 -04:00
kenji yoshida 767ebec906
[2.x] override sbt.Tests.Group hashCode (#9065) 2026-04-11 13:40:28 -04:00
kenji yoshida 6fe83aa021
[2.x] Remove `whitesource` from LintUnused (#9064) 2026-04-11 13:39:02 -04:00
kenji yoshida 2e0a724c63
[2.x] refactor: Remove return from sbtw/Main (#9066) 2026-04-11 13:06:50 -04:00
kenji yoshida 78afa8fb96
[2.x] test: Fix warnings in scripted tests (#9062) 2026-04-11 03:07:52 -04:00
kenji yoshida 160a6c1fb0
[2.x] Fix scaladoc issue in mainProj and sbtIvyProj (#9061) 2026-04-11 02:29:54 -04:00
kenji yoshida 7408fc93c7
[2.x] Delete bootDirectory in cleanFull (#9060) 2026-04-11 02:28:38 -04:00
kenji yoshida f8a8742dbe
[2.x] Format pom.xml (#9059) 2026-04-10 19:20:02 -04:00
BitToby e0bdb531f7
[2.x] fix: Widen IOException catch in organicTask to cover result serialization (#9050)
**Problem**
When a file referenced during cache serialization is deleted between task
execution and cache storage, sbt crashes with an uncaught NoSuchFileException.
The IOException catch added in #8699 only wraps store.put(), but
Converter.toJsonUnsafe(result) and mkInput() also call
hashedVirtualFileRefToStr which calls Files.readAttributes — and these are
outside the try-catch.

**Solution**
Move the try/catch IOException to wrap the entire post-action cache storage
section, so NoSuchFileException from result serialization or cache key
computation is caught and handled gracefully (skip caching, return result).

Fixes #9044

Co-authored-by: bittoby <218712309+bittoby@users.noreply.github.co>
2026-04-10 01:44:08 -04:00
BrianHotopp d765ba263a
[2.x] fix: Return JSON-RPC error for unknown server methods (#9002)
The fallback ServerHandler silently dropped requests with unknown
methods, violating the JSON-RPC spec. Clients like Metals that send
unrecognized requests would never receive a response, potentially
causing timeouts or hangs.

Return a -32601 (Method not found) error response instead.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 01:33:20 -04:00
BrianHotopp 00632754ab
[2.x] fix: Add --fail to curl in launcher to prevent corrupt jars (#9003)
When the download URL returns an HTTP error (e.g. 404), curl without
--fail exits 0 and saves the error page HTML as the jar file. This
leaves a corrupt jar that causes confusing errors on subsequent runs.

With --fail, curl returns a non-zero exit code on HTTP errors and
does not write the response body to the output file.

Fixes #6654

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 01:31:52 -04:00
kenji yoshida 7218b2a1ac
[2.x] ci: Remove unnecessary code in build file (#9045) 2026-04-08 23:58:39 -04:00
Rikito Taniguchi e292d05322
[2.x] Fix Scala 3 .previous expansion for unstable path (#9041)
**problem**
.previous was implemented as an inline expansion to wrapInitTask(Previous.runtime(in)(<instance of JsonFormat[A1]))

For example, the .previous on taskKey[String] gets inlined like
this, and then sbt's macro moves `Previous.runtime(...)(using StringJsonFormat)` into task input.

lazy val fingerprints = taskKey[String]("...")
val previousFingerprints = fingerprints.previous

// inlined
val previousFingerprints: Option[String] = {
  InputWrapper.wrapInitTask(
    Previous.runtime(...)(using StringJsonFormat)
  )
}

- 6c8ee6ea37/main-settings/src/main/scala/sbt/Def.scala (L410-L412)
- 6c8ee6ea37/core-macros/src/main/scala/sbt/internal/util/appmacro/Cont.scala (L468)

However, if the return type of task is a bit more complicated like
Seq[String], it doesn't work:

Scala 3 Compiler's inliner creates a synthetic proxy symbol if the
inlining tree is an application, whose arguments are unstable path.

For example,

lazy val fingerprints = taskKey[Seq[String]]("...")
val previousFingerprints = fingerprints.previous

// inline to
val previousFingerprints: Option[Seq[String]] = {
  val x$2$proxy1 = immSeqFormat(StringJsonFormat)
  InputWrapper.wrapInitTask(
    Previous.runtime(...)(using x$2$proxy1)
  )
}

cc7d6db700/compiler/src/dotty/tools/dotc/inlines/Inliner.scala (L324-L329)

However, sbt2's Cont macro captures only `Previous.runtime(...)(using x$2$proxy1)`, while it doesn't capture the proxy definition. Consequently, while sbt macro moves the `Previous.runtime(...)` application as a task input, the proxy definition is left in the task body.

mapN(
  (
    link / fingerprints,
    Previous.runtime(...)(using x$2$proxy1) // here x$2$proxy1 can't be found
  )
) {
  ...
  val x$2$proxy1 = ...
}

Then we get:

-- Error: /.../build.sbt:14:59
14 |  val previousFingerprints = (link / fingerprints).previous
   |                                                           ^
   |While expanding a macro, a reference to value x$2$proxy1 was used outside the scope where it was defined

**How this PR fixed**
This commit fixes the problem by defining a dedicated Scala3 macro for .previous that summon JsonFormat[A1] inside the macro before constructing the wrapped previous.runtime(...)(using ...) by inliner. The macro insert the found given value tree directly into the previous.runtime(...)(using $found).

This way, Cont macro always moves the Previous.runtime tree along with it's given argument, without leaking compiler-generated inline proxies across scopes.
2026-04-07 22:45:01 -04:00
kenji yoshida 1601570602
Update mima setting (#9039) 2026-04-07 17:54:53 -04:00
kenji yoshida 75dcd1229b
Enable project-matrix/native test (#9038) 2026-04-07 08:15:43 -04:00
eugene yokota 6c8ee6ea37
[2.x] Remove Path type from caching (#9032)
**Problem**
Like File, Path normally captures the absolute path,
so likely not a good candidate for caching.

**Solution**
Ban it.

---------

Co-authored-by: Anatolii Kmetiuk <anatoliikmt@proton.me>
2026-04-06 14:40:33 -04:00
BrianHotopp 3890cc7086
[2.x] fix: Resolve relative paths from -sbt-dir / sbt.global.base (#9001)
getFileProperty returned relative File objects when system properties
like sbt.global.base were set to relative paths (e.g. via -sbt-dir
../cache in .sbtopts). This caused an assertion failure in
IO.directoryURI: "Not absolute: ../cache/plugins".

Also fixes misleading scaladoc in SemanticSelector that claimed
`<=1.0` is equivalent to `<1.1.0` — they differ for pre-release
versions like 1.1.0-M1 (#4423).

Fixes #3729

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 19:27:34 -04:00
kenji yoshida 4e4ab9f464
[2.x] Update sbt version in launcher-package test (#9021) 2026-04-05 19:26:05 -04:00
Albert Meltzer fdccd8a569
[2.x] Prefer local ScalaModuleInfo over global config (#9028)
Otherwise, a user will never be able to download scala library at any
other version.
2026-04-05 18:41:30 -04:00
kenji yoshida 8ad6ada60f
[2.x] Scala 3.8.3 (#8997) 2026-04-05 14:28:47 -04:00
corevibe555 606bb3b59c
[2.x] Fix: strip pipelining scalacOptions before launching the REPL (#8986)
**Problem**
When usePipelining := true in a multi-project build, sbt appends  
-Ypickle-java and -Ypickle-write <path>/early.jar to scalacOptions 
for fast parallel compilation. These flags were being leaked into the Scala  
REPL, causing failure on console

**Solution**
Strip pipelining flags before forwarding to the REPL  in Deafults.scala.
2026-04-05 13:47:36 -04:00
kenji yoshida bff386d276
[2.x] Deprecate unused code in TaskMacro (#9026) 2026-04-05 13:25:36 -04:00
kenji yoshida 67e3b8b01b
[2.x] refactor: Remove unnecessary language.experimental.macros import (#9025) 2026-04-05 13:17:37 -04:00
kenji yoshida 7ab07e1177
Remove unnecessary reflection in IvyXml (#9024) 2026-04-05 13:13:32 -04:00
eugene yokota 5ad9abac2f
[2.x] fix: Fixes metabuild reloading (#9019)
**Problem**
There seems to be multiple problems around metabuild reloading (reload plugins).

1. Originally reported issue 9006 states that the build can't come back
   from reload plugins.
2. During the course of fixing, I discovered that when reload plugins is used
   the project name is set to "project" instead of foo-build etc.
3. Also there was a bug in the rootPaths when reload plugins is used,
   which results in class not defined error.

**Solution**
1. Fix the plugin context so reload plugin still behaves like a metabuild.
2. Fix the rootPaths.
2026-04-05 03:13:23 -04:00
kenji yoshida fa07cc921d
[2.x] ci: Update sbt-native-image plugin (#9016) 2026-04-05 01:03:38 -04:00
eugene yokota 90770b6ad1
[2.x] fix: Fixes pollInterval (#9020)
**Problem/Solution**
checkBuildSources / pollInterval should just fallback to some value.
2026-04-05 00:52:29 -04:00
kenji yoshida ed49601662
[2.x] ci: Organize scalatest dependency (#9015) 2026-04-04 23:54:09 -04:00
BitCompass 1f2d14aa3e
[2.x] fix: derivedProjects not invoked when no explicit root project is defined (#9012)
**Problem**
When build.sbt contains no explicit project definition (e.g. just bare settings with no lazy val root = project.in(file("."))), sbt creates a synthetic root project. In Load.loadTransitive, this synthetic root was processed with expand = false, which prevented AutoPlugin.derivedProjects from being called.
Any plugin relying on derivedProjects to inject projects would fail with "Reference to undefined setting" errors.

The workaround was to add an explicit root project in build.sbt (val root = project.in(file("."))), which caused the Some(root) branch to execute with expand = true.

**Solution**

Removed the expand variable from loadTransitive and pass true directly to processProject. Previously, the Some(root) branch set expand = true while the None branch set expand = false. Since derivedProjects should always be invoked for the root project regardless of whether it was explicitly defined or auto-generated, both branches should behave the same way. Eliminating the variable makes this intent clear.
2026-04-04 14:55:42 -04:00
corevibe555 4d71c15e87
[2.x] fix: resolve virtual path in -Ypickle-write scalac option (#9011)
earlyOutput is a virtual file reference, so passing it directly via
.toString produces a virtual path that scalac cannot resolve. Use
fileConverter.value.toPath() to convert it to an actual filesystem path.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 23:13:16 -04:00
Dream 544f56695a
[2.x] feat: Add cacheVersion setting for global cache invalidation (#8993)
* [2.x] feat: Add cacheVersion setting for global cache invalidation

**Problem**
There was no escape hatch to invalidate all task caches when needed.

**Solution**
Add `Global / cacheVersion` setting that incorporates into the cache key
hash. Changing it invalidates all caches. Defaults to reading system
property `sbt.cacheversion`, or else 0L. When 0L, the hash is identical
to the previous behavior (backward compatible).

Fixes #8992

* [2.x] refactor: Simplify BuildWideCacheConfiguration and add cacheVersion test

- Replace auxiliary constructors with default parameter values
- Add unit test verifying cacheVersion invalidates the cache

* [2.x] fix: Restore auxiliary constructors for binary compatibility

* [2.x] test: Improve cacheVersion scripted test and add release note

- Scripted test now verifies cache invalidation via a counter
  that increments only when the task body actually executes
- Add release note documenting the cacheVersion setting
2026-04-01 11:23:10 +09:00
kenji yoshida 6d44aca9b1
Add parentheses (#9000) 2026-03-31 13:48:59 -04:00
kenji yoshida f2ce52e985
[2.x] refactor: Fix warning in Settings.scala (#8999) 2026-03-31 02:00:15 -04:00
BrianHotopp 4f06b90534
[2.x] fix: Write maven-metadata-local.xml during publishM2 for SNAPSHOTs (#8996)
publishM2 never wrote maven-metadata-local.xml, which Maven uses to
distinguish local installs from remote artifacts. Without it, Maven
re-downloads remote SNAPSHOTs even when a local copy exists, making
publishM2 effectively broken for SNAPSHOT workflows.

Fixes #2053

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 01:58:57 -04:00
BrianHotopp 5697f074c1
[2.x] fix: Update ++ help text to reflect SemanticSelector matching (#8995)
The first paragraph of `help ++` still said "binary compatible" from
before PR #6946 changed the behavior to use SemanticSelector pattern
matching. Update it to match the already-correct second paragraph.

Fixes #6988

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 01:50:45 -04:00
kenji yoshida 77e4b3c745
Fix old shell syntax warning (#8998) 2026-03-31 01:05:16 -04:00