cabal2nix 1.2 → 1.3
raw patch · 2 files changed
+68/−31 lines, 2 filesdep +HTTPdep +process
Dependencies added: HTTP, process
Files
- cabal2nix.cabal +17/−10
- cabal2nix.hs +51/−21
cabal2nix.cabal view
@@ -1,5 +1,5 @@ Name: cabal2nix-Version: 1.2+Version: 1.3 Copyright: (c) 2011 Peter Simons License: BSD3 License-File: LICENSE@@ -10,18 +10,25 @@ Synopsis: Convert Cabal files into Nix build instructions Cabal-Version: >= 1.6 Build-Type: Simple-Tested-With: GHC == 7.0.2+Tested-With: GHC == 7.0.4 Description: This utility converts Cabal files into Nix build- instructions. Run the binary as follows:+ instructions. The commandline syntax is: .- > cabal2nix foo.cabal 57ae0330a3d0520bae3d1e447d7d5c88de9ecbf0de133f31f2cc42961c81d47f+ > cabal2nix cabal-file-uri [sha256-hash] .- The first argument is the path to the cabal file- to be converted, the second argument is the- SHA256 hash of the corresponding source tarball.+ The first argument is the path to the cabal+ file. That path can be an HTTP URL or local file+ path. For example: .- The Nix build instructions will be written to- stdout.+ > cabal2nix.hs http://hackage.haskell.org/packages/archive/cabal2nix/1.2/cabal2nix.cabal 0m7zgsd1pxmw504xpvl7dg25ana6dkk1mcyjj4c1wdbkvhvbn3gn+ > cabal2nix.hs file:///tmp/cabal2nix.cabal 0m7zgsd1pxmw504xpvl7dg25ana6dkk1mcyjj4c1wdbkvhvbn3gn+ > cabal2nix.hs /tmp/cabal2nix.cabal 0m7zgsd1pxmw504xpvl7dg25ana6dkk1mcyjj4c1wdbkvhvbn3gn+ .+ The second argument -- the hash of the source+ tarball -- is optional. If it's not specified,+ cabal2nix calls @nix-prefetch-url@ to determine+ the hash automatically. This causes network+ traffic, obviously. Source-Repository head Type: git@@ -29,5 +36,5 @@ Executable cabal2nix main-is: cabal2nix.hs- Build-Depends: base >= 3 && < 5, Cabal+ Build-Depends: base >= 3 && < 5, Cabal, process, HTTP Ghc-Options: -Wall
cabal2nix.hs view
@@ -10,7 +10,6 @@ import Control.Exception import System.Exit import Distribution.PackageDescription.Parse-import Distribution.Verbosity ( silent ) import Distribution.PackageDescription import Distribution.Package import Distribution.License@@ -18,6 +17,8 @@ import Data.List import Control.Monad import Data.Char+import Network.HTTP+import System.Process type PkgName = String type PkgVersion = [Int]@@ -77,38 +78,67 @@ showLic OtherLicense = "unknown" showLic l = error $ "unknown license: " ++ show l -readPackage :: FilePath -> String -> IO Pkg-readPackage cabalFile sha256 = do- cabal <- readPackageDescription silent cabalFile- let pkg = packageDescription cabal- PackageName pkgname = pkgName (package pkg)- pkgver = versionBranch (pkgVersion (package pkg))- lic = license pkg- url = homepage pkg- desc = synopsis pkg- -- globalDeps = buildDepends pkg- libDeps = maybe [] (\x -> [x]) (condLibrary cabal)- exeDeps = [ tree | (_,tree) <- condExecutables cabal ]- libs = concat [ extraLibs (libBuildInfo (condTreeData x)) | x <- libDeps ]- libs' = concat [ extraLibs (buildInfo (condTreeData x)) | x <- exeDeps ]- return (Pkg pkgname pkgver sha256 url desc lic (map simplify libDeps ++ map simplify exeDeps) (libs++libs'))- where+cabal2nix :: GenericPackageDescription -> PkgSHA256 -> Pkg+cabal2nix cabal sha256 = Pkg pkgname pkgver sha256 url desc lic (map simplify libDeps ++ map simplify exeDeps) (libs++libs')+ where+ pkg = packageDescription cabal+ PackageName pkgname = pkgName (package pkg)+ pkgver = versionBranch (pkgVersion (package pkg))+ lic = license pkg+ url = homepage pkg+ desc = synopsis pkg+ -- globalDeps = buildDepends pkg+ libDeps = maybe [] (\x -> [x]) (condLibrary cabal)+ exeDeps = [ tree | (_,tree) <- condExecutables cabal ]+ libs = concat [ extraLibs (libBuildInfo (condTreeData x)) | x <- libDeps ]+ libs' = concat [ extraLibs (buildInfo (condTreeData x)) | x <- exeDeps ] simplify :: CondTree ConfVar [Dependency] a -> CondTree ConfVar [Dependency] () simplify (CondNode _ deps nodes) = CondNode () deps (map simp nodes) where simp (cond,tree,mtree) = (cond, simplify tree, maybe Nothing (Just . simplify) mtree) +readCabalFile :: FilePath -> IO String+readCabalFile path+ | "http://" `isPrefixOf` path = Network.HTTP.simpleHTTP (getRequest path) >>= getResponseBody+ | "file://" `isPrefixOf` path = readCabalFile (drop 7 path)+ | otherwise = readFile path++hashPackage :: GenericPackageDescription -> IO String+hashPackage pkg = readProcess "bash" ["-c", "exec nix-prefetch-url 2>/dev/tty " ++ url] ""+ where+ url = "http://hackage.haskell.org/packages/archive/" ++ name ++ "/" ++ version ++ "/" ++ name ++ "-" ++ version ++ ".tar.gz"+ PackageIdentifier (PackageName name) version' = package (packageDescription pkg)+ version = showVersion version'+ main :: IO () main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do args <- getArgs - when (length args /= 2) $ do+ let usage = "Usage: cabal2nix url-to-cabal-file [sha256-hash]"++ when (length args < 1 || length args > 2) $ do mapM_ (hPutStrLn stderr) [ "*** invalid command line syntax"- , "Usage: cabal2nix cabal-file sha256-hash"+ , usage ] exitFailure - let cabalFile:sha256:[] = args- pkg <- readPackage cabalFile sha256+ when ("--help" `elem` args || "-h" `elem` args) $ do+ putStrLn usage+ exitFailure++ cabal' <- fmap parsePackageDescription (readCabalFile (head args))+ cabal <- case cabal' of+ ParseOk _ a -> return a+ ParseFailed err -> do+ hPutStrLn stderr ("*** cannot parse cabal file: " ++ show err)+ exitFailure++ sha256 <- case args of+ _:hash:[] -> return hash+ _ -> hashPackage cabal++ let pkg = cabal2nix cabal sha256 putStr (toNix pkg)++