git.iko.soy/typeable/cabal2nix
on master help sign in
Add --subpath to support repos with Cabal files in subdirectories.
85a2076Jacob Mitchell
cabal2nix.cabal+1
@@ -39,6 +39,7 @@ author: Peter Simons,
39 Felix Kunzmann,
39 Felix Kunzmann,
40 Gabriel Ebner,
40 Gabriel Ebner,
41 Gergely Risko,
41 Gergely Risko,
42+ Jacob Mitchell,
42 Joachim Fasting,
43 Joachim Fasting,
43 John Albietz,
44 John Albietz,
44 John Chee,
45 John Chee,
cabal2nix/Main.hs+4−1
@@ -45,6 +45,7 @@ data Options = Options
45 , optFlags :: [String]
45 , optFlags :: [String]
46 , optCompiler :: CompilerId
46 , optCompiler :: CompilerId
47 , optSystem :: Platform
47 , optSystem :: Platform
48+ , optSubpath :: Maybe FilePath
48 , optUrl :: String
49 , optUrl :: String
49 }
50 }
50 deriving (Show)
51 deriving (Show)
@@ -68,6 +69,7 @@ options = Options
68 <*> many (strOption $ short 'f' <> long "flag" <> help "Cabal flag (may be specified multiple times)")
69 <*> many (strOption $ short 'f' <> long "flag" <> help "Cabal flag (may be specified multiple times)")
69 <*> option (readP parse) (long "compiler" <> help "compiler to use when evaluating the Cabal file" <> value buildCompilerId <> showDefaultWith display)
70 <*> option (readP parse) (long "compiler" <> help "compiler to use when evaluating the Cabal file" <> value buildCompilerId <> showDefaultWith display)
70 <*> option (readP parsePlatform) (long "system" <> help "target system to use when evaluating the Cabal file" <> value buildPlatform <> showDefaultWith display)
71 <*> option (readP parsePlatform) (long "system" <> help "target system to use when evaluating the Cabal file" <> value buildPlatform <> showDefaultWith display)
72+ <*> optional (strOption $ long "subpath" <> metavar "PATH" <> help "Path to Cabal file's directory relative to the URI (default is root directory)")
71 <*> strArgument (metavar "URI")
73 <*> strArgument (metavar "URI")
72
74
73readP :: P.ReadP a a -> ReadM a
75readP :: P.ReadP a a -> ReadM a
@@ -112,7 +114,7 @@ main :: IO ()
112main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do
114main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do
113 Options {..} <- execParser pinfo
115 Options {..} <- execParser pinfo
114
116
115− pkg <- getPackage optHackageDb $ Source optUrl (fromMaybe "" optRevision) (maybe UnknownHash Guess optSha256)
117+ pkg <- getPackage optHackageDb $ Source optUrl (fromMaybe "" optRevision) (maybe UnknownHash Guess optSha256) (fromMaybe "." optSubpath)
116
118
117 let
119 let
118 deriv :: Derivation
120 deriv :: Derivation
@@ -124,6 +126,7 @@ main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> do
124 []
126 []
125 (pkgCabal pkg)
127 (pkgCabal pkg)
126 & src .~ pkgSource pkg
128 & src .~ pkgSource pkg
129+ & subpath .~ (fromMaybe "." optSubpath)
127 & runHaddock .~ optHaddock
130 & runHaddock .~ optHaddock
128 & jailbreak .~ optJailbreak
131 & jailbreak .~ optJailbreak
129 & hyperlinkSource .~ optHyperlinkSource
132 & hyperlinkSource .~ optHyperlinkSource
package.yaml+1
@@ -29,6 +29,7 @@ author:
29 - Felix Kunzmann
29 - Felix Kunzmann
30 - Gabriel Ebner
30 - Gabriel Ebner
31 - Gergely Risko
31 - Gergely Risko
32+ - Jacob Mitchell
32 - Joachim Fasting
33 - Joachim Fasting
33 - John Albietz
34 - John Albietz
34 - John Chee
35 - John Chee
src/Distribution/Nixpkgs/Fetch.hs+3−2
@@ -31,6 +31,7 @@ data Source = Source
31 , sourceRevision :: String -- ^ Revision to use. For protocols where this doesn't make sense (such as HTTP), this
31 , sourceRevision :: String -- ^ Revision to use. For protocols where this doesn't make sense (such as HTTP), this
32 -- should be the empty string.
32 -- should be the empty string.
33 , sourceHash :: Hash -- ^ The expected hash of the source, if available.
33 , sourceHash :: Hash -- ^ The expected hash of the source, if available.
34+ , sourceCabalDir :: String -- ^ Directory where Cabal file is found.
34 } deriving (Show, Eq, Ord, Generic)
35 } deriving (Show, Eq, Ord, Generic)
35
36
36instance NFData Source
37instance NFData Source
@@ -68,7 +69,7 @@ instance FromJSON DerivationSource where
68 parseJSON _ = error "invalid DerivationSource"
69 parseJSON _ = error "invalid DerivationSource"
69
70
70fromDerivationSource :: DerivationSource -> Source
71fromDerivationSource :: DerivationSource -> Source
71−fromDerivationSource DerivationSource{..} = Source derivUrl derivRevision $ Certain derivHash
72+fromDerivationSource DerivationSource{..} = Source derivUrl derivRevision (Certain derivHash) "."
72
73
73-- | Fetch a source, trying any of the various nix-prefetch-* scripts.
74-- | Fetch a source, trying any of the various nix-prefetch-* scripts.
74fetch :: forall a. (String -> MaybeT IO a) -- ^ This function is passed the output path name as an argument.
75fetch :: forall a. (String -> MaybeT IO a) -- ^ This function is passed the output path name as an argument.
@@ -104,7 +105,7 @@ fetch f = runMaybeT . fetchers where
104 localArchive :: FilePath -> MaybeT IO (DerivationSource, a)
105 localArchive :: FilePath -> MaybeT IO (DerivationSource, a)
105 localArchive path = do
106 localArchive path = do
106 absolutePath <- liftIO $ canonicalizePath path
107 absolutePath <- liftIO $ canonicalizePath path
107− unpacked <- snd <$> fetchWith (False, "zip", []) (Source ("file://" ++ absolutePath) "" UnknownHash)
108+ unpacked <- snd <$> fetchWith (False, "zip", []) (Source ("file://" ++ absolutePath) "" UnknownHash ".")
108 process (DerivationSource "" absolutePath "" "", unpacked)
109 process (DerivationSource "" absolutePath "" "", unpacked)
109
110
110 process :: (DerivationSource, FilePath) -> MaybeT IO (DerivationSource, a)
111 process :: (DerivationSource, FilePath) -> MaybeT IO (DerivationSource, a)
src/Distribution/Nixpkgs/Haskell/Derivation.hs+9−1
@@ -4,7 +4,7 @@
4{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
4{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
5
5
6module Distribution.Nixpkgs.Haskell.Derivation
6module Distribution.Nixpkgs.Haskell.Derivation
7− ( Derivation, nullDerivation, pkgid, revision, src, isLibrary, isExecutable
7+ ( Derivation, nullDerivation, pkgid, revision, src, subpath, isLibrary, isExecutable
8 , extraFunctionArgs, libraryDepends, executableDepends, testDepends, configureFlags
8 , extraFunctionArgs, libraryDepends, executableDepends, testDepends, configureFlags
9 , cabalFlags, runHaddock, jailbreak, doCheck, testTarget, hyperlinkSource, enableSplitObjs
9 , cabalFlags, runHaddock, jailbreak, doCheck, testTarget, hyperlinkSource, enableSplitObjs
10 , enableLibraryProfiling, enableExecutableProfiling, phaseOverrides, editedCabalFile, metaSection
10 , enableLibraryProfiling, enableExecutableProfiling, phaseOverrides, editedCabalFile, metaSection
@@ -36,6 +36,7 @@ data Derivation = MkDerivation
36 { _pkgid :: PackageIdentifier
36 { _pkgid :: PackageIdentifier
37 , _revision :: Int
37 , _revision :: Int
38 , _src :: DerivationSource
38 , _src :: DerivationSource
39+ , _subpath :: FilePath
39 , _isLibrary :: Bool
40 , _isLibrary :: Bool
40 , _isExecutable :: Bool
41 , _isExecutable :: Bool
41 , _extraFunctionArgs :: Set Binding
42 , _extraFunctionArgs :: Set Binding
@@ -65,6 +66,7 @@ nullDerivation = MkDerivation
65 { _pkgid = error "undefined Derivation.pkgid"
66 { _pkgid = error "undefined Derivation.pkgid"
66 , _revision = error "undefined Derivation.revision"
67 , _revision = error "undefined Derivation.revision"
67 , _src = error "undefined Derivation.src"
68 , _src = error "undefined Derivation.src"
69+ , _subpath = error "undefined Derivation.subpath"
68 , _isLibrary = error "undefined Derivation.isLibrary"
70 , _isLibrary = error "undefined Derivation.isLibrary"
69 , _isExecutable = error "undefined Derivation.isExecutable"
71 , _isExecutable = error "undefined Derivation.isExecutable"
70 , _extraFunctionArgs = error "undefined Derivation.extraFunctionArgs"
72 , _extraFunctionArgs = error "undefined Derivation.extraFunctionArgs"
@@ -104,6 +106,7 @@ instance Pretty Derivation where
104 [ attr "pname" $ doubleQuotes $ disp (packageName _pkgid)
106 [ attr "pname" $ doubleQuotes $ disp (packageName _pkgid)
105 , attr "version" $ doubleQuotes $ disp (packageVersion _pkgid)
107 , attr "version" $ doubleQuotes $ disp (packageVersion _pkgid)
106 , sourceAttr _src
108 , sourceAttr _src
109+ , onlyIf (_subpath /= ".") $ attr "postUnpack" postUnpack
107 , onlyIf (_revision > 0) $ attr "revision" $ doubleQuotes $ int _revision
110 , onlyIf (_revision > 0) $ attr "revision" $ doubleQuotes $ int _revision
108 , onlyIf (not (null _editedCabalFile) && _revision > 0) $ attr "editedCabalFile" $ string _editedCabalFile
111 , onlyIf (not (null _editedCabalFile) && _revision > 0) $ attr "editedCabalFile" $ string _editedCabalFile
109 , listattr "configureFlags" empty (map (show . show) renderedFlags)
112 , listattr "configureFlags" empty (map (show . show) renderedFlags)
@@ -149,3 +152,8 @@ instance Pretty Derivation where
149 , rbrace <> semi
152 , rbrace <> semi
150 ]
153 ]
151 | otherwise = attr "src" $ text derivUrl
154 | otherwise = attr "src" $ text derivUrl
155+
156+ postUnpack = doubleQuotes $ vcat
157+ [ text "sourceRoot=\\${sourceRoot}/" <> text _subpath
158+ , text "echo Source root reset to \\${sourceRoot}"
159+ ]
src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs+7−7
@@ -32,18 +32,18 @@ data Package = Package
32getPackage :: Maybe String -> Source -> IO Package
32getPackage :: Maybe String -> Source -> IO Package
33getPackage optHackageDB source = do
33getPackage optHackageDB source = do
34 (derivSource, pkgDesc) <- fetchOrFromDB optHackageDB source
34 (derivSource, pkgDesc) <- fetchOrFromDB optHackageDB source
35− flip Package pkgDesc <$> maybe (sourceFromHackage (sourceHash source) $ showPackageIdentifier pkgDesc) return derivSource
35+ flip Package pkgDesc <$> maybe (sourceFromHackage (sourceHash source) (showPackageIdentifier pkgDesc) $ sourceCabalDir source) return derivSource
36
36
37
37
38fetchOrFromDB :: Maybe String -> Source -> IO (Maybe DerivationSource, Cabal.GenericPackageDescription)
38fetchOrFromDB :: Maybe String -> Source -> IO (Maybe DerivationSource, Cabal.GenericPackageDescription)
39fetchOrFromDB optHackageDB src
39fetchOrFromDB optHackageDB src
40 | "cabal://" `isPrefixOf` sourceUrl src = fmap ((,) Nothing) . fromDB optHackageDB . drop (length "cabal://") $ sourceUrl src
40 | "cabal://" `isPrefixOf` sourceUrl src = fmap ((,) Nothing) . fromDB optHackageDB . drop (length "cabal://") $ sourceUrl src
41 | otherwise = do
41 | otherwise = do
42− r <- fetch cabalFromPath src
42+ r <- fetch (\dir -> cabalFromPath (dir </> sourceCabalDir src)) src
43 case r of
43 case r of
44 Nothing ->
44 Nothing ->
45 hPutStrLn stderr "*** failed to fetch source. Does the URL exist?" >> exitFailure
45 hPutStrLn stderr "*** failed to fetch source. Does the URL exist?" >> exitFailure
46− Just (derivSource, (externalSource, pkgDesc)) ->
46+ Just (derivSource, (externalSource, pkgDesc)) -> do
47 return (derivSource <$ guard externalSource, pkgDesc)
47 return (derivSource <$ guard externalSource, pkgDesc)
48
48
49fromDB :: Maybe String -> String -> IO Cabal.GenericPackageDescription
49fromDB :: Maybe String -> String -> IO Cabal.GenericPackageDescription
@@ -77,8 +77,8 @@ hashCachePath pid = do
77 createDirectoryIfMissing True cacheDir
77 createDirectoryIfMissing True cacheDir
78 return $ cacheDir </> pid <.> "sha256"
78 return $ cacheDir </> pid <.> "sha256"
79
79
80−sourceFromHackage :: Hash -> String -> IO DerivationSource
80+sourceFromHackage :: Hash -> String -> String -> IO DerivationSource
81−sourceFromHackage optHash pkgId = do
81+sourceFromHackage optHash pkgId cabalDir = do
82 cacheFile <- hashCachePath pkgId
82 cacheFile <- hashCachePath pkgId
83 cachedHash <-
83 cachedHash <-
84 case optHash of
84 case optHash of
@@ -99,7 +99,7 @@ sourceFromHackage optHash pkgId = do
99 seq (length hash) $
99 seq (length hash) $
100 DerivationSource "url" url "" hash <$ writeFile cacheFile hash
100 DerivationSource "url" url "" hash <$ writeFile cacheFile hash
101 UnknownHash -> do
101 UnknownHash -> do
102− maybeHash <- runMaybeT (derivHash . fst <$> fetchWith (False, "url", []) (Source url "" UnknownHash))
102+ maybeHash <- runMaybeT (derivHash . fst <$> fetchWith (False, "url", []) (Source url "" UnknownHash cabalDir))
103 case maybeHash of
103 case maybeHash of
104 Just hash ->
104 Just hash ->
105 seq (length hash) $
105 seq (length hash) $
@@ -133,7 +133,7 @@ cabalFromDirectory dir = do
133 cabals <- liftIO $ getDirectoryContents dir >>= filterM doesFileExist . map (dir </>) . filter (".cabal" `isSuffixOf`)
133 cabals <- liftIO $ getDirectoryContents dir >>= filterM doesFileExist . map (dir </>) . filter (".cabal" `isSuffixOf`)
134 case cabals of
134 case cabals of
135 [cabalFile] -> cabalFromFile True cabalFile
135 [cabalFile] -> cabalFromFile True cabalFile
136− _ -> liftIO $ hPutStrLn stderr "*** found zero or more than one cabal file. Exiting." >> exitFailure
136+ _ -> liftIO $ hPutStrLn stderr ("*** found zero or more than one cabal file (" ++ show cabals ++ "). Exiting.") >> exitFailure
137
137
138handleIO :: (Exception.IOException -> IO a) -> IO a -> IO a
138handleIO :: (Exception.IOException -> IO a) -> IO a -> IO a
139handleIO = Exception.handle
139handleIO = Exception.handle