mirror of
https://github.com/nmattia/niv.git
synced 2024-09-18 19:07:19 +03:00
Add the attribute 'type' to set the package URL type
The main objective is to be able to fetch packages that are just a file which was not possible. The value of this attribute is either 'file' or 'tarball'. By default, the value of this attribute is inferred by using the suffix of the URL. If the URL ends with 'tar.gz' the type is set to 'tarball', otherwise it is 'file'. This attribute is used by the Nix expression to select the appropriate fetcher ('fetchurl' or 'fetchTarball') and by `nix-prefetch-url` to set or not the `--unpack` flag.
This commit is contained in:
parent
47cd53f704
commit
d23a8626a0
49
Main.hs
49
Main.hs
@ -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
|
||||
|]
|
||||
|
10
README.md
10
README.md
@ -214,7 +214,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:
|
||||
@ -226,6 +226,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
|
||||
|
||||
```
|
||||
@ -241,7 +244,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:
|
||||
@ -252,6 +255,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
|
||||
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user