From de3c09f99d9fa6bcb3df25fabaf8a6f3a7ae3543 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Sat, 2 Feb 2019 12:02:38 -0800 Subject: [PATCH] Move clean task implementation to Clean.scala The Defaults.scala file has a lot going on. I am trying to generally follow the pattern of implementing the default task implementation in a different file and just adding the appropriate declarations in Defaults.scala. --- main/src/main/scala/sbt/Defaults.scala | 45 +------------- main/src/main/scala/sbt/internal/Clean.scala | 62 ++++++++++++++++++++ 2 files changed, 65 insertions(+), 42 deletions(-) create mode 100644 main/src/main/scala/sbt/internal/Clean.scala diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index a9ce86ebc..cac5e7338 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -9,7 +9,6 @@ package sbt import java.io.{ File, PrintWriter } import java.net.{ URI, URL } -import java.nio.file.{ DirectoryNotEmptyException, Files } import java.util.Optional import java.util.concurrent.{ Callable, TimeUnit } @@ -569,14 +568,14 @@ object Defaults extends BuildCommon { globalDefaults(enableBinaryCompileAnalysis := true) lazy val configTasks: Seq[Setting[_]] = docTaskSettings(doc) ++ inTask(compile)( - compileInputsSettings :+ (clean := cleanTaskIn(ThisScope).value) + compileInputsSettings :+ (clean := Clean.taskIn(ThisScope).value) ) ++ configGlobal ++ defaultCompileSettings ++ compileAnalysisSettings ++ Seq( outputs := Seq( compileAnalysisFileTask.value.toGlob, classDirectory.value ** "*.class" ) ++ (sourceGenerators / outputs).value, compile := compileTask.value, - clean := cleanTaskIn(ThisScope).value, + clean := Clean.taskIn(ThisScope).value, manipulateBytecode := compileIncremental.value, compileIncremental := (compileIncrementalTask tag (Tags.Compile, Tags.CPU)).value, printWarnings := printWarningsTask.value, @@ -622,7 +621,7 @@ object Defaults extends BuildCommon { cleanFiles := cleanFilesTask.value, cleanKeepFiles := Vector.empty, cleanKeepGlobs := historyPath.value.map(_.toGlob).toSeq, - clean := cleanTaskIn(ThisScope).value, + clean := Clean.taskIn(ThisScope).value, consoleProject := consoleProjectTask.value, watchTransitiveSources := watchTransitiveSourcesTask.value, watchProjectTransitiveSources := watchTransitiveSourcesTaskImpl(watchProjectSources).value, @@ -1313,44 +1312,6 @@ object Defaults extends BuildCommon { /** Implements `cleanFiles` task. */ private[sbt] def cleanFilesTask: Initialize[Task[Vector[File]]] = Def.task { Vector.empty[File] } - /** - * Provides an implementation for the clean task. It delegates to [[cleanTaskIn]] using the - * resolvedScoped key to set the scope. - * @return the clean task definition. - */ - def cleanTask: Initialize[Task[Unit]] = - Def.taskDyn(cleanTaskIn(resolvedScoped.value.scope)) tag Tags.Clean - - /** - * Implements the clean task in a given scope. It uses the outputs task value in the provided - * scope to determine which files to delete. - * @param scope the scope in which the clean task is implemented - * @return the clean task definition. - */ - def cleanTaskIn(scope: Scope): Initialize[Task[Unit]] = - Def.task { - val excludes = cleanKeepFiles.value.map { - // This mimics the legacy behavior of cleanFilesTask - case f if f.isDirectory => f * AllPassFilter - case f => f.toGlob - } ++ cleanKeepGlobs.value - val excludeFilter: File => Boolean = excludes.toFileFilter.accept - val globDeletions = (outputs in scope).value.unique.filterNot(excludeFilter) - val toDelete = cleanFiles.value.filterNot(excludeFilter) match { - case f @ Seq(_, _*) => (globDeletions ++ f).distinct - case _ => globDeletions - } - val logger = streams.value.log - toDelete.sorted.reverseIterator.foreach { f => - logger.debug(s"clean -- deleting file $f") - try Files.deleteIfExists(f.toPath) - catch { - case _: DirectoryNotEmptyException => - logger.debug(s"clean -- unable to delete non-empty directory $f") - } - } - } tag Tags.Clean - def bgRunMainTask( products: Initialize[Task[Classpath]], classpath: Initialize[Task[Classpath]], diff --git a/main/src/main/scala/sbt/internal/Clean.scala b/main/src/main/scala/sbt/internal/Clean.scala new file mode 100644 index 000000000..f66323e74 --- /dev/null +++ b/main/src/main/scala/sbt/internal/Clean.scala @@ -0,0 +1,62 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt +package internal + +import java.io.IOException +import java.nio.file.{ DirectoryNotEmptyException, Files } + +import sbt.Def._ +import sbt.Keys._ +import sbt.Project.richInitializeTask +import sbt.internal.GlobLister._ +import sbt.io.AllPassFilter +import sbt.io.syntax._ + +object Clean { + + /** + * Provides an implementation for the clean task. It delegates to [[taskIn]] using the + * resolvedScoped key to set the scope. + * @return the clean task definition. + */ + def task: Def.Initialize[Task[Unit]] = + Def.taskDyn(taskIn(Keys.resolvedScoped.value.scope)) tag Tags.Clean + + /** + * Implements the clean task in a given scope. It uses the outputs task value in the provided + * scope to determine which files to delete. + * @param scope the scope in which the clean task is implemented + * @return the clean task definition. + */ + def taskIn(scope: Scope): Def.Initialize[Task[Unit]] = + Def.task { + val excludes = cleanKeepFiles.value.map { + // This mimics the legacy behavior of cleanFilesTask + case f if f.isDirectory => f * AllPassFilter + case f => f.toGlob + } ++ cleanKeepGlobs.value + val excludeFilter: File => Boolean = excludes.toFileFilter.accept + val globDeletions = (outputs in scope).value.unique.filterNot(excludeFilter) + val toDelete = cleanFiles.value.filterNot(excludeFilter) match { + case f @ Seq(_, _*) => (globDeletions ++ f).distinct + case _ => globDeletions + } + val logger = streams.value.log + toDelete.sorted.reverseIterator.foreach { f => + logger.debug(s"clean -- deleting file $f") + try Files.deleteIfExists(f.toPath) + catch { + case _: DirectoryNotEmptyException => + logger.debug(s"clean -- unable to delete non-empty directory $f") + case e: IOException => + logger.debug(s"Caught unexpected exception $e deleting $f") + } + } + } tag Tags.Clean +}