@@ -4,18 +4,19 @@ import System.IO
44import System.Environment
55import Control.Exception
66import System.Exit
7−import Distribution.PackageDescription.Parse
8−import Distribution.PackageDescription
7+import Distribution.PackageDescription.Parse ( parsePackageDescription, ParseResult(..) )
8+import Distribution.PackageDescription ( GenericPackageDescription, package, packageDescription )
99import Distribution.Package
1010import Distribution.Text
1111import Data.Version
1212import Data.List
1313import Control.Monad
1414import Network.HTTP
15−import System.Process
15+import System.Console.GetOpt
1616
17−import Cabal2Nix.Package
17+import System.Process
1818
19+import Cabal2Nix.Package ( showNixPkg, cabal2nix )
1920
2021data Ext = TarGz | Cabal deriving Eq
2122
@@ -43,39 +44,61 @@ hashPackage :: GenericPackageDescription -> IO String
4344hashPackage pkg = do
4445 hash <- readProcess "bash" ["-c", "exec nix-prefetch-url 2>/dev/tty " ++ url] ""
4546 return (reverse (dropWhile (=='\n') (reverse hash)))
46−
4747 where
4848 url = hackagePath pid TarGz
4949 pid = package (packageDescription pkg)
5050
51+data CliOption = PrintHelp | SHA256 String | Maintainer String | Platform String
52+ deriving (Eq)
53+
5154main :: IO ()
5255main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do
53− args <- getArgs
54−
55− let usage = "Usage: cabal2nix url-to-cabal-file [sha256-hash]"
56−
57− when (length args < 1 || length args > 2) $ do
58− mapM_ (hPutStrLn stderr) [ "*** invalid command line syntax"
59− , usage
60− ]
61− exitFailure
62−
63− when ("--help" `elem` args || "-h" `elem` args) $ do
64− putStrLn usage
65− exitFailure
66−
67− cabal' <- fmap parsePackageDescription (readCabalFile (head args))
56+ let options :: [OptDescr CliOption]
57+ options =
58+ [ Option ['h'] ["help"] (NoArg PrintHelp) "show this help text"
59+ , Option [] ["sha256"] (ReqArg SHA256 "HASH") "sha256 hash of source tarball"
60+ , Option [] ["maintainer"] (ReqArg Maintainer "MAINTAINER") "maintainer of this package (may be specified multiple times)"
61+ , Option [] ["platform"] (ReqArg Platform "PLATFORM") "supported build platforms (may be specified multiple times)"
62+ ]
63+
64+ usage :: String
65+ usage = usageInfo "Usage: cabal2nix [options] url-to-cabal-file" options ++
66+ "\n\
67+ \Recognized URI schemes:\n\
68+ \\n\
69+ \ cabal:///pkgname-pkgversion download the specified package from Hackage\n\
70+ \ http://host/path fetch the Cabel file via HTTP\n\
71+ \ file:///local/path load the Cabal file from the local disk\n\
72+ \ /local/path abbreviated version of file URI\n"
73+
74+ cmdlineError :: String -> IO a
75+ cmdlineError "" = hPutStrLn stderr usage >> exitFailure
76+ cmdlineError errMsg = hPutStrLn stderr errMsg >> cmdlineError ""
77+
78+ args' <- getArgs
79+ (opts,args) <- case getOpt Permute options args' of
80+ (o,n,[] ) -> return (o,n)
81+ (_,_,errs) -> cmdlineError (concatMap (\e -> '*':'*':'*':' ':e) errs)
82+
83+ when (PrintHelp `elem` opts) (cmdlineError "")
84+
85+ let uri = args
86+ hash = [ h | SHA256 h <- opts ]
87+ platforms = [ p | Platform p <- opts ]
88+ maintainers = [ m | Maintainer m <- opts ]
89+
90+ when (length uri /= 1) (cmdlineError "*** exactly one URI must be specified")
91+ when (length hash > 1) (cmdlineError "*** the --sha256 option may be specified only once")
92+
93+ cabal' <- fmap parsePackageDescription (readCabalFile (head uri))
6894 cabal <- case cabal' of
6995 ParseOk _ a -> return a
7096 ParseFailed err -> do
7197 hPutStrLn stderr ("*** cannot parse cabal file: " ++ show err)
7298 exitFailure
7399
74− sha256 <- case args of
75− _:hash:[] -> return hash
76− _ -> hashPackage cabal
77−
78− let pkg = cabal2nix cabal sha256
79− putStr (toNix pkg)
80−
100+ sha256 <- case hash of
101+ h:[] -> return h
102+ _ -> hashPackage cabal
81103
104+ putStr (showNixPkg (cabal2nix cabal sha256 platforms maintainers))