cpkg-0.2.3.3: app/Main.hs
module Main (main) where
import Control.Monad (void, when)
import Data.Semigroup
import qualified Data.Text as T
import qualified Data.Version as V
import Options.Applicative hiding (auto)
import Package.C hiding (Command, name)
import qualified Paths_cpkg as P
import System.Directory (doesDirectoryExist, removeDirectoryRecursive)
cpkgVersion :: V.Version
cpkgVersion = P.version
-- dhallStandardVersion
-- dhallVersion
data DumpTarget = Linker { _pkgGet :: String }
| Compiler { _pkgGet :: String }
| PkgConfig { _pkgGets :: [String] }
| IncludePath { _pkgGet :: String }
| LibPath { _pkgGet :: String }
| LdLibPath { _pkgGets :: [String] }
data Command = Install { _pkgName :: String, _verbosity :: Verbosity, _target :: Maybe Platform, _static :: Bool, _global :: Bool, _packageSet :: Maybe String }
| Uninstall { _pkgStr :: String, _verbosity :: Verbosity, _target :: Maybe Platform }
| Check { _dhallFile :: String, _verbosity :: Verbosity }
| CheckSet { _dhallFile :: String, _verbosity :: Verbosity }
| Dump { _dumpTarget :: DumpTarget, _host :: Maybe Platform }
| DumpCabal { _pkgGetsCabal :: [String], _host :: Maybe Platform }
| List { _packageSet :: Maybe String }
| Find { _findPkg :: String }
| Nuke
| NukeCache
| GarbageCollect { _verbosity :: Verbosity }
verbosityInt :: Parser Int
verbosityInt = length <$>
many (flag' () (short 'v' <> long "verbose" <> help "Turn up verbosity"))
verbosity :: Parser Verbosity
verbosity = fmap intToVerbosity verbosityInt
intToVerbosity :: Int -> Verbosity
intToVerbosity 0 = Normal
intToVerbosity 1 = Verbose
intToVerbosity 2 = Loud
intToVerbosity 3 = Diagnostic
intToVerbosity _ = Normal
wrapper :: ParserInfo Command
wrapper = info (helper <*> versionInfo <*> userCmd)
(fullDesc
<> progDesc "The cpkg build tool and package manager."
<> header "cpkg - a build tool for C")
versionInfo :: Parser (a -> a)
versionInfo = infoOption ("cpkg version: " ++ V.showVersion cpkgVersion) (short 'V' <> long "version" <> help "Show version")
dumpTarget :: Parser DumpTarget
dumpTarget = hsubparser
(command "linker" (info (Linker <$> package) (progDesc "Dump linker flags for a package"))
<> command "compiler" (info (Compiler <$> package) (progDesc "Dump compiler flags for a package"))
<> command "pkg-config" (info (PkgConfig <$> some package) (progDesc "Dump pkg-config path for a package")) -- TODO: make pkg-config recursive or something?
<> command "include" (info (IncludePath <$> package) (progDesc "Dump C_INCLUDE_PATH for a package"))
<> command "library" (info (LibPath <$> package) (progDesc "Dump LD_LIBRARY_PATH or LIBRARY_PATH info for a package"))
<> command "ld-path" (info (LdLibPath <$> some package) (progDesc "Dump LD_LIBRARY_PATH or LIBRARY_PATH for a package"))
)
userCmd :: Parser Command
userCmd = hsubparser
(command "install" (info install (progDesc "Install a package from the global package set"))
<> command "uninstall" (info uninstall (progDesc "Uninstall a package"))
<> command "check" (info check (progDesc "Check a Dhall expression to ensure it can be used to build a package"))
<> command "check-set" (info checkSet (progDesc "Check a package set defined in Dhall"))
<> command "dump" (info dump (progDesc "Display flags to link against a particular library"))
<> command "dump-cabal" (info dumpCabal (progDesc "Display flags to use with cabal new-build"))
<> command "list" (info list (progDesc "List all available packages"))
<> command "find" (info find (progDesc "Find a package and list information"))
<> command "nuke" (info (pure Nuke) (progDesc "Remove all globally installed libraries"))
<> command "nuke-cache" (info (pure NukeCache) (progDesc "Remove cached soure tarballs"))
<> command "garbage-collect" (info garbageCollect' (progDesc "Garbage collect redundant packages"))
)
list :: Parser Command
list = List <$> packageSet
find :: Parser Command
find = Find
<$> argument str
(metavar "PACKAGE"
<> help "Name of package"
)
ftypeCompletions :: String -> Mod ArgumentFields a
ftypeCompletions ext = completer . bashCompleter $ "file -X '!*." ++ ext ++ "' -o plusdirs"
dhallCompletions :: Mod ArgumentFields a
dhallCompletions = ftypeCompletions "dhall"
uninstall :: Parser Command
uninstall = Uninstall
<$> argument str
(metavar "PACKAGE"
<> help "Name of package to uninstall"
<> completer (listIOCompleter allPackages))
<*> verbosity
<*> target
install :: Parser Command
install = Install
<$> argument str
(metavar "PACKAGE"
<> help "Name of package to install")
<*> verbosity
<*> target
<*> static'
<*> switch
(long "global"
<> short 'g'
<> help "Install globally")
<*> packageSet
packageSet :: Parser (Maybe String)
packageSet = optional
(strOption
(metavar "EXPRESSION"
<> long "pkg-set"
<> help "Dhall expression for the package set to be used"
))
static' :: Parser Bool
static' =
switch
(long "static"
<> help "Build static libaries")
garbageCollect' :: Parser Command
garbageCollect' = GarbageCollect <$> verbosity
check :: Parser Command
check = Check <$> dhallFile <*> verbosity
checkSet :: Parser Command
checkSet = CheckSet <$> dhallFile <*> verbosity
target :: Parser (Maybe Platform)
target = optional
(strOption
(metavar "TARGET"
<> long "target"
<> help "Host platform, e.g. arm-linux-gnueabihf"
))
package :: Parser String
package =
argument str
(metavar "PACKAGE"
<> help "Name of package you want to link against"
<> completer (listIOCompleter allPackages)
)
dumpCabal :: Parser Command
dumpCabal = DumpCabal
<$> some package
<*> target
dump :: Parser Command
dump = Dump
<$> dumpTarget
<*> target
dhallFile :: Parser String
dhallFile =
argument str
(metavar "EXPRESSION"
<> help "File containing a Dhall expression"
<> dhallCompletions
)
run :: Command -> IO ()
run (Uninstall pkId v host') = do
parsedHost <- parseHostIO host'
runPkgM v $ uninstallPkgByName pkId parsedHost
run (Install pkId v host' sta glob pkSet) = do
parsedHost <- parseHostIO host'
runPkgM v $ buildByName (T.pack pkId) parsedHost pkSet sta glob
run (Check file' v) = void $ getCPkg v file'
run (CheckSet file' v) = void $ getPkgs v file'
run (Dump (Linker name) host) = runPkgM Normal $ printLinkerFlags name host
run (Dump (Compiler name) host) = runPkgM Normal $ printCompilerFlags name host
run (Dump (PkgConfig names) host) = runPkgM Normal $ printPkgConfigPath names host
run (Dump (IncludePath name) host) = runPkgM Normal $ printIncludePath name host
run (Dump (LibPath name) host) = runPkgM Normal $ printLibPath name host
run (Dump (LdLibPath names) host) = runPkgM Normal $ printLdLibPath names host
run (DumpCabal names host) = runPkgM Normal $ printCabalFlags names host
run Nuke = do
pkgDir <- globalPkgDir
exists <- doesDirectoryExist pkgDir
when exists $
removeDirectoryRecursive pkgDir
run NukeCache = cleanCache
run (List pkSet) = displayPackageSet pkSet
run (Find pk) = displayPackage pk
run (GarbageCollect v) = runPkgM v garbageCollect
main :: IO ()
main = run =<< execParser wrapper