diff --git a/app/Commands/Clean.hs b/app/Commands/Clean.hs new file mode 100644 index 0000000000..3b17c394ed --- /dev/null +++ b/app/Commands/Clean.hs @@ -0,0 +1,8 @@ +module Commands.Clean where + +import Commands.Base + +runCommand :: Members '[Files, App] r => Sem r () +runCommand = do + buildDir <- askBuildDir + whenM (directoryExists' buildDir) (removeDirectoryRecursive' buildDir) diff --git a/app/TopCommand.hs b/app/TopCommand.hs index fb313f0f7b..b8cf0735e8 100644 --- a/app/TopCommand.hs +++ b/app/TopCommand.hs @@ -1,6 +1,7 @@ module TopCommand where import Commands.Base hiding (Format) +import Commands.Clean qualified as Clean import Commands.Compile qualified as Compile import Commands.Dev qualified as Dev import Commands.Doctor qualified as Doctor @@ -32,6 +33,7 @@ runTopCommand = \case Dev opts -> Dev.runCommand opts Typecheck opts -> Typecheck.runCommand opts Compile opts -> Compile.runCommand opts + Clean -> runFilesIO Clean.runCommand Eval opts -> Eval.runCommand opts Html opts -> Html.runCommand opts JuvixRepl opts -> Repl.runCommand opts diff --git a/app/TopCommand/Options.hs b/app/TopCommand/Options.hs index 37f372fcb3..e8af769396 100644 --- a/app/TopCommand/Options.hs +++ b/app/TopCommand/Options.hs @@ -19,6 +19,7 @@ data TopCommand | DisplayHelp | Typecheck TypecheckOptions | Compile CompileOptions + | Clean | Eval EvalOptions | Html HtmlOptions | Dev Dev.DevCommand @@ -87,7 +88,8 @@ parseUtility = commandInit, commandDev, commandRepl, - commandFormat + commandFormat, + commandClean ] ) where @@ -121,18 +123,25 @@ parseUtility = command "format" $ info (JuvixFormat <$> parseFormat) - ( progDescDoc + ( headerDoc ( Just ( vsep - [ "Format a Juvix file or Juvix project", + [ "juvix format is used to format Juvix source files.", "", - "When the command is run with an unformatted file it prints the reformatted source to standard output.", - "When the command is run with a project directory it prints a list of unformatted files in the project." + "Given an unformatted file, it prints the reformatted source to standard output.", + "Given a project directory it prints a list of unformatted files in the project." ] ) ) + <> progDesc "Format a Juvix file or Juvix project" ) + commandClean :: Mod CommandFields TopCommand + commandClean = + command + "clean" + (info (pure Clean) (progDesc "Delete build artifacts")) + commandCheck :: Mod CommandFields TopCommand commandCheck = command "typecheck" $ diff --git a/tests/smoke/Commands/clean.smoke.yaml b/tests/smoke/Commands/clean.smoke.yaml new file mode 100644 index 0000000000..8e1bf02a25 --- /dev/null +++ b/tests/smoke/Commands/clean.smoke.yaml @@ -0,0 +1,61 @@ +working-directory: ./../../../ + +tests: + - name: clean-with-no-build-dir + command: + shell: + - bash + script: | + temp=$(mktemp -d) + trap 'rm -rf -- "$temp"' EXIT + cd $temp + juvix clean + stdout: "" + exit-status: 0 + + - name: clean-with-default-build-dir + command: + shell: + - bash + script: | + temp=$(mktemp -d) + trap 'rm -rf -- "$temp"' EXIT + cd ./examples/milestone/HelloWorld + juvix compile -o $temp/Hello HelloWorld.juvix + juvix clean + [ -d $temp/.juvix-build ] + stdout: "" + exit-status: 1 + + - name: clean-with-internal-build-dir + command: + shell: + - bash + script: | + temp=$(mktemp -d) + trap 'rm -rf -- "$temp"' EXIT + temp_build_dir=$(mktemp -d) + trap 'rm -rf -- "$temp_build_dir"' EXIT + cd ./examples/milestone/HelloWorld + juvix compile -o $temp/Hello HelloWorld.juvix --internal-build-dir "$temp_build_dir" + juvix --internal-build-dir "$temp_build_dir" clean + [ -d $temp_build_dir ] + stdout: "" + exit-status: 1 + + - name: clean-with-internal-build-dir-does-not-remove-default-build-dir + command: + shell: + - bash + script: | + temp=$(mktemp -d) + trap 'rm -rf -- "$temp"' EXIT + temp_build_dir=$(mktemp -d) + trap 'rm -rf -- "$temp_build_dir"' EXIT + cp -r ./examples/milestone/HelloWorld/. $temp + cd $temp + juvix compile HelloWorld.juvix + juvix --internal-build-dir "$temp_build_dir" clean + [ -d $temp/.juvix-build ] + stdout: "" + exit-status: 0