Skip to content

Commit 321fd52

Browse files
committed
Fix multiple download issue in stack-to-nix
1 parent 3e8c06a commit 321fd52

File tree

4 files changed

+45
-42
lines changed

4 files changed

+45
-42
lines changed

nix-tools/cabal2nix/Main.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ main = getArgs >>= \case
4444
[url,hash] | "http" `isPrefixOf` url ->
4545
let subdir = "." in
4646
fetch (\dir -> cabalFromPath url hash subdir $ dir </> subdir)
47-
(Source url mempty UnknownHash subdir) >>= \case
47+
(Source url mempty UnknownHash) >>= \case
4848
(Just (DerivationSource{..}, genBindings)) -> genBindings derivHash
4949
_ -> return ()
5050
[path,file] -> doesDirectoryExist file >>= \case

nix-tools/lib/Distribution/Nixpkgs/Fetch.hs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ data Source = Source
3131
, sourceRevision :: String -- ^ Revision to use. For protocols where this doesn't make sense (such as HTTP), this
3232
-- should be the empty string.
3333
, sourceHash :: Hash -- ^ The expected hash of the source, if available.
34-
, sourceCabalDir :: String -- ^ Directory where Cabal file is found.
3534
} deriving (Show, Eq, Ord, Generic)
3635

3736
instance NFData Source
@@ -69,24 +68,26 @@ instance FromJSON DerivationSource where
6968
parseJSON _ = error "invalid DerivationSource"
7069

7170
fromDerivationSource :: DerivationSource -> Source
72-
fromDerivationSource DerivationSource{..} = Source derivUrl derivRevision (Certain derivHash) "."
71+
fromDerivationSource DerivationSource{..} = Source derivUrl derivRevision (Certain derivHash)
72+
73+
firstJust :: Monad m => [m (Maybe a)] -> m (Maybe a)
74+
firstJust [] = pure Nothing
75+
firstJust (x:xs) = x >>= maybe (firstJust xs) (pure . Just)
7376

