@@ -43,6 +43,7 @@ import Data.Conduit.Process.Typed ( createSource )
4343import Data.Conduit.Zlib ( ungzip )
4444import Data.List.Split ( splitOn )
4545import qualified Data.Map as Map
46+ import Data.Maybe ( fromJust )
4647import qualified Data.Set as Set
4748import qualified Data.Text as T
4849import qualified Data.Text.Lazy as TL
@@ -65,16 +66,17 @@ import Network.HTTP.StackClient
6566 )
6667import Network.HTTP.Simple ( getResponseHeader )
6768import Path
68- ( (</>) , addExtension , filename , parent , parseAbsDir
69- , parseAbsFile , parseRelDir , parseRelFile , toFilePath
69+ ( (</>) , addExtension , filename , fromAbsDir , parent
70+ , parseAbsDir , parseAbsFile , parseRelDir , parseRelFile
71+ , toFilePath
7072 )
7173import Path.CheckInstall ( warnInstallSearchPathIssues )
7274import Path.Extended ( fileExtension )
7375import Path.Extra ( toFilePathNoTrailingSep )
7476import Path.IO
7577 ( canonicalizePath , doesFileExist , ensureDir , executable
7678 , getPermissions , ignoringAbsence , listDir , removeDirRecur
77- , renameDir , renameFile , resolveFile'
79+ , renameDir , renameFile , resolveFile' , withTempDir
7880 )
7981import RIO.List
8082 ( headMaybe , intercalate , intersperse , isPrefixOf
@@ -165,7 +167,7 @@ import Stack.Types.VersionedDownloadInfo
165167import qualified System.Directory as D
166168import System.Environment ( getExecutablePath , lookupEnv )
167169import System.IO.Error ( isPermissionError )
168- import System.FilePath ( searchPathSeparator )
170+ import System.FilePath ( searchPathSeparator , takeDrive )
169171import qualified System.FilePath as FP
170172import System.Permissions ( setFileExecutable )
171173import System.Uname ( getRelease )
@@ -2344,18 +2346,23 @@ withUnpackedTarball7z name si archiveFile archiveType destDir = do
23442346 -- We use a short name for the temporary directory to reduce the risk of a
23452347 -- filepath length of more than 260 characters, which can be problematic for
23462348 -- 7-Zip even if Long Filepaths are enabled on Windows.
2347- let tmpName = " tmp"
2349+ let tmpName = " stack-tmp"
2350+ destDrive = fromJust $ parseAbsDir $ takeDrive $ fromAbsDir destDir
23482351 ensureDir (parent destDir)
23492352 withRunInIO $ \ run ->
2350- -- We use the system temporary directory to reduce the risk of a filepath
2351- -- length of more than 260 characters, which can be problematic for
2352- -- 7-Zip even if Long Filepaths are enabled on Windows.
2353- withSystemTempDir tmpName $ \ tmpDir ->
2353+ -- We use a temporary directory in the same drive as that of 'destDir' to
2354+ -- reduce the risk of a filepath length of more than 260 characters, which can
2355+ -- be problematic for 7-Zip even if Long Filepaths are enabled on Windows. We
2356+ -- do not use the system temporary directory as it may be on a different
2357+ -- drive.
2358+ withTempDir destDrive tmpName $ \ tmpDir ->
23542359 run $ do
23552360 liftIO $ ignoringAbsence (removeDirRecur destDir)
23562361 run7z tmpDir archiveFile
23572362 run7z tmpDir (tmpDir </> tarFile)
23582363 absSrcDir <- expectSingleUnpackedDir archiveFile tmpDir
2364+ -- On Windows, 'renameDir' does not work across drives. However, we have
2365+ -- ensured that 'tmpDir' has the same drive as 'destDir'.
23592366 renameDir absSrcDir destDir
23602367
23612368expectSingleUnpackedDir ::
0 commit comments