diff options
-rw-r--r-- | stage2/BasicBuild.scala | 9 | ||||
-rw-r--r-- | stage2/Lib.scala | 81 | ||||
-rw-r--r-- | test/test.scala | 21 |
3 files changed, 72 insertions, 39 deletions
diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala index f784299..410d68f 100644 --- a/stage2/BasicBuild.scala +++ b/stage2/BasicBuild.scala @@ -137,8 +137,13 @@ trait BaseBuild extends DependencyImplementation with BuildInterface with Trigge def run: ExitCode = lib.runMainIfFound( runClass, context.args, classLoader(context.classLoaderCache) ) def clean = { - val arg = if (context.args.length > 1) context.args(1) else "" - lib.clean(scalaTarget, arg) + lib.clean( + target, + context.args.contains("force"), + context.args.contains("dry-run"), + context.args.contains("list"), + context.args.contains("help") + ) } def test: Option[ExitCode] = diff --git a/stage2/Lib.scala b/stage2/Lib.scala index e05085e..5b175c1 100644 --- a/stage2/Lib.scala +++ b/stage2/Lib.scala @@ -4,7 +4,7 @@ import java.io._ import java.net._ import java.lang.reflect.InvocationTargetException import java.nio.file.{Path =>_,_} -import java.nio.file.Files.{readAllBytes, deleteIfExists} +import java.nio.file.Files.{readAllBytes, deleteIfExists, delete} import java.security.MessageDigest import java.util.jar._ import java.lang.reflect.Method @@ -199,42 +199,57 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{ } } - def clean (compileTarget : File, option: String) : ExitCode = { - /* recursively deletes folders*/ - def deleteRecursive(file: File): Boolean = { - if (file.isDirectory) { - file.listFiles.map(deleteRecursive(_)) - } - deleteIfExists(file.toPath) + def clean(target: File, force: Boolean, dryRun: Boolean, list: Boolean, help: Boolean): ExitCode = { + def depthFirstFileStream(file: File): Vector[File] = { + ( + if (file.isDirectory) { + file.listFiles.toVector.flatMap(depthFirstFileStream(_)) + } else Vector() + ) :+ file } + lazy val files = depthFirstFileStream( target ) + + if( help ){ + System.err.println( s""" + list lists files to be delete + force does not ask for confirmation + dry-run does not actually delete files +""" ) + ExitCode.Success + } else if (!target.exists){ + System.err.println( "Nothing to clean. Does not exist: " ++ target.string ) + ExitCode.Success + } else if( list ){ + files.map(_.string).foreach( println ) + ExitCode.Success + } else { + val performDelete = ( + force || { + val console = Option(System.console).getOrElse( + throw new Exception("Can't access Console. Try running `cbt direct clean` or `cbt clean list` or `cbt clean force`.") + ) + System.err.println("Files to be deleted:\n\n") + files.foreach( System.err.println ) + System.err.println("") + System.err.print("To delete the above files type 'delete': ") + console.readLine() == "delete" + } + ) - def listFilesToDelete(file: File): Unit = { - if (file.isDirectory) { - file.listFiles.map(listFilesToDelete(_)) - } - println(file.toString) - } - listFilesToDelete(compileTarget) - val delete = if (option != "-f") { - Option(System.console).getOrElse( - throw new Exception("Can't access Console. Try running `cbt direct clean` or `cbt clean -f`.") - ).readLine( - "Delete file(s) [y/n]: " - ).head.toLower - } else 'y' - - if (delete == 'y') { - logger.lib(s"""Cleaning ${compileTarget}""") - if (!compileTarget.exists) return ExitCode.Success - if (deleteRecursive(compileTarget)) { - logger.lib("Succeeded") - ExitCode.Success - } else { - logger.lib("Failed") + if( !performDelete ) { + System.err.println( "Ok, not cleaning." ) ExitCode.Failure + } else { + // use same Vector[File] that was displayed earlier as a safety measure + files.foreach{ file => + System.err.println( red("Deleting") ++ " " ++ file.string ) + if(!dryRun){ + delete( file.toPath ) + } + } + System.err.println( "Done." ) + ExitCode.Success } - } else { - ExitCode.Failure } } diff --git a/test/test.scala b/test/test.scala index 13209ff..7bbf1d9 100644 --- a/test/test.scala +++ b/test/test.scala @@ -1,6 +1,7 @@ import cbt._ import java.util.concurrent.ConcurrentHashMap import java.io.File +import java.nio.file._ import java.net.URL // micro framework @@ -73,9 +74,22 @@ object Main{ } def clean(path: String)(implicit logger: Logger) = { - val res = runCbt(path, Seq("clean", "-f")) - val debugToken = "clean " ++ path ++ " " + val res = runCbt(path, Seq("clean", "dry-run", "force")) + val debugToken = "\n"++lib.red("Deleting") ++ " " ++ Paths.get("test/"++path++"/target").toAbsolutePath.toString++"\n" + val debugToken2 = "\n"++lib.red("Deleting") ++ " " ++ Paths.get("test/"++path).toAbsolutePath.toString++"\n" assertSuccess(res,debugToken) + assert(res.out == "", debugToken ++ " " ++ res.toString) + assert(res.err.contains(debugToken), debugToken ++ " " ++ res.toString) + assert( + !res.err.contains(debugToken2), + "Tried to delete too much: " ++ debugToken2 ++ " " ++ res.toString + ) + res.err.split("\n").filter(_.startsWith(lib.red("Deleting"))).foreach{ line => + assert( + line.size >= debugToken2.trim.size, + "Tried to delete too much: " ++ line + ) + } } logger.test( "Running tests " ++ _args.toList.toString ) @@ -156,7 +170,7 @@ object Main{ usage("nothing") compile("nothing") - clean("nothing") + //clean("nothing") usage("multi-build") compile("multi-build") clean("multi-build") @@ -165,7 +179,6 @@ object Main{ clean("simple") usage("simple-fixed") compile("simple-fixed") - clean("simple-fixed") compile("../plugins/sbt_layout") compile("../plugins/scalafmt") |