Commit Graph
18045 Commits
Author SHA1 Message Date
Dmitrii NaumenkoandCodex bfd744b2c7 [2.0.x] fix: Notify listeners before LinkageError escapes suites (#9667)
TestRunner now calls endGroup(name, error) before rethrowing an otherwise escaping LinkageError. This completes the TestReportListener lifecycle while preserving the original error propagation and non-zero task result.

Previously, the outer suite catch handled only NonFatal errors. A suite failing with ExceptionInInitializerError could therefore start a listener group and terminate without a terminal callback, forcing integrations to infer failure from rendered output. The direct TestRunner regression checks the error callback, absence of a normal result callback, and rethrow of the same error.

Co-authored-by: Codex <[email protected]>
2026-08-24 13:04:28 -04:00
Eugene Yokota 6913814ffd sbt 2.0.7 v2.0.7 2026-08-20 22:49:56 -04:00
eugene yokota 917a785975 Merge pull request #9647 from eed3si9n/bport2/bport
[2.0.x] Backports
2026-08-20 21:46:44 -04:00
stasimus bb8926ca0c [2.0.x] fix: disable BSP over TCP and gate requests before auth 2026-08-20 18:31:13 -04:00
eugene yokota 81ed7a82bd [2.0.x] Update sbtn to 2.0.0-8753a981 (#9630) 2026-08-20 17:11:09 -04:00
Christian Harrington f965e0afed [2.0.x] fix: Fixes filesystem traversal order affecting cache stability (#9646)
**Problem**
CompileInputs2.sources and packageBin / mappings are hashed positionally but arrive in
filesystem traversal order, which differs between APFS, ext4 and overlayfs. Two machines
hash an identical tree into different cache keys and cannot use each other's entries.

**Solution**
Sort sourcesVF by virtualized id, and mappings where packageConfigurationTask reads
it. Both are where the keys are built, so nothing appended later escapes the sort.

Generated-by: Claude Opus 5
2026-08-20 17:09:06 -04:00
Mai Huy HoàngandClaude Opus 5 0b18207f70 [2.0.x] perf: Stop re-converting the classpath in compileOptions (#9622)
Both compileOptions sites mapped the whole classpath through
converter.toPath -> converter.toVirtualFile. Going through toPath
defeats FileConverter.toVirtualFile(VirtualFileRef), which already
returns the ref unchanged when it is a VirtualFile, so every entry was
rebuilt from scratch. For a class directory that means walking the
entire output tree, once per dependent.

backendOutput is converted explicitly because it is a settingKey
evaluated once at project load, so reusing it would pin the listing
taken before anything compiled.

Co-authored-by: Claude Opus 5 <[email protected]>
2026-08-20 17:08:30 -04:00
eugene yokotaandAnatolii Kmetiuk a3c503ad88 [2.0.x] fix: Fixes -V parsing in sbt runners (#9636)
Problem: -V is consumed by the launcher instead of sbt in sbt tasks -V.

Solution: in the parser's -V behavior, lookback to see if there are commands going before it, in which case, forward -V to sbt.

Co-authored-by: Anatolii Kmetiuk <[email protected]>
2026-08-19 17:30:43 -04:00
8d2e582c34 [2.0.x] Add a resolvedScalacOptions task that resolves cache placeholders (#9629)
Add a resolvedScalacOptions task that resolves cache placeholders in scalacOptions to absolute machine paths.

Co-authored-by: azdrojowa123 <[email protected]>
Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
2026-08-19 13:04:12 -04:00
Dmitrii NaumenkoandCodex 6893ad9b43 [2.0.x] fix: Avoid rewriting unchanged plugin descriptors (#9612) (#9624)
Only rewrite generated plugin descriptors when their normalized lines change, preserving the descriptor timestamp and downstream cache inputs for unchanged plugin discovery.

Add unit coverage plus direct packageBin and assembly Scripted scenarios. The descriptor regressions fail with the former unconditional write and pass with this change; the packageBin fixture also preserves SBT 2’s existing cache-hit behavior.

Co-authored-by: Codex <[email protected]>
2026-08-19 05:13:45 -04:00
eugene yokotaandAlbert Meltzer 087513f4d9 [2.0.x] fix: Name the platform in CrossVersion(module, scalaModuleInfo) (#9621)
**Problem**
CrossVersion(module, scalaModuleInfo) is handed everything needed to name an
artifact, including ScalaModuleInfo.platform, and the name it returns is what
a caller publishes or resolves under. Nothing covers what it does with the
platform.

**Solution**
Name the artifact in full: platform suffix before cross suffix, matching the
coordinate (sbt/sbt#9117), through addPlatformSuffix, which already knows that
jvm contributes no suffix.

Generated-by: Claude Opus 5

Co-authored-by: Albert Meltzer <[email protected]>
2026-08-18 11:55:19 -04:00
eugene yokota abe1b26bb7 [2.0.x] fix: Guard diskcache against path traversal (#9616)
**Problem**
There are several places in diskcache where resolve is called
without guards.

**Solution**
This adds guards to prevent path traversal.
2026-08-17 15:52:05 -04:00
eugene yokota d27611674b [2.0.x] ci: Remove cla-checker v1 (#9570) (#9571) 2026-08-07 14:51:38 -04:00
Eugene Yokota 6e5f1ebf58 sbt 2.0.6 v2.0.6 2026-08-06 22:43:27 -04:00
Eugene Yokota f2c54d042a Merge branch 'bport2/fix-lsp' into 2.0.x 2026-08-06 22:04:26 -04:00
eugene yokota 3fcc8ce1af Merge pull request #9565 from eed3si9n/bport2/backports
[2.0.x] Backports
2026-08-06 22:03:14 -04:00
eugene yokota 5d5e2badf2 [2.0.x] fix: Preserve file timestamp in local diskcache (#9559)
**Problem**
In theory, we shouldn't have to care about the timestamps,
but for local optimization it's still a useful key for caching.
Currently local Analysis cache gets invalidated after
syncBlob replaces the Analysis file with a symlink.

**Solution**
This preserves the original timestamp when copying files to
the local diskcache.
2026-08-06 21:06:43 -04:00
tanaka takaya e3820eb6b3 [2.x] perf: Memoize the artifact content hash in LibraryManagementCodec (#9563)
**Problem**
Serializing an UpdateReport re-reads every artifact through sjson-new's
File iso to recompute its sha256, so every ActionCache key computation
and Tracked write-back re-reads the whole dependency classpath on every
invocation, including no-ops.

**Solution**
Override the iso with a hash memoized by (path, size, lastModified),
with the same invalidation semantics as the digest cache in sbt/sbt#8363,
and mix it into the generated codec via contrabandCodecParents.

Generated-by: Claude Fable 5
2026-08-06 20:54:18 -04:00
Eugene Yokota 4cf650ac86 Remove the test from 2.0.x branch 2026-08-06 14:40:55 -04:00
Eugene Yokota 72aff3c13c [2.x] Retire textDocument/definition 2026-08-06 14:07:35 -04:00
Eugene Yokota e23053fb89 [2.x] fix: Gate LSP calls behind auth
**Problem**
Some custom LSP calls do not check initialize-handshake,
which over TCP includes token-based authentication.

**Solution**
This adds checkAuthenticated check around sbt/exec etc.
2026-08-06 14:07:13 -04:00
Eugene Yokota f35903ee73 sbt 2.0.5 v2.0.5 2026-08-03 18:39:57 -04:00
eugene yokota ab507bb622 Merge pull request #9548 from eed3si9n/bport2/backports2
[2.0.x] Backports
2026-08-03 16:59:51 -04:00
BrianHotopp d0960b8fa6 [2.0.x] fix: Complete earlyOutputPing on cache-hit and failed compiles (#9542)
With usePipelining enabled, earlyOutputPing was completed only as a side
effect of zinc reporting progress mid-compile (CompileProgress.afterEarlyOutput
via writeEarlyOut / notifyNoEarlyOut in zinc-core). On an action-cache hit zinc
never runs, and on a failed compile it never reports, so the promise stayed
unfulfilled and every task waiting on it - compileEarly and makePickleProducts
across downstream pipelined projects - parked forever. A warm compile;compile
on a multi-module build hung indefinitely (#9486).

The compile task now completes the ping on every resolution path. Zinc's own
completion still wins when zinc ran (tryComplete is atomic, so it can never
pre-empt it); a cache hit completes it from the pickle jar's presence on disk
(absent jar means downstream falls back to a full compile, which is the correct
degradation); a failed compile completes it false so waiters take the full
compile path and propagate the failure instead of hanging.

Generated-by: kimi-code/k3 (Oh My Pi)
2026-08-03 16:29:01 -04:00
eugene yokota bea2a1801a [2.0.x] fix: Fixes a/build.sbt leakage (#9519)
**Problem**
subproject build.sbt like a/build.sbt leaks to siblings.

**Solution**
Don't forward freshly computed common settings unless
the build.sbt is at root.
2026-08-03 16:25:08 -04:00
eugene yokota c86d3c8255 Merge pull request #9543 from eed3si9n/bport2/backports
[2.0.x] Backports
2026-08-03 04:24:26 -04:00
Eugene Yokota fe6c1fe29d [2.0.x] sbtn 2.0.0-731e6666 2026-08-03 03:33:24 -04:00
eugene yokota f1e31054fe [2.x] fix: Fixes AccessDeniedException issue on Windows (#9538)
**Problem**
When test classloader holds on to the JAR file, Windows gets
AccessDefinedException on packageBin.

**Solution**
Flip the default to close the test class loader.
2026-08-03 01:01:03 -04:00
KilianSwissborg b86b297996 [2.x] fix: Preserve '=' in remote cache header values (#9534)
**Problem**
`remoteCacheHeaders` entries are parsed in GrpcActionCacheStore.AuthCallCredentials
with h.split("="), which splits on every =. Java's split discards trailing empty
strings, so a Basic auth header such as authorization=Basic dXNlcjpwdw== produces
exactly two elements and matches List(k, v) with the base64 padding silently removed.
The truncated credential is rejected by the cache server with UNAUTHENTICATED.

**Solution**
Split on the first = only, keeping the remainder of the string verbatim as the header
value. The error case narrows to a header containing no = at all.

Generated-by: Claude Opus 5
2026-08-03 01:01:03 -04:00
eugene yokota 3995669971 [2.x] fix: Fixes forked run baseDirectory, take 2 (#9531)
**Problem**
Forked run baseDirectory was changed to current directory in sbt 2.0.4,
which on its own is fine, but it doesn't respect
Compile / run / baseDirectory.

**Solution**
This fixes that.
2026-08-03 01:01:03 -04:00
Mai Huy HoàngandClaude Opus 5 b797f9b231 [2.0.x] perf: Stop content-hashing artifacts when writing update caches (#9524)
sjsonnew serializes a File as a (uri, Long) pair whose Long is a SHA-256 of the
file's contents, and the read direction discards it. A report names each
artifact once per configuration it resolved in, and the projects of a build
largely share their dependencies, so writing the caches re-reads the whole
downloaded classpath many times over: on a 302-module monorepo, 755 GB of jars
and about 11 minutes of CPU for bytes no reader looks at.

Staleness comes from LibraryManagement.fileUptodate instead, which checks
File.exists and the modification time against UpdateReport.stamps.

UpdateReportPersistence.CacheCodec extends the LibraryManagementCodec trait and overrides
the inherited fileStringLongIso so the pair carries 0. That member is virtual,
so the override also reaches the Vector[(Artifact, File)] nested inside the
generated ModuleReportFormat, which a locally-scoped JsonFormat[File] could
not. The inputs store keeps the stock codec, so Tracked.inputChanged still
hashes contents for invalidation.

The JSON shape is unchanged, so caches stay readable in both directions.

Co-authored-by: Claude Opus 5 <[email protected]>
2026-08-03 01:01:03 -04:00
Mai Huy HoàngandClaude Opus 5 da8ec49608 [2.x] perf: Read the resolution's project cache once per report (#9522)
Resolution.projectCache is not a field: it maps projectCache0 into a
version-string-keyed copy on every call. SbtUpdateReport read it once per
dependency, and again per parent POM while assembling inherited licence info, so
for N modules resolved that is N rebuilds of an N-entry immutable map -- turning
a Resolution into an UpdateReport was quadratic in the modules it names.

On a 301-project build this was 61.9% of the CPU update spends, 83% of it
entering through lookupProject.

Read it once per report and reuse it, at every call site including the eviction
loop, which read it three times per conflict. The report produced is unchanged;
only the number of times the same map is built.

Co-authored-by: Claude Opus 5 <[email protected]>
2026-08-03 00:34:40 -04:00
Fabrizio Colonna 15bed7c087 [2.0.x] fix: sbt.bat fails to start client/server mode on Windows (#9520)
sbt.bat fails to start in client/server mode on Windows, falling back to running the full JVM in the foreground.

sbtn uses CreateProcess to spawn the server process. The original %%20 path encoding doesn't work in batch delayed expansion context, and the default install path C:\Program Files (x86) contains spaces that CreateProcess splits at.
2026-08-03 00:31:34 -04:00
Eugene Yokota 837ad17e62 sbt 2.0.4 v2.0.4 2026-07-26 16:44:31 -04:00
eugene yokota e36dbf894c Merge pull request #9509 from eed3si9n/bport2/backports
[2.0.x] Backport fixes
2026-07-26 16:11:55 -04:00
eugene yokota e4f3e7f66b [2.x] Zinc 2.0.4 (#9508) 2026-07-26 15:49:44 -04:00
Jozef Koval ff2a76e769 [2.0.x] fix: Make forked run inherit sbt's working directory (#9442)
forked run used the project's baseDirectory as the working directory, while non-forked execution inherits sbt's own working directory — so toggling fork silently changed how relative paths resolved.

forked run (and forked console) now inherit sbt's working directory, consistent with non-forked execution and `sbtn` expectations.
2026-07-26 15:49:44 -04:00
eugene yokota 3155bde5ab [2.0.x] fix: Fixes scalaCompilerBridgeBin (#9506)
**Problem/Solution**
Fixes scalaCompilerBridgeBin leaking project names
across different builds.
2026-07-26 15:49:44 -04:00
Eugene Yokota 30f573f1c3 [2.0.x] Move compiler bridge to Update
**Problem**
We want to grab tooling artifacts in update.

**Solution**
This adds binary compiler bridge artifacts into the update graph.
2026-07-26 15:49:44 -04:00
BrianHotoppandClaude Opus 4.8 8266803408 [2.0.x] fix: Complete server teardown before logging so reboot works from sbtn (#9497)
Running reboot in the sbt shell dropped to the OS shell instead of rebooting.
The break was in teardown: Server.shutdown opened with
log.info, and during a client-initiated reboot the terminal in scope is that
client's already-closed virtual terminal, so the log write throws
ClosedChannelException through the terminal proxy. That aborted teardown
before the portfile was deleted and the server socket closed, and the
exception was swallowed by the shutdown hook (whose own error print goes to
the same dead terminal).

Server.shutdown now completes its state cleanup (portfile, tokenfile, running
flag, server socket) before logging, and CommandExchange.shutdown wraps each
channel shutdown and the server shutdown individually so one failing step
cannot skip the rest.

Fixes #9095

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-26 15:04:46 -04:00
Eugene Yokota aacbf737c0 Add remote-cache test 2026-07-26 15:03:07 -04:00
Eugene Yokota aed2719f02 [2.x] fix: Intern GrpcActionCacheStore
**Problem**
GrpcActionCacheStore gets recreated per reload.

**Solution**
This interns GrpcActionCacheStore based on the parameters.
2026-07-26 15:00:58 -04:00
eugene yokota 6ea3eb7e87 [2.0.x] sbtn 2.0.0-a0c4773a (#9503) 2026-07-26 15:00:15 -04:00
eugene yokota c7fb328142 Merge pull request #9501 from eed3si9n/bport2/backports
[2.0.x] Backport fixes
2026-07-25 17:30:46 -04:00
Eugene Yokota 752f5d42b1 Add missing imports 2026-07-25 16:21:53 -04:00
Kevin Lee fa2f8b87b8 [2.0.x] fix: Fixes three test-classloader / jar-handle leaks in the sbt server JVM (#9485)
2 independent, pre-existing retention bugs kept the classloader of a
finished in-process test run -- and the open jar handles it holds -- alive
for the rest of the server session.

- JUnitXmlTestsListener: testSuite is an InheritableThreadLocal, so
  threads spawned during a run (e.g. async-framework pool workers) inherit
  a copy of the suite reference that remove() cannot reach.

- ClassLoaderCache: loaders evicted from delegate by clearExpiredLoaders
  are unreachable from the map and never enqueued on the ReferenceQueue, so
  neither clear()/close() nor the cleanup thread could ever close them.

SuiteResult now documents the retention hazard on throwables. Adds
deterministic, cross-platform tests for all three severed chains.
2026-07-25 16:02:21 -04:00
eugene yokota fd4e7c4863 [2.x] fix: Skip checksum generation for asc file, take 2 (#9499)
**Problem**
Checksums are still generated for asc file.
1. localStaging is a file repo, which was not handled
2. It was checking Artifact name, not the file name

**Solution**
This fixes both.
2026-07-25 15:59:42 -04:00
Eugene Yokota 9b295a6d41 [2.0.x] Zinc 2.0.3 2026-07-25 15:59:09 -04:00
BrianHotoppandClaude Opus 4.8 67b8c54432 [2.x] fix: Keep file I/O out of cache-write serialization (#9496)
putBlobsIfNeeded reads each blob's hash and size once, up front, and
returns only plain HashedVirtualFileRef values, so serializing an ActionResult
(disk, in-memory, or remote store) performs no file I/O and nothing re-stats a
blob after its CAS entry is written: a file vanishing once stored no longer
prevents the write, and I/O errors on an output file surface upfront at blob
storage time rather than mid-serialization.

Fixes #9349

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-25 15:57:32 -04:00
66e0a3ed93 [2.x] fix: Register every Def.declareOutput execution, not one per call site (#9492)
The cached-task macro allocated one mutable slot per syntactic
Def.declareOutput / Def.declareOutputDirectory call site and snapshotted the
slots into the task's outputs after the body ran. A call inside a loop or .map
over a runtime-determined list is a single syntactic site executed many times,
so each iteration overwrote the same slot and only the last file was cached and
restored on a cache hit. There was also no way for a conditional call site that
did not execute to stay out of the outputs: its slot remained null.

Declared outputs now accumulate in a per-task ListBuffer: the macro emits one
buffer at the top of the cached body and rewrites each call site to
ActionCache.registerOutput(vf, buffer), which appends and returns the value.
Every execution registers, an unexecuted site contributes nothing, and the
static multi-site shape is unchanged.

Refs #9462 (the declareOutput-in-a-loop half)

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Co-authored-by: eugene yokota <[email protected]>
2026-07-25 15:57:06 -04:00