@@ -7,63 +7,77 @@ import Distribution.NixOS.Derivation.Meta
77
88import Control.Exception ( bracket )
99import Control.Monad ( when )
10+import Data.List ( nub, sort )
1011import Distribution.PackageDescription ( package, packageDescription )
1112import Distribution.PackageDescription.Parse ( parsePackageDescription, ParseResult(..) )
1213import Distribution.Text ( disp )
1314import System.Console.GetOpt ( OptDescr(..), ArgDescr(..), ArgOrder(..), usageInfo, getOpt )
1415import System.Environment ( getArgs )
15−import System.Exit ( exitFailure )
16+import System.Exit ( exitFailure, exitSuccess )
1617import System.IO ( hPutStrLn, hFlush, stdout, stderr )
1718
18−data CliOption = PrintHelp | SHA256 String | Maintainer String | Platform String | NoHaddock
19− deriving (Eq)
19+data Configuration = Configuration
20+ { optPrintHelp :: Bool
21+ , optPrintVersion :: Bool
22+ , optSha256 :: String
23+ , optMaintainer :: [String]
24+ , optPlatform :: [String]
25+ , optHaddock :: Bool
26+ }
27+ deriving (Show)
2028
21−main :: IO ()
22−main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do
23− let options :: [OptDescr CliOption]
24− options =
25− [ Option ['h'] ["help"] (NoArg PrintHelp) "show this help text"
26− , Option [] ["sha256"] (ReqArg SHA256 "HASH") "sha256 hash of source tarball"
27− , Option ['m'] ["maintainer"] (ReqArg Maintainer "MAINTAINER") "maintainer of this package (may be specified multiple times)"
28− , Option ['p'] ["platform"] (ReqArg Platform "PLATFORM") "supported build platforms (may be specified multiple times)"
29− , Option [] ["no-haddock"] (NoArg NoHaddock) "don't run Haddock when building this package"
30− ]
29+defaultConfiguration :: Configuration
30+defaultConfiguration = Configuration
31+ { optPrintHelp = False
32+ , optPrintVersion = False
33+ , optSha256 = ""
34+ , optMaintainer = []
35+ , optPlatform = []
36+ , optHaddock = True
37+ }
38+
39+options :: [OptDescr (Configuration -> Configuration)]
40+options =
41+ [ Option ['h'] ["help"] (NoArg (\o -> o { optPrintHelp = True })) "show this help text"
42+ , Option [] ["sha256"] (ReqArg (\x o -> o { optSha256 = x }) "HASH") "sha256 hash of source tarball"
43+ , Option ['m'] ["maintainer"] (ReqArg (\x o -> o { optMaintainer = x : optMaintainer o }) "MAINTAINER") "maintainer of this package (may be specified multiple times)"
44+ , Option ['p'] ["platform"] (ReqArg (\x o -> o { optPlatform = x : optPlatform o }) "PLATFORM") "supported build platforms (may be specified multiple times)"
45+ , Option [] ["no-haddock"] (NoArg (\o -> o { optHaddock = False })) "don't run Haddock when building this package"
46+ ]
3147
32− usage :: String
33− usage = usageInfo "Usage: cabal2nix [options] url-to-cabal-file" options ++ unlines
34− [ ""
35− , "Recognized URI schemes:"
36− , ""
37− , " cabal://pkgname-pkgversion download the specified package from Hackage"
38− , " http://host/path fetch the Cabel file via HTTP"
39− , " file:///local/path load the Cabal file from the local disk"
40− , " /local/path abbreviated version of file URI"
41− ]
48+usage :: String
49+usage = usageInfo "Usage: cabal2nix [options] url-to-cabal-file" options ++ unlines
50+ [ ""
51+ , "Recognized URI schemes:"
52+ , ""
53+ , " cabal://pkgname-pkgversion download the specified package from Hackage"
54+ , " http://host/path fetch the Cabel file via HTTP"
55+ , " file:///local/path load the Cabal file from the local disk"
56+ , " /local/path abbreviated version of file URI"
57+ ]
4258
43− cmdlineError :: String -> IO a
44− cmdlineError "" = hPutStrLn stderr usage >> exitFailure
45− cmdlineError errMsg = hPutStrLn stderr errMsg >> cmdlineError ""
59+cmdlineError :: String -> IO a
60+cmdlineError "" = hPutStrLn stderr usage >> exitFailure
61+cmdlineError errMsg = hPutStrLn stderr errMsg >> cmdlineError ""
4662
63+main :: IO ()
64+main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do
4765 args' <- getArgs
48− (opts,args) <- case getOpt Permute options args' of
49− (o,n,[] ) -> return (o,n)
50− (_,_,errs) -> cmdlineError (concatMap (\e -> '*':'*':'*':' ':e) errs)
51−
52− when (PrintHelp `elem` opts) (cmdlineError "")
66+ (cfg',args) <- case getOpt Permute options args' of
67+ (o,n,[] ) -> return (foldl (flip ($)) defaultConfiguration o,n)
68+ (_,_,errs) -> cmdlineError (concatMap ("*** "++) errs)
5369
54− let uri = args
55− hash = [ h | SHA256 h <- opts ]
56− noHaddock = NoHaddock `elem` opts
57− maints = [ if '.' `elem` m then m else "self.stdenv.lib.maintainers." ++ m | Maintainer m <- opts ]
58− plats' = [ if '.' `elem` p then p else "self.stdenv.lib.platforms." ++ p | Platform p <- opts ]
59− plats
60− | null plats' = if not (null maints) then ["self.ghc.meta.platforms"] else []
61− | otherwise = plats'
70+ when (optPrintHelp cfg') (putStr usage >> exitSuccess)
71+ when (length args /= 1) (cmdlineError "*** exactly one url-to-cabal-file must be specified\n")
6272
63− when (length uri /= 1) (cmdlineError "*** exactly one URI must be specified")
64− when (length hash > 1) (cmdlineError "*** the --sha256 option may be specified only once")
73+ let maints = [ if '.' `elem` m then m else "self.stdenv.lib.maintainers." ++ m | m <- optMaintainer cfg' ]
74+ plats = [ if '.' `elem` p then p else "self.stdenv.lib.platforms." ++ p | p <- optPlatform cfg' ]
75+ cfg = cfg'
76+ { optMaintainer = nub (sort maints)
77+ , optPlatform = nub (sort (if null plats then ["self.ghc.meta.platforms"] else plats))
78+ }
6579
66− cabal' <- fmap parsePackageDescription (readCabalFile (head uri))
80+ cabal' <- fmap parsePackageDescription (readCabalFile (head args))
6781 cabal <- case cabal' of
6882 ParseOk _ a -> return a
6983 ParseFailed err -> do
@@ -72,12 +86,12 @@ main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do
7286
7387 let packageId = package (packageDescription cabal)
7488
75− sha <- if null hash then hashPackage packageId else return (head hash)
89+ sha <- if null (optSha256 cfg) then hashPackage packageId else return (optSha256 cfg)
7690
77− let deriv = (cabal2nix cabal) { sha256 = sha, runHaddock = not noHaddock }
91+ let deriv = (cabal2nix cabal) { sha256 = sha, runHaddock = optHaddock cfg }
7892 deriv' = deriv { metaSection = (metaSection deriv)
79− { maintainers = maints
80− , platforms = plats
93+ { maintainers = optMaintainer cfg
94+ , platforms = optPlatform cfg
8195 }
8296 }
8397