aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Vogt <oss.nsp@cvogt.org>2016-08-14 20:13:44 -0400
committerChristopher Vogt <oss.nsp@cvogt.org>2016-08-28 23:37:16 -0400
commit9022c5ffbe4aa993da436f71dd732567c64a6c24 (patch)
treeb6e8f4a9c89645f79076963b85f6727e5e7d188b
parent2d291a4fe19330020d7c1845bbb1deee204c6d69 (diff)
downloadcbt-9022c5ffbe4aa993da436f71dd732567c64a6c24.tar.gz
cbt-9022c5ffbe4aa993da436f71dd732567c64a6c24.tar.bz2
cbt-9022c5ffbe4aa993da436f71dd732567c64a6c24.zip
Add a bunch of options to try to allow safe usage of clean
try to make tests safer (fixed tests don't have clean yet, nothing has nothing to delete, so current test code would fail)
-rw-r--r--stage2/BasicBuild.scala9
-rw-r--r--stage2/Lib.scala81
-rw-r--r--test/test.scala21
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")