**Problem**
sbt 2.x currently constructs the test classloader using symlinks
to the JARs in CAS (content-addressable storage).
This causes issues because JVM apparently caches opened JAR files by path,
and since the symlink itself doesn't change it could end up
serving stale resource files.
**Solution**
We can workaround this issue by resolving the symlinks to the real path.
For the purposes of matching resolved dependencies to reverse-dependency entries, do not use dependency overrides to check equality.
Co-authored-by: Anatolii Kmetiuk <anatoliikmt@proton.me>
Restores override-build-repos config option responsible for passing the JVM flag to the launcher.
Co-authored-by: Anatolii Kmetiuk <anatoliikmt@proton.me>
Problem:
When useIvy := false, ivyless publishing dropped the optional
scala_[scalaVersion]/ and sbt_[sbtVersion]/ path segments from Ivy-style
plugin publish patterns. This caused sbt 1 plugins published from sbt 2 builds
to land under non-plugin Ivy paths, so consumers looking under
scala_2.12/sbt_1.0/ could not resolve them.
Solution:
Read the plugin cross-version attributes from the CsrProject module and use
them when constructing ivyless Ivy-layout publish paths. Apply the same
substitution for local/file Ivy publishing and remote Ivy-style URL publishing,
while continuing to omit those optional segments when the attributes are absent.
Add scripted regressions for local and HTTP Ivy-style publishing of an sbt 1
plugin with useIvy := false.
A task that floods stdout could not be stopped promptly: cancelling it
(Ctrl+C from the thin client) stopped the task, but the server kept
draining the already-queued output to the client for several seconds,
because onCancellationRequest never discarded the pending backlog.
onCancellationRequest now sets a per-channel isCanceled flag and clears the
queued frames and buffered stdout (discardPending), and jsonRpcNotify
drops the cancelled task's systemOut/systemErr while the flag is set, so
output stops promptly.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The byteStreamStub lazy val applied withDeadlineAfter once, baking in an
absolute deadline that was reused for the store's whole (session-long)
lifetime. remoteTimeoutInSec after the first blob transfer, every later
ByteStream read/write was rejected with DEADLINE_EXCEEDED, so the remote
cache could neither upload nor download blobs >chunkSizeBytes for the rest
of the sbt server's life.
Derive a fresh stub with the deadline per RPC so each call gets its own
relative timeout.
Co-authored-by: Yannick Heiber <yhe@famly.co>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NetworkChannel batches writes to the client at most once per 20ms to
reduce terminal flicker and byte volume. forceFlush(), used to order
buffered stdout ahead of a control-plane message, called
flushExecutor.shutdownNow() -- the only place the executor was ever
shut down. Once it ran during active output it tore the executor
down (and, if a coalesced flush was pending, cancelled its future
without resetting flushFuture, leaving the slot stuck), so the 20ms
coalescing was gone for the rest of the connection: stdout was then
flushed per write via the inline fallback instead of batched. Output
still reaches the client, so the effect is extra flushes rather than
lost output, but shutting the shared executor down on the first
forceFlush is clearly unintended.
Extract the flush state machine into CoalescingFlusher. forceFlush now
drains immediately and leaves the timer live (a pending coalesced
drain harmlessly drains the remainder when it fires); the executor is
shut down once, at channel teardown, so it no longer leaks. doFlush
now holds a lock across both the drain and the publish so an inline
forceFlush and the timer's drain can't deliver two stdout batches out
of order.
Fixes#9415
Co-authored-by: BrianHotopp <brihoto@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This applies a range of optimisations local to ClassStamper that bring the time needed for refinedTestDigests down to acceptable levels (see #9108):
* Cache the digests of transitive dependencies (big impact)
* Avoid sorting of digest subsets that would later get sorted again (small)
* Pre-compute which Analysis instances are required for each class to avoid repeated scanning of the whole list (medium)
* Merge two loops on relations.externalDeps into one (small)
* Compute the set of extra digests outside loop (small)
* Track the digest closure of each test via a BitSet (big)
**Problem**
sbt runner script defaults to sbtn, even on the operating system
where sbtn is not available.
**Solution**
This fallbacks to the jvm client.
**Problem**
Global plugin loading doesn't work.
**Solution**
1. Use ModuleID from to supply the location of global-plugin module.
2. Update pluginData with the global plugin classpath.
- Use Builders to avoid building intermediate collections
- Use a mutable.Set for alreadySeen
- Use plain Set instead of SortedSet
- Sorting only needs to happen at the end of the computation in transitiveStamp
Co-authored-by: Matt Dziuban <mrdziuban@gmail.com>
Def.setting and Def.task macro expansion looks for internal wrapper
call generated for .value.
It visits all function calls in the macro. If the block contains
functions call whose type parameter is HKT, macro expansion crashed.
Macro expansion tries to match IO against '[a], and failed with MatchError.
This commit adds wildcard pattern, and leave unmatched type arguments unchanged.
**Problem**
Test is based on https://github.com/sbt/sbt/issues/9345#issuecomment-4718229113 which gives us the following sequence:
1. Metals sends buildTarget/compile.
2. sbt publishes real non-empty diagnostics.
3. Metals sends buildTarget/scalaMainClasses.
4. During that request, sbt emits build/publishDiagnostics with diagnostics: [] and reset: true.
5. The following build/taskFinish still reports errors: 1.
Previously, errors for diagnostics reporting via bsp were collected from a live compilation run. In the sequence above, that is triggered by buildTarget/compile. Then, buildTarget/scalaMainClasses does not trigger such a run for the second time, it uses the cached compilation result. Therefore, the diagnostics is not populated.
**Solution**
The proposed fix modifies sendFailureReport to accept an optional CompileFailed object that contains the diagnostics even in case the actual compiler did not run because the cached result was used. If no problems were found for a file via default means, this CompileFailed object is queried to see if it has any information about problems in a given file.
Problem
When build.properties contains whitespaces like sbt.version = 1.12.12, parsing fails and the detected sbt version falls back to 2.0.0.
Solution
Trim whitespaces in build.properties.
Avoid launching sbt just to render --version by reading sbt.version directly from project/build.properties in the shell script, batch script, and sbtw wrapper. Tighten launcher integration assertions to verify version output no longer depends on the sbtVersion command output.
Co-authored-by: bitloi <89318445+bitloi@users.noreply.github.com>
**Problem**
console / javaOptions is ignored.
**Solution**
1. This enables forked console even for sbt --server mode.
2. This includes console / javaOptions to the forkOptions.
**Problem**
Chunked upload/download doesn't work.
**Solution**
1. This fixes the SERVICE_NAME shading.
2. This fixes the resource name.
3. This fixes download stream processing.