summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLaurent P. René de Cotret <LaurentRDC@users.noreply.github.com>2020-06-30 08:57:47 -0400
committerGitHub <noreply@github.com>2020-06-30 14:57:47 +0200
commit3afebc0c8e80d1493e1605863176e9bfdf89784a (patch)
tree069b12f8e30a5f69ac99d167dbec6ce1b8273276 /lib
parent8afbb62ed5e969d78d8664df205646504f52f278 (diff)
downloadhakyll-3afebc0c8e80d1493e1605863176e9bfdf89784a.tar.gz
Continuous integration on Windows and Linux
Diffstat (limited to 'lib')
-rw-r--r--lib/Hakyll/Core/Util/File.hs30
1 files changed, 29 insertions, 1 deletions
diff --git a/lib/Hakyll/Core/Util/File.hs b/lib/Hakyll/Core/Util/File.hs
index 9db6b11..02b8ece 100644
--- a/lib/Hakyll/Core/Util/File.hs
+++ b/lib/Hakyll/Core/Util/File.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE CPP #-}
--------------------------------------------------------------------------------
-- | A module containing various file utility functions
module Hakyll.Core.Util.File
@@ -8,10 +10,12 @@ module Hakyll.Core.Util.File
--------------------------------------------------------------------------------
+import Control.Concurrent (threadDelay)
+import Control.Exception (SomeException, catch)
import Control.Monad (filterM, forM, when)
import System.Directory (createDirectoryIfMissing,
doesDirectoryExist, getDirectoryContents,
- removeDirectoryRecursive)
+ removeDirectoryRecursive, removePathForcibly)
import System.FilePath (takeDirectory, (</>))
@@ -51,6 +55,30 @@ getRecursiveContents ignore top = go ""
--------------------------------------------------------------------------------
removeDirectory :: FilePath -> IO ()
+#ifndef mingw32_HOST_OS
removeDirectory fp = do
e <- doesDirectoryExist fp
when e $ removeDirectoryRecursive fp
+#else
+-- Deleting files on Windows is unreliable. If a file/directory is open by a program (e.g. antivirus),
+-- then removing related directories *quickly* may fail with strange messages.
+-- See here for discussions:
+-- https://github.com/haskell/directory/issues/96
+-- https://github.com/haskell/win32/pull/129
+--
+-- The hacky solution is to retry deleting directories a few times,
+-- with a delay, on Windows only.
+removeDirectory = retryWithDelay 10 . removePathForcibly
+#endif
+
+
+--------------------------------------------------------------------------------
+-- | Retry an operation at most /n/ times (/n/ must be positive).
+-- If the operation fails the /n/th time it will throw that final exception.
+-- A delay of 100ms is introduced between every retry.
+retryWithDelay :: Int -> IO a -> IO a
+retryWithDelay i x
+ | i <= 0 = error "Hakyll.Core.Util.File.retry: retry count must be 1 or more"
+ | i == 1 = x
+ | otherwise = catch x $ \(_::SomeException) -> threadDelay 100 >> retryWithDelay (i-1) x
+