7477
-- | Fetch a source, trying any of the various nix-prefetch-* scripts.
7578
fetch :: forall a. (String -> MaybeT IO a) -- ^ This function is passed the output path name as an argument.
7679
-- It should return 'Nothing' if the file doesn't match the expected format.
7780
-- This is required, because we cannot always check if a download succeeded otherwise.
7881
-> Source -- ^ The source to fetch from.
7982
-> IO (Maybe (DerivationSource, a)) -- ^ The derivation source and the result of the processing function. Returns Nothing if the download failed.
80-
fetch f = runMaybeT . fetchers where
81-
fetchers :: Source -> MaybeT IO (DerivationSource, a)
82-
fetchers source = msum . (fetchLocal source :) $ map (\fetcher -> fetchWith fetcher source >>= process)
83-
[ (False, "url", [])
84-
, (True, "git", ["--fetch-submodules"])
83+
fetch f source = firstJust . map runMaybeT . (fetchLocal source :) $ map (\fetcher -> fetchWith fetcher source >>= process)
84+
[ (True, "git", ["--fetch-submodules"])
8585
, (True, "hg", [])
8686
, (True, "svn", [])
8787
, (True, "bzr", [])
88+
, (False, "url", [])
8889
]
89-
90+
where
9091
-- | Remove '/' from the end of the path. Nix doesn't accept paths that
9192
-- end in a slash.
9293
stripSlashSuffix :: String -> String
@@ -105,7 +106,7 @@ fetch f = runMaybeT . fetchers where
105106
localArchive :: FilePath -> MaybeT IO (DerivationSource, a)
106107
localArchive path = do
107108
absolutePath <- liftIO $ canonicalizePath path
108-
unpacked <- snd <$> fetchWith (False, "url", ["--unpack"]) (Source ("file://" ++ absolutePath) "" UnknownHash ".")
109+
unpacked <- snd <$> fetchWith (False, "url", ["--unpack"]) (Source ("file://" ++ absolutePath) "" UnknownHash)
109110
process (DerivationSource "" absolutePath "" "", unpacked)
110111

111112
process :: (DerivationSource, FilePath) -> MaybeT IO (DerivationSource, a)

nix-tools/lib/Stack2nix.hs

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module Stack2nix
88

99
import qualified Data.Text as T
1010
import Data.String (fromString)
11+
import Data.Maybe (fromMaybe)
1112

1213
import Control.Monad.Trans.Maybe
1314
import Control.Monad.IO.Class (liftIO)
@@ -161,42 +162,43 @@ packages2nix args pkgs =
161162
prettyNix <$> cabal2nix True (argDetailLevel args) src cabalFile
162163
return (fromString pkg, fromString pkg $= mkPath False nix)
163164
(DVCS (Git url rev) _ subdirs) ->
164-
fmap concat . forM subdirs $ \subdir ->
165-
do cacheHits <- liftIO $ cacheHits (argCacheFile args) url rev subdir
166-
case cacheHits of
167-
[] -> do
168-
fetch (\dir -> cabalFromPath url rev subdir $ dir </> subdir)
169-
(Source url rev UnknownHash subdir) >>= \case
170-
(Just (DerivationSource{..}, genBindings)) -> genBindings derivHash
171-
_ -> return []
172-
hits ->
173-
forM hits $ \( pkg, nix ) -> do
165+
do hits <- forM subdirs $ \subdir -> liftIO $ cacheHits (argCacheFile args) url rev subdir
166+
if any null hits
167+
then
168+
fetch (return . cabalFromPath url rev subdirs)
169+
(Source url rev UnknownHash) >>= \case
170+
(Just (DerivationSource{..}, genBindings)) -> fromMaybe [] <$> runMaybeT (genBindings derivHash)
171+
_ -> return []
172+
else
173+
forM (concat hits) $ \( pkg, nix ) ->
174174
return (fromString pkg, fromString pkg $= mkPath False nix)
175175
_ -> return []
176176
where relPath = shortRelativePath (argOutputDir args) (dropFileName (argStackYaml args))
177177
cabalFromPath
178-
:: String -- URL
179-
-> String -- Revision
180-
-> FilePath -- Subdir
181-
-> FilePath -- Local Directory
182-
-> MaybeT IO (String -> IO [(T.Text, Binding NExpr)])
183-
cabalFromPath url rev subdir path = do
184-
d <- liftIO $ doesDirectoryExist path
185-
unless d $ fail ("not a directory: " ++ path)
186-
cabalFiles <- liftIO $ findCabalFiles (argHpackUse args) path
187-
return $ \sha256 ->
178+
:: String -- URL
179+
-> String -- Revision
180+
-> [FilePath] -- Subdirs
181+
-> FilePath -- Local Directory
182+
-> String -- Sha256
183+
-> MaybeT IO [(T.Text, Binding NExpr)]
184+
cabalFromPath url rev subdirs dir sha256 =
185+
fmap concat . forM subdirs $ \subdir -> do
186+
let path = dir </> subdir
187+
d <- liftIO $ doesDirectoryExist path
188+
unless d $ fail ("not a directory: " ++ path)
189+
cabalFiles <- liftIO $ findCabalFiles (argHpackUse args) path
188190
forM cabalFiles $ \cabalFile -> do
189-
let pkg = cabalFilePkgName cabalFile
190-
nix = pkg <.> "nix"
191-
nixFile = argOutputDir args </> nix
192-
subdir' = if subdir == "." then Nothing
193-
else Just subdir
194-
src = Just $ C2N.Git url rev (Just sha256) subdir'
195-
createDirectoryIfMissing True (takeDirectory nixFile)
196-
writeDoc nixFile =<<
197-
prettyNix <$> cabal2nix True (argDetailLevel args) src cabalFile
198-
liftIO $ appendCache (argCacheFile args) url rev subdir sha256 pkg nix
199-
return (fromString pkg, fromString pkg $= mkPath False nix)
191+
let pkg = cabalFilePkgName cabalFile
192+
nix = pkg <.> "nix"
193+
nixFile = argOutputDir args </> nix
194+
subdir' = if subdir == "." then Nothing
195+
else Just subdir
196+
src = Just $ C2N.Git url rev (Just sha256) subdir'
197+
liftIO $ createDirectoryIfMissing True (takeDirectory nixFile)
198+
liftIO $ writeDoc nixFile =<<
199+
prettyNix <$> cabal2nix True (argDetailLevel args) src cabalFile
200+
liftIO $ appendCache (argCacheFile args) url rev subdir sha256 pkg nix
201+
return (fromString pkg, fromString pkg $= mkPath False nix)
200202

201203
defaultNixContents :: String
202204
defaultNixContents = unlines

nix-tools/plan2nix/Plan2Nix.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ plan2nix args (Plan { packages, extras, compilerVersion, compilerPackages }) = d
9898
case cacheHits of
9999
[] -> do
100100
fetch (\dir -> cabalFromPath url rev subdir $ dir </> subdir)
101-
(Source url rev UnknownHash subdir) >>= \case
101+
(Source url rev UnknownHash) >>= \case
102102
(Just (DerivationSource{..}, genBindings)) -> genBindings derivHash
103103
_ -> return []
104104
hits ->

0 commit comments

Comments
 (0)