Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add completions sub-command to generate shell completion scripts #592

Merged
merged 2 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>>> bash\n\nAdd this to your `~/.bash_profile`:\n\n eval \"$(oxide completion -s bash)\"\n\n>>> zsh\n\nGenerate an `_oxide` completion script and put it somewhere in your\n`$fpath`, for example:\n\n oxide completion -s zsh > ~/.zfunc/_oxide\n\nand check that you have the following lines in your `~/.zshrc`:\n\n autoload -U compinit\n compinit -i\n\n>>> fish\n\nGenerate an `oxide.fish` completion script:\n\n oxide completion -s fish > ~/.config/fish/completions/oxide.fish\n\n>>> PowerShell\n\nOpen your profile script with:\n\n mkdir -Path (Split-Path -Parent $profile)\n notepad $profile\n\nAdd the following line and save the file:\n\n Invoke-Expression -Command $(oxide completion -s powershell | Out-String)\n\n>>> Elvish\n\nGenerate an `oxide.elv` completion script and put it in a module search\ndirectory, for example:\n\n oxide completion -s elvish > ~/.local/share/elvish/lib/oxide.elv\n\nand import this by adding the following to `~/.config/elvish/rc.elv`\n\n use oxide",
"args": [
{
"long": "shell",
"short": "s",
"values": [
"bash",
"elvish",
"fish",
"powershell",
"zsh"
],
"help": "Type of the shell"
}
]
},
{
"name": "current-user",
"subcommands": [
Expand Down
83 changes: 83 additions & 0 deletions cli/src/cmd_completion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// 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.
///
/// >>> bash
///
/// Add this to your `~/.bash_profile`:
///
/// eval "$(oxide completion -s bash)"
///
/// >>> zsh
///
/// Generate an `_oxide` completion script and put it somewhere in your
/// `$fpath`, for example:
///
/// oxide completion -s zsh > ~/.zfunc/_oxide
///
/// and check that you have the following lines in your `~/.zshrc`:
///
/// autoload -U compinit
/// compinit -i
///
/// >>> fish
///
/// Generate an `oxide.fish` completion script:
///
/// oxide completion -s fish > ~/.config/fish/completions/oxide.fish
///
/// >>> PowerShell
///
/// Open your profile script with:
///
/// mkdir -Path (Split-Path -Parent $profile)
/// notepad $profile
///
/// Add the following line and save the file:
///
/// 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:
///
/// oxide completion -s elvish > ~/.local/share/elvish/lib/oxide.elv
///
/// and import this by adding the following to `~/.config/elvish/rc.elv`
///
/// use oxide
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beautiful comment, might need formatting tweaks depending on how it renders on the docs site. I believe we treat this as markdown. Testing now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. Working on a PR to this PR since my iteration cycle alone is a lot faster than me suggesting changes to you and you pushing commits and me testing them.

image

#[derive(Parser, Debug, Clone)]
#[command(verbatim_doc_comment)]
#[command(name = "generate-completions")]
pub struct CmdCompletion {
/// Type of the shell
#[clap(short, long)]
shell: Shell,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comes out perfectly in the docs. Great.

image

}

#[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
Loading