|
|
1
|
+{-# LANGUAGE ImpredicativeTypes #-}
|
|
1
|
2
|
{-# LANGUAGE TypeFamilies #-}
|
|
|
3
|
+
|
|
2
|
4
|
module Hadrian.Utilities (
|
|
3
|
5
|
-- * List manipulation
|
|
4
|
6
|
fromSingleton, replaceEq, minusOrd, intersectOrd, lookupAll, chunksOfSize,
|
| ... |
... |
@@ -14,7 +16,7 @@ module Hadrian.Utilities ( |
|
14
|
16
|
|
|
15
|
17
|
-- * Paths
|
|
16
|
18
|
BuildRoot (..), buildRoot, buildRootRules, isGeneratedSource,
|
|
17
|
|
- KeepResponseFiles (..), keepResponseFiles, withResponseFile, withResponseFileOnWindows,
|
|
|
19
|
+ KeepResponseFiles (..), keepResponseFiles, withResponseFile, withResponseFileIfLongCmd,
|
|
18
|
20
|
|
|
19
|
21
|
-- * File system operations
|
|
20
|
22
|
copyFile, copyFileUntracked, createFileLink, fixFile,
|
| ... |
... |
@@ -50,7 +52,6 @@ import Development.Shake.Classes |
|
50
|
52
|
import Development.Shake.FilePath
|
|
51
|
53
|
import GHC.ResponseFile (escapeArgs)
|
|
52
|
54
|
import System.Environment (lookupEnv)
|
|
53
|
|
-import System.Info.Extra (isWindows)
|
|
54
|
55
|
import System.IO (hClose, openTempFile)
|
|
55
|
56
|
import System.IO.Error (isPermissionError)
|
|
56
|
57
|
|
| ... |
... |
@@ -61,6 +62,7 @@ import qualified System.Directory.Extra as IO |
|
61
|
62
|
import qualified System.Info.Extra as IO
|
|
62
|
63
|
import qualified System.IO as IO
|
|
63
|
64
|
import qualified System.FilePath.Posix as Posix
|
|
|
65
|
+import Development.Shake.Command (CmdArgument (..), IsCmdArgument (toCmdArgument))
|
|
64
|
66
|
|
|
65
|
67
|
-- | Extract a value from a singleton list, or terminate with an error message
|
|
66
|
68
|
-- if the list does not contain exactly one value.
|
| ... |
... |
@@ -330,20 +332,26 @@ keepResponseFiles = do |
|
330
|
332
|
KeepResponseFiles keep <- userSetting (KeepResponseFiles False)
|
|
331
|
333
|
return keep
|
|
332
|
334
|
|
|
333
|
|
--- | Run an action either with command arguments direcly or by, on Windows,
|
|
334
|
|
--- placing those arguments into a response file escaped with @GHC.ResponseFile.escapeArgs@.
|
|
|
335
|
+-- | Run an command with the given arguments. If the command is too long then the
|
|
|
336
|
+-- response file arguments are placed into a response file and escaped with @GHC.ResponseFile.escapeArgs@.
|
|
335
|
337
|
--
|
|
336
|
338
|
-- With @--keep-response-files@, the file is left on disk (if used)
|
|
337
|
|
-withResponseFileOnWindows ::
|
|
338
|
|
- ([String] -> Action a) -- ^ Action to perform given arguments (of the form @["\@reponseFilePath"]@ on Windows)
|
|
339
|
|
- -> [String] -- ^ Command arguments
|
|
340
|
|
- -> Action a
|
|
341
|
|
-withResponseFileOnWindows action commandArgs = do
|
|
342
|
|
- if isWindows
|
|
|
339
|
+withResponseFileIfLongCmd :: (CmdResult c) =>
|
|
|
340
|
+ CmdArgument -- ^ Command and arguments before the response file arguments.
|
|
|
341
|
+ -> [String] -- ^ Response file aruguments.
|
|
|
342
|
+ -> CmdArgument -- ^ Command arguments after the response file arguments.
|
|
|
343
|
+ -> Action c
|
|
|
344
|
+withResponseFileIfLongCmd argsPre argsResp argsPost = do
|
|
|
345
|
+ let cmdLineLengh = sum
|
|
|
346
|
+ [ length arg
|
|
|
347
|
+ | let CmdArgument args = argsPre <> toCmdArgument argsResp <> argsPost
|
|
|
348
|
+ , Right arg <- args
|
|
|
349
|
+ ]
|
|
|
350
|
+ if cmdLineLengh >= cmdLineLengthLimit
|
|
343
|
351
|
then withResponseFile $ \tmp -> do
|
|
344
|
|
- writeFile' tmp (escapeArgs commandArgs)
|
|
345
|
|
- action ['@' : tmp]
|
|
346
|
|
- else action commandArgs
|
|
|
352
|
+ writeFile' tmp (escapeArgs argsResp)
|
|
|
353
|
+ cmd argsPre ('@' : tmp) argsPost
|
|
|
354
|
+ else cmd argsPre argsResp argsPost
|
|
347
|
355
|
|
|
348
|
356
|
-- | Run an action with a response file path.
|
|
349
|
357
|
--
|