From 4226278e5a2dc653120bf425cc138d70f1c87127 Mon Sep 17 00:00:00 2001 From: Kevin K Date: Tue, 25 May 2021 03:10:16 -0400 Subject: [PATCH] client, server: add shell completions (#84) This subcommand takes a shell as an argument and generates shell completions for that shell to stdout. example: ``` $ innernet completions bash OR $ innernet-server completions bash ``` --- client/Cargo.toml | 6 + client/src/main.rs | 10 + doc/innernet-server.completions.bash | 283 ++++++++++++ doc/innernet-server.completions.elvish | 104 +++++ doc/innernet-server.completions.fish | 49 +++ doc/innernet-server.completions.powershell | 120 ++++++ doc/innernet-server.completions.zsh | 240 +++++++++++ doc/innernet.completions.bash | 473 +++++++++++++++++++++ doc/innernet.completions.elvish | 189 ++++++++ doc/innernet.completions.fish | 88 ++++ doc/innernet.completions.powershell | 215 ++++++++++ doc/innernet.completions.zsh | 472 ++++++++++++++++++++ release.sh | 4 + rpm/Dockerfile | 2 +- server/Cargo.toml | 6 + server/src/main.rs | 10 + 16 files changed, 2270 insertions(+), 1 deletion(-) create mode 100644 doc/innernet-server.completions.bash create mode 100644 doc/innernet-server.completions.elvish create mode 100644 doc/innernet-server.completions.fish create mode 100644 doc/innernet-server.completions.powershell create mode 100644 doc/innernet-server.completions.zsh create mode 100644 doc/innernet.completions.bash create mode 100644 doc/innernet.completions.elvish create mode 100644 doc/innernet.completions.fish create mode 100644 doc/innernet.completions.powershell create mode 100644 doc/innernet.completions.zsh diff --git a/client/Cargo.toml b/client/Cargo.toml index d32996b..3d8ba73 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -39,6 +39,9 @@ assets = [ ["target/release/innernet", "usr/bin/inn", "755"], ["innernet@.service", "usr/lib/systemd/system/", "644"], ["../doc/innernet.8.gz", "usr/share/man/man8/", "644"], + ["../doc/innernet.completions.bash", "etc/bash_completion.d/innernet", "644"], + ["../doc/innernet.completions.fish", "usr/share/fish/vendor_completions.d/innernet.fish", "644"], + ["../doc/innernet.completions.zsh", "usr/share/zsh/site-functions/_innernet", "644"], ] depends = "libc6, libgcc1, systemd" extended-description = "innernet client binary for fetching peer information and conducting admin tasks such as adding a new peer." @@ -56,6 +59,9 @@ buildflags = ["--release"] [package.metadata.rpm.files] "../../doc/innernet-server.8.gz" = { path = "/usr/share/man/man8/innernet.8.gz" } "../innernet@.service" = { path = "/usr/lib/systemd/system/innernet@.service" } +"../../doc/innernet.completions.bash" = { path = "/etc/bash_completion.d/innernet" } +"../../doc/innernet.completions.fish" = { path = "/usr/share/fish/vendor_completions.d/innernet.fish" } +"../../doc/innernet.completions.zsh" = { path = "/usr/share/zsh/site-functions/_innernet" } [package.metadata.rpm.targets] innernet = { path = "/usr/bin/innernet" } diff --git a/client/src/main.rs b/client/src/main.rs index d79cfd5..9e396be 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -193,6 +193,12 @@ enum Command { #[structopt(short, long)] unset: bool, }, + + /// Generate shell completion scripts + Completions { + #[structopt(possible_values = &structopt::clap::Shell::variants(), case_insensitive = true)] + shell: structopt::clap::Shell, + }, } /// Application-level error. @@ -995,6 +1001,10 @@ fn run(opt: Opts) -> Result<(), Error> { Command::OverrideEndpoint { interface, unset } => { override_endpoint(&interface, unset, opt.network)? }, + Command::Completions { shell } => { + Opts::clap().gen_completions_to("innernet", shell, &mut std::io::stdout()); + std::process::exit(0); + }, } Ok(()) diff --git a/doc/innernet-server.completions.bash b/doc/innernet-server.completions.bash new file mode 100644 index 0000000..a5dfdfd --- /dev/null +++ b/doc/innernet-server.completions.bash @@ -0,0 +1,283 @@ +_innernet-server() { + local i cur prev opts cmds + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + cmd="" + opts="" + + for i in ${COMP_WORDS[@]} + do + case "${i}" in + innernet-server) + cmd="innernet-server" + ;; + + add-cidr) + cmd+="__add__cidr" + ;; + add-peer) + cmd+="__add__peer" + ;; + completions) + cmd+="__completions" + ;; + delete-cidr) + cmd+="__delete__cidr" + ;; + help) + cmd+="__help" + ;; + init) + cmd+="__init" + ;; + new) + cmd+="__new" + ;; + serve) + cmd+="__serve" + ;; + uninstall) + cmd+="__uninstall" + ;; + *) + ;; + esac + done + + case "${cmd}" in + innernet-server) + opts=" -h -V --no-routing --help --version --backend new uninstall serve add-peer add-cidr delete-cidr completions help init init" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --backend) + COMPREPLY=($(compgen -W "kernel userspace" -- "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + + innernet__server__add__cidr) + opts=" -h -V --yes --help --version --name --cidr --parent " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --cidr) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --parent) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__server__add__peer) + opts=" -h -V --auto-ip --yes --help --version --name --ip --cidr --admin --save-config --invite-expires " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --ip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --cidr) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --admin) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --save-config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --invite-expires) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__server__completions) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__server__delete__cidr) + opts=" -h -V --yes --help --version --name " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__server__help) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__server__init) + opts=" -h -V --auto-external-endpoint --help --version --network-name --network-cidr --external-endpoint --listen-port " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --network-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --network-cidr) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --external-endpoint) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --listen-port) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__server__new) + opts=" -h -V --auto-external-endpoint --help --version --network-name --network-cidr --external-endpoint --listen-port " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --network-name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --network-cidr) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --external-endpoint) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --listen-port) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__server__serve) + opts=" -h -V --no-routing --help --version --backend " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --backend) + COMPREPLY=($(compgen -W "kernel userspace" -- "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__server__uninstall) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + esac +} + +complete -F _innernet-server -o bashdefault -o default innernet-server diff --git a/doc/innernet-server.completions.elvish b/doc/innernet-server.completions.elvish new file mode 100644 index 0000000..39c290b --- /dev/null +++ b/doc/innernet-server.completions.elvish @@ -0,0 +1,104 @@ + +edit:completion:arg-completer[innernet-server] = [@words]{ + fn spaces [n]{ + repeat $n ' ' | joins '' + } + fn cand [text desc]{ + edit:complex-candidate $text &display-suffix=' '(spaces (- 14 (wcswidth $text)))$desc + } + command = 'innernet-server' + for word $words[1:-1] { + if (has-prefix $word '-') { + break + } + command = $command';'$word + } + completions = [ + &'innernet-server'= { + cand --backend 'Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability' + cand --no-routing 'Whether the routing should be done by innernet or is done by an external tool like e.g. babeld' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + cand new 'Create a new network' + cand uninstall 'Permanently uninstall a created network, rendering it unusable. Use with care' + cand serve 'Serve the coordinating server for an existing network' + cand add-peer 'Add a peer to an existing network' + cand add-cidr 'Add a new CIDR to an existing network' + cand delete-cidr 'Delete a CIDR' + cand completions 'Generate shell completion scripts' + cand help 'Prints this message or the help of the given subcommand(s)' + } + &'innernet-server;new'= { + cand --network-name 'The network name (ex: evilcorp)' + cand --network-cidr 'The network CIDR (ex: 10.42.0.0/16)' + cand --external-endpoint 'This server''s external endpoint (ex: 100.100.100.100:51820)' + cand --listen-port 'Port to listen on (for the WireGuard interface)' + cand --auto-external-endpoint 'Auto-resolve external endpoint' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet-server;uninstall'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet-server;serve'= { + cand --backend 'Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability' + cand --no-routing 'Whether the routing should be done by innernet or is done by an external tool like e.g. babeld' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet-server;add-peer'= { + cand --name 'Name of new peer' + cand --ip 'Specify desired IP of new peer (within parent CIDR)' + cand --cidr 'Name of CIDR to add new peer under' + cand --admin 'Make new peer an admin?' + cand --save-config 'Save the config to the given location' + cand --invite-expires 'Invite expiration period (eg. "30d", "7w", "2h", "60m", "1000s")' + cand --auto-ip 'Auto-assign the peer the first available IP within the CIDR' + cand --yes 'Bypass confirmation' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet-server;add-cidr'= { + cand --name 'The CIDR name (eg. "engineers")' + cand --cidr 'The CIDR network (eg. "10.42.5.0/24")' + cand --parent 'The CIDR parent name' + cand --yes 'Bypass confirmation' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet-server;delete-cidr'= { + cand --name 'The CIDR name (eg. "engineers")' + cand --yes 'Bypass confirmation' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet-server;completions'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet-server;help'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + ] + $completions[$command] +} diff --git a/doc/innernet-server.completions.fish b/doc/innernet-server.completions.fish new file mode 100644 index 0000000..c6f6395 --- /dev/null +++ b/doc/innernet-server.completions.fish @@ -0,0 +1,49 @@ +complete -c innernet-server -n "__fish_use_subcommand" -l backend -d 'Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability' -r -f -a "kernel userspace" +complete -c innernet-server -n "__fish_use_subcommand" -l no-routing -d 'Whether the routing should be done by innernet or is done by an external tool like e.g. babeld' +complete -c innernet-server -n "__fish_use_subcommand" -s h -l help -d 'Prints help information' +complete -c innernet-server -n "__fish_use_subcommand" -s V -l version -d 'Prints version information' +complete -c innernet-server -n "__fish_use_subcommand" -f -a "new" -d 'Create a new network' +complete -c innernet-server -n "__fish_use_subcommand" -f -a "uninstall" -d 'Permanently uninstall a created network, rendering it unusable. Use with care' +complete -c innernet-server -n "__fish_use_subcommand" -f -a "serve" -d 'Serve the coordinating server for an existing network' +complete -c innernet-server -n "__fish_use_subcommand" -f -a "add-peer" -d 'Add a peer to an existing network' +complete -c innernet-server -n "__fish_use_subcommand" -f -a "add-cidr" -d 'Add a new CIDR to an existing network' +complete -c innernet-server -n "__fish_use_subcommand" -f -a "delete-cidr" -d 'Delete a CIDR' +complete -c innernet-server -n "__fish_use_subcommand" -f -a "completions" -d 'Generate shell completion scripts' +complete -c innernet-server -n "__fish_use_subcommand" -f -a "help" -d 'Prints this message or the help of the given subcommand(s)' +complete -c innernet-server -n "__fish_seen_subcommand_from new" -l network-name -d 'The network name (ex: evilcorp)' +complete -c innernet-server -n "__fish_seen_subcommand_from new" -l network-cidr -d 'The network CIDR (ex: 10.42.0.0/16)' +complete -c innernet-server -n "__fish_seen_subcommand_from new" -l external-endpoint -d 'This server\'s external endpoint (ex: 100.100.100.100:51820)' +complete -c innernet-server -n "__fish_seen_subcommand_from new" -l listen-port -d 'Port to listen on (for the WireGuard interface)' +complete -c innernet-server -n "__fish_seen_subcommand_from new" -l auto-external-endpoint -d 'Auto-resolve external endpoint' +complete -c innernet-server -n "__fish_seen_subcommand_from new" -s h -l help -d 'Prints help information' +complete -c innernet-server -n "__fish_seen_subcommand_from new" -s V -l version -d 'Prints version information' +complete -c innernet-server -n "__fish_seen_subcommand_from uninstall" -s h -l help -d 'Prints help information' +complete -c innernet-server -n "__fish_seen_subcommand_from uninstall" -s V -l version -d 'Prints version information' +complete -c innernet-server -n "__fish_seen_subcommand_from serve" -l backend -d 'Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability' -r -f -a "kernel userspace" +complete -c innernet-server -n "__fish_seen_subcommand_from serve" -l no-routing -d 'Whether the routing should be done by innernet or is done by an external tool like e.g. babeld' +complete -c innernet-server -n "__fish_seen_subcommand_from serve" -s h -l help -d 'Prints help information' +complete -c innernet-server -n "__fish_seen_subcommand_from serve" -s V -l version -d 'Prints version information' +complete -c innernet-server -n "__fish_seen_subcommand_from add-peer" -l name -d 'Name of new peer' +complete -c innernet-server -n "__fish_seen_subcommand_from add-peer" -l ip -d 'Specify desired IP of new peer (within parent CIDR)' +complete -c innernet-server -n "__fish_seen_subcommand_from add-peer" -l cidr -d 'Name of CIDR to add new peer under' +complete -c innernet-server -n "__fish_seen_subcommand_from add-peer" -l admin -d 'Make new peer an admin?' +complete -c innernet-server -n "__fish_seen_subcommand_from add-peer" -l save-config -d 'Save the config to the given location' +complete -c innernet-server -n "__fish_seen_subcommand_from add-peer" -l invite-expires -d 'Invite expiration period (eg. "30d", "7w", "2h", "60m", "1000s")' +complete -c innernet-server -n "__fish_seen_subcommand_from add-peer" -l auto-ip -d 'Auto-assign the peer the first available IP within the CIDR' +complete -c innernet-server -n "__fish_seen_subcommand_from add-peer" -l yes -d 'Bypass confirmation' +complete -c innernet-server -n "__fish_seen_subcommand_from add-peer" -s h -l help -d 'Prints help information' +complete -c innernet-server -n "__fish_seen_subcommand_from add-peer" -s V -l version -d 'Prints version information' +complete -c innernet-server -n "__fish_seen_subcommand_from add-cidr" -l name -d 'The CIDR name (eg. "engineers")' +complete -c innernet-server -n "__fish_seen_subcommand_from add-cidr" -l cidr -d 'The CIDR network (eg. "10.42.5.0/24")' +complete -c innernet-server -n "__fish_seen_subcommand_from add-cidr" -l parent -d 'The CIDR parent name' +complete -c innernet-server -n "__fish_seen_subcommand_from add-cidr" -l yes -d 'Bypass confirmation' +complete -c innernet-server -n "__fish_seen_subcommand_from add-cidr" -s h -l help -d 'Prints help information' +complete -c innernet-server -n "__fish_seen_subcommand_from add-cidr" -s V -l version -d 'Prints version information' +complete -c innernet-server -n "__fish_seen_subcommand_from delete-cidr" -l name -d 'The CIDR name (eg. "engineers")' +complete -c innernet-server -n "__fish_seen_subcommand_from delete-cidr" -l yes -d 'Bypass confirmation' +complete -c innernet-server -n "__fish_seen_subcommand_from delete-cidr" -s h -l help -d 'Prints help information' +complete -c innernet-server -n "__fish_seen_subcommand_from delete-cidr" -s V -l version -d 'Prints version information' +complete -c innernet-server -n "__fish_seen_subcommand_from completions" -s h -l help -d 'Prints help information' +complete -c innernet-server -n "__fish_seen_subcommand_from completions" -s V -l version -d 'Prints version information' +complete -c innernet-server -n "__fish_seen_subcommand_from help" -s h -l help -d 'Prints help information' +complete -c innernet-server -n "__fish_seen_subcommand_from help" -s V -l version -d 'Prints version information' diff --git a/doc/innernet-server.completions.powershell b/doc/innernet-server.completions.powershell new file mode 100644 index 0000000..07d3041 --- /dev/null +++ b/doc/innernet-server.completions.powershell @@ -0,0 +1,120 @@ + +using namespace System.Management.Automation +using namespace System.Management.Automation.Language + +Register-ArgumentCompleter -Native -CommandName 'innernet-server' -ScriptBlock { + param($wordToComplete, $commandAst, $cursorPosition) + + $commandElements = $commandAst.CommandElements + $command = @( + 'innernet-server' + for ($i = 1; $i -lt $commandElements.Count; $i++) { + $element = $commandElements[$i] + if ($element -isnot [StringConstantExpressionAst] -or + $element.StringConstantType -ne [StringConstantType]::BareWord -or + $element.Value.StartsWith('-')) { + break + } + $element.Value + }) -join ';' + + $completions = @(switch ($command) { + 'innernet-server' { + [CompletionResult]::new('--backend', 'backend', [CompletionResultType]::ParameterName, 'Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability') + [CompletionResult]::new('--no-routing', 'no-routing', [CompletionResultType]::ParameterName, 'Whether the routing should be done by innernet or is done by an external tool like e.g. babeld') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('new', 'new', [CompletionResultType]::ParameterValue, 'Create a new network') + [CompletionResult]::new('uninstall', 'uninstall', [CompletionResultType]::ParameterValue, 'Permanently uninstall a created network, rendering it unusable. Use with care') + [CompletionResult]::new('serve', 'serve', [CompletionResultType]::ParameterValue, 'Serve the coordinating server for an existing network') + [CompletionResult]::new('add-peer', 'add-peer', [CompletionResultType]::ParameterValue, 'Add a peer to an existing network') + [CompletionResult]::new('add-cidr', 'add-cidr', [CompletionResultType]::ParameterValue, 'Add a new CIDR to an existing network') + [CompletionResult]::new('delete-cidr', 'delete-cidr', [CompletionResultType]::ParameterValue, 'Delete a CIDR') + [CompletionResult]::new('completions', 'completions', [CompletionResultType]::ParameterValue, 'Generate shell completion scripts') + [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Prints this message or the help of the given subcommand(s)') + break + } + 'innernet-server;new' { + [CompletionResult]::new('--network-name', 'network-name', [CompletionResultType]::ParameterName, 'The network name (ex: evilcorp)') + [CompletionResult]::new('--network-cidr', 'network-cidr', [CompletionResultType]::ParameterName, 'The network CIDR (ex: 10.42.0.0/16)') + [CompletionResult]::new('--external-endpoint', 'external-endpoint', [CompletionResultType]::ParameterName, 'This server''s external endpoint (ex: 100.100.100.100:51820)') + [CompletionResult]::new('--listen-port', 'listen-port', [CompletionResultType]::ParameterName, 'Port to listen on (for the WireGuard interface)') + [CompletionResult]::new('--auto-external-endpoint', 'auto-external-endpoint', [CompletionResultType]::ParameterName, 'Auto-resolve external endpoint') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet-server;uninstall' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet-server;serve' { + [CompletionResult]::new('--backend', 'backend', [CompletionResultType]::ParameterName, 'Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability') + [CompletionResult]::new('--no-routing', 'no-routing', [CompletionResultType]::ParameterName, 'Whether the routing should be done by innernet or is done by an external tool like e.g. babeld') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet-server;add-peer' { + [CompletionResult]::new('--name', 'name', [CompletionResultType]::ParameterName, 'Name of new peer') + [CompletionResult]::new('--ip', 'ip', [CompletionResultType]::ParameterName, 'Specify desired IP of new peer (within parent CIDR)') + [CompletionResult]::new('--cidr', 'cidr', [CompletionResultType]::ParameterName, 'Name of CIDR to add new peer under') + [CompletionResult]::new('--admin', 'admin', [CompletionResultType]::ParameterName, 'Make new peer an admin?') + [CompletionResult]::new('--save-config', 'save-config', [CompletionResultType]::ParameterName, 'Save the config to the given location') + [CompletionResult]::new('--invite-expires', 'invite-expires', [CompletionResultType]::ParameterName, 'Invite expiration period (eg. "30d", "7w", "2h", "60m", "1000s")') + [CompletionResult]::new('--auto-ip', 'auto-ip', [CompletionResultType]::ParameterName, 'Auto-assign the peer the first available IP within the CIDR') + [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Bypass confirmation') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet-server;add-cidr' { + [CompletionResult]::new('--name', 'name', [CompletionResultType]::ParameterName, 'The CIDR name (eg. "engineers")') + [CompletionResult]::new('--cidr', 'cidr', [CompletionResultType]::ParameterName, 'The CIDR network (eg. "10.42.5.0/24")') + [CompletionResult]::new('--parent', 'parent', [CompletionResultType]::ParameterName, 'The CIDR parent name') + [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Bypass confirmation') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet-server;delete-cidr' { + [CompletionResult]::new('--name', 'name', [CompletionResultType]::ParameterName, 'The CIDR name (eg. "engineers")') + [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Bypass confirmation') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet-server;completions' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet-server;help' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + }) + + $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | + Sort-Object -Property ListItemText +} diff --git a/doc/innernet-server.completions.zsh b/doc/innernet-server.completions.zsh new file mode 100644 index 0000000..9439462 --- /dev/null +++ b/doc/innernet-server.completions.zsh @@ -0,0 +1,240 @@ +#compdef innernet-server + +autoload -U is-at-least + +_innernet-server() { + typeset -A opt_args + typeset -a _arguments_options + local ret=1 + + if is-at-least 5.2; then + _arguments_options=(-s -S -C) + else + _arguments_options=(-s -C) + fi + + local context curcontext="$curcontext" state line + _arguments "${_arguments_options[@]}" \ +'--backend=[Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability]: :(kernel userspace)' \ +'--no-routing[Whether the routing should be done by innernet or is done by an external tool like e.g. babeld]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +":: :_innernet-server_commands" \ +"*::: :->innernet-server" \ +&& ret=0 + case $state in + (innernet-server) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:innernet-server-command-$line[1]:" + case $line[1] in + (init) +_arguments "${_arguments_options[@]}" \ +'--network-name=[The network name (ex: evilcorp)]' \ +'--network-cidr=[The network CIDR (ex: 10.42.0.0/16)]' \ +'(--auto-external-endpoint)--external-endpoint=[This server'\''s external endpoint (ex: 100.100.100.100:51820)]' \ +'--listen-port=[Port to listen on (for the WireGuard interface)]' \ +'--auto-external-endpoint[Auto-resolve external endpoint]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +&& ret=0 +;; +(init) +_arguments "${_arguments_options[@]}" \ +'--network-name=[The network name (ex: evilcorp)]' \ +'--network-cidr=[The network CIDR (ex: 10.42.0.0/16)]' \ +'(--auto-external-endpoint)--external-endpoint=[This server'\''s external endpoint (ex: 100.100.100.100:51820)]' \ +'--listen-port=[Port to listen on (for the WireGuard interface)]' \ +'--auto-external-endpoint[Auto-resolve external endpoint]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +&& ret=0 +;; +(new) +_arguments "${_arguments_options[@]}" \ +'--network-name=[The network name (ex: evilcorp)]' \ +'--network-cidr=[The network CIDR (ex: 10.42.0.0/16)]' \ +'(--auto-external-endpoint)--external-endpoint=[This server'\''s external endpoint (ex: 100.100.100.100:51820)]' \ +'--listen-port=[Port to listen on (for the WireGuard interface)]' \ +'--auto-external-endpoint[Auto-resolve external endpoint]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +&& ret=0 +;; +(uninstall) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(serve) +_arguments "${_arguments_options[@]}" \ +'--backend=[Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability]: :(kernel userspace)' \ +'--no-routing[Whether the routing should be done by innernet or is done by an external tool like e.g. babeld]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(add-peer) +_arguments "${_arguments_options[@]}" \ +'--name=[Name of new peer]' \ +'(--auto-ip)--ip=[Specify desired IP of new peer (within parent CIDR)]' \ +'--cidr=[Name of CIDR to add new peer under]' \ +'--admin=[Make new peer an admin?]' \ +'--save-config=[Save the config to the given location]' \ +'--invite-expires=[Invite expiration period (eg. "30d", "7w", "2h", "60m", "1000s")]' \ +'--auto-ip[Auto-assign the peer the first available IP within the CIDR]' \ +'--yes[Bypass confirmation]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(add-cidr) +_arguments "${_arguments_options[@]}" \ +'--name=[The CIDR name (eg. "engineers")]' \ +'--cidr=[The CIDR network (eg. "10.42.5.0/24")]' \ +'--parent=[The CIDR parent name]' \ +'--yes[Bypass confirmation]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(delete-cidr) +_arguments "${_arguments_options[@]}" \ +'--name=[The CIDR name (eg. "engineers")]' \ +'--yes[Bypass confirmation]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(completions) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':shell:(zsh bash fish powershell elvish)' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +&& ret=0 +;; + esac + ;; +esac +} + +(( $+functions[_innernet-server_commands] )) || +_innernet-server_commands() { + local commands; commands=( + "new:Create a new network" \ +"uninstall:Permanently uninstall a created network, rendering it unusable. Use with care" \ +"serve:Serve the coordinating server for an existing network" \ +"add-peer:Add a peer to an existing network" \ +"add-cidr:Add a new CIDR to an existing network" \ +"delete-cidr:Delete a CIDR" \ +"completions:Generate shell completion scripts" \ +"help:Prints this message or the help of the given subcommand(s)" \ + ) + _describe -t commands 'innernet-server commands' commands "$@" +} +(( $+functions[_innernet-server__add-cidr_commands] )) || +_innernet-server__add-cidr_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet-server add-cidr commands' commands "$@" +} +(( $+functions[_innernet-server__add-peer_commands] )) || +_innernet-server__add-peer_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet-server add-peer commands' commands "$@" +} +(( $+functions[_innernet-server__completions_commands] )) || +_innernet-server__completions_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet-server completions commands' commands "$@" +} +(( $+functions[_innernet-server__delete-cidr_commands] )) || +_innernet-server__delete-cidr_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet-server delete-cidr commands' commands "$@" +} +(( $+functions[_innernet-server__help_commands] )) || +_innernet-server__help_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet-server help commands' commands "$@" +} +(( $+functions[_init_commands] )) || +_init_commands() { + local commands; commands=( + + ) + _describe -t commands 'init commands' commands "$@" +} +(( $+functions[_innernet-server__init_commands] )) || +_innernet-server__init_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet-server init commands' commands "$@" +} +(( $+functions[_innernet-server__new_commands] )) || +_innernet-server__new_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet-server new commands' commands "$@" +} +(( $+functions[_innernet-server__serve_commands] )) || +_innernet-server__serve_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet-server serve commands' commands "$@" +} +(( $+functions[_innernet-server__uninstall_commands] )) || +_innernet-server__uninstall_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet-server uninstall commands' commands "$@" +} + +_innernet-server "$@" \ No newline at end of file diff --git a/doc/innernet.completions.bash b/doc/innernet.completions.bash new file mode 100644 index 0000000..fd1e35e --- /dev/null +++ b/doc/innernet.completions.bash @@ -0,0 +1,473 @@ +_innernet() { + local i cur prev opts cmds + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + cmd="" + opts="" + + for i in ${COMP_WORDS[@]} + do + case "${i}" in + innernet) + cmd="innernet" + ;; + + add-association) + cmd+="__add__association" + ;; + add-cidr) + cmd+="__add__cidr" + ;; + add-peer) + cmd+="__add__peer" + ;; + completions) + cmd+="__completions" + ;; + delete-association) + cmd+="__delete__association" + ;; + delete-cidr) + cmd+="__delete__cidr" + ;; + disable-peer) + cmd+="__disable__peer" + ;; + down) + cmd+="__down" + ;; + enable-peer) + cmd+="__enable__peer" + ;; + fetch) + cmd+="__fetch" + ;; + help) + cmd+="__help" + ;; + install) + cmd+="__install" + ;; + list) + cmd+="__list" + ;; + list-associations) + cmd+="__list__associations" + ;; + override-endpoint) + cmd+="__override__endpoint" + ;; + redeem) + cmd+="__redeem" + ;; + set-listen-port) + cmd+="__set__listen__port" + ;; + show) + cmd+="__show" + ;; + uninstall) + cmd+="__uninstall" + ;; + up) + cmd+="__up" + ;; + *) + ;; + esac + done + + case "${cmd}" in + innernet) + opts=" -v -h -V --no-routing --help --version --backend install show up fetch uninstall down add-peer add-cidr delete-cidr disable-peer enable-peer add-association delete-association list-associations set-listen-port override-endpoint completions help redeem redeem list list" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --backend) + COMPREPLY=($(compgen -W "kernel userspace" -- "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + + innernet__add__association) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__add__cidr) + opts=" -h -V --yes --help --version --name --cidr --parent " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --cidr) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --parent) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__add__peer) + opts=" -h -V --auto-ip --yes --help --version --name --ip --cidr --admin --save-config --invite-expires " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --ip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --cidr) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --admin) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --save-config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --invite-expires) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__completions) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__delete__association) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__delete__cidr) + opts=" -h -V --yes --help --version --name " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__disable__peer) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__down) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__enable__peer) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__fetch) + opts=" -h -V --no-write-hosts --help --version --hosts-path " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --hosts-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__help) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__install) + opts=" -d -h -V --no-write-hosts --default-name --delete-invite --help --version --hosts-path --name " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --hosts-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__list) + opts=" -s -t -h -V --short --tree --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__list__associations) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__override__endpoint) + opts=" -u -h -V --unset --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__redeem) + opts=" -d -h -V --no-write-hosts --default-name --delete-invite --help --version --hosts-path --name " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --hosts-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --name) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__set__listen__port) + opts=" -u -h -V --unset --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__show) + opts=" -s -t -h -V --short --tree --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__uninstall) + opts=" -h -V --help --version " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + innernet__up) + opts=" -d -h -V --daemon --no-write-hosts --help --version --interval --hosts-path " + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + + --interval) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --hosts-path) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; + esac +} + +complete -F _innernet -o bashdefault -o default innernet diff --git a/doc/innernet.completions.elvish b/doc/innernet.completions.elvish new file mode 100644 index 0000000..7edab4e --- /dev/null +++ b/doc/innernet.completions.elvish @@ -0,0 +1,189 @@ + +edit:completion:arg-completer[innernet] = [@words]{ + fn spaces [n]{ + repeat $n ' ' | joins '' + } + fn cand [text desc]{ + edit:complex-candidate $text &display-suffix=' '(spaces (- 14 (wcswidth $text)))$desc + } + command = 'innernet' + for word $words[1:-1] { + if (has-prefix $word '-') { + break + } + command = $command';'$word + } + completions = [ + &'innernet'= { + cand --backend 'Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability' + cand -v 'v' + cand --no-routing 'Whether the routing should be done by innernet or is done by an external tool like e.g. babeld' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + cand install 'Install a new innernet config' + cand show 'Enumerate all innernet connections' + cand up 'Bring up your local interface, and update it with latest peer list' + cand fetch 'Fetch and update your local interface with the latest peer list' + cand uninstall 'Uninstall an innernet network' + cand down 'Bring down the interface (equivalent to "wg-quick down ")' + cand add-peer 'Add a new peer' + cand add-cidr 'Add a new CIDR' + cand delete-cidr 'Delete a CIDR' + cand disable-peer 'Disable an enabled peer' + cand enable-peer 'Enable a disabled peer' + cand add-association 'Add an association between CIDRs' + cand delete-association 'Delete an association between CIDRs' + cand list-associations 'List existing assocations between CIDRs' + cand set-listen-port 'Set the local listen port' + cand override-endpoint 'Override your external endpoint that the server sends to other peers' + cand completions 'Generate shell completion scripts' + cand help 'Prints this message or the help of the given subcommand(s)' + } + &'innernet;install'= { + cand --hosts-path 'The path to write hosts to' + cand --name 'Set a specific interface name' + cand --no-write-hosts 'Don''t write to any hosts files' + cand --default-name 'Use the network name inside the invitation as the interface name' + cand -d 'Delete the invitation after a successful install' + cand --delete-invite 'Delete the invitation after a successful install' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;show'= { + cand -s 'One-line peer list' + cand --short 'One-line peer list' + cand -t 'Display peers in a tree based on the CIDRs' + cand --tree 'Display peers in a tree based on the CIDRs' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;up'= { + cand --interval 'Keep fetching the latest peer list at the specified interval in seconds. Valid only in daemon mode' + cand --hosts-path 'The path to write hosts to' + cand -d 'Enable daemon mode i.e. keep the process running, while fetching the latest peer list periodically' + cand --daemon 'Enable daemon mode i.e. keep the process running, while fetching the latest peer list periodically' + cand --no-write-hosts 'Don''t write to any hosts files' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;fetch'= { + cand --hosts-path 'The path to write hosts to' + cand --no-write-hosts 'Don''t write to any hosts files' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;uninstall'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;down'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;add-peer'= { + cand --name 'Name of new peer' + cand --ip 'Specify desired IP of new peer (within parent CIDR)' + cand --cidr 'Name of CIDR to add new peer under' + cand --admin 'Make new peer an admin?' + cand --save-config 'Save the config to the given location' + cand --invite-expires 'Invite expiration period (eg. "30d", "7w", "2h", "60m", "1000s")' + cand --auto-ip 'Auto-assign the peer the first available IP within the CIDR' + cand --yes 'Bypass confirmation' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;add-cidr'= { + cand --name 'The CIDR name (eg. "engineers")' + cand --cidr 'The CIDR network (eg. "10.42.5.0/24")' + cand --parent 'The CIDR parent name' + cand --yes 'Bypass confirmation' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;delete-cidr'= { + cand --name 'The CIDR name (eg. "engineers")' + cand --yes 'Bypass confirmation' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;disable-peer'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;enable-peer'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;add-association'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;delete-association'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;list-associations'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;set-listen-port'= { + cand -u 'Unset the local listen port to use a randomized port' + cand --unset 'Unset the local listen port to use a randomized port' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;override-endpoint'= { + cand -u 'Unset an existing override to use the automatic endpoint discovery' + cand --unset 'Unset an existing override to use the automatic endpoint discovery' + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;completions'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + &'innernet;help'= { + cand -h 'Prints help information' + cand --help 'Prints help information' + cand -V 'Prints version information' + cand --version 'Prints version information' + } + ] + $completions[$command] +} diff --git a/doc/innernet.completions.fish b/doc/innernet.completions.fish new file mode 100644 index 0000000..dd8df80 --- /dev/null +++ b/doc/innernet.completions.fish @@ -0,0 +1,88 @@ +complete -c innernet -n "__fish_use_subcommand" -l backend -d 'Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability' -r -f -a "kernel userspace" +complete -c innernet -n "__fish_use_subcommand" -s v +complete -c innernet -n "__fish_use_subcommand" -l no-routing -d 'Whether the routing should be done by innernet or is done by an external tool like e.g. babeld' +complete -c innernet -n "__fish_use_subcommand" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_use_subcommand" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_use_subcommand" -f -a "install" -d 'Install a new innernet config' +complete -c innernet -n "__fish_use_subcommand" -f -a "show" -d 'Enumerate all innernet connections' +complete -c innernet -n "__fish_use_subcommand" -f -a "up" -d 'Bring up your local interface, and update it with latest peer list' +complete -c innernet -n "__fish_use_subcommand" -f -a "fetch" -d 'Fetch and update your local interface with the latest peer list' +complete -c innernet -n "__fish_use_subcommand" -f -a "uninstall" -d 'Uninstall an innernet network' +complete -c innernet -n "__fish_use_subcommand" -f -a "down" -d 'Bring down the interface (equivalent to "wg-quick down ")' +complete -c innernet -n "__fish_use_subcommand" -f -a "add-peer" -d 'Add a new peer' +complete -c innernet -n "__fish_use_subcommand" -f -a "add-cidr" -d 'Add a new CIDR' +complete -c innernet -n "__fish_use_subcommand" -f -a "delete-cidr" -d 'Delete a CIDR' +complete -c innernet -n "__fish_use_subcommand" -f -a "disable-peer" -d 'Disable an enabled peer' +complete -c innernet -n "__fish_use_subcommand" -f -a "enable-peer" -d 'Enable a disabled peer' +complete -c innernet -n "__fish_use_subcommand" -f -a "add-association" -d 'Add an association between CIDRs' +complete -c innernet -n "__fish_use_subcommand" -f -a "delete-association" -d 'Delete an association between CIDRs' +complete -c innernet -n "__fish_use_subcommand" -f -a "list-associations" -d 'List existing assocations between CIDRs' +complete -c innernet -n "__fish_use_subcommand" -f -a "set-listen-port" -d 'Set the local listen port' +complete -c innernet -n "__fish_use_subcommand" -f -a "override-endpoint" -d 'Override your external endpoint that the server sends to other peers' +complete -c innernet -n "__fish_use_subcommand" -f -a "completions" -d 'Generate shell completion scripts' +complete -c innernet -n "__fish_use_subcommand" -f -a "help" -d 'Prints this message or the help of the given subcommand(s)' +complete -c innernet -n "__fish_seen_subcommand_from install" -l hosts-path -d 'The path to write hosts to' +complete -c innernet -n "__fish_seen_subcommand_from install" -l name -d 'Set a specific interface name' +complete -c innernet -n "__fish_seen_subcommand_from install" -l no-write-hosts -d 'Don\'t write to any hosts files' +complete -c innernet -n "__fish_seen_subcommand_from install" -l default-name -d 'Use the network name inside the invitation as the interface name' +complete -c innernet -n "__fish_seen_subcommand_from install" -s d -l delete-invite -d 'Delete the invitation after a successful install' +complete -c innernet -n "__fish_seen_subcommand_from install" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from install" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from show" -s s -l short -d 'One-line peer list' +complete -c innernet -n "__fish_seen_subcommand_from show" -s t -l tree -d 'Display peers in a tree based on the CIDRs' +complete -c innernet -n "__fish_seen_subcommand_from show" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from show" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from up" -l interval -d 'Keep fetching the latest peer list at the specified interval in seconds. Valid only in daemon mode' +complete -c innernet -n "__fish_seen_subcommand_from up" -l hosts-path -d 'The path to write hosts to' +complete -c innernet -n "__fish_seen_subcommand_from up" -s d -l daemon -d 'Enable daemon mode i.e. keep the process running, while fetching the latest peer list periodically' +complete -c innernet -n "__fish_seen_subcommand_from up" -l no-write-hosts -d 'Don\'t write to any hosts files' +complete -c innernet -n "__fish_seen_subcommand_from up" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from up" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from fetch" -l hosts-path -d 'The path to write hosts to' +complete -c innernet -n "__fish_seen_subcommand_from fetch" -l no-write-hosts -d 'Don\'t write to any hosts files' +complete -c innernet -n "__fish_seen_subcommand_from fetch" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from fetch" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from uninstall" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from uninstall" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from down" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from down" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from add-peer" -l name -d 'Name of new peer' +complete -c innernet -n "__fish_seen_subcommand_from add-peer" -l ip -d 'Specify desired IP of new peer (within parent CIDR)' +complete -c innernet -n "__fish_seen_subcommand_from add-peer" -l cidr -d 'Name of CIDR to add new peer under' +complete -c innernet -n "__fish_seen_subcommand_from add-peer" -l admin -d 'Make new peer an admin?' +complete -c innernet -n "__fish_seen_subcommand_from add-peer" -l save-config -d 'Save the config to the given location' +complete -c innernet -n "__fish_seen_subcommand_from add-peer" -l invite-expires -d 'Invite expiration period (eg. "30d", "7w", "2h", "60m", "1000s")' +complete -c innernet -n "__fish_seen_subcommand_from add-peer" -l auto-ip -d 'Auto-assign the peer the first available IP within the CIDR' +complete -c innernet -n "__fish_seen_subcommand_from add-peer" -l yes -d 'Bypass confirmation' +complete -c innernet -n "__fish_seen_subcommand_from add-peer" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from add-peer" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from add-cidr" -l name -d 'The CIDR name (eg. "engineers")' +complete -c innernet -n "__fish_seen_subcommand_from add-cidr" -l cidr -d 'The CIDR network (eg. "10.42.5.0/24")' +complete -c innernet -n "__fish_seen_subcommand_from add-cidr" -l parent -d 'The CIDR parent name' +complete -c innernet -n "__fish_seen_subcommand_from add-cidr" -l yes -d 'Bypass confirmation' +complete -c innernet -n "__fish_seen_subcommand_from add-cidr" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from add-cidr" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from delete-cidr" -l name -d 'The CIDR name (eg. "engineers")' +complete -c innernet -n "__fish_seen_subcommand_from delete-cidr" -l yes -d 'Bypass confirmation' +complete -c innernet -n "__fish_seen_subcommand_from delete-cidr" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from delete-cidr" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from disable-peer" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from disable-peer" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from enable-peer" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from enable-peer" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from add-association" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from add-association" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from delete-association" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from delete-association" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from list-associations" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from list-associations" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from set-listen-port" -s u -l unset -d 'Unset the local listen port to use a randomized port' +complete -c innernet -n "__fish_seen_subcommand_from set-listen-port" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from set-listen-port" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from override-endpoint" -s u -l unset -d 'Unset an existing override to use the automatic endpoint discovery' +complete -c innernet -n "__fish_seen_subcommand_from override-endpoint" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from override-endpoint" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from completions" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from completions" -s V -l version -d 'Prints version information' +complete -c innernet -n "__fish_seen_subcommand_from help" -s h -l help -d 'Prints help information' +complete -c innernet -n "__fish_seen_subcommand_from help" -s V -l version -d 'Prints version information' diff --git a/doc/innernet.completions.powershell b/doc/innernet.completions.powershell new file mode 100644 index 0000000..a0fe2a6 --- /dev/null +++ b/doc/innernet.completions.powershell @@ -0,0 +1,215 @@ + +using namespace System.Management.Automation +using namespace System.Management.Automation.Language + +Register-ArgumentCompleter -Native -CommandName 'innernet' -ScriptBlock { + param($wordToComplete, $commandAst, $cursorPosition) + + $commandElements = $commandAst.CommandElements + $command = @( + 'innernet' + for ($i = 1; $i -lt $commandElements.Count; $i++) { + $element = $commandElements[$i] + if ($element -isnot [StringConstantExpressionAst] -or + $element.StringConstantType -ne [StringConstantType]::BareWord -or + $element.Value.StartsWith('-')) { + break + } + $element.Value + }) -join ';' + + $completions = @(switch ($command) { + 'innernet' { + [CompletionResult]::new('--backend', 'backend', [CompletionResultType]::ParameterName, 'Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability') + [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'v') + [CompletionResult]::new('--no-routing', 'no-routing', [CompletionResultType]::ParameterName, 'Whether the routing should be done by innernet or is done by an external tool like e.g. babeld') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('install', 'install', [CompletionResultType]::ParameterValue, 'Install a new innernet config') + [CompletionResult]::new('show', 'show', [CompletionResultType]::ParameterValue, 'Enumerate all innernet connections') + [CompletionResult]::new('up', 'up', [CompletionResultType]::ParameterValue, 'Bring up your local interface, and update it with latest peer list') + [CompletionResult]::new('fetch', 'fetch', [CompletionResultType]::ParameterValue, 'Fetch and update your local interface with the latest peer list') + [CompletionResult]::new('uninstall', 'uninstall', [CompletionResultType]::ParameterValue, 'Uninstall an innernet network') + [CompletionResult]::new('down', 'down', [CompletionResultType]::ParameterValue, 'Bring down the interface (equivalent to "wg-quick down ")') + [CompletionResult]::new('add-peer', 'add-peer', [CompletionResultType]::ParameterValue, 'Add a new peer') + [CompletionResult]::new('add-cidr', 'add-cidr', [CompletionResultType]::ParameterValue, 'Add a new CIDR') + [CompletionResult]::new('delete-cidr', 'delete-cidr', [CompletionResultType]::ParameterValue, 'Delete a CIDR') + [CompletionResult]::new('disable-peer', 'disable-peer', [CompletionResultType]::ParameterValue, 'Disable an enabled peer') + [CompletionResult]::new('enable-peer', 'enable-peer', [CompletionResultType]::ParameterValue, 'Enable a disabled peer') + [CompletionResult]::new('add-association', 'add-association', [CompletionResultType]::ParameterValue, 'Add an association between CIDRs') + [CompletionResult]::new('delete-association', 'delete-association', [CompletionResultType]::ParameterValue, 'Delete an association between CIDRs') + [CompletionResult]::new('list-associations', 'list-associations', [CompletionResultType]::ParameterValue, 'List existing assocations between CIDRs') + [CompletionResult]::new('set-listen-port', 'set-listen-port', [CompletionResultType]::ParameterValue, 'Set the local listen port') + [CompletionResult]::new('override-endpoint', 'override-endpoint', [CompletionResultType]::ParameterValue, 'Override your external endpoint that the server sends to other peers') + [CompletionResult]::new('completions', 'completions', [CompletionResultType]::ParameterValue, 'Generate shell completion scripts') + [CompletionResult]::new('help', 'help', [CompletionResultType]::ParameterValue, 'Prints this message or the help of the given subcommand(s)') + break + } + 'innernet;install' { + [CompletionResult]::new('--hosts-path', 'hosts-path', [CompletionResultType]::ParameterName, 'The path to write hosts to') + [CompletionResult]::new('--name', 'name', [CompletionResultType]::ParameterName, 'Set a specific interface name') + [CompletionResult]::new('--no-write-hosts', 'no-write-hosts', [CompletionResultType]::ParameterName, 'Don''t write to any hosts files') + [CompletionResult]::new('--default-name', 'default-name', [CompletionResultType]::ParameterName, 'Use the network name inside the invitation as the interface name') + [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'Delete the invitation after a successful install') + [CompletionResult]::new('--delete-invite', 'delete-invite', [CompletionResultType]::ParameterName, 'Delete the invitation after a successful install') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;show' { + [CompletionResult]::new('-s', 's', [CompletionResultType]::ParameterName, 'One-line peer list') + [CompletionResult]::new('--short', 'short', [CompletionResultType]::ParameterName, 'One-line peer list') + [CompletionResult]::new('-t', 't', [CompletionResultType]::ParameterName, 'Display peers in a tree based on the CIDRs') + [CompletionResult]::new('--tree', 'tree', [CompletionResultType]::ParameterName, 'Display peers in a tree based on the CIDRs') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;up' { + [CompletionResult]::new('--interval', 'interval', [CompletionResultType]::ParameterName, 'Keep fetching the latest peer list at the specified interval in seconds. Valid only in daemon mode') + [CompletionResult]::new('--hosts-path', 'hosts-path', [CompletionResultType]::ParameterName, 'The path to write hosts to') + [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'Enable daemon mode i.e. keep the process running, while fetching the latest peer list periodically') + [CompletionResult]::new('--daemon', 'daemon', [CompletionResultType]::ParameterName, 'Enable daemon mode i.e. keep the process running, while fetching the latest peer list periodically') + [CompletionResult]::new('--no-write-hosts', 'no-write-hosts', [CompletionResultType]::ParameterName, 'Don''t write to any hosts files') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;fetch' { + [CompletionResult]::new('--hosts-path', 'hosts-path', [CompletionResultType]::ParameterName, 'The path to write hosts to') + [CompletionResult]::new('--no-write-hosts', 'no-write-hosts', [CompletionResultType]::ParameterName, 'Don''t write to any hosts files') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;uninstall' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;down' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;add-peer' { + [CompletionResult]::new('--name', 'name', [CompletionResultType]::ParameterName, 'Name of new peer') + [CompletionResult]::new('--ip', 'ip', [CompletionResultType]::ParameterName, 'Specify desired IP of new peer (within parent CIDR)') + [CompletionResult]::new('--cidr', 'cidr', [CompletionResultType]::ParameterName, 'Name of CIDR to add new peer under') + [CompletionResult]::new('--admin', 'admin', [CompletionResultType]::ParameterName, 'Make new peer an admin?') + [CompletionResult]::new('--save-config', 'save-config', [CompletionResultType]::ParameterName, 'Save the config to the given location') + [CompletionResult]::new('--invite-expires', 'invite-expires', [CompletionResultType]::ParameterName, 'Invite expiration period (eg. "30d", "7w", "2h", "60m", "1000s")') + [CompletionResult]::new('--auto-ip', 'auto-ip', [CompletionResultType]::ParameterName, 'Auto-assign the peer the first available IP within the CIDR') + [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Bypass confirmation') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;add-cidr' { + [CompletionResult]::new('--name', 'name', [CompletionResultType]::ParameterName, 'The CIDR name (eg. "engineers")') + [CompletionResult]::new('--cidr', 'cidr', [CompletionResultType]::ParameterName, 'The CIDR network (eg. "10.42.5.0/24")') + [CompletionResult]::new('--parent', 'parent', [CompletionResultType]::ParameterName, 'The CIDR parent name') + [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Bypass confirmation') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;delete-cidr' { + [CompletionResult]::new('--name', 'name', [CompletionResultType]::ParameterName, 'The CIDR name (eg. "engineers")') + [CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Bypass confirmation') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;disable-peer' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;enable-peer' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;add-association' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;delete-association' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;list-associations' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;set-listen-port' { + [CompletionResult]::new('-u', 'u', [CompletionResultType]::ParameterName, 'Unset the local listen port to use a randomized port') + [CompletionResult]::new('--unset', 'unset', [CompletionResultType]::ParameterName, 'Unset the local listen port to use a randomized port') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;override-endpoint' { + [CompletionResult]::new('-u', 'u', [CompletionResultType]::ParameterName, 'Unset an existing override to use the automatic endpoint discovery') + [CompletionResult]::new('--unset', 'unset', [CompletionResultType]::ParameterName, 'Unset an existing override to use the automatic endpoint discovery') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;completions' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + 'innernet;help' { + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Prints help information') + [CompletionResult]::new('-V', 'V', [CompletionResultType]::ParameterName, 'Prints version information') + [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Prints version information') + break + } + }) + + $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | + Sort-Object -Property ListItemText +} diff --git a/doc/innernet.completions.zsh b/doc/innernet.completions.zsh new file mode 100644 index 0000000..240da13 --- /dev/null +++ b/doc/innernet.completions.zsh @@ -0,0 +1,472 @@ +#compdef innernet + +autoload -U is-at-least + +_innernet() { + typeset -A opt_args + typeset -a _arguments_options + local ret=1 + + if is-at-least 5.2; then + _arguments_options=(-s -S -C) + else + _arguments_options=(-s -C) + fi + + local context curcontext="$curcontext" state line + _arguments "${_arguments_options[@]}" \ +'--backend=[Specify a WireGuard backend to use. If not set, innernet will auto-select based on availability]: :(kernel userspace)' \ +'*-v[]' \ +'--no-routing[Whether the routing should be done by innernet or is done by an external tool like e.g. babeld]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +":: :_innernet_commands" \ +"*::: :->innernet" \ +&& ret=0 + case $state in + (innernet) + words=($line[1] "${words[@]}") + (( CURRENT += 1 )) + curcontext="${curcontext%:*:*}:innernet-command-$line[1]:" + case $line[1] in + (redeem) +_arguments "${_arguments_options[@]}" \ +'--hosts-path=[The path to write hosts to]' \ +'(--default-name)--name=[Set a specific interface name]' \ +'(--hosts-path)--no-write-hosts[Don'\''t write to any hosts files]' \ +'--default-name[Use the network name inside the invitation as the interface name]' \ +'-d[Delete the invitation after a successful install]' \ +'--delete-invite[Delete the invitation after a successful install]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':invite -- Path to the invitation file:_files' \ +&& ret=0 +;; +(redeem) +_arguments "${_arguments_options[@]}" \ +'--hosts-path=[The path to write hosts to]' \ +'(--default-name)--name=[Set a specific interface name]' \ +'(--hosts-path)--no-write-hosts[Don'\''t write to any hosts files]' \ +'--default-name[Use the network name inside the invitation as the interface name]' \ +'-d[Delete the invitation after a successful install]' \ +'--delete-invite[Delete the invitation after a successful install]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':invite -- Path to the invitation file:_files' \ +&& ret=0 +;; +(install) +_arguments "${_arguments_options[@]}" \ +'--hosts-path=[The path to write hosts to]' \ +'(--default-name)--name=[Set a specific interface name]' \ +'(--hosts-path)--no-write-hosts[Don'\''t write to any hosts files]' \ +'--default-name[Use the network name inside the invitation as the interface name]' \ +'-d[Delete the invitation after a successful install]' \ +'--delete-invite[Delete the invitation after a successful install]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':invite -- Path to the invitation file:_files' \ +&& ret=0 +;; +(list) +_arguments "${_arguments_options[@]}" \ +'-s[One-line peer list]' \ +'--short[One-line peer list]' \ +'-t[Display peers in a tree based on the CIDRs]' \ +'--tree[Display peers in a tree based on the CIDRs]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +'::interface:_files' \ +&& ret=0 +;; +(list) +_arguments "${_arguments_options[@]}" \ +'-s[One-line peer list]' \ +'--short[One-line peer list]' \ +'-t[Display peers in a tree based on the CIDRs]' \ +'--tree[Display peers in a tree based on the CIDRs]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +'::interface:_files' \ +&& ret=0 +;; +(show) +_arguments "${_arguments_options[@]}" \ +'-s[One-line peer list]' \ +'--short[One-line peer list]' \ +'-t[Display peers in a tree based on the CIDRs]' \ +'--tree[Display peers in a tree based on the CIDRs]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +'::interface:_files' \ +&& ret=0 +;; +(up) +_arguments "${_arguments_options[@]}" \ +'--interval=[Keep fetching the latest peer list at the specified interval in seconds. Valid only in daemon mode]' \ +'--hosts-path=[The path to write hosts to]' \ +'-d[Enable daemon mode i.e. keep the process running, while fetching the latest peer list periodically]' \ +'--daemon[Enable daemon mode i.e. keep the process running, while fetching the latest peer list periodically]' \ +'(--hosts-path)--no-write-hosts[Don'\''t write to any hosts files]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(fetch) +_arguments "${_arguments_options[@]}" \ +'--hosts-path=[The path to write hosts to]' \ +'(--hosts-path)--no-write-hosts[Don'\''t write to any hosts files]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(uninstall) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(down) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(add-peer) +_arguments "${_arguments_options[@]}" \ +'--name=[Name of new peer]' \ +'(--auto-ip)--ip=[Specify desired IP of new peer (within parent CIDR)]' \ +'--cidr=[Name of CIDR to add new peer under]' \ +'--admin=[Make new peer an admin?]' \ +'--save-config=[Save the config to the given location]' \ +'--invite-expires=[Invite expiration period (eg. "30d", "7w", "2h", "60m", "1000s")]' \ +'--auto-ip[Auto-assign the peer the first available IP within the CIDR]' \ +'--yes[Bypass confirmation]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(add-cidr) +_arguments "${_arguments_options[@]}" \ +'--name=[The CIDR name (eg. "engineers")]' \ +'--cidr=[The CIDR network (eg. "10.42.5.0/24")]' \ +'--parent=[The CIDR parent name]' \ +'--yes[Bypass confirmation]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(delete-cidr) +_arguments "${_arguments_options[@]}" \ +'--name=[The CIDR name (eg. "engineers")]' \ +'--yes[Bypass confirmation]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(disable-peer) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(enable-peer) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(add-association) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +'::cidr1 -- The first cidr to associate:_files' \ +'::cidr2 -- The second cidr to associate:_files' \ +&& ret=0 +;; +(delete-association) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(list-associations) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(set-listen-port) +_arguments "${_arguments_options[@]}" \ +'-u[Unset the local listen port to use a randomized port]' \ +'--unset[Unset the local listen port to use a randomized port]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(override-endpoint) +_arguments "${_arguments_options[@]}" \ +'-u[Unset an existing override to use the automatic endpoint discovery]' \ +'--unset[Unset an existing override to use the automatic endpoint discovery]' \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':interface:_files' \ +&& ret=0 +;; +(completions) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +':shell:(zsh bash fish powershell elvish)' \ +&& ret=0 +;; +(help) +_arguments "${_arguments_options[@]}" \ +'-h[Prints help information]' \ +'--help[Prints help information]' \ +'-V[Prints version information]' \ +'--version[Prints version information]' \ +&& ret=0 +;; + esac + ;; +esac +} + +(( $+functions[_innernet_commands] )) || +_innernet_commands() { + local commands; commands=( + "install:Install a new innernet config" \ +"show:Enumerate all innernet connections" \ +"up:Bring up your local interface, and update it with latest peer list" \ +"fetch:Fetch and update your local interface with the latest peer list" \ +"uninstall:Uninstall an innernet network" \ +"down:Bring down the interface (equivalent to "wg-quick down ")" \ +"add-peer:Add a new peer" \ +"add-cidr:Add a new CIDR" \ +"delete-cidr:Delete a CIDR" \ +"disable-peer:Disable an enabled peer" \ +"enable-peer:Enable a disabled peer" \ +"add-association:Add an association between CIDRs" \ +"delete-association:Delete an association between CIDRs" \ +"list-associations:List existing assocations between CIDRs" \ +"set-listen-port:Set the local listen port" \ +"override-endpoint:Override your external endpoint that the server sends to other peers" \ +"completions:Generate shell completion scripts" \ +"help:Prints this message or the help of the given subcommand(s)" \ + ) + _describe -t commands 'innernet commands' commands "$@" +} +(( $+functions[_innernet__add-association_commands] )) || +_innernet__add-association_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet add-association commands' commands "$@" +} +(( $+functions[_innernet__add-cidr_commands] )) || +_innernet__add-cidr_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet add-cidr commands' commands "$@" +} +(( $+functions[_innernet__add-peer_commands] )) || +_innernet__add-peer_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet add-peer commands' commands "$@" +} +(( $+functions[_innernet__completions_commands] )) || +_innernet__completions_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet completions commands' commands "$@" +} +(( $+functions[_innernet__delete-association_commands] )) || +_innernet__delete-association_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet delete-association commands' commands "$@" +} +(( $+functions[_innernet__delete-cidr_commands] )) || +_innernet__delete-cidr_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet delete-cidr commands' commands "$@" +} +(( $+functions[_innernet__disable-peer_commands] )) || +_innernet__disable-peer_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet disable-peer commands' commands "$@" +} +(( $+functions[_innernet__down_commands] )) || +_innernet__down_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet down commands' commands "$@" +} +(( $+functions[_innernet__enable-peer_commands] )) || +_innernet__enable-peer_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet enable-peer commands' commands "$@" +} +(( $+functions[_innernet__fetch_commands] )) || +_innernet__fetch_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet fetch commands' commands "$@" +} +(( $+functions[_innernet__help_commands] )) || +_innernet__help_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet help commands' commands "$@" +} +(( $+functions[_innernet__install_commands] )) || +_innernet__install_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet install commands' commands "$@" +} +(( $+functions[_innernet__list_commands] )) || +_innernet__list_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet list commands' commands "$@" +} +(( $+functions[_list_commands] )) || +_list_commands() { + local commands; commands=( + + ) + _describe -t commands 'list commands' commands "$@" +} +(( $+functions[_innernet__list-associations_commands] )) || +_innernet__list-associations_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet list-associations commands' commands "$@" +} +(( $+functions[_innernet__override-endpoint_commands] )) || +_innernet__override-endpoint_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet override-endpoint commands' commands "$@" +} +(( $+functions[_innernet__redeem_commands] )) || +_innernet__redeem_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet redeem commands' commands "$@" +} +(( $+functions[_redeem_commands] )) || +_redeem_commands() { + local commands; commands=( + + ) + _describe -t commands 'redeem commands' commands "$@" +} +(( $+functions[_innernet__set-listen-port_commands] )) || +_innernet__set-listen-port_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet set-listen-port commands' commands "$@" +} +(( $+functions[_innernet__show_commands] )) || +_innernet__show_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet show commands' commands "$@" +} +(( $+functions[_innernet__uninstall_commands] )) || +_innernet__uninstall_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet uninstall commands' commands "$@" +} +(( $+functions[_innernet__up_commands] )) || +_innernet__up_commands() { + local commands; commands=( + + ) + _describe -t commands 'innernet up commands' commands "$@" +} + +_innernet "$@" \ No newline at end of file diff --git a/release.sh b/release.sh index 7386977..1300a7a 100755 --- a/release.sh +++ b/release.sh @@ -27,6 +27,10 @@ git reset --soft @~1 cargo build for binary in "innernet" "innernet-server"; do + for shell in {fish,zsh,bash,powershell,elvish}; do + "target/debug/$binary" completions $shell > doc/$binary.completions.$shell + git diff --quiet -- doc/$binary.completions.$shell || die "CLI and Completions out of sync for $shell" + done help2man --no-discard-stderr -s8 "target/debug/$binary" -N > "doc/$binary.8" gzip -fk "doc/$binary.8" done diff --git a/rpm/Dockerfile b/rpm/Dockerfile index 29eb0b5..9fd2d15 100644 --- a/rpm/Dockerfile +++ b/rpm/Dockerfile @@ -14,7 +14,7 @@ RUN rm -rf target RUN source $HOME/.cargo/env && \ cargo install cargo-rpm && \ - cargo build --release --verbose&& \ + cargo build --release --verbose && \ # device::tests::test_add_peers will fail due to restricted docker env cargo test --release --verbose -- --skip test_add_peers && \ cd server && cargo rpm build && \ diff --git a/server/Cargo.toml b/server/Cargo.toml index 5b86023..8c8012c 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -50,6 +50,9 @@ assets = [ ["target/release/innernet-server", "usr/bin/", "755"], ["innernet-server@.service", "usr/lib/systemd/system/", "644"], ["../doc/innernet-server.8.gz", "usr/share/man/man8/", "644"], + ["../doc/innernet-server.completions.zsh", "usr/share/zsh/site-functions/_innernet-server", "644"], + ["../doc/innernet-server.completions.bash", "etc/bash_completion.d/innernet-server", "644"], + ["../doc/innernet-server.completions.fish", "usr/share/fish/vendor_completions.d/innernet-server.fish", "644"], ] depends = "libc6, libgcc1, libsqlite3-0, zlib1g, systemd" maintainer = "tonari " @@ -66,6 +69,9 @@ buildflags = ["--release"] [package.metadata.rpm.files] "../../doc/innernet-server.8.gz" = { path = "/usr/share/man/man8/innernet-server.8.gz" } "../innernet-server@.service" = { path = "/usr/lib/systemd/system/innernet-server@.service" } +"../../doc/innernet-server.completions.bash" = { path = "/etc/bash_completion.d/innernet-server" } +"../../doc/innernet-server.completions.fish" = { path = "/usr/share/fish/vendor_completions.d/innernet-server.fish" } +"../../doc/innernet-server.completions.zsh" = { path = "/usr/share/zsh/site-functions/_innernet-server" } [package.metadata.rpm.targets] innernet-server = { path = "/usr/bin/innernet-server" } diff --git a/server/src/main.rs b/server/src/main.rs index acdf028..5f218fa 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -95,6 +95,12 @@ enum Command { #[structopt(flatten)] args: DeleteCidrOpts, }, + + /// Generate shell completion scripts + Completions { + #[structopt(possible_values = &structopt::clap::Shell::variants(), case_insensitive = true)] + shell: structopt::clap::Shell, + }, } pub type Db = Arc>; @@ -232,6 +238,10 @@ async fn main() -> Result<(), Box> { Command::AddPeer { interface, args } => add_peer(&interface, &conf, args, opt.network)?, Command::AddCidr { interface, args } => add_cidr(&interface, &conf, args)?, Command::DeleteCidr { interface, args } => delete_cidr(&interface, &conf, args)?, + Command::Completions { shell } => { + Opt::clap().gen_completions_to("innernet-server", shell, &mut std::io::stdout()); + std::process::exit(0); + }, } Ok(())