1
1
mirror of https://github.com/nmattia/niv.git synced 2024-11-07 22:36:53 +03:00

Merge pull request #27 from nlewo/fetcher

Add `fetcher` options
This commit is contained in:
Nicolas Mattia 2019-03-05 18:59:22 +01:00 committed by GitHub
commit 3386273b6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 9 deletions

49
Main.hs
View File

@ -13,6 +13,7 @@ import Control.Monad
import Control.Monad.State
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
import Data.Char (toUpper)
import Data.Functor ((<&>))
import Data.Hashable (Hashable)
import Data.Maybe (mapMaybe, fromMaybe)
import Data.String.QQ (s)
@ -100,6 +101,12 @@ parsePackageSpec =
Opts.short 't' <>
Opts.metavar "URL" <>
Opts.help "Used during 'update' when building URL. Occurrences of <foo> are replaced with attribute 'foo'."
)) <|>
(("type",) <$> Opts.strOption
( Opts.long "type" <>
Opts.short 'T' <>
Opts.metavar "TYPE" <>
Opts.help "The type of the URL target. The value can be either 'file' or 'tarball'. If not set, the value is inferred from the suffix of the URL."
))
-- Parse "key=val" into ("key", "val")
@ -153,6 +160,20 @@ updatePackageSpec = execStateT $ do
_ -> pure ()
)
-- If the type attribute is not set, we try to infer its value based on the url suffix
(,) <$> getPackageSpecAttr "type" <*> getPackageSpecAttr "url" >>= \case
-- If an url type is set, we'll use it
(Just _, _) -> pure ()
-- We need an url to infer a url type
(_, Nothing) -> pure ()
(Nothing, Just (Aeson.String url)) -> do
let urlType = if "tar.gz" `T.isSuffixOf` url
then "tarball"
else "file"
setPackageSpecAttr "type" (Aeson.String $ T.pack urlType)
-- If the JSON value is not a string, we ignore it
(_, _) -> pure ()
-- Updates the sha256 based on the URL contents
(,) <$> getPackageSpecAttr "url" <*> getPackageSpecAttr "sha256" >>= \case
-- If no URL is set, we simply can't prefetch
@ -167,7 +188,11 @@ updatePackageSpec = execStateT $ do
prefetch :: Aeson.Value -> StateT PackageSpec IO ()
prefetch = \case
Aeson.String (T.unpack -> url) -> do
sha256 <- liftIO $ nixPrefetchURL url
unpack <- getPackageSpecAttr "type" <&> \case
-- Do not unpack if the url type is 'file'
Just (Aeson.String urlType) -> not $ T.unpack urlType == "file"
_ -> True
sha256 <- liftIO $ nixPrefetchURL unpack url
setPackageSpecAttr "sha256" (Aeson.String $ T.pack sha256)
_ -> pure ()
@ -564,12 +589,13 @@ abort msg = do
putStrLn msg
exitFailure
nixPrefetchURL :: String -> IO String
nixPrefetchURL url =
lines <$> readProcess "nix-prefetch-url" ["--unpack", url] "" >>=
nixPrefetchURL :: Bool -> String -> IO String
nixPrefetchURL unpack url =
lines <$> readProcess "nix-prefetch-url" args "" >>=
\case
(l:_) -> pure l
_ -> abortNixPrefetchExpectedOutput
where args = if unpack then ["--unpack", url] else [url]
-------------------------------------------------------------------------------
-- Files and their content
@ -583,7 +609,7 @@ pathNixSourcesNix = "nix" </> "sources.nix"
initNixSourcesNixContent :: String
initNixSourcesNixContent = [s|
# A record, from name to path, of the third-party packages
with
with rec
{
sources = builtins.fromJSON (builtins.readFile ./sources.json);
@ -597,8 +623,17 @@ with
mapAttrs = builtins.mapAttrs or
(f: set: with builtins;
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)));
};
getFetcher = spec:
let fetcherName =
if builtins.hasAttr "type" spec
then builtins.getAttr "type" spec
else "tarball";
in builtins.getAttr fetcherName {
"tarball" = builtins.fetchTarball;
"file" = builtins.fetchurl;
};
};
# NOTE: spec must _not_ have an "outPath" attribute
mapAttrs (_: spec:
if builtins.hasAttr "outPath" spec
@ -608,7 +643,7 @@ mapAttrs (_: spec:
if builtins.hasAttr "url" spec && builtins.hasAttr "sha256" spec
then
spec //
{ outPath = fetchTarball { inherit (spec) url sha256; } ; }
{ outPath = getFetcher spec { inherit (spec) url sha256; } ; }
else spec
) sources
|]

View File

@ -220,7 +220,7 @@ Examples:
Usage: niv add [-n|--name NAME] PACKAGE ([-a|--attribute KEY=VAL] |
[-b|--branch BRANCH] | [-o|--owner OWNER] | [-r|--repo REPO] |
[-v|--version VERSION] | [-t|--template URL])
[-v|--version VERSION] | [-t|--template URL] | [-T|--type TYPE])
Add dependency
Available options:
@ -232,6 +232,9 @@ Available options:
-v,--version VERSION Equivalent to --attribute version=<VERSION>
-t,--template URL Used during 'update' when building URL. Occurrences
of <foo> are replaced with attribute 'foo'.
-T,--type TYPE The type of the URL target. The value can be either
'file' or 'tarball'. If not set, the value is
inferred from the suffix of the URL.
-h,--help Show this help text
```
@ -247,7 +250,7 @@ Examples:
Usage: niv update [PACKAGE] ([-a|--attribute KEY=VAL] | [-b|--branch BRANCH] |
[-o|--owner OWNER] | [-r|--repo REPO] | [-v|--version VERSION]
| [-t|--template URL])
| [-t|--template URL] | [-T|--type TYPE])
Update dependencies
Available options:
@ -258,6 +261,9 @@ Available options:
-v,--version VERSION Equivalent to --attribute version=<VERSION>
-t,--template URL Used during 'update' when building URL. Occurrences
of <foo> are replaced with attribute 'foo'.
-T,--type TYPE The type of the URL target. The value can be either
'file' or 'tarball'. If not set, the value is
inferred from the suffix of the URL.
-h,--help Show this help text
```