mirror of
https://github.com/nmattia/niv.git
synced 2024-11-12 23:06:35 +03:00
Allow JSON attributes values with -a foo=bar
This commit is contained in:
parent
d9e35d67d8
commit
271677ec6e
18
README.md
18
README.md
@ -227,13 +227,17 @@ Examples:
|
|||||||
niv add my-package -v alpha-0.1 -t http://example.com/archive/<version>.zip
|
niv add my-package -v alpha-0.1 -t http://example.com/archive/<version>.zip
|
||||||
|
|
||||||
Usage: niv add [-n|--name NAME] PACKAGE ([-a|--attribute KEY=VAL] |
|
Usage: niv add [-n|--name NAME] PACKAGE ([-a|--attribute KEY=VAL] |
|
||||||
[-b|--branch BRANCH] | [-o|--owner OWNER] | [-r|--repo REPO] |
|
[-s|--string-attribute KEY=VAL] | [-b|--branch BRANCH] |
|
||||||
[-v|--version VERSION] | [-t|--template URL] | [-T|--type TYPE])
|
[-o|--owner OWNER] | [-r|--repo REPO] | [-v|--version VERSION] |
|
||||||
|
[-t|--template URL] | [-T|--type TYPE])
|
||||||
Add dependency
|
Add dependency
|
||||||
|
|
||||||
Available options:
|
Available options:
|
||||||
-n,--name NAME Set the package name to <NAME>
|
-n,--name NAME Set the package name to <NAME>
|
||||||
-a,--attribute KEY=VAL Set the package spec attribute <KEY> to <VAL>
|
-a,--attribute KEY=VAL Set the package spec attribute <KEY> to <VAL>, where
|
||||||
|
<VAL> may be JSON.
|
||||||
|
-s,--string-attribute KEY=VAL
|
||||||
|
Set the package spec attribute <KEY> to <VAL>.
|
||||||
-b,--branch BRANCH Equivalent to --attribute branch=<BRANCH>
|
-b,--branch BRANCH Equivalent to --attribute branch=<BRANCH>
|
||||||
-o,--owner OWNER Equivalent to --attribute owner=<OWNER>
|
-o,--owner OWNER Equivalent to --attribute owner=<OWNER>
|
||||||
-r,--repo REPO Equivalent to --attribute repo=<REPO>
|
-r,--repo REPO Equivalent to --attribute repo=<REPO>
|
||||||
@ -256,13 +260,17 @@ Examples:
|
|||||||
niv update nixpkgs # update nixpkgs
|
niv update nixpkgs # update nixpkgs
|
||||||
niv update my-package -v beta-0.2 # update my-package to version "beta-0.2"
|
niv update my-package -v beta-0.2 # update my-package to version "beta-0.2"
|
||||||
|
|
||||||
Usage: niv update [PACKAGE] ([-a|--attribute KEY=VAL] | [-b|--branch BRANCH] |
|
Usage: niv update [PACKAGE] ([-a|--attribute KEY=VAL] |
|
||||||
|
[-s|--string-attribute KEY=VAL] | [-b|--branch BRANCH] |
|
||||||
[-o|--owner OWNER] | [-r|--repo REPO] | [-v|--version VERSION]
|
[-o|--owner OWNER] | [-r|--repo REPO] | [-v|--version VERSION]
|
||||||
| [-t|--template URL] | [-T|--type TYPE])
|
| [-t|--template URL] | [-T|--type TYPE])
|
||||||
Update dependencies
|
Update dependencies
|
||||||
|
|
||||||
Available options:
|
Available options:
|
||||||
-a,--attribute KEY=VAL Set the package spec attribute <KEY> to <VAL>
|
-a,--attribute KEY=VAL Set the package spec attribute <KEY> to <VAL>, where
|
||||||
|
<VAL> may be JSON.
|
||||||
|
-s,--string-attribute KEY=VAL
|
||||||
|
Set the package spec attribute <KEY> to <VAL>.
|
||||||
-b,--branch BRANCH Equivalent to --attribute branch=<BRANCH>
|
-b,--branch BRANCH Equivalent to --attribute branch=<BRANCH>
|
||||||
-o,--owner OWNER Equivalent to --attribute owner=<OWNER>
|
-o,--owner OWNER Equivalent to --attribute owner=<OWNER>
|
||||||
-r,--repo REPO Equivalent to --attribute repo=<REPO>
|
-r,--repo REPO Equivalent to --attribute repo=<REPO>
|
||||||
|
@ -11,6 +11,8 @@ module Niv.Cli where
|
|||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Data.Aeson ((.=))
|
import Data.Aeson ((.=))
|
||||||
|
import Data.Bifunctor
|
||||||
|
import Data.Maybe
|
||||||
import Data.Char (isSpace)
|
import Data.Char (isSpace)
|
||||||
import Data.Functor
|
import Data.Functor
|
||||||
import Data.HashMap.Strict.Extended
|
import Data.HashMap.Strict.Extended
|
||||||
@ -70,45 +72,57 @@ parsePackageName = PackageName <$>
|
|||||||
|
|
||||||
parsePackageSpec :: Opts.Parser PackageSpec
|
parsePackageSpec :: Opts.Parser PackageSpec
|
||||||
parsePackageSpec =
|
parsePackageSpec =
|
||||||
(PackageSpec . HMS.fromList . fmap fixupAttributes) <$>
|
(PackageSpec . HMS.fromList) <$>
|
||||||
many parseAttribute
|
many parseAttribute
|
||||||
where
|
where
|
||||||
parseAttribute :: Opts.Parser (T.Text, T.Text)
|
parseAttribute :: Opts.Parser (T.Text, Aeson.Value)
|
||||||
parseAttribute =
|
parseAttribute =
|
||||||
Opts.option (Opts.maybeReader parseKeyVal)
|
Opts.option (Opts.maybeReader parseKeyValJSON)
|
||||||
( Opts.long "attribute" <>
|
( Opts.long "attribute" <>
|
||||||
Opts.short 'a' <>
|
Opts.short 'a' <>
|
||||||
Opts.metavar "KEY=VAL" <>
|
Opts.metavar "KEY=VAL" <>
|
||||||
Opts.help "Set the package spec attribute <KEY> to <VAL>"
|
Opts.help "Set the package spec attribute <KEY> to <VAL>, where <VAL> may be JSON."
|
||||||
) <|> shortcutAttributes <|>
|
) <|>
|
||||||
(("url_template",) <$> Opts.strOption
|
Opts.option (Opts.maybeReader (parseKeyVal (Aeson.String . T.pack)))
|
||||||
|
( Opts.long "string-attribute" <>
|
||||||
|
Opts.short 's' <>
|
||||||
|
Opts.metavar "KEY=VAL" <>
|
||||||
|
Opts.help "Set the package spec attribute <KEY> to <VAL>."
|
||||||
|
) <|>
|
||||||
|
shortcutAttributes <|>
|
||||||
|
((\x -> ("url_template",Aeson.String x)) <$> Opts.strOption
|
||||||
( Opts.long "template" <>
|
( Opts.long "template" <>
|
||||||
Opts.short 't' <>
|
Opts.short 't' <>
|
||||||
Opts.metavar "URL" <>
|
Opts.metavar "URL" <>
|
||||||
Opts.help "Used during 'update' when building URL. Occurrences of <foo> are replaced with attribute 'foo'."
|
Opts.help "Used during 'update' when building URL. Occurrences of <foo> are replaced with attribute 'foo'."
|
||||||
)) <|>
|
)) <|>
|
||||||
(("type",) <$> Opts.strOption
|
((\x -> ("type", Aeson.String x)) <$> Opts.strOption
|
||||||
( Opts.long "type" <>
|
( Opts.long "type" <>
|
||||||
Opts.short 'T' <>
|
Opts.short 'T' <>
|
||||||
Opts.metavar "TYPE" <>
|
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."
|
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")
|
parseKeyValJSON = parseKeyVal $ \x ->
|
||||||
parseKeyVal :: String -> Maybe (T.Text, T.Text)
|
fromMaybe (Aeson.String $ T.pack x) (Aeson.decodeStrict (B8.pack x))
|
||||||
parseKeyVal str = case span (/= '=') str of
|
|
||||||
(key, '=':val) -> Just (T.pack key, T.pack val)
|
-- Parse "key=val" into ("key", val)
|
||||||
|
parseKeyVal
|
||||||
|
:: (String -> Aeson.Value) -- ^ how to convert to JSON
|
||||||
|
-> String -> Maybe (T.Text, Aeson.Value)
|
||||||
|
parseKeyVal toJSON str = case span (/= '=') str of
|
||||||
|
(key, '=':val) -> Just (T.pack key, toJSON val)
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
-- Shortcuts for common attributes
|
-- Shortcuts for common attributes
|
||||||
shortcutAttributes :: Opts.Parser (T.Text, T.Text)
|
shortcutAttributes :: Opts.Parser (T.Text, Aeson.Value)
|
||||||
shortcutAttributes = foldr (<|>) empty $ mkShortcutAttribute <$>
|
shortcutAttributes = foldr (<|>) empty $ mkShortcutAttribute <$>
|
||||||
[ "branch", "owner", "repo", "version" ]
|
[ "branch", "owner", "repo", "version" ]
|
||||||
|
|
||||||
-- TODO: infer those shortcuts from 'Update' keys
|
-- TODO: infer those shortcuts from 'Update' keys
|
||||||
mkShortcutAttribute :: T.Text -> Opts.Parser (T.Text, T.Text)
|
mkShortcutAttribute :: T.Text -> Opts.Parser (T.Text, Aeson.Value)
|
||||||
mkShortcutAttribute = \case
|
mkShortcutAttribute = \case
|
||||||
attr@(T.uncons -> Just (c,_)) -> (attr,) <$> Opts.strOption
|
attr@(T.uncons -> Just (c,_)) -> fmap (second Aeson.String) $ (attr,) <$> Opts.strOption
|
||||||
( Opts.long (T.unpack attr) <>
|
( Opts.long (T.unpack attr) <>
|
||||||
Opts.short c <>
|
Opts.short c <>
|
||||||
Opts.metavar (T.unpack $ T.toUpper attr) <>
|
Opts.metavar (T.unpack $ T.toUpper attr) <>
|
||||||
@ -120,9 +134,6 @@ parsePackageSpec =
|
|||||||
)
|
)
|
||||||
_ -> empty
|
_ -> empty
|
||||||
|
|
||||||
fixupAttributes :: (T.Text, T.Text) -> (T.Text, Aeson.Value)
|
|
||||||
fixupAttributes (k, v) = (k, Aeson.String v)
|
|
||||||
|
|
||||||
parsePackage :: Opts.Parser (PackageName, PackageSpec)
|
parsePackage :: Opts.Parser (PackageName, PackageSpec)
|
||||||
parsePackage = (,) <$> parsePackageName <*> parsePackageSpec
|
parsePackage = (,) <$> parsePackageName <*> parsePackageSpec
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user