stack-clean-old 0.3.1 → 0.4
raw patch · 9 files changed
+235/−131 lines, 9 files
Files
- ChangeLog.md +7/−0
- README.md +13/−8
- src/Directories.hs +9/−8
- src/GHC.hs +15/−14
- src/Main.hs +123/−48
- src/Remove.hs +11/−9
- src/Snapshots.hs +44/−43
- src/Types.hs +11/−0
- stack-clean-old.cabal +2/−1
ChangeLog.md view
@@ -1,5 +1,12 @@ # Release history for stack-clean-old-work +## 0.4 (2021-09-26)+- dryrun is now default: use --delete for actual removal+ (suggested by @andreasabel #6)+- new --subdirs and --recursive options+- various output improvements+- purge-older now also says "would be removed" when dryrun+ ## 0.3.1 (2021-08-01) - 'delete-work': use find -prune and ignore inaccessible files (@petrem, #4)
README.md view
@@ -5,7 +5,7 @@ ## Usage ```-stack-clean-old [size|list|remove|keep-minor|purge-older|delete-work] [(-p|--project) | (-g|--ghc)] [GHCVER]+stack-clean-old [size|list|remove|keep-minor|purge-older|delete-work] [(-p|--project) | (-g|--ghc)] [--delete] [GHCVER] ``` Options: @@ -26,7 +26,7 @@ removes for the specified ghc version (the GHCVER argument is required). `keep-minor`:- removes the builds/installs for previous minor ghc versions.+ removes the builds/installs for older minor releases of ghc major versions. If GHCVER is given then only minor versions older than it are removed. `purge-older` and `delete-work`:@@ -36,8 +36,9 @@ then you would have to rebuild them again for any projects still using them, so removal should be used cautiously, but it can recover a lot of diskspace. -NBB: All the command support `--dry-run` (`-n`), so please use it to-check the effect of running them safely beforehand.+Since version 0.4 dry-run mode is now the default and one needs to use+`--delete` (`-d`) for actual deletion of files,+after checking the dry-run output first. ### Example usage To remove project builds for ghc-8.2.2:@@ -46,7 +47,7 @@ 154M 8.2.2 (5 dirs) 154M 8.4.4 (5 dirs) 163M 8.6.5 (5 dirs)-$ stack-clean-old remove -p 8.2.2+$ stack-clean-old remove --delete -p 8.2.2 ``` Remove stack ghc-8.4 snapshot builds and compilers before 8.4.4:@@ -56,7 +57,7 @@ 368M 8.4.2 (6 dirs) 489M 8.4.3 (8 dirs) 799M 8.4.4 (24 dirs)-$ stack-clean-old keep-minor -g 8.4.4+$ stack-clean-old keep-minor -d -g 8.4.4 ghc-tinfo6-8.4.3 removed 7 dirs removed for 8.4.1 6 dirs removed for 8.4.2@@ -82,7 +83,7 @@ (seems same as `stack clean --full`). `stack-clean-old delete-work --all` works from outside stack projects:-please test with `--dry-run` first.+please use with care. ## Installation @@ -92,12 +93,16 @@ This tool complements [stack-all](https://hackage.haskell.org/package/stack-all) which builds projects over LTS major versions and hence generates lot of stack builds. +[cabal-clean](https://hackage.haskell.org/package/cabal-clean) is+a similar tool for cleaning old cached cabal build files.+ ## Contributing BSD license Project: https://github.com/juhp/stack-clean-old ## Warning disclaimer-Use at your own risk: the author takes no responsibility for any loss or damaged caused by using this tool, as also mentioned in LICENSE.+Use at your own risk: the author takes no responsibility for any loss or+damaged caused by using this tool. Bug reports, suggestions, and improvements are welcome.
src/Directories.hs view
@@ -5,7 +5,6 @@ ) where -import Control.Monad.Extra import Data.List.Extra import SimpleCmd (error') import System.Directory@@ -23,14 +22,16 @@ switchToSystemDirUnder :: FilePath -> IO () switchToSystemDirUnder dir = do- ifM (doesDirectoryExist dir)- (setCurrentDirectory dir)- (error' $ dir ++ " not found")+ exists <- doesDirectoryExist dir+ if exists+ then setCurrentDirectory dir+ else error' $ dir ++ " not found" systems <- listDirectory "." -- FIXME be more precise/check "system" dirs -- eg 64bit intel Linux: x86_64-linux-tinfo6- let system = case systems of- [] -> error' $ "No OS system in " ++ dir- [sys] -> sys- _ -> error' "More than one OS systems found " ++ dir ++ " (unsupported)"+ let system =+ case systems of+ [] -> error' $ "No OS system in " ++ dir+ [sys] -> sys+ _ -> error' "More than one OS systems found " ++ dir ++ " (unsupported)" setCurrentDirectory system
src/GHC.hs view
@@ -14,6 +14,7 @@ import Directories (getStackSubdir, globDirs, switchToSystemDirUnder) import qualified Remove+import Types import Versions getStackProgramsDir :: IO FilePath@@ -51,31 +52,31 @@ Nothing -> dirs Just ghcver -> filter ((== ghcver) . (if isMajorVersion ghcver then majorVersion else id) . ghcInstallVersion) dirs -removeGhcVersionInstallation :: Bool -> Version -> IO ()-removeGhcVersionInstallation dryrun ghcver = do+removeGhcVersionInstallation :: Deletion -> Version -> IO ()+removeGhcVersionInstallation deletion ghcver = do installs <- getGhcInstallDirs (Just ghcver) case installs of [] -> putStrLn $ "stack ghc compiler version " ++ showVersion ghcver ++ " not found"- [g] | not (isMajorVersion ghcver) -> doRemoveGhcVersion dryrun g+ [g] | not (isMajorVersion ghcver) -> doRemoveGhcVersion deletion g gs -> if isMajorVersion ghcver then do- Remove.prompt dryrun ("all stack ghc " ++ showVersion ghcver ++ " installations: ")- mapM_ (doRemoveGhcVersion dryrun) gs+ Remove.prompt deletion ("all stack ghc " ++ showVersion ghcver ++ " installations: ")+ mapM_ (doRemoveGhcVersion deletion) gs else error' "more than one match found!!" -removeGhcMinorInstallation :: Bool -> Maybe Version -> IO ()-removeGhcMinorInstallation dryrun mghcver = do+removeGhcMinorInstallation :: Deletion -> Maybe Version -> IO ()+removeGhcMinorInstallation deletion mghcver = do dirs <- getGhcInstallDirs (majorVersion <$> mghcver) case mghcver of Nothing -> do let majors = groupOn (majorVersion . ghcInstallVersion) dirs forM_ majors $ \ minors ->- forM_ (init minors) $ doRemoveGhcVersion dryrun+ forM_ (init minors) $ doRemoveGhcVersion deletion Just ghcver -> do let minors = filter ((< ghcver) . ghcInstallVersion) dirs- forM_ minors $ doRemoveGhcVersion dryrun+ forM_ minors $ doRemoveGhcVersion deletion -doRemoveGhcVersion :: Bool -> FilePath -> IO ()-doRemoveGhcVersion dryrun ghcinst = do- Remove.doRemoveDirectory dryrun ghcinst- Remove.removeFile dryrun (ghcinst <.> "installed")- putStrLn $ ghcinst ++ " compiler " ++ (if dryrun then "would be " else "") ++ "removed"+doRemoveGhcVersion :: Deletion -> FilePath -> IO ()+doRemoveGhcVersion deletion ghcinst = do+ Remove.doRemoveDirectory deletion ghcinst+ Remove.removeFile deletion (ghcinst <.> "installed")+ putStrLn $ ghcinst ++ " compiler " ++ (if isDelete deletion then "" else "would be ") ++ "removed"
src/Main.hs view
@@ -5,18 +5,28 @@ #if !MIN_VERSION_simple_cmd_args(0,1,3) import Control.Applicative ((<|>)) #endif+import Control.Monad+import qualified Data.List as L+import Data.List.Extra+import Data.Maybe import Data.Version.Extra+import Numeric.Natural import SimpleCmd import SimpleCmdArgs import System.Directory+import System.FilePath import System.IO (BufferMode(NoBuffering), hSetBuffering, stdout) import GHC import Paths_stack_clean_old (version) import Snapshots+import Types data Mode = Default | Project | Snapshots | Compilers | GHC +data Recursion = Subdirs | Recursive+ deriving Eq+ main :: IO () main = do hSetBuffering stdout NoBuffering@@ -24,93 +34,158 @@ "Cleans away old stack-work builds (and pending: stack snapshots) to recover diskspace." $ subcommands [ Subcommand "size" "Total size" $- sizeCmd <$> modeOpt <*> notHumanOpt+ sizeCmd <$> modeOpt <*> recursionOpt <*> notHumanOpt , Subcommand "list" "List sizes per ghc version" $- listCmd <$> modeOpt <*> optional ghcVerArg+ listCmd <$> modeOpt <*> recursionOpt <*> optional ghcVerArg , Subcommand "remove" "Remove for a ghc version" $- removeCmd <$> dryrun <*> modeOpt <*> ghcVerArg+ removeCmd <$> deleteOpt <*> modeOpt <*> recursionOpt <*> ghcVerArg , Subcommand "keep-minor" "Remove for previous ghc minor versions" $- removeMinorsCmd <$> dryrun <*> modeOpt <*> optional ghcVerArg+ removeMinorsCmd <$> deleteOpt <*> modeOpt <*> recursionOpt <*> optional ghcVerArg , Subcommand "purge-older" "Purge older builds in .stack-work/install" $- cleanOldStackWork <$> dryrun <*> keepOption+ purgeOlderCmd <$> deleteOpt <*> keepOption <*> recursionOpt , Subcommand "delete-work" "Remove project's .stack-work subdirs recursively" $- removeStackWorks <$> dryrun <*> switchWith 'a' "all" "Find all .stack-work/ subdirs, even if current directory not a stack project"+ deleteWorkCmd <$> deleteOpt <*> recursionOpt ] where modeOpt =- flagWith' Project 'p' "project" "Act on current project's .stack-work/ [default in project dir]" <|>- flagWith' GHC 'g' "global" "Act on both ~/.stack/{programs,snapshots}/ [default outside project dir]" <|>- flagWith' Snapshots 's' "snapshots" "Act on ~/.stack/snapshots/" <|>- flagWith Default Compilers 'c' "compilers" "Act on ~/.stack/programs/"+ flagWith' Project 'P' "project" "Act on current project's .stack-work/ [default in project dir]" <|>+ flagWith' GHC 'G' "global" "Act on both ~/.stack/{programs,snapshots}/ [default outside project dir]" <|>+ flagWith' Snapshots 'S' "snapshots" "Act on ~/.stack/snapshots/" <|>+ flagWith Default Compilers 'C' "compilers" "Act on ~/.stack/programs/" - dryrun = switchWith 'n' "dry-run" "Show what would be done, without removing"+ deleteOpt = flagWith Dryrun Delete 'd' "delete" "Do deletion [default is dryrun]" + recursionOpt =+ optional (+ flagWith' Subdirs 's' "subdirs" "List subdirectories"+ <|> flagWith' Recursive 'r' "recursive" "List subdirectories")+ notHumanOpt = switchWith 'H' "not-human-size" "Do not use du --human-readable" ghcVerArg = readVersion <$> strArg "GHCVER" - keepOption = positive <$> optionalWith auto 'k' "keep" "INT" "number of project builds per ghc version [default 5]" 5+ keepOption = optionalWith auto 'k' "keep" "INT" "number of project builds per ghc version [default 5]" 5 - positive :: Int -> Int- positive n = if n > 0 then n else error' "Must be positive integer" +withRecursion :: Maybe Recursion -> IO () -> IO ()+withRecursion mrecursion act = do+ case mrecursion of+ Just recursion -> do+ dirs <- if recursion == Recursive+ then map takeDirectory <$> findStackWorks+ else listStackSubdirs+ forM_ dirs $ \dir ->+ withCurrentDirectory dir $ do+ putStrLn $ "\n" ++ takeFileName dir+ act+ Nothing -> act -sizeCmd :: Mode -> Bool -> IO ()-sizeCmd mode notHuman =+withRecursion' :: Maybe Recursion -> (FilePath -> IO ()) -> IO ()+withRecursion' mrecursion act = do+ case mrecursion of+ Just recursion -> do+ dirs <- if recursion == Recursive+ then map (dropPrefix "./" . takeDirectory) <$> findStackWorks+ else listStackSubdirs+ mapM_ act dirs+ Nothing -> act ""++sizeCmd :: Mode -> Maybe Recursion -> Bool -> IO ()+sizeCmd mode mrecursion notHuman =+ withRecursion' mrecursion $ \dir -> case mode of- Project -> sizeStackWork notHuman+ Project -> sizeStackWork notHuman dir Snapshots -> sizeSnapshots notHuman Compilers -> sizeGhcInstalls notHuman GHC -> do- sizeCmd Compilers notHuman- sizeCmd Snapshots notHuman- Default -> do+ sizeCmd Compilers Nothing notHuman+ sizeCmd Snapshots Nothing notHuman+ Default ->+ if isJust mrecursion+ then sizeStackWork notHuman dir+ else do isProject <- doesDirectoryExist ".stack-work" if isProject- then sizeCmd Project notHuman- else sizeCmd GHC notHuman+ then sizeCmd Project Nothing notHuman+ else sizeCmd GHC Nothing notHuman -listCmd :: Mode -> Maybe Version -> IO ()-listCmd mode mver =+listCmd :: Mode -> Maybe Recursion -> Maybe Version -> IO ()+listCmd mode mrecursion mver =+ withRecursion mrecursion $ case mode of- Project -> listGhcSnapshots setStackWorkDir mver- Snapshots -> listGhcSnapshots setStackSnapshotsDir mver+ Project -> setStackWorkInstallDir >> listGhcSnapshots mver+ Snapshots -> setStackSnapshotsDir >> listGhcSnapshots mver Compilers -> listGhcInstallation mver GHC -> do- listCmd Compilers mver- listCmd Snapshots mver+ listCmd Compilers Nothing mver+ listCmd Snapshots Nothing mver Default -> do isProject <- doesDirectoryExist ".stack-work" if isProject- then listCmd Project mver- else listCmd GHC mver+ then listCmd Project Nothing mver+ else listCmd GHC Nothing mver -removeCmd :: Bool -> Mode -> Version -> IO ()-removeCmd dryrun mode ghcver =+removeCmd :: Deletion -> Mode -> Maybe Recursion -> Version -> IO ()+removeCmd deletion mode mrecursion ghcver =+ withRecursion mrecursion $ case mode of- Project -> cleanGhcSnapshots setStackWorkDir dryrun ghcver- Snapshots -> cleanGhcSnapshots setStackSnapshotsDir dryrun ghcver- Compilers -> removeGhcVersionInstallation dryrun ghcver+ Project -> do+ cwd <- getCurrentDirectory+ setStackWorkInstallDir+ cleanGhcSnapshots deletion cwd ghcver+ Snapshots -> do+ cwd <- getCurrentDirectory+ setStackSnapshotsDir+ cleanGhcSnapshots deletion cwd ghcver+ Compilers -> removeGhcVersionInstallation deletion ghcver GHC -> do- removeCmd dryrun Compilers ghcver- removeCmd dryrun Snapshots ghcver+ removeCmd deletion Compilers Nothing ghcver+ removeCmd deletion Snapshots Nothing ghcver Default -> do isProject <- doesDirectoryExist ".stack-work" if isProject- then removeCmd dryrun Project ghcver- else removeCmd dryrun GHC ghcver+ then removeCmd deletion Project Nothing ghcver+ else removeCmd deletion GHC Nothing ghcver -removeMinorsCmd :: Bool -> Mode -> Maybe Version -> IO ()-removeMinorsCmd dryrun mode mver =+removeMinorsCmd :: Deletion -> Mode -> Maybe Recursion -> Maybe Version+ -> IO ()+removeMinorsCmd deletion mode mrecursion mver =+ withRecursion mrecursion $ case mode of- Project -> cleanMinorSnapshots setStackWorkDir dryrun mver- Snapshots -> cleanMinorSnapshots setStackSnapshotsDir dryrun mver- Compilers -> removeGhcMinorInstallation dryrun mver+ Project -> do+ cwd <- getCurrentDirectory+ setStackWorkInstallDir+ cleanMinorSnapshots deletion cwd mver+ Snapshots -> do+ cwd <- getCurrentDirectory+ setStackSnapshotsDir+ cleanMinorSnapshots deletion cwd mver+ Compilers -> removeGhcMinorInstallation deletion mver GHC -> do- removeMinorsCmd dryrun Compilers mver- removeMinorsCmd dryrun Snapshots mver+ removeMinorsCmd deletion Compilers Nothing mver+ removeMinorsCmd deletion Snapshots Nothing mver Default -> do isProject <- doesDirectoryExist ".stack-work" if isProject- then removeMinorsCmd dryrun Project mver- else removeMinorsCmd dryrun GHC mver+ then removeMinorsCmd deletion Project Nothing mver+ else removeMinorsCmd deletion GHC Nothing mver++purgeOlderCmd :: Deletion -> Natural -> Maybe Recursion -> IO ()+purgeOlderCmd deletion keep mrecursion =+ withRecursion mrecursion $+ cleanOldStackWork deletion keep++deleteWorkCmd :: Deletion -> Maybe Recursion -> IO ()+deleteWorkCmd deletion mrecursion =+ withRecursion mrecursion $+ removeStackWork deletion++findStackWorks :: IO [FilePath]+findStackWorks =+ -- ignore find errors (e.g. access rights)+ cmdIgnoreErr "find" [".", "-type", "d", "-name", ".stack-work", "-prune"] []+ >>= fmap L.sort . filterM (doesDirectoryExist . (</> "install")) . lines++listStackSubdirs :: IO [FilePath]+listStackSubdirs =+ listDirectory "." >>= filterM (\f -> doesDirectoryExist (f </> ".stack-work")) . L.sort
src/Remove.hs view
@@ -8,19 +8,21 @@ import Control.Monad.Extra import qualified System.Directory as D -doRemoveDirectory :: Bool -> FilePath -> IO ()-doRemoveDirectory dryrun dir =- unless dryrun $+import Types++doRemoveDirectory :: Deletion -> FilePath -> IO ()+doRemoveDirectory deletion dir =+ when (isDelete deletion) $ D.removeDirectoryRecursive dir -removeFile :: Bool -> FilePath -> IO ()-removeFile dryrun file =- unless dryrun $+removeFile :: Deletion -> FilePath -> IO ()+removeFile deletion file =+ when (isDelete deletion) $ whenM (D.doesFileExist file) $ D.removeFile file -prompt :: Bool -> String -> IO ()-prompt dryrun str =- unless dryrun $ do+prompt :: Deletion -> String -> IO ()+prompt deletion str =+ when (isDelete deletion) $ do putStr $ "Press Enter to delete " ++ str ++ ": " void getLine
src/Snapshots.hs view
@@ -8,16 +8,17 @@ cleanOldStackWork, listGhcSnapshots, setStackSnapshotsDir,- setStackWorkDir,+ setStackWorkInstallDir, sizeSnapshots, sizeStackWork,- removeStackWorks+ removeStackWork ) where import Control.Monad.Extra import Data.List.Extra import Data.Version.Extra+import Numeric.Natural import SimpleCmd #if MIN_VERSION_simple_cmd(0,2,1) hiding (whenM)@@ -28,6 +29,7 @@ import Directories (globDirs, getStackSubdir, switchToSystemDirUnder) import qualified Remove+import Types import Versions data SnapshotInstall =@@ -79,46 +81,54 @@ snapshots <- getStackSubdir "snapshots" cmd_ "du" $ ["-h" | not nothuman] ++ ["-s", snapshots] -listGhcSnapshots :: IO () -> Maybe Version -> IO ()-listGhcSnapshots setdir mghcver = do- setdir+listGhcSnapshots :: Maybe Version -> IO ()+listGhcSnapshots mghcver = do ghcs <- getSnapshotDirs mghcver mapM_ printTotalGhcSize ghcs -removeVersionSnaps :: Bool -> VersionSnapshots -> IO ()-removeVersionSnaps dryrun versnap = do+plural :: String -> Int -> String+plural thing n = show n ++ " " ++ thing ++ if n == 1 then "" else "s"++removeVersionSnaps :: Deletion -> FilePath -> VersionSnapshots -> IO ()+removeVersionSnaps deletion cwd versnap = do let dirs = snapsHashes versnap- mapM_ (Remove.doRemoveDirectory dryrun) dirs- putStrLn $ show (length dirs) ++ " dirs in ~/.stack/snapshots/ " ++ (if dryrun then "would be " else "") ++ "removed for " ++ showVersion (snapsVersion versnap)+ dir <- getCurrentDirectory+ home <- getHomeDirectory+ putStrLn $ plural "dir" (length dirs) ++ " in " ++ renderDir home dir ++ " " ++ (if isDelete deletion then "" else "would be ") ++ "removed for " ++ showVersion (snapsVersion versnap)+ mapM_ (Remove.doRemoveDirectory deletion) dirs+ where+ renderDir :: FilePath -> FilePath -> FilePath+ renderDir home fp =+ case stripPrefix (cwd ++ "/") fp of+ Just reldir -> reldir+ Nothing -> "~" </> dropPrefix (home ++ "/") fp -cleanGhcSnapshots :: IO () -> Bool -> Version -> IO ()-cleanGhcSnapshots setDir dryrun ghcver = do- setDir+cleanGhcSnapshots :: Deletion -> FilePath -> Version -> IO ()+cleanGhcSnapshots deletion cwd ghcver = do ghcs <- getSnapshotDirs (Just ghcver) when (isMajorVersion ghcver) $ do- Remove.prompt dryrun ("all " ++ showVersion ghcver ++ " builds")- mapM_ (removeVersionSnaps dryrun) ghcs+ Remove.prompt deletion ("all " ++ showVersion ghcver ++ " builds")+ mapM_ (removeVersionSnaps deletion cwd) ghcs -cleanMinorSnapshots :: IO () -> Bool -> Maybe Version -> IO ()-cleanMinorSnapshots setDir dryrun mghcver = do- setDir+cleanMinorSnapshots :: Deletion -> FilePath -> Maybe Version -> IO ()+cleanMinorSnapshots deletion cwd mghcver = do ghcs <- getSnapshotDirs (majorVersion <$> mghcver) case mghcver of Nothing -> do let majors = groupOn (majorVersion . snapsVersion) ghcs forM_ majors $ \ gmajor -> when (length gmajor > 1) $- mapM_ (removeVersionSnaps dryrun) (init gmajor)+ mapM_ (removeVersionSnaps deletion cwd) (init gmajor) Just ghcver -> do let newestMinor = if isMajorVersion ghcver then (snapsVersion . last) ghcs else ghcver gminors = filter ((< newestMinor) . snapsVersion) ghcs- mapM_ (removeVersionSnaps dryrun) gminors+ mapM_ (removeVersionSnaps deletion cwd) gminors -cleanOldStackWork :: Bool -> Int -> IO ()-cleanOldStackWork dryrun keep = do- setStackWorkDir+cleanOldStackWork :: Deletion -> Natural -> IO ()+cleanOldStackWork deletion keep = do+ setStackWorkInstallDir dirs <- sortOn takeFileName . lines <$> shell ( unwords $ "ls" : ["-d", "*/*"]) let ghcs = groupOn takeFileName dirs mapM_ removeOlder ghcs@@ -126,10 +136,10 @@ removeOlder :: [FilePath] -> IO () removeOlder dirs = do let ghcver = (takeFileName . head) dirs- oldfiles <- drop keep . reverse <$> sortedByAge- mapM_ (Remove.doRemoveDirectory dryrun . takeDirectory) oldfiles+ oldfiles <- drop (fromEnum keep) . reverse <$> sortedByAge+ mapM_ (Remove.doRemoveDirectory deletion . takeDirectory) oldfiles unless (null oldfiles) $- putStrLn $ show (length oldfiles) ++ " dirs removed for " ++ ghcver+ putStrLn $ plural "dir" (length oldfiles) ++ (if isDelete deletion then "" else " would be") ++ " removed for " ++ ghcver where sortedByAge = do fileTimes <- mapM newestTimeStamp dirs@@ -144,9 +154,9 @@ stackWorkInstall :: FilePath stackWorkInstall = ".stack-work/install" -sizeStackWork :: Bool -> IO ()-sizeStackWork nothuman = do- let path = stackWorkInstall+sizeStackWork :: Bool -> FilePath -> IO ()+sizeStackWork nothuman dir = do+ let path = dir </> ".stack-work" whenM (doesDirectoryExist path) $ cmd_ "du" $ ["-h" | not nothuman] ++ ["-s", path] @@ -155,24 +165,15 @@ total <- head . words . last <$> cmdLines "du" ("-shc":snapsHashes versnaps) printf "%4s %-6s (%d dirs)\n" total ((showVersion . snapsVersion) versnaps) (length (snapsHashes versnaps)) -setStackWorkDir :: IO ()-setStackWorkDir = do+setStackWorkInstallDir :: IO ()+setStackWorkInstallDir = do switchToSystemDirUnder stackWorkInstall setStackSnapshotsDir :: IO () setStackSnapshotsDir = do getStackSubdir "snapshots" >>= switchToSystemDirUnder -removeStackWorks :: Bool -> Bool -> IO ()-removeStackWorks dryrun allrecurse = do- recurse <-- if allrecurse then return True- else doesDirectoryExist ".stack-work"- if recurse then do- -- ignore find errors (e.g. access rights)- workdirs <- sort . lines <$> cmdIgnoreErr "find" [".", "-type", "d", "-name", ".stack-work", "-prune"] []- unless (null workdirs) $ do- mapM_ putStrLn workdirs- Remove.prompt dryrun "these dirs"- mapM_ (Remove.doRemoveDirectory dryrun) workdirs- else error' "run in a project dir (containing .stack-work/)\n or use --all to find and remove all .stack-work/ subdirectories"+removeStackWork :: Deletion -> IO ()+removeStackWork deletion = do+ Remove.prompt deletion "this dir"+ Remove.doRemoveDirectory deletion ".stack-work"
+ src/Types.hs view
@@ -0,0 +1,11 @@+module Types (+ Deletion (..),+ isDelete+ )+where++data Deletion = Dryrun | Delete+ deriving Eq++isDelete :: Deletion -> Bool+isDelete = (== Delete)
stack-clean-old.cabal view
@@ -1,5 +1,5 @@ name: stack-clean-old-version: 0.3.1+version: 0.4 synopsis: Clean away old stack build artefacts description: A tool for removing old .stack-work/install builds and@@ -29,6 +29,7 @@ GHC Remove Snapshots+ Types Versions hs-source-dirs: src build-depends: base >= 4.8 && < 5