Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make stack clean be more thorough by default #4385

Merged
merged 11 commits into from
Mar 8, 2019
20 changes: 20 additions & 0 deletions doc/GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,26 @@ As you can see from that path (and as emphasized earlier), the installation is
placed to not interfere with any other GHC installation, whether system-wide or
even different GHC versions installed by stack.

## Cleaning your project

You can clean up build artifacts for your project using the `stack clean` and `stack purge` commands.

### `stack clean`

`stack clean` deletes the local working directories containing compiler output.
By default, that means the contents of directories in `.stack-work/dist`, for all the `.stack-work` directories within a project.

Use `stack clean <specific-package>` to delete the output for the package _specific-package_ only.

### `stack purge`

`stack purge` deletes the local stack working directories, including extra-deps, git dependencies and the compiler output (including logs).
It does not delete any snapshot packages, compilers or programs installed using `stack install`. This essentially
reverts the project to a completely fresh state, as if it had never been built.
`stack purge` is just a shortcut for `stack clean --full`

- Note: `stack purge` is not available when used in docker

### The build command

The build command is the heart and soul of stack. It is the engine that powers
Expand Down
8 changes: 7 additions & 1 deletion src/Stack/Clean.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
module Stack.Clean
(clean
,CleanOpts(..)
,CleanCommand(..)
,StackCleanException(..)
) where

Expand Down Expand Up @@ -55,12 +56,17 @@ dirsToDelete cleanOpts = do
-- | Options for @stack clean@.
data CleanOpts
= CleanShallow [PackageName]
-- ^ Delete the "dist directories" as defined in 'Stack.Constants.distRelativeDir'
-- ^ Delete the "dist directories" as defined in 'Stack.Constants.Config.distRelativeDir'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😀

-- for the given local packages. If no packages are given, all project packages
-- should be cleaned.
| CleanFull
-- ^ Delete all work directories in the project.

-- | Clean commands
data CleanCommand
= Clean
| Purge

-- | Exceptions during cleanup.
newtype StackCleanException
= NonLocalPackages [PackageName]
Expand Down
12 changes: 7 additions & 5 deletions src/Stack/Options/CleanParser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@
module Stack.Options.CleanParser where

import Options.Applicative
import Stack.Clean (CleanOpts (..))
import Stack.Clean (CleanCommand(..), CleanOpts (..))
import Stack.Prelude
import Stack.Types.PackageName

-- | Command-line parser for the clean command.
cleanOptsParser :: Parser CleanOpts
cleanOptsParser = CleanShallow <$> packages <|> doFullClean
cleanOptsParser :: CleanCommand -> Parser CleanOpts
cleanOptsParser Clean = CleanShallow <$> packages <|> doFullClean
where
packages =
many
(packageNameArgument
(metavar "PACKAGE" <>
help "If none specified, clean all local packages"))
help "If none specified, clean all project packages"))
doFullClean =
flag'
CleanFull
(long "full" <>
help "Delete all work directories (.stack-work by default) in the project")
help "Delete the project’s stack working directories (.stack-work by default).")

cleanOptsParser Purge = pure CleanFull
10 changes: 7 additions & 3 deletions src/main/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import RIO.PrettyPrint
import qualified RIO.PrettyPrint as PP (style)
import Stack.Build
import Stack.Build.Target (NeedTargets(..))
import Stack.Clean (CleanOpts(..), clean)
import Stack.Clean (CleanCommand(..), CleanOpts(..), clean)
import Stack.Config
import Stack.ConfigCmd as ConfigCmd
import Stack.Constants
Expand Down Expand Up @@ -403,9 +403,13 @@ commandLineHandler currentDir progName isInterpreter = complicatedOptions
evalCmd
(evalOptsParser "CODE")
addCommand' "clean"
"Clean the local packages"
"Delete build artefacts for the project packages."
cleanCmd
cleanOptsParser
(cleanOptsParser Clean)
addCommand' "purge"
"Delete the project stack working directories (.stack-work by default). Shortcut for 'stack clean --full'"
cleanCmd
(cleanOptsParser Purge)
addCommand' "list-dependencies"
"List the dependencies"
(listDependenciesCmd True)
Expand Down
39 changes: 39 additions & 0 deletions test/integration/tests/3863-purge-command/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import StackTest
import Data.Maybe (listToMaybe, fromMaybe)
import System.Directory
import System.FilePath

main :: IO ()
main =
-- For these commands, we'll need to know the `dist` directory.
-- This is usually `.stack-work/dist/$compiler-variant/Cabal-xxxx`
stackCheckStdout [defaultResolverArg, "path", "--dist-dir"] $ \distDir ->

stackCheckStdout [defaultResolverArg, "path", "--local-install-root"] $ \localInstallRoot -> do

-- Usually `.stack-work`
let stackWork = fromMaybe (error "There must be a stack working directory.") $
listToMaybe (splitDirectories distDir)

-- First, clean the .stack-work directory.
-- This is only necessary when running individual tests.
stack [defaultResolverArg, "purge"]
doesNotExist stackWork

-- The dist directory should exist after a build
stack [defaultResolverArg, "build"]
doesExist distDir
doesExist localInstallRoot
doesExist stackWork

-- The dist directory should not exist after a clean, whereas the
-- .stack-work directory should
stack [defaultResolverArg, "clean"]
run "exa" ["-T", ".stack-work"]
doesNotExist distDir
doesExist localInstallRoot
doesExist stackWork

-- The .stack-work directory should not exist after a purge
stack [defaultResolverArg, "purge"]
doesNotExist stackWork
11 changes: 11 additions & 0 deletions test/integration/tests/3863-purge-command/files/new-template.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: new-template
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.10


library
hs-source-dirs: src
exposed-modules: Lib
build-depends: base >= 4.7 && < 5
default-language: Haskell2010
4 changes: 4 additions & 0 deletions test/integration/tests/3863-purge-command/files/src/Lib.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Lib where

someFunc :: ()
someFunc = ()
5 changes: 5 additions & 0 deletions test/integration/tests/3863-purge-command/files/stack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
flags: {}
packages:
- '.'
extra-deps: []
resolver: lts-11.22