-
Notifications
You must be signed in to change notification settings - Fork 842
/
Clean.hs
73 lines (65 loc) · 2.71 KB
/
Clean.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
-- | Clean a project.
module Stack.Clean
(clean
,CleanOpts(..)
,StackCleanException(..)
) where
import Stack.Prelude
import Data.List ((\\),intercalate)
import qualified Data.Map.Strict as Map
import Path.IO (ignoringAbsence, removeDirRecur)
import Stack.Constants.Config (distDirFromDir, workDirFromDir)
import Stack.Types.Config
import System.Exit (exitFailure)
-- | Deletes build artifacts in the current project.
--
-- Throws 'StackCleanException'.
clean :: HasEnvConfig env => CleanOpts -> RIO env ()
clean cleanOpts = do
failures <- mapM cleanDir =<< dirsToDelete cleanOpts
when (or failures) $ liftIO exitFailure
where
cleanDir dir =
liftIO (ignoringAbsence (removeDirRecur dir) >> return False) `catchAny` \ex -> do
logError $ "Exception while recursively deleting " <> fromString (toFilePath dir) <> "\n" <> displayShow ex
logError "Perhaps you do not have permission to delete these files or they are in use?"
return True
dirsToDelete :: HasEnvConfig env => CleanOpts -> RIO env [Path Abs Dir]
dirsToDelete cleanOpts = do
packages <- view $ buildConfigL.to bcPackages
case cleanOpts of
CleanShallow [] ->
-- Filter out packages listed as extra-deps
mapM (distDirFromDir . ppRoot) $ Map.elems packages
CleanShallow targets -> do
let localPkgNames = Map.keys packages
getPkgDir pkgName' = fmap ppRoot (Map.lookup pkgName' packages)
case targets \\ localPkgNames of
[] -> mapM distDirFromDir (mapMaybe getPkgDir targets)
xs -> throwM (NonLocalPackages xs)
CleanFull -> do
pkgWorkDirs <- mapM (workDirFromDir . ppRoot) $ Map.elems packages
projectWorkDir <- getProjectWorkDir
return (projectWorkDir : pkgWorkDirs)
-- | Options for @stack clean@.
data CleanOpts
= CleanShallow [PackageName]
-- ^ Delete the "dist directories" as defined in 'Stack.Constants.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.
-- | Exceptions during cleanup.
newtype StackCleanException
= NonLocalPackages [PackageName]
deriving (Typeable)
instance Show StackCleanException where
show (NonLocalPackages pkgs) =
"The following packages are not part of this project: " ++
intercalate ", " (map show pkgs)
instance Exception StackCleanException