From 9c83baf9eebea5a8c31de976e03fcc9c2add096d Mon Sep 17 00:00:00 2001 From: XyLyXyRR <39663597+XyLyXyRR@users.noreply.github.com> Date: Sat, 22 Oct 2022 01:06:26 +0800 Subject: [PATCH] feat: shell completions (#343) --- Cargo.lock | 10 ++++++++++ cargo-shuttle/Cargo.toml | 1 + cargo-shuttle/src/args.rs | 10 ++++++++++ cargo-shuttle/src/lib.rs | 14 ++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 17b86bc1a..7b9447b54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1191,6 +1191,7 @@ dependencies = [ "cargo_metadata", "chrono", "clap 3.2.17", + "clap_complete", "crossbeam-channel", "crossterm", "dirs", @@ -1357,6 +1358,15 @@ dependencies = [ "termcolor", ] +[[package]] +name = "clap_complete" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f7a2e0a962c45ce25afce14220bc24f9dade0a1787f185cecf96bfba7847cd8" +dependencies = [ + "clap 3.2.17", +] + [[package]] name = "clap_derive" version = "3.2.17" diff --git a/cargo-shuttle/Cargo.toml b/cargo-shuttle/Cargo.toml index 00ed551af..b4bea91e9 100644 --- a/cargo-shuttle/Cargo.toml +++ b/cargo-shuttle/Cargo.toml @@ -15,6 +15,7 @@ cargo-edit = { version = "0.10.4", features = ["cli"] } cargo_metadata = "0.15.0" chrono = "0.4.22" clap = { version = "3.2.17", features = ["derive", "env"] } +clap_complete = "3.2.5" crossbeam-channel = "0.5.6" crossterm = "0.25.0" dirs = "4.0.0" diff --git a/cargo-shuttle/src/args.rs b/cargo-shuttle/src/args.rs index dd6c93973..de3f12a63 100644 --- a/cargo-shuttle/src/args.rs +++ b/cargo-shuttle/src/args.rs @@ -6,6 +6,7 @@ use std::{ }; use clap::Parser; +use clap_complete::Shell; use shuttle_common::project::ProjectName; use uuid::Uuid; @@ -56,6 +57,15 @@ pub enum Command { Deployment(DeploymentCommand), /// create a new shuttle service Init(InitArgs), + /// generate shell completions + Generate { + /// which shell + #[clap(short, long, env, default_value_t = Shell::Bash)] + shell: Shell, + /// output to file or stdout by default + #[clap(short, long, env)] + output: Option, + }, /// view the status of a shuttle service Status, /// view the logs of a deployment in this shuttle service diff --git a/cargo-shuttle/src/lib.rs b/cargo-shuttle/src/lib.rs index a68760084..291fbe200 100644 --- a/cargo-shuttle/src/lib.rs +++ b/cargo-shuttle/src/lib.rs @@ -19,6 +19,8 @@ use cargo::core::resolver::CliFeatures; use cargo::core::Workspace; use cargo::ops::{PackageOpts, Packages}; use cargo_metadata::Message; +use clap::CommandFactory; +use clap_complete::{generate, Shell}; use config::RequestContext; use crossterm::style::Stylize; use factory::LocalFactory; @@ -61,6 +63,7 @@ impl Shuttle { match args.cmd { Command::Init(init_args) => self.init(init_args).await, + Command::Generate { shell, output } => self.complete(shell, output).await, Command::Login(login_args) => self.login(login_args).await, Command::Run(run_args) => self.local_run(run_args).await, need_client => { @@ -175,6 +178,17 @@ impl Shuttle { Ok(()) } + async fn complete(&self, shell: Shell, output: Option) -> Result<()> { + let name = env!("CARGO_PKG_NAME"); + let mut app = Command::command(); + match output { + Some(v) => generate(shell, &mut app, name, &mut File::create(v)?), + None => generate(shell, &mut app, name, &mut stdout()), + }; + + Ok(()) + } + async fn status(&self, client: &Client) -> Result<()> { let summary = client.get_service_summary(self.ctx.project_name()).await?;