Skip to content

Commit 0ec2a49

Browse files
committed
Impement removeFileForcibly and use it instead of removeFile
1 parent 7cc84c5 commit 0ec2a49

20 files changed

Lines changed: 61 additions & 70 deletions

File tree

Cabal-tests/tests/UnitTests/Distribution/Simple/Utils.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Distribution.Verbosity
1111
import Data.IORef
1212
import System.Directory ( doesDirectoryExist, doesFileExist
1313
, getTemporaryDirectory
14-
, removePathForcibly, removeFile )
14+
, removePathForcibly )
1515
import System.FilePath ( (<.>) )
1616
import System.IO (hClose, localeEncoding, hPutStrLn)
1717
import System.IO.Error
@@ -32,7 +32,7 @@ withTempFileRemovedTest :: Assertion
3232
withTempFileRemovedTest = do
3333
withTempFile ".foo" $ \fileName handle -> do
3434
hClose handle
35-
removeFile fileName
35+
removeFileForcibly fileName
3636

3737
withTempDirTest :: Assertion
3838
withTempDirTest = do

Cabal-tests/tests/custom-setup/IdrisSetup.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,8 @@ idrisPostSDist args flags desc lbi = do
301301
let targetFile = "src" </> "Target_idris" Px.<.> "hs"
302302
putStrLn $ "Removing generated modules:\n "
303303
++ file ++ "\n" ++ targetFile
304-
removeFile file
305-
removeFile targetFile)
304+
removeFileForcible file
305+
removeFileForcible targetFile)
306306
(\e -> let e' = (e :: SomeException) in return ())
307307
postSDist simpleUserHooks args flags desc lbi
308308
#endif

Cabal/src/Distribution/Simple/Build.hs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ import Control.Monad
128128
import qualified Data.ByteString.Lazy as LBS
129129
import qualified Data.Map as Map
130130

131-
import System.Directory (doesFileExist, removeFile)
132131
import System.FilePath (takeDirectory)
133132

134133
-- -----------------------------------------------------------------------------
@@ -307,10 +306,9 @@ dumpBuildInfo verbosity distPref dumpBuildInfoFlag pkg_descr lbi flags = do
307306
++ unlines warns
308307
LBS.writeFile buildInfoFile buildInfoText
309308

310-
when (not shouldDumpBuildInfo) $ do
309+
when (not shouldDumpBuildInfo) $
311310
-- Remove existing build-info.json as it might be outdated now.
312-
exists <- doesFileExist buildInfoFile
313-
when exists $ removeFile buildInfoFile
311+
removeFileForcibly buildInfoFile
314312
where
315313
buildInfoFile = interpretSymbolicPathLBI lbi $ buildInfoPref distPref
316314
shouldDumpBuildInfo = fromFlagOrDefault NoDumpBuildInfo dumpBuildInfoFlag == DumpBuildInfo

Cabal/src/Distribution/Simple/Configure.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ import System.Directory
156156
, doesFileExist
157157
, doesPathExist
158158
, listDirectory
159-
, removeFile
160159
)
161160
import System.FilePath
162161
( isAbsolute
@@ -2620,7 +2619,7 @@ checkForeignDeps pkg lbi verbosity =
26202619
++ (baseDir </> hdr)
26212620
++ "; removing "
26222621
++ (baseDir </> hdr)
2623-
removeFile (baseDir </> hdr)
2622+
removeFileForcibly (baseDir </> hdr)
26242623

26252624
findOffendingHdr =
26262625
ifBuildsWith

Cabal/src/Distribution/Simple/GHC/Build/Link.hs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ import Distribution.Version
5151
import System.Directory
5252
( createDirectoryIfMissing
5353
, doesDirectoryExist
54-
, doesFileExist
55-
, removeFile
5654
, renameFile
5755
)
5856
import System.FilePath
@@ -524,10 +522,8 @@ linkExecutable linkerOpts (way, buildOpts) targetDir targetName runGhcProg lbi =
524522
-- situation, see #3294
525523
let target =
526524
targetDir </> makeRelativePathEx (exeTargetName (hostPlatform lbi) targetName)
527-
when (compilerVersion comp < mkVersion [7, 7]) $ do
528-
let targetPath = interpretSymbolicPathLBI lbi target
529-
e <- doesFileExist targetPath
530-
when e (removeFile targetPath)
525+
when (compilerVersion comp < mkVersion [7, 7]) $
526+
removeFileForcibly (interpretSymbolicPathLBI lbi target)
531527
runGhcProg linkOpts{ghcOptOutputFile = toFlag target}
532528

533529
-- | Link a foreign library component

Cabal/src/Distribution/Simple/GHCJS.hs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ import System.Directory
9797
, createDirectoryIfMissing
9898
, doesFileExist
9999
, getAppUserDataDirectory
100-
, removeFile
101100
, renameFile
102101
)
103102
import System.FilePath
@@ -1570,10 +1569,8 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do
15701569
-- Work around old GHCs not relinking in this
15711570
-- situation, see #3294
15721571
let target = targetDir </> makeRelativePathEx targetName
1573-
when (compilerVersion comp < mkVersion [7, 7]) $ do
1574-
let targetPath = i target
1575-
e <- doesFileExist targetPath
1576-
when e (removeFile targetPath)
1572+
when (compilerVersion comp < mkVersion [7, 7]) $
1573+
removeFileForcibly (i target)
15771574
runGhcProg linkOpts{ghcOptOutputFile = toFlag target}
15781575
GBuildFLib flib -> do
15791576
let rtsInfo = extractRtsInfo lbi

