{-# LANGUAGE CPP #-}
module Main (main) where
#if !MIN_VERSION_simple_cmd_args(0,1,3)
import Control.Applicative ((<|>))
#endif
import Data.Version.Extra
import SimpleCmd
import SimpleCmdArgs
import System.Directory
import System.IO (BufferMode(NoBuffering), hSetBuffering, stdout)
import GHC
import Paths_stack_clean_old (version)
import Snapshots
data Mode = Default | Project | Snapshots | Compilers | GHC
main :: IO ()
main = do
hSetBuffering stdout NoBuffering
simpleCmdArgs (Just version) "Stack clean up tool"
"Cleans away old stack-work builds (and pending: stack snapshots) to recover diskspace." $
subcommands
[ Subcommand "size" "Total size" $
sizeCmd <$> modeOpt <*> notHumanOpt
, Subcommand "list" "List sizes per ghc version" $
listCmd <$> modeOpt <*> optional ghcVerArg
, Subcommand "remove" "Remove for a ghc version" $
removeCmd <$> dryrun <*> modeOpt <*> ghcVerArg
, Subcommand "keep-minor" "Remove for previous ghc minor versions" $
removeMinorsCmd <$> dryrun <*> modeOpt <*> optional ghcVerArg
, Subcommand "purge-older" "Purge older builds in .stack-work/install" $
cleanOldStackWork <$> dryrun <*> keepOption
, 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"
]
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/"
dryrun = switchWith 'n' "dry-run" "Show what would be done, without removing"
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
positive :: Int -> Int
positive n = if n > 0 then n else error' "Must be positive integer"
sizeCmd :: Mode -> Bool -> IO ()
sizeCmd mode notHuman =
case mode of
Project -> sizeStackWork notHuman
Snapshots -> sizeSnapshots notHuman
Compilers -> sizeGhcInstalls notHuman
GHC -> do
sizeCmd Compilers notHuman
sizeCmd Snapshots notHuman
Default -> do
isProject <- doesDirectoryExist ".stack-work"
if isProject
then sizeCmd Project notHuman
else sizeCmd GHC notHuman
listCmd :: Mode -> Maybe Version -> IO ()
listCmd mode mver =
case mode of
Project -> listGhcSnapshots setStackWorkDir mver
Snapshots -> listGhcSnapshots setStackSnapshotsDir mver
Compilers -> listGhcInstallation mver
GHC -> do
listCmd Compilers mver
listCmd Snapshots mver
Default -> do
isProject <- doesDirectoryExist ".stack-work"
if isProject
then listCmd Project mver
else listCmd GHC mver
removeCmd :: Bool -> Mode -> Version -> IO ()
removeCmd dryrun mode ghcver =
case mode of
Project -> cleanGhcSnapshots setStackWorkDir dryrun ghcver
Snapshots -> cleanGhcSnapshots setStackSnapshotsDir dryrun ghcver
Compilers -> removeGhcVersionInstallation dryrun ghcver
GHC -> do
removeCmd dryrun Compilers ghcver
removeCmd dryrun Snapshots ghcver
Default -> do
isProject <- doesDirectoryExist ".stack-work"
if isProject
then removeCmd dryrun Project ghcver
else removeCmd dryrun GHC ghcver
removeMinorsCmd :: Bool -> Mode -> Maybe Version -> IO ()
removeMinorsCmd dryrun mode mver =
case mode of
Project -> cleanMinorSnapshots setStackWorkDir dryrun mver
Snapshots -> cleanMinorSnapshots setStackSnapshotsDir dryrun mver
Compilers -> removeGhcMinorInstallation dryrun mver
GHC -> do
removeMinorsCmd dryrun Compilers mver
removeMinorsCmd dryrun Snapshots mver
Default -> do
isProject <- doesDirectoryExist ".stack-work"
if isProject
then removeMinorsCmd dryrun Project mver
else removeMinorsCmd dryrun GHC mver