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]>
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**
Like File, Path normally captures the absolute path,
so likely not a good candidate for caching.
**Solution**
Ban it.
---------
Co-authored-by: Anatolii Kmetiuk <[email protected]>
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)
This flips the default `:=` operation to the cached task.
To opt out of the cache, use `Def.uncached(...)` or
mark the key with `@cacheLevel(include = Array.empty)`
It's sometimes useful to get the output of the macro-generated code.
This adds a mechanism to allow plugins.sbt to pass in scalacOptions,
which we can later check from the macro.
1. -Xmacro-settings:sbt:Vprint prints out the code.
2. Adding -Xmacro-settings:sbt:print-tree-structure prints out the tree structure.
**Problem**
Nested macro that expands to map or mapN fails to
find the qual because the trees end up being different
between the record scan and actual replacement.
**Solution**
First try for equals normally, then compare the show strings.
For the details about this PR, please see the blog post https://eed3si9n.com/sbt-remote-cache/.
* Add cache basics
* Refactor Attributed to use StringAttributeMap, which is Map[StringAttributeKey, String]
* Implement disk cache
* Rename Package to Pkg
* Virtualize packageBin
* Use HashedVirtualFileRef for packageBin
* Virtualize compile task