Skip to content

Commit e00f3ee

Browse files
authored
Better support for file: urls in repositories (#1915)
If you have a repository whose URL is a `file:` URL, then you will end up with package sources being specified by `fetchurl` calls with `file:` URLs. Now, in principle `curl` can fetch from `file:` URLs, but the Nix sandbox isn't relaxed in the right way to allow it to see the file (just the internet!). We can get around this by using `builtins.path` instead.
1 parent 78dd45b commit e00f3ee

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

nix-tools/lib/Cabal2Nix.hs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import Distribution.Package
2121
import qualified System.FilePath.Posix as FilePath.Posix
2222
( joinPath, splitDirectories )
2323
import Network.URI
24-
( URI(uriAuthority, uriPath), URIAuth(..), parseURI )
24+
( URI(uriAuthority, uriPath, uriScheme), URIAuth(..), parseURI )
2525

2626
import Distribution.Types.CondTree
2727
import Distribution.Types.Library
@@ -221,14 +221,35 @@ toNixPackageDescription isLocal detailLevel pd = mkNonRecSet $
221221
srcToNix :: PackageIdentifier -> Src -> NExpr
222222
srcToNix _ (Path p) = mkRecSet [ "src" $= applyMkDefault (mkRelPath p) ]
223223
srcToNix pi' (Repo url mHash)
224-
= mkNonRecSet
225-
[ "src" $= applyMkDefault (mkSym pkgs @. "fetchurl" @@ mkNonRecSet
226-
[ "url" $= mkStr (fromString . show $ mkPrivateHackageUrl url pi')
227-
, "sha256" $= case mHash of
228-
Nothing -> mkSym "config" @. "sha256"
229-
Just hash -> mkStr (fromString hash)
230-
])
231-
]
224+
= let uri = mkPrivateHackageUrl url pi'
225+
in if "file:" == uriScheme uri
226+
then
227+
-- It's a file: URL. In principle curl can fetch file URLs, but in
228+
-- practice fetchurl can't. This is (I believe) because the Nix sandbox
229+
-- is relaxed to allow fetchurl to access the internet, but _not_ to
230+
-- let is access random files, even if it has a hash specified.
231+
-- But builtins.path can do that, so we just use that instead.
232+
mkNonRecSet
233+
[ "src" $= applyMkDefault (mkSym "builtins" @. "path" @@ mkNonRecSet
234+
[ "path" $= mkStr (fromString $ uriPath uri)
235+
, "sha256" $= case mHash of
236+
Nothing -> mkSym "config" @. "sha256"
237+
Just hash -> mkStr (fromString hash)
238+
-- needed for the hash to match what you would use for fetchurl
239+
, "recursive" $= mkBool False
240+
])
241+
]
242+
else
243+
-- It's some other kind of URL, just use fetchurl and hope curl
244+
-- can fetch it.
245+
mkNonRecSet
246+
[ "src" $= applyMkDefault (mkSym pkgs @. "fetchurl" @@ mkNonRecSet
247+
[ "url" $= mkStr (fromString . show $ uri)
248+
, "sha256" $= case mHash of
249+
Nothing -> mkSym "config" @. "sha256"
250+
Just hash -> mkStr (fromString hash)
251+
])
252+
]
232253
srcToNix _ (Git url rev mbSha256 mbPath)
233254
= mkNonRecSet $
234255
[ "src" $= applyMkDefault (mkSym pkgs @. "fetchgit" @@ mkNonRecSet

0 commit comments

Comments
 (0)