**Problem**
Current MixedAnalyzingCompiler analysis cache caches using the last write,
assuming all writing happens via it. However, this doesn't work with
sbt 2.x caching system where the gz file under it can switch.
**Solution**
This switches to using caffeine caching, which includes file size
and file timestamp for local analysis caching.
**Problem**
Some tests are failing.
**Solution**
* Port EvictionErrorSpec to lm-coursier
* Port EvictionWarningSpec to lm-coursier
* Port InclExclSpec to lm-coursier
* Port ZincComponentCompilerSpec to lm-coursier
* Apparently we still need lmIvy
Bumps io to released 1.12.0 which contains the atomic-write changes
to IO.copyFile, IO.transfer(InputStream, File), and IO.jar/zip.
ActionCacheStore.putBlob now uses IO.transfer instead of duplicating
staging logic.
**Problem**
Projects defined in subdirectory build.sbt files are
not correctly resolved to the base directory relative to the file.
**Solution**
Call resolveBase.
Bug 1: bgRun forks with inheritIO() instead of LoggedOutput
bgRunTask / bgRunMainTask resolve their fork options via (run / forkOptions), which inherits run / connectInput := true. That has two downstream consequences:
1. ForkRun.configLogged (in run/src/main/scala/sbt/Run.scala) skips installing OutputStrategy.LoggedOutput(log) whenever config.connectInput == true.
2. Fork.apply (in run/src/main/scala/sbt/Fork.scala) sees connectInput && outputStrategy == StdoutOutput and takes the interactiveFork path, which calls jpb.inheritIO().
Bug 2: Background-job log relay drops messages after the spawning task ends
Even after Bug 1 is fixed, LoggedOutput routes the forked process's stdout into the background ManagedLogger, whose appenders include a shared RelayAppender. The relay calls CommandExchange.logMessage(event), which uses isChannelOwner(c) to pick the target channel.
**Problem**
In sbt 2.x, forking still creates layered classloader in the worker process,
which doesn't work for some tests.
**Solution**
This provides an escape hatch to emulate the sbt 1.x semantics of
using the system classpath for testing.
**Problem**
`dependencyTree` with `--browse` can throw when desktop browse is unavailable (for example on Wayland/headless environments), causing command failure.
**Solution**
Handle unsupported desktop/browse actions and runtime browse failures gracefully by logging a warning instead of throwing, and add regression tests for unsupported/throwing desktop scenarios.
Generated-by: Cursor Codex 5.3
**Problem**
When using scala-native, we can't enable semanticdb etc
because of the platform-level platform.
**Solution**
Since compilerPlugin(...) is always going to be JVM,
just add an explicit JVM platform to the given ModuleID.
* Add Test configuration to evictionWarningOptions
* Add Test configuration to default evictionWarningOptions
* Deduplicate eviction errors based on callers.
* Update eviction error test for semantic versioning.
* Group evictions by configuration and update test.
**Problem**
When managedScalaInstance is set to false, we stopped creating
ScalaInstance, but the documentation says the user can
pull in their own dependencies.
**Solution**
Attempt to construct a ScalaInstance from update report
even when managedScalaInstance is set to false.
- Cache AutoPlugin.projectSettings and projectConfigurations via AutoPluginCache so they are evaluated once per plugin instance during build loading, not once per subproject (N×M → M)
- Make GroupedAutoPlugins.globalSettings a lazy val and pre-compute buildSettingsMap to avoid repeated aggregation
Rather than using the FileConverter to replace virtual paths, this uses the rootPaths directly. It only replaces a virtual path in a scalac option if the given segment of the option begins with the root path key.