hsenv-0.5: src/Args.hs
{-# LANGUAGE Arrows, CPP #-}
module Args (getArgs) where
import Control.Arrow
import Data.Char
import Util.Args
import Types
#ifdef cabal
import Util.Cabal (prettyVersion)
import Paths_hsenv (version)
versionString :: String
versionString = prettyVersion version
#else
versionString :: String
versionString = "dev"
#endif
verbosityOpt, veryVerbosityOpt, skipSanityOpt, sharingOpt, noPS1Opt :: Switch
verbosityOpt = Switch { switchName = "verbose"
, switchHelp = "Print some debugging info"
, switchShort = Just 'v'
}
veryVerbosityOpt = Switch { switchName = "very-verbose"
, switchHelp = "Print some more debugging info"
, switchShort = Nothing
}
skipSanityOpt = Switch { switchName = "skip-sanity-check"
, switchHelp = "Skip all the sanity checks (use at your own risk)"
, switchShort = Nothing
}
sharingOpt = Switch { switchName = "dont-share-cabal-cache"
, switchHelp = "Don't share ~/.cabal/packages (hackage download cache)"
, switchShort = Nothing
}
noPS1Opt =
Switch { switchName = "no-ps1-indicator"
, switchHelp =
"Don't modify the shell prompt to indicate the current hsenv"
, switchShort = Nothing
}
nameOpt, ghcOpt :: DynOpt
nameOpt = DynOpt
{ dynOptName = "name"
, dynOptTemplate = "NAME"
, dynOptDescription = "current directory name"
, dynOptHelp = "Use NAME as name of the Virtual Haskell Environment"
}
ghcOpt = DynOpt
{ dynOptName = "ghc"
, dynOptTemplate = "VERSION|URL|FILE"
, dynOptDescription = "system's copy of GHC"
, dynOptHelp =
"Use GHC from provided location -- a GHC version number, an HTTP or HTTPS URL or a path to a tarball (e.g. ghc-7.0.4-i386-unknown-linux.tar.bz2)"
}
makeOpt :: StaticOpt
makeOpt = StaticOpt
{ staticOptName = "make-cmd"
, staticOptTemplate = "CMD"
, staticOptDefault = "make"
, staticOptHelp =
"Used as make substitute for installing GHC from tarball (e.g. gmake)"
}
argParser :: ArgArrow () Options
argParser = proc () -> do
verbosityFlag <- getOpt verbosityOpt -< ()
verbosityFlag2 <- getOpt veryVerbosityOpt -< ()
let verboseness = case (verbosityFlag, verbosityFlag2) of
(_, True) -> VeryVerbose
(True, False) -> Verbose
(False, False) -> Quiet
name <- getOpt nameOpt -< ()
ghcFlag <- getOpt ghcOpt -< ()
noPS1' <- getOpt noPS1Opt -< ()
let ghc = case ghcFlag of
Nothing -> System
-- First check for URLs (@//@ is not meaningful in Posix file
-- paths), then versions and then default to path.
Just s | "https://" == take 8 s -> Url s
| "http://" == take 7 s -> Url s
| isVersion s -> Release s
| otherwise -> Tarball s
skipSanityCheckFlag <- getOpt skipSanityOpt -< ()
noSharingFlag <- getOpt sharingOpt -< ()
make <- getOpt makeOpt -< ()
returnA -< Options{ verbosity = verboseness
, skipSanityCheck = skipSanityCheckFlag
, hsEnvName = name
, ghcSource = ghc
, makeCmd = make
, noSharing = noSharingFlag
, noPS1 = noPS1'
}
getArgs :: IO Options
getArgs = parseArgs argParser versionString outro
where
outro = "Creates Virtual Haskell Environment in the current directory.\n"
++ "All files will be stored in the .hsenv[_NAME]/ subdirectory.\n"
++ "\n"
++ "To activate a sandbox in the current directory, run:\n"
++ "\n"
++ " source .hsenv/bin/activate\n"
++ "\n"
++ "To deactivate an active sandbox, run:\n"
++ "\n"
++ " deactivate_hsenv"
isVersion :: String -> Bool
isVersion s = case dropWhile isDigit s of
"" -> s /= ""
'.':s' -> s /= '.':s' && isVersion s'
_ -> False