mirror of
https://github.com/nmattia/niv.git
synced 2024-12-01 15:56:03 +03:00
Fix parsing of subcommands
This commit is contained in:
parent
c8b5412835
commit
1e7abae029
10
README.md
10
README.md
@ -209,7 +209,7 @@ Available options:
|
|||||||
Available commands:
|
Available commands:
|
||||||
init Initialize a Nix project. Existing files won't be
|
init Initialize a Nix project. Existing files won't be
|
||||||
modified.
|
modified.
|
||||||
add Add dependency
|
add Add a GitHub dependency
|
||||||
show
|
show
|
||||||
update Update dependencies
|
update Update dependencies
|
||||||
modify Modify dependency
|
modify Modify dependency
|
||||||
@ -226,11 +226,11 @@ Examples:
|
|||||||
niv add NixOS/nixpkgs-channels -n nixpkgs -b nixos-19.03
|
niv add NixOS/nixpkgs-channels -n nixpkgs -b nixos-19.03
|
||||||
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 PACKAGE [-n|--name NAME] ([-a|--attribute KEY=VAL] |
|
||||||
[-s|--string-attribute KEY=VAL] | [-b|--branch BRANCH] |
|
[-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])
|
||||||
Add dependency
|
Add a GitHub dependency
|
||||||
|
|
||||||
Available options:
|
Available options:
|
||||||
-n,--name NAME Set the package name to <NAME>
|
-n,--name NAME Set the package name to <NAME>
|
||||||
@ -250,8 +250,8 @@ Available options:
|
|||||||
-h,--help Show this help text
|
-h,--help Show this help text
|
||||||
|
|
||||||
Experimental commands:
|
Experimental commands:
|
||||||
git Echo a message back
|
git Add a git dependency. Experimental.
|
||||||
github Add dependency
|
github Add a GitHub dependency
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ import Control.Applicative
|
|||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Data.Aeson ((.=))
|
import Data.Aeson ((.=))
|
||||||
import Data.Char (isSpace)
|
import Data.Char (isSpace)
|
||||||
import Data.Functor
|
|
||||||
import Data.HashMap.Strict.Extended
|
import Data.HashMap.Strict.Extended
|
||||||
import Data.Hashable (Hashable)
|
import Data.Hashable (Hashable)
|
||||||
import Data.String.QQ (s)
|
import Data.String.QQ (s)
|
||||||
@ -141,38 +140,67 @@ cmdInit = do
|
|||||||
parseCmdAdd :: Opts.ParserInfo (IO ())
|
parseCmdAdd :: Opts.ParserInfo (IO ())
|
||||||
parseCmdAdd =
|
parseCmdAdd =
|
||||||
Opts.info
|
Opts.info
|
||||||
((sp <|> shortcutGitHub) <**> Opts.helper) $
|
((parseCommands <|> parseShortcuts) <**> Opts.helper) $
|
||||||
(description githubCmd)
|
(description githubCmd)
|
||||||
where
|
where
|
||||||
shortcutGitHub = uncurry (cmdAdd (updateCmd githubCmd)) <$> parseArgs
|
-- XXX: this should parse many shortcuts (github, git). Right now we only
|
||||||
|
-- parse GitHub because the git interface is still experimental. note to
|
||||||
|
-- implementer: it'll be tricky to have the correct arguments show up
|
||||||
|
-- without repeating "PACKAGE PACKAGE PACKAGE" for every package type.
|
||||||
|
parseShortcuts = parseShortcut githubCmd
|
||||||
|
parseShortcut cmd = uncurry (cmdAdd (updateCmd cmd)) <$> (parseShortcutArgs cmd)
|
||||||
|
parseCmd cmd = uncurry (cmdAdd (updateCmd cmd)) <$> (parseCmdArgs cmd)
|
||||||
parseCmdAddGit =
|
parseCmdAddGit =
|
||||||
Opts.info
|
Opts.info (parseCmd gitCmd <**> Opts.helper) (description gitCmd)
|
||||||
(uncurry (cmdAdd (updateCmd gitCmd)) <$> parseArgs <**> Opts.helper) $
|
|
||||||
(description gitCmd)
|
|
||||||
parseCmdAddGitHub =
|
parseCmdAddGitHub =
|
||||||
Opts.info
|
Opts.info (parseCmd githubCmd <**> Opts.helper) (description githubCmd)
|
||||||
(uncurry (cmdAdd (updateCmd githubCmd)) <$> parseArgs <**> Opts.helper) $
|
parseCommands = Opts.subparser
|
||||||
(description githubCmd)
|
|
||||||
|
|
||||||
sp = Opts.subparser
|
|
||||||
( Opts.hidden <>
|
( Opts.hidden <>
|
||||||
Opts.commandGroup "Experimental commands:" <>
|
Opts.commandGroup "Experimental commands:" <>
|
||||||
Opts.command "git" parseCmdAddGit <>
|
Opts.command "git" parseCmdAddGit <>
|
||||||
Opts.command "github" parseCmdAddGitHub
|
Opts.command "github" parseCmdAddGitHub
|
||||||
)
|
)
|
||||||
|
|
||||||
parseArgs :: Opts.Parser (PackageName, Attrs)
|
-- | only used in shortcuts (niv add foo/bar ...) because PACKAGE is NOT
|
||||||
parseArgs = collapse <$> parseNameAndShortcut <*> (parsePackageSpec githubCmd)
|
-- optional
|
||||||
|
parseShortcutArgs :: Cmd -> Opts.Parser (PackageName, Attrs)
|
||||||
|
parseShortcutArgs cmd = collapse <$> parseNameAndShortcut <*> parsePackageSpec cmd
|
||||||
|
where
|
||||||
|
collapse specAndName pspec = (pname, specToLockedAttrs $ pspec <> baseSpec)
|
||||||
|
where
|
||||||
|
(pname, baseSpec) = case specAndName of
|
||||||
|
((_, spec), Just pname') -> (pname', PackageSpec spec)
|
||||||
|
((pname', spec), Nothing) -> (pname', PackageSpec spec)
|
||||||
parseNameAndShortcut =
|
parseNameAndShortcut =
|
||||||
(,) <$>
|
(,) <$>
|
||||||
optName <*>
|
Opts.argument
|
||||||
(Opts.strArgument (Opts.metavar "PACKAGE") <&> (parseShortcut githubCmd))
|
(Opts.maybeReader (parseCmdShortcut cmd . T.pack))
|
||||||
-- collaspe a "name or shortcut" with package spec
|
(Opts.metavar "PACKAGE") <*>
|
||||||
collapse nameAndSpec pspec = (pname, specToLockedAttrs $ pspec <> baseSpec)
|
optName
|
||||||
|
optName = Opts.optional $ PackageName <$> Opts.strOption
|
||||||
|
( Opts.long "name" <>
|
||||||
|
Opts.short 'n' <>
|
||||||
|
Opts.metavar "NAME" <>
|
||||||
|
Opts.help "Set the package name to <NAME>"
|
||||||
|
)
|
||||||
|
|
||||||
|
-- | only used in command (niv add <cmd> ...) because PACKAGE is optional
|
||||||
|
parseCmdArgs :: Cmd -> Opts.Parser (PackageName, Attrs)
|
||||||
|
parseCmdArgs cmd = collapse <$> parseNameAndShortcut <*> parsePackageSpec cmd
|
||||||
|
where
|
||||||
|
collapse specAndName pspec = (pname, specToLockedAttrs $ pspec <> baseSpec)
|
||||||
where
|
where
|
||||||
(pname, baseSpec) = case nameAndSpec of
|
(pname, baseSpec) = case specAndName of
|
||||||
(Just pname', (_, spec)) -> (pname', PackageSpec spec)
|
(Just (_, spec), Just pname') -> (pname', PackageSpec spec)
|
||||||
(Nothing, (pname', spec)) -> (pname', PackageSpec spec)
|
(Just (pname', spec), Nothing) -> (pname', PackageSpec spec)
|
||||||
|
(Nothing, Just pname') -> (pname', PackageSpec HMS.empty)
|
||||||
|
(Nothing, Nothing) -> (PackageName "unnamed", PackageSpec HMS.empty)
|
||||||
|
parseNameAndShortcut =
|
||||||
|
(,) <$>
|
||||||
|
Opts.optional (Opts.argument
|
||||||
|
(Opts.maybeReader (parseCmdShortcut cmd . T.pack))
|
||||||
|
(Opts.metavar "PACKAGE")) <*>
|
||||||
|
optName
|
||||||
optName = Opts.optional $ PackageName <$> Opts.strOption
|
optName = Opts.optional $ PackageName <$> Opts.strOption
|
||||||
( Opts.long "name" <>
|
( Opts.long "name" <>
|
||||||
Opts.short 'n' <>
|
Opts.short 'n' <>
|
||||||
|
@ -11,8 +11,7 @@ import qualified Options.Applicative as Opts
|
|||||||
-- TODO: add filter
|
-- TODO: add filter
|
||||||
data Cmd = Cmd
|
data Cmd = Cmd
|
||||||
{ description :: forall a. Opts.InfoMod a
|
{ description :: forall a. Opts.InfoMod a
|
||||||
-- TODO: should be "Maybe"
|
, parseCmdShortcut :: T.Text -> Maybe (PackageName, Aeson.Object)
|
||||||
, parseShortcut :: T.Text -> (PackageName, Aeson.Object)
|
|
||||||
, parsePackageSpec :: Opts.Parser PackageSpec
|
, parsePackageSpec :: Opts.Parser PackageSpec
|
||||||
, updateCmd :: Update () ()
|
, updateCmd :: Update () ()
|
||||||
, name :: T.Text
|
, name :: T.Text
|
||||||
|
@ -4,20 +4,27 @@ module Niv.Git.Cmd (gitCmd) where
|
|||||||
|
|
||||||
import Niv.Cmd
|
import Niv.Cmd
|
||||||
import qualified Options.Applicative as Opts
|
import qualified Options.Applicative as Opts
|
||||||
|
import qualified Options.Applicative.Help.Pretty as Opts
|
||||||
|
|
||||||
gitCmd :: Cmd
|
gitCmd :: Cmd
|
||||||
gitCmd = Cmd
|
gitCmd = Cmd
|
||||||
{ description = describeGit
|
{ description = describeGit
|
||||||
, parseShortcut = error "no parse for git"
|
, parseCmdShortcut = pure Nothing
|
||||||
, parsePackageSpec = pure mempty
|
, parsePackageSpec = pure mempty
|
||||||
, updateCmd = undefined
|
, updateCmd = error "git update is not implemented yet"
|
||||||
, name = "git"
|
, name = "git"
|
||||||
}
|
}
|
||||||
|
|
||||||
describeGit :: Opts.InfoMod a
|
describeGit :: Opts.InfoMod a
|
||||||
describeGit = mconcat
|
describeGit = mconcat
|
||||||
[ Opts.fullDesc
|
[ Opts.fullDesc
|
||||||
, Opts.progDesc "Echo a message back"
|
, Opts.progDesc "Add a git dependency. Experimental."
|
||||||
|
, Opts.headerDoc $ Just $
|
||||||
|
"Examples:" Opts.<$$>
|
||||||
|
"" Opts.<$$>
|
||||||
|
" niv add git@github.com:stedolan/jq" Opts.<$$>
|
||||||
|
" niv add ssh://git@github.com/stedolan/jq" Opts.<$$>
|
||||||
|
" niv add https://github.com/stedolan/jq.git"
|
||||||
]
|
]
|
||||||
|
|
||||||
-- for git:
|
-- for git:
|
||||||
|
@ -30,7 +30,7 @@ import qualified Options.Applicative.Help.Pretty as Opts
|
|||||||
githubCmd :: Cmd
|
githubCmd :: Cmd
|
||||||
githubCmd = Cmd
|
githubCmd = Cmd
|
||||||
{ description = describeGitHub
|
{ description = describeGitHub
|
||||||
, parseShortcut = parseAddShortcutGitHub
|
, parseCmdShortcut = parseAddShortcutGitHub
|
||||||
, parsePackageSpec = parseGitHubPackageSpec
|
, parsePackageSpec = parseGitHubPackageSpec
|
||||||
, updateCmd = githubUpdate'
|
, updateCmd = githubUpdate'
|
||||||
, name = "github"
|
, name = "github"
|
||||||
@ -104,7 +104,7 @@ parseGitHubPackageSpec =
|
|||||||
describeGitHub :: Opts.InfoMod a
|
describeGitHub :: Opts.InfoMod a
|
||||||
describeGitHub = mconcat
|
describeGitHub = mconcat
|
||||||
[ Opts.fullDesc
|
[ Opts.fullDesc
|
||||||
, Opts.progDesc "Add dependency"
|
, Opts.progDesc "Add a GitHub dependency"
|
||||||
, Opts.headerDoc $ Just $
|
, Opts.headerDoc $ Just $
|
||||||
"Examples:" Opts.<$$>
|
"Examples:" Opts.<$$>
|
||||||
"" Opts.<$$>
|
"" Opts.<$$>
|
||||||
@ -114,17 +114,19 @@ describeGitHub = mconcat
|
|||||||
]
|
]
|
||||||
|
|
||||||
-- parse a github shortcut of the form "owner/repo"
|
-- parse a github shortcut of the form "owner/repo"
|
||||||
parseAddShortcutGitHub :: T.Text -> (PackageName, Aeson.Object)
|
parseAddShortcutGitHub :: T.Text -> Maybe (PackageName, Aeson.Object)
|
||||||
parseAddShortcutGitHub str = -- Opts.strArgument (Opts.metavar "PACKAGE") <&>
|
parseAddShortcutGitHub str =
|
||||||
-- parses a string "owner/repo" into package name (repo) and spec (owner +
|
-- parses a string "owner/repo" into package name (repo) and spec (owner +
|
||||||
-- repo)
|
-- repo)
|
||||||
case T.span (/= '/') str of
|
case T.span (/= '/') str of
|
||||||
(owner@(T.null -> False)
|
(owner@(T.null -> False)
|
||||||
, T.uncons -> Just ('/', repo@(T.null -> False))) ->
|
, T.uncons -> Just ('/', repo@(T.null -> False))) -> Just
|
||||||
( PackageName repo
|
( PackageName repo
|
||||||
, HMS.fromList [ "owner" .= owner, "repo" .= repo ])
|
, HMS.fromList [ "owner" .= owner, "repo" .= repo ])
|
||||||
_ -> (PackageName str, HMS.empty)
|
-- XXX: this should be "Nothing" but for the time being we keep
|
||||||
|
-- backwards compatibility with "niv add foo" adding "foo" as a
|
||||||
|
-- package name.
|
||||||
|
_ -> Just (PackageName str, HMS.empty)
|
||||||
|
|
||||||
-- | The IO (real) github update
|
-- | The IO (real) github update
|
||||||
githubUpdate' :: Update () ()
|
githubUpdate' :: Update () ()
|
||||||
|
Loading…
Reference in New Issue
Block a user