Merge pull request #8379 from eed3si9n/wip/clean

[2.x] Adds cleanFull command
This commit is contained in:
eugene yokota 2025-11-23 18:07:57 -05:00 committed by GitHub
commit 9bfc80c65c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 55 additions and 25 deletions

View File

@ -252,7 +252,10 @@ $AliasCommand name=
def continuousBriefHelp: (String, String) =
(ContinuousExecutePrefix + " <command>", continuousDetail)
def ClearCaches: String = "clearCaches"
def ClearCachesDetailed: String = "Clears all of sbt's internal caches."
def ClearCachesDetailed: String = "Clears sbt's internal caches."
val CleanFull: String = "cleanFull"
def cleanFullDetailed: String = "Clears sbt's local caches."
private[sbt] val networkExecPrefix = "__"
private[sbt] val DisconnectNetworkChannel = s"${networkExecPrefix}disconnectNetworkChannel"

View File

@ -28,13 +28,12 @@ import sbt.internal.nio.{ CheckBuildSources, FileTreeRepository }
import sbt.internal.server.{ BuildServerProtocol, NetworkChannel }
import sbt.internal.util.Terminal.hasConsole
import sbt.internal.util.Types.{ const, idFun }
import sbt.internal.util.complete.{ Parser, SizeParser }
import sbt.internal.util.complete.Parser
import sbt.internal.util.{ Terminal as ITerminal, * }
import sbt.io.*
import sbt.io.syntax.*
import sbt.util.{ Level, Logger, Show }
import xsbti.AppProvider
import xsbti.compile.CompilerCache
import scala.annotation.{ nowarn, tailrec }
import scala.concurrent.ExecutionContext
@ -352,6 +351,7 @@ object BuiltinCommands {
act,
continuous,
clearCaches,
Clean.cleanFull,
NetworkChannel.disconnect,
waitCmd,
promptChannel,
@ -970,7 +970,7 @@ object BuiltinCommands {
session,
structure,
s2,
st => setupGlobalFileTreeRepository(addCacheStoreFactoryFactory(st))
st => setupGlobalFileTreeRepository(Clean.addCacheStoreFactoryFactory(st))
)
val s4 = s3.put(Keys.useLog4J.key, Project.extract(s3).get(Keys.useLog4J))
addSuperShellParams(CheckBuildSources.init(LintUnused.lintUnusedFunc(s4)))
@ -992,27 +992,9 @@ object BuiltinCommands {
.put(Keys.superShellThreshold.key, threshold)
.put(Keys.superShellMaxTasks.key, maxItems)
}
private val addCacheStoreFactoryFactory: State => State = (s: State) => {
val size = Project
.extract(s)
.getOpt(Keys.fileCacheSize)
.flatMap(SizeParser(_))
.getOrElse(SysProp.fileCacheSize)
s.get(Keys.cacheStoreFactoryFactory).foreach(_.close())
s.put(Keys.cacheStoreFactoryFactory, InMemoryCacheStore.factory(size))
}
def registerCompilerCache(s: State): State = {
s.get(Keys.stateCompilerCache).foreach(_.clear())
s.put(Keys.stateCompilerCache, CompilerCache.fresh)
}
def clearCaches: Command = {
val help = Help.more(ClearCaches, ClearCachesDetailed)
val f: State => State =
registerCompilerCache andThen (_.initializeClassLoaderCache) andThen addCacheStoreFactoryFactory
Command.command(ClearCaches, help)(f)
}
def registerCompilerCache(s: State): State = Clean.registerCompilerCache(s)
def clearCaches: Command = Clean.clearCaches
private[sbt] def waitCmd: Command =
Command.arb(_ =>

View File

@ -12,19 +12,23 @@ package internal
import java.io.IOException
import java.nio.file.{ DirectoryNotEmptyException, Files, Path }
import sbt.BasicCommandStrings.*
import sbt.Def.*
import sbt.Keys.*
// import sbt.Project.richInitializeTask
import sbt.ProjectExtra.*
import sbt.ScopeAxis.Zero
import sbt.io.syntax.*
import sbt.io.IO
import sbt.nio.Keys.*
import sbt.nio.file.*
import sbt.nio.file.syntax.pathToPathOps
import sbt.nio.file.Glob.{ GlobOps }
import sbt.util.Level
import sbt.util.{ DiskActionCacheStore, Level }
import sbt.internal.util.complete.SizeParser
import sjsonnew.JsonFormat
import xsbti.{ PathBasedFile, VirtualFileRef }
import xsbti.compile.CompilerCache
private[sbt] object Clean {
@ -187,4 +191,41 @@ private[sbt] object Clean {
debug(s"Caught unexpected exception $e deleting $path")
}
}
val registerCompilerCache: State => State = (s: State) =>
s.get(Keys.stateCompilerCache).foreach(_.clear())
s.put(Keys.stateCompilerCache, CompilerCache.fresh)
val addCacheStoreFactoryFactory: State => State = (s: State) =>
val size = Project
.extract(s)
.getOpt(Keys.fileCacheSize)
.flatMap(SizeParser(_))
.getOrElse(SysProp.fileCacheSize)
s.get(Keys.cacheStoreFactoryFactory).foreach(_.close())
s.put(Keys.cacheStoreFactoryFactory, InMemoryCacheStore.factory(size))
private val clearCachesFun: State => State =
registerCompilerCache
.andThen(_.initializeClassLoaderCache)
.andThen(addCacheStoreFactoryFactory)
def clearCaches: Command =
val help = Help.more(ClearCaches, ClearCachesDetailed)
Command.command(ClearCaches, help)(clearCachesFun)
def cleanFull: Command =
val h = Help.more(CleanFull, cleanFullDetailed)
val expunge: State => State =
(s: State) =>
val outputDirectory = s
.get(BasicKeys.rootOutputDirectory)
.getOrElse(sys.error("outputDirectory has not been set"))
val cacheStore = s.get(BasicKeys.cacheStores).getOrElse(Nil)
cacheStore.foreach:
case d: DiskActionCacheStore => d.clear()
case _ => ()
IO.delete(outputDirectory.toFile())
s
Command.command(CleanFull, h)(expunge andThen clearCachesFun)
}

View File

@ -192,6 +192,10 @@ class DiskActionCacheStore(base: Path, converter: FileConverter) extends Abstrac
private val symlinkSupported: AtomicBoolean = AtomicBoolean(true)
override def storeName: String = "disk"
def clear(): Unit =
if Files.exists(base) then IO.delete(base.toFile())
else ()
override def get(request: GetActionResultRequest): Either[Throwable, ActionResult] =
val acFile = acBase.toFile / request.actionDigest.toString.replace("/", "-")
if acFile.exists then