Cabal/src/Distribution/Simple/Test.hs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,7 @@ import Distribution.Types.InstalledPackageInfo (InstalledPackageInfo (libraryDir
5454
import Distribution.Types.LocalBuildInfo (LocalBuildInfo (..))
5555
import System.Directory
5656
( createDirectoryIfMissing
57-
, doesFileExist
5857
, listDirectory
59-
, removeFile
6058
)
6159

6260
-- | Perform the \"@.\/setup test@\" action.
@@ -151,8 +149,7 @@ test args verbHandles pkg_descr lbi0 flags = do
151149

152150
-- Delete ordinary files from test log directory.
153151
listDirectory (i testLogDir)
154-
>>= filterM doesFileExist . map (i testLogDir </>)
155-
>>= traverse_ removeFile
152+
>>= traverse_ (removeFileForcibly . (i testLogDir </>))
156153

157154
-- We configured the unit-ids of libraries we should cover in our coverage
158155
-- report at configure time into the local build info. At build time, we built

Cabal/src/Distribution/Simple/Test/LibV09.hs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ import System.Directory
4848
, createDirectoryIfMissing
4949
, doesFileExist
5050
, getCurrentDirectory
51-
, removeFile
5251
, removePathForcibly
5352
, setCurrentDirectory
5453
)
@@ -91,7 +90,7 @@ runTest verbHandles pkg_descr lbi clbi hpcMarkupInfo flags suite = do
9190
-- Write summary notices indicating start of test suite
9291
notice verbosity $ summarizeSuiteStart testName'
9392

94-
suiteLog <- CE.bracket openCabalTemp deleteIfExists $ \tempLog -> do
93+
suiteLog <- CE.bracket openCabalTemp removeFileForcibly $ \tempLog -> do
9594
-- Compute the appropriate environment for running the test suite
9695
let progDb = LBI.withPrograms lbi
9796
pathVar = progSearchPath progDb
@@ -209,10 +208,6 @@ runTest verbHandles pkg_descr lbi clbi hpcMarkupInfo flags suite = do
209208
common = testCommonFlags flags
210209
testName' = unUnqualComponentName $ PD.testName suite
211210

212-
deleteIfExists file = do
213-
exists <- doesFileExist file
214-
when exists $ removeFile file
215-
216211
testLogDir = distPref </> makeRelativePathEx "test"
217212
openCabalTemp = do
218213
(f, h) <- openTempFile (i testLogDir) $ "cabal-test-" <.> "log"

Cabal/src/Distribution/Simple/Utils.hs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ module Distribution.Simple.Utils
9797
, copyFileTo
9898
, copyFileToCwd
9999

100+
-- * removing files
101+
, removeFileForcibly
102+
100103
-- * installing files
101104
, installOrdinaryFile
102105
, installExecutableFile
@@ -244,6 +247,7 @@ import Data.Typeable
244247
( cast
245248
)
246249

250+
import Control.Concurrent (threadDelay)
247251
import qualified Control.Exception as Exception
248252
import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime)
249253
import qualified Data.Version as DV
@@ -1812,6 +1816,26 @@ copyFilesWith doCopy verbosity targetDir srcFiles = withFrozenCallStack $ do
18121816
copyFiles :: Verbosity -> FilePath -> [(FilePath, FilePath)] -> IO ()
18131817
copyFiles v fp fs = withFrozenCallStack (copyFilesWith copyFileVerbose v fp fs)
18141818

1819+
-- | A robust helper to remove an existing file, which does not throw
1820+
-- an exception if such file never existed, thus akin to removePathForcibly.
1821+
removeFileForcibly :: FilePath -> IO ()
1822+
removeFileForcibly fp = catch (removeFile fp) $ \case
1823+
e
1824+
-- If the file never existed in the first place, we are golden.
1825+
| isDoesNotExistError e -> pure ()
1826+
-- If we got a permission error, chances are that it's a read-only
1827+
-- file on Windows. Removing read-only attribute ourselves requires
1828+
-- reaching out for internal API, so instead of it we call 'removePathForcibly',
1829+
-- which is a bit of overkill for a single file, but well.
1830+
| isPermissionError e -> removePathForcibly fp
1831+
-- If device is busy, wait 1ms and give it another go.
1832+
-- EBUSY from unlink(2) gets mapped to UnsatisfiedConstraints.
1833+
| ioeGetErrorType e == GHC.UnsatisfiedConstraints -> do
1834+
threadDelay 1000
1835+
removeFile fp
1836+
-- Else we give up.
1837+
| otherwise -> throwIO e
1838+
18151839
-- | This is like 'copyFiles' but uses 'installOrdinaryFile'.
18161840
installOrdinaryFiles :: Verbosity -> FilePath -> [(FilePath, FilePath)] -> IO ()
18171841
installOrdinaryFiles v fp fs = withFrozenCallStack (copyFilesWith installOrdinaryFile v fp fs)

cabal-install/src/Distribution/Client/CmdClean.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import Distribution.Simple.Setup
5151
import Distribution.Simple.Utils
5252
( dieWithException
5353
, info
54+
, removeFileForcibly
5455
, wrapText
5556
)
5657
import Distribution.System
@@ -85,7 +86,6 @@ import System.Directory
8586
, doesDirectoryExist
8687
, doesFileExist
8788
, listDirectory
88-
, removeFile
8989
, removePathForcibly
9090
)
9191
import System.FilePath
@@ -216,5 +216,5 @@ cleanAction (ProjectFlags{..}, CleanFlags{..}) extraArgs _ = do
216216

217217
removeEnvFiles :: FilePath -> IO ()
218218
removeEnvFiles dir =
219-
(traverse_ (removeFile . (dir </>)) . filter ((".ghc.environment" ==) . take 16))
219+
(traverse_ (removeFileForcibly . (dir </>)) . filter ((".ghc.environment" ==) . take 16))
220220
=<< listDirectory dir

0 commit comments

Comments
 (0)