{-# LANGUAGE CPP #-}
module Development.Shake.Internal.History.Symlink(
copyFileLink,
createLinkMaybe
) where
import Control.Monad.Extra
import General.Extra
import System.Directory
import System.FilePath
#ifdef mingw32_HOST_OS
import Foreign.Ptr
import Foreign.C.String
#else
import System.Posix.Files(createLink)
#endif
createLinkMaybe :: FilePath -> FilePath -> IO (Maybe String)
#ifdef mingw32_HOST_OS
#ifdef x86_64_HOST_ARCH
#define CALLCONV ccall
#else
#define CALLCONV stdcall
#endif
foreign import CALLCONV unsafe "Windows.h CreateHardLinkW " c_CreateHardLinkW :: CWString -> CWString -> Ptr () -> IO Bool
createLinkMaybe from to = withCWString from $ \cfrom -> withCWString to $ \cto -> do
res <- c_CreateHardLinkW cto cfrom nullPtr
pure $ if res then Nothing else Just "CreateHardLink failed."
#else
createLinkMaybe from to = handleIO (pure . Just . show) $ createLink from to >> pure Nothing
#endif
copyFileLink :: Bool -> FilePath -> FilePath -> IO ()
copyFileLink useSymlink from to = do
createDirectoryRecursive $ takeDirectory to
removeFile_ to
if not useSymlink then copyFile from to else do
b <- createLinkMaybe from to
whenJust b $ \_ ->
copyFile from to
forM_ [from, to] $ \x -> do
perm <- getPermissions x
setPermissions x perm{writable=False}