@@ -93,7 +93,7 @@ import qualified System.Directory as Directory (findExecutable)
9393import System.Environment (getEnvironment , getProgName , getArgs , withArgs )
9494import System.Exit
9595import System.FileLock (lockFile , tryLockFile , unlockFile , SharedExclusive (Exclusive ), FileLock )
96- import System.FilePath (searchPathSeparator )
96+ import System.FilePath (pathSeparator , searchPathSeparator )
9797import System.IO (hIsTerminalDevice , stderr , stdin , stdout , hSetBuffering , BufferMode (.. ), hPutStrLn , Handle , hGetEncoding , hSetEncoding )
9898import System.Process.Read
9999
@@ -166,6 +166,12 @@ main = do
166166 printExceptionStderr e
167167 exitFailure
168168
169+ -- Vertically combine only the error component of the first argument with the
170+ -- error component of the second.
171+ vcatErrorHelp :: ParserHelp -> ParserHelp -> ParserHelp
172+ vcatErrorHelp (ParserHelp e1 _ _ _ _) (ParserHelp e2 h2 u2 b2 f2) =
173+ ParserHelp (vcatChunks [e2, e1]) h2 u2 b2 f2
174+
169175commandLineHandler
170176 :: String
171177 -> Bool
@@ -190,13 +196,11 @@ commandLineHandler progName isInterpreter = complicatedOptions
190196 parseResultHandler args f =
191197 if isInterpreter
192198 then do
193- let hlp = stringChunk
199+ let hlp = errorHelp $ stringChunk
194200 (unwords [" Error executing interpreter command:"
195201 , progName
196202 , unwords args])
197- let vcatErrChunk err (ParserHelp e h u b ft) =
198- ParserHelp (vcatChunks [err, e]) h u b ft
199- handleParseResult (overFailure (vcatErrChunk hlp) (Failure f))
203+ handleParseResult (overFailure (vcatErrorHelp hlp) (Failure f))
200204 else handleParseResult (Failure f)
201205
202206 globalOpts hide =
@@ -460,43 +464,59 @@ secondaryCommandHandler
460464-- fall-through to external executables in `git` style if they exist
461465-- (i.e. `stack something` looks for `stack-something` before
462466-- failing with "Invalid argument `something'")
463- secondaryCommandHandler args f = do
467+ secondaryCommandHandler args f =
468+ -- don't even try when the argument looks like a path
469+ if elem pathSeparator cmd
470+ then return f
471+ else do
472+ mExternalExec <- Directory. findExecutable cmd
473+ case mExternalExec of
474+ Just ex -> do
475+ menv <- getEnvOverride buildPlatform
476+ -- TODO show the command in verbose mode
477+ -- hPutStrLn stderr $ unwords $
478+ -- ["Running", "[" ++ ex, unwords (tail args) ++ "]"]
479+ _ <- runNoLoggingT (exec menv ex (tail args))
480+ return f
481+ Nothing -> return $ fmap (vcatErrorHelp (noSuchCmd cmd)) f
482+ where
464483 -- FIXME this is broken when any options are specified before the command
465484 -- e.g. stack --verbosity silent cmd
466- mExternalExec <- Directory. findExecutable cmd
467- case mExternalExec of
468- Just ex -> do
469- menv <- getEnvOverride buildPlatform
470- -- TODO show the command in verbose mode
471- -- hPutStrLn stderr $ unwords $
472- -- ["Running", "[" ++ ex, unwords (tail args) ++ "]"]
473- _ <- runNoLoggingT (exec menv ex (tail args))
474- return f
475- Nothing -> return $ fmap (flip mappend (noSuchCmd cmd)) f
476- where
477485 cmd = stackProgName ++ " -" ++ (head args)
478486 noSuchCmd name = errorHelp $ stringChunk
479- (" \n No such auxiliary command in path `" ++ name ++ " '" )
487+ (" Auxiliary command not found in path `" ++ name ++ " '" )
480488
481489interpreterHandler
482490 :: Monoid t
483491 => [String ]
484492 -> ParserFailure ParserHelp
485493 -> IO (GlobalOptsMonoid , (GlobalOpts -> IO () , t ))
486494interpreterHandler args f = do
487- let file = head args
488495 isFile <- doesFileExist file
489496 if isFile
490497 then runInterpreterCommand file
491- else parseResultHandler (flip mappend (noSuchFile file))
498+ else parseResultHandler (errorCombine (noSuchFile file))
492499 where
500+ file = head args
501+
502+ -- if the filename contains a path separator then we know that it is not a
503+ -- command it is a file to be interpreted. In that case we only show the
504+ -- interpreter error message and exclude the command related error messages.
505+ errorCombine =
506+ if elem pathSeparator file
507+ then overrideErrorHelp
508+ else vcatErrorHelp
509+
510+ overrideErrorHelp (ParserHelp e1 _ _ _ _) (ParserHelp _ h2 u2 b2 f2) =
511+ ParserHelp e1 h2 u2 b2 f2
512+
493513 parseResultHandler fn = handleParseResult (overFailure fn (Failure f))
494514 noSuchFile name = errorHelp $ stringChunk
495- (" \n No such source file to interpret `" ++ name ++ " '" )
515+ (" File does not exist or is not a regular file `" ++ name ++ " '" )
496516
497- runInterpreterCommand file = do
517+ runInterpreterCommand path = do
498518 progName <- getProgName
499- iargs <- getInterpreterArgs file
519+ iargs <- getInterpreterArgs path
500520 let parseCmdLine = commandLineHandler progName True
501521 let cmdArgs = iargs ++ " --" : args
502522 -- TODO show the command in verbose mode
0 commit comments