Skip to content

Commit

Permalink
Add completions sub-command to generate shell completion scripts (#592)
Browse files Browse the repository at this point in the history
* Add completions sub-command to generate shell completion scripts

---------

Co-authored-by: David Crespo <[email protected]>
  • Loading branch information
citrus-it and david-crespo authored Mar 18, 2024
1 parent 7726222 commit 8fc14f8
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ base64 = "0.21.7"
built = { version = "0.7.1", features = ["git2"] }
chrono = { version = "0.4.34", features = ["serde"] }
clap = { version = "4.5.1", features = ["derive", "string", "env"] }
clap_complete = "4.5.1"
dialoguer = "0.10.4"
dirs = "4.0.0"
dropshot = { git = "https://github.com/oxidecomputer/dropshot" }
Expand Down
1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ async-trait = { workspace = true }
base64 = { workspace = true }
chrono = { workspace = true }
clap = { workspace = true }
clap_complete = { workspace = true }
dialoguer = { workspace = true }
dirs = { workspace = true }
env_logger = { workspace = true }
Expand Down
19 changes: 19 additions & 0 deletions cli/docs/cli.json
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,25 @@
}
]
},
{
"name": "completion",
"about": "Generate shell completion scripts for Oxide CLI commands.",
"long_about": "Generate shell completion scripts for Oxide CLI commands.\n\nThis command generates scripts for various shells that can be used to\nenable completion.\n\n## Installation\n\n### Bash\n\nAdd this to your `~/.bash_profile`:\n\n```sh\neval \"$(oxide completion -s bash)\"\n```\n\n### Zsh\n\nGenerate an `_oxide` completion script and put it somewhere in your\n`$fpath`, for example:\n\n```sh\noxide completion -s zsh > ~/.zfunc/_oxide\n```\n\nand check that you have the following lines in your `~/.zshrc`:\n\n```sh\nautoload -U compinit\ncompinit -i\n```\n\n### Fish\n\nGenerate an `oxide.fish` completion script:\n\n```sh\noxide completion -s fish > ~/.config/fish/completions/oxide.fish\n```\n\n### PowerShell\n\nOpen your profile script with:\n\n```sh\nmkdir -Path (Split-Path -Parent $profile)\nnotepad $profile\n```\n\nAdd the following line and save the file:\n\n```powershell\nInvoke-Expression -Command $(oxide completion -s powershell | Out-String)\n```\n\n### Elvish\n\nGenerate an `oxide.elv` completion script and put it in a module search\ndirectory, for example:\n\n```sh\noxide completion -s elvish > ~/.local/share/elvish/lib/oxide.elv\n```\n\nand import this by adding the following to `~/.config/elvish/rc.elv`\n\n```\nuse oxide\n```",
"args": [
{
"long": "shell",
"short": "s",
"values": [
"bash",
"elvish",
"fish",
"powershell",
"zsh"
],
"help": "Shell type"
}
]
},
{
"name": "current-user",
"subcommands": [
Expand Down
101 changes: 101 additions & 0 deletions cli/src/cmd_completion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

// Copyright 2024 Oxide Computer Company

use crate::RunnableCmd;
use anyhow::Result;
use async_trait::async_trait;
use clap::Parser;
use clap_complete::{generate, Shell};
use std::io;

/// Generate shell completion scripts for Oxide CLI commands.
///
/// This command generates scripts for various shells that can be used to
/// enable completion.
///
/// ## Installation
///
/// ### Bash
///
/// Add this to your `~/.bash_profile`:
///
/// ```sh
/// eval "$(oxide completion -s bash)"
/// ```
///
/// ### Zsh
///
/// Generate an `_oxide` completion script and put it somewhere in your
/// `$fpath`, for example:
///
/// ```sh
/// oxide completion -s zsh > ~/.zfunc/_oxide
/// ```
///
/// and check that you have the following lines in your `~/.zshrc`:
///
/// ```sh
/// autoload -U compinit
/// compinit -i
/// ```
///
/// ### Fish
///
/// Generate an `oxide.fish` completion script:
///
/// ```sh
/// oxide completion -s fish > ~/.config/fish/completions/oxide.fish
/// ```
///
/// ### PowerShell
///
/// Open your profile script with:
///
/// ```sh
/// mkdir -Path (Split-Path -Parent $profile)
/// notepad $profile
/// ```
///
/// Add the following line and save the file:
///
/// ```powershell
/// Invoke-Expression -Command $(oxide completion -s powershell | Out-String)
/// ```
///
/// ### Elvish
///
/// Generate an `oxide.elv` completion script and put it in a module search
/// directory, for example:
///
/// ```sh
/// oxide completion -s elvish > ~/.local/share/elvish/lib/oxide.elv
/// ```
///
/// and import this by adding the following to `~/.config/elvish/rc.elv`
///
/// ```
/// use oxide
/// ```
#[derive(Parser, Debug, Clone)]
#[command(verbatim_doc_comment)]
#[command(name = "generate-completions")]
pub struct CmdCompletion {
/// Shell type
#[clap(short, long)]
shell: Shell,
}

#[async_trait]
impl RunnableCmd for CmdCompletion {
async fn run(&self, _ctx: &oxide::context::Context) -> Result<()> {
let cli = crate::make_cli();
let mut cmd = cli.command_take();
let name = cmd.get_name().to_string();
generate(self.shell, &mut cmd, name, &mut io::stdout());

Ok(())
}
}
2 changes: 2 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use oxide::types::{IdpMetadataSource, IpRange, Ipv4Range, Ipv6Range};
mod cli_builder;
mod cmd_api;
mod cmd_auth;
mod cmd_completion;
mod cmd_disk;
mod cmd_docs;
mod cmd_instance;
Expand Down Expand Up @@ -47,6 +48,7 @@ pub fn make_cli() -> NewCli<'static> {
.add_custom::<cmd_disk::CmdDiskImport>("disk import")
.add_custom::<cmd_instance::CmdInstanceSerial>("instance serial")
.add_custom::<cmd_instance::CmdInstanceFromImage>("instance from-image")
.add_custom::<cmd_completion::CmdCompletion>("completion")
}

#[tokio::main]
Expand Down

0 comments on commit 8fc14f8

Please sign in to comment.