gw-0.1: app/Main.hs
{-# language DerivingStrategies #-}
{-# language GeneralizedNewtypeDeriving #-}
{-# language LambdaCase #-}
{-# language OverloadedStrings #-}
{-# language ScopedTypeVariables #-}
{-# language ViewPatterns #-}
module Main
( main
) where
import System.Environment (getArgs)
import qualified Data.List as List
import qualified System.Posix.Process as P
main :: IO ()
main = parseArgs >>= runCmd
parseArgs :: IO Cmd
parseArgs = getArgs >>= \case
[] -> pure Help
("-v":_) -> pure Version
("--version":_) -> pure Version
("-h":_) -> pure Help
("--help":_) -> pure Help
("-p":xs) -> go Pure xs
("--pure":xs) -> go Pure xs
xs -> go Impure xs
where
go :: Purity -> [String] -> IO Cmd
go p = \case
[] -> pure BadCmd
(x:xs) -> case readGhc x of
Left str -> do
putStr (str ++ "\n")
pure BadCmd
Right g -> pure $ GhcWith p g (PkgSet xs)
ghcWith :: Ghc -> PkgSet -> String
ghcWith (showGhc -> ghc) (showPkgSet -> pkgs) = mconcat
[ "haskell.packages."
, ghc
, ".ghcWithPackages (pkgs: with pkgs; [ "
, pkgs
, " ])"
]
ghcWithIO :: Ghc -> PkgSet -> Purity -> IO ()
ghcWithIO g pkgs p
= P.executeFile "nix-shell" True (p' ++ ["-p",ghcWith g pkgs]) Nothing
where
p' = case p of
Pure -> ["--pure"]
Impure -> []
data Cmd
= Help
| Version
| GhcWith Purity Ghc PkgSet
| BadCmd
runCmd :: Cmd -> IO ()
runCmd = \case
Help -> putStr help
Version -> putStr version
GhcWith p g pkgs -> ghcWithIO g pkgs p
BadCmd -> putStr badCmd
help,version,badCmd :: String
help = mconcat
[ "\n"
, " gw - a utility for entering a nix-shell using ghcWithPackages\n\n"
, " Usage: gw <OPTIONS> <GHC> <PKGS>\n\n"
, " Available options:\n"
, " -h,--help Display this help menu\n"
, " -p,--pure Enter a pure nix-shell\n"
, " -v,--version Display the version of gw\n"
, "\n"
]
version = "gw 0.1"
badCmd = mconcat
[ "\n"
, "Malformed command. Help menu:\n"
, help
]
readGhc :: String -> Either String Ghc
readGhc = \case
"ghc710" -> Right Ghc710
"ghc801" -> Right Ghc801
"ghc802" -> Right Ghc802
"ghc821" -> Right Ghc821
"ghc822" -> Right Ghc822
"ghc841" -> Right Ghc841
"ghc842" -> Right Ghc842
"ghc843" -> Right Ghc843
"ghc844" -> Right Ghc844
"ghc861" -> Right Ghc861
"ghc862" -> Right Ghc862
"ghc863" -> Right Ghc863
"ghc864" -> Right Ghc864
"ghc865" -> Right Ghc865
"ghcHEAD" -> Right GhcHead
x -> Left $ "GHC arg \"" ++ x ++ "\" passed is not one of " ++ ghcSet
showGhc :: Ghc -> String
showGhc = \case
Ghc710 -> "ghc710"
Ghc801 -> "ghc801"
Ghc802 -> "ghc802"
Ghc821 -> "ghc821"
Ghc822 -> "ghc822"
Ghc841 -> "ghc841"
Ghc842 -> "ghc842"
Ghc843 -> "ghc843"
Ghc844 -> "ghc844"
Ghc861 -> "ghc861"
Ghc862 -> "ghc862"
Ghc863 -> "ghc863"
Ghc864 -> "ghc864"
Ghc865 -> "ghc865"
GhcHead -> "ghcHEAD"
data Ghc
= Ghc710
| Ghc801
| Ghc802
| Ghc821
| Ghc822
| Ghc841
| Ghc842
| Ghc843
| Ghc844
| Ghc861
| Ghc862
| Ghc863
| Ghc864
| Ghc865
| GhcHead
deriving stock (Eq,Ord,Enum,Bounded,Show)
ghcSet :: String
ghcSet = mconcat
[ "{"
, (List.intercalate ", " (map showGhc [minBound..maxBound :: Ghc]))
, "}"
]
newtype PkgSet = PkgSet [String]
deriving newtype (Eq,Show)
showPkgSet :: PkgSet -> String
showPkgSet (PkgSet set) = List.unwords set
data Purity = Pure | Impure
deriving stock (Eq,Show)