module Elm.Utils ((|>), (<|), getAsset, run, unwrappedRun, CommandError(..)) where
import Control.Monad.Error (MonadError, MonadIO, liftIO, throwError)
import System.Directory (doesFileExist)
import System.Environment (getEnv)
import System.Exit (ExitCode(ExitSuccess, ExitFailure))
import System.FilePath ((</>))
import System.IO.Error (tryIOError)
import System.Process (readProcessWithExitCode)
import qualified Elm.Compiler.Version as Version
(|>) :: a -> (a -> b) -> b
x |> f = f x
(<|) :: (a -> b) -> a -> b
f <| x = f x
infixr 0 <|
infixl 0 |>
data CommandError
= MissingExe String
| CommandFailed String String
run :: (MonadError String m, MonadIO m) => String -> [String] -> m String
run command args =
do result <- liftIO (unwrappedRun command args)
case result of
Right out -> return out
Left err ->
throwError (context (message err))
where
context msg =
"failure when running:" ++ concatMap (' ':) (command:args) ++ "\n" ++ msg
message err =
case err of
CommandFailed stderr stdout ->
stdout ++ stderr
MissingExe msg ->
msg
unwrappedRun :: String -> [String] -> IO (Either CommandError String)
unwrappedRun command args =
do (exitCode, stdout, stderr) <- readProcessWithExitCode command args ""
return $
case exitCode of
ExitSuccess -> Right stdout
ExitFailure code
| code == 127 -> Left (missingExe command)
| code == 9009 -> Left (missingExe command)
| otherwise -> Left (CommandFailed stdout stderr)
missingExe :: String -> CommandError
missingExe command =
MissingExe $
"Could not find command '" ++ command ++ "'. Do you have it installed?\n\
\ Can it be run from anywhere? Is it on your PATH?"
getAsset :: String -> (FilePath -> IO FilePath) -> FilePath -> IO FilePath
getAsset project getDataFileName name =
do path <- getDataFileName name
exists <- doesFileExist path
if exists
then return path
else do
environment <- tryIOError (getEnv "ELM_HOME")
case environment of
Right env ->
return (env </> project </> name)
Left _ ->
fail (errorNotFound name)
errorNotFound :: FilePath -> String
errorNotFound name =
unlines
[ "Unable to find the ELM_HOME environment variable when searching"
, "for the " ++ name ++ " file."
, ""
, "If you installed Elm Platform with the Mac or Windows installer, it looks like"
, "ELM_HOME was not set automatically. Look up how to set environment variables"
, "on your platform and set ELM_HOME to the directory that contains Elm's static"
, "files:"
, ""
, " * On Mac it is /usr/local/share/elm"
, " * On Windows it is one of the following:"
, " C:/Program Files/Elm Platform/" ++ Version.version ++ "/share"
, " C:/Program Files (x86)/Elm Platform/" ++ Version.version ++ "/share"
, ""
, "If it seems like a more complex issue, please report it here:"
, " <https://github.com/elm-lang/elm-platform/issues>"
]