Skip to content

Commit

Permalink
Merge pull request #4609 from commercialhaskell/vanceism7-fix-3863
Browse files Browse the repository at this point in the history
Make stack clean be more thorough by default (supersedes #4385)
  • Loading branch information
snoyberg authored Mar 8, 2019
2 parents 311b6f8 + 8948132 commit 77aa9c3
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 9 deletions.
2 changes: 2 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ Other enhancements:
* `stack clean` will delete the entire `.stack-work/dist` directory,
not just the relevant subdirectory for the current GHC version. See
[#4480](https://github.com/commercialhaskell/stack/issues/4480).
* Add `stack purge` as a shortcut for `stack clean --full`. See
[#3863](https://github.com/commercialhaskell/stack/issues/3863).

Bug fixes:

Expand Down
18 changes: 18 additions & 0 deletions doc/GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,24 @@ 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`

### 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 @@ -58,12 +59,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'
-- 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 @@ -54,7 +54,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 @@ -410,9 +410,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

0 comments on commit 77aa9c3

Please sign in to comment.