Adds shell completion generation.
This commit is contained in:
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -558,6 +558,15 @@ dependencies = [
|
|||||||
"strsim",
|
"strsim",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_complete"
|
||||||
|
version = "4.6.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3be2ad0423bdbbb0e25bc89add796f3559706d4a95e1bc98e4d9662a957b6a19"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.6.4"
|
version = "4.6.4"
|
||||||
@@ -2492,6 +2501,7 @@ name = "nut"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
|
"clap_complete",
|
||||||
"indicatif",
|
"indicatif",
|
||||||
"nextcloud_client",
|
"nextcloud_client",
|
||||||
"open",
|
"open",
|
||||||
|
|||||||
14
Tasks.md
14
Tasks.md
@@ -71,7 +71,6 @@ This document defines the complete project roadmap and task tracking system for
|
|||||||
| ID | Title | Status | Type |
|
| ID | Title | Status | Type |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| [NUT-019](#nut-019) | Implement Homebrew/Winget/Chocolatey Manifests | Triage | Chore |
|
| [NUT-019](#nut-019) | Implement Homebrew/Winget/Chocolatey Manifests | Triage | Chore |
|
||||||
| [NUT-022](#nut-022) | Implement CLI Shell Completions Generation | Triage | Feature |
|
|
||||||
| [NUT-023](#nut-023) | Write Comprehensive CLI Documentation and Automation Guides | Triage | Chore |
|
| [NUT-023](#nut-023) | Write Comprehensive CLI Documentation and Automation Guides | Triage | Chore |
|
||||||
| [NUT-024](#nut-024) | Create Docker/Podman Nextcloud Integration Test Harness | Triage | Foundation |
|
| [NUT-024](#nut-024) | Create Docker/Podman Nextcloud Integration Test Harness | Triage | Foundation |
|
||||||
| [NUT-001](#nut-001) | Establish Repository Structure | Fixed | Foundation |
|
| [NUT-001](#nut-001) | Establish Repository Structure | Fixed | Foundation |
|
||||||
@@ -94,6 +93,7 @@ This document defines the complete project roadmap and task tracking system for
|
|||||||
| [NUT-018](#nut-018) | Implement Packaging for macOS, Windows, Linux | Fixed | Chore |
|
| [NUT-018](#nut-018) | Implement Packaging for macOS, Windows, Linux | Fixed | Chore |
|
||||||
| [NUT-020](#nut-020) | Write Documentation + Examples | Fixed | Chore |
|
| [NUT-020](#nut-020) | Write Documentation + Examples | Fixed | Chore |
|
||||||
| [NUT-021](#nut-021) | Support Headless & SSH Remote Authentication Modes | Fixed | Feature |
|
| [NUT-021](#nut-021) | Support Headless & SSH Remote Authentication Modes | Fixed | Feature |
|
||||||
|
| [NUT-022](#nut-022) | Implement CLI Shell Completions Generation | Fixed | Feature |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -522,20 +522,20 @@ Ensure smooth authentication experiences when running the CLI over SSH or in hea
|
|||||||
- NUT-008
|
- NUT-008
|
||||||
|
|
||||||
|
|
||||||
<a id="nut-022" class="task" data-status="triage" data-task-type="feature"></a>
|
<a id="nut-022" class="task" data-status="done" data-task-type="feature"></a>
|
||||||
### Implement CLI Shell Completions Generation
|
### Implement CLI Shell Completions Generation
|
||||||
**ID:** NUT-022
|
**ID:** NUT-022
|
||||||
**Status:** Triage
|
**Status:** Fixed
|
||||||
**Type:** Feature
|
**Type:** Feature
|
||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
Add automated shell completion script generation using `clap_complete` for major shells (`bash`, `zsh`, `fish`, `powershell`, `elvish`).
|
Add automated shell completion script generation using `clap_complete` for major shells (`bash`, `zsh`, `fish`, `powershell`, `elvish`).
|
||||||
|
|
||||||
**Requirements:**
|
**Requirements:**
|
||||||
- [ ] Add `clap_complete` crate dependency
|
- [x] Add `clap_complete` crate dependency
|
||||||
- [ ] Implement `nut completions <SHELL>` subcommand
|
- [x] Implement `nut completions <SHELL>` subcommand
|
||||||
- [ ] Support `bash`, `zsh`, `fish`, `powershell`, and `elvish` output to stdout
|
- [x] Support `bash`, `zsh`, `fish`, `powershell`, and `elvish` output to stdout
|
||||||
- [ ] Include quick installation instructions in command help
|
- [x] Include quick installation instructions in command help
|
||||||
|
|
||||||
**Dependencies:**
|
**Dependencies:**
|
||||||
- NUT-008
|
- NUT-008
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ edition = "2024"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
nextcloud_client = { path = "../nextcloud_client" }
|
nextcloud_client = { path = "../nextcloud_client" }
|
||||||
clap = { version = "4.5", features = ["derive", "cargo"] }
|
clap = { version = "4.5", features = ["derive", "cargo"] }
|
||||||
|
clap_complete = "4.5"
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
reqwest = { version = "0.12", default-features = false, features = ["json", "default-tls"] }
|
reqwest = { version = "0.12", default-features = false, features = ["json", "default-tls"] }
|
||||||
open = "5.3"
|
open = "5.3"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use clap::{Args, Parser, Subcommand};
|
use clap::{Args, CommandFactory, Parser, Subcommand};
|
||||||
|
use clap_complete::{generate, Shell};
|
||||||
use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@@ -39,6 +40,13 @@ enum Commands {
|
|||||||
|
|
||||||
/// Quick alias to list all configured accounts
|
/// Quick alias to list all configured accounts
|
||||||
Accounts(AccountListArgs),
|
Accounts(AccountListArgs),
|
||||||
|
|
||||||
|
/// Generate shell completion scripts for bash, zsh, fish, powershell, or elvish
|
||||||
|
Completions {
|
||||||
|
/// Target shell to generate completions for
|
||||||
|
#[arg(value_enum)]
|
||||||
|
shell: Shell,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args, Debug, PartialEq)]
|
#[derive(Args, Debug, PartialEq)]
|
||||||
@@ -207,6 +215,10 @@ async fn main() {
|
|||||||
handle_account_set_default(&account)
|
handle_account_set_default(&account)
|
||||||
}
|
}
|
||||||
Commands::Account(AccountCommands::Delete { account }) => handle_account_delete(&account),
|
Commands::Account(AccountCommands::Delete { account }) => handle_account_delete(&account),
|
||||||
|
Commands::Completions { shell } => {
|
||||||
|
handle_completions(shell);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
@@ -215,6 +227,12 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate shell completion scripts for supported shells.
|
||||||
|
fn handle_completions(shell: Shell) {
|
||||||
|
let mut cmd = Cli::command();
|
||||||
|
generate(shell, &mut cmd, "nut", &mut io::stdout());
|
||||||
|
}
|
||||||
|
|
||||||
/// Handle interactive or non-interactive login flows.
|
/// Handle interactive or non-interactive login flows.
|
||||||
async fn handle_login(args: LoginArgs) -> Result<()> {
|
async fn handle_login(args: LoginArgs) -> Result<()> {
|
||||||
let server_url = ClientConfig::normalize_url(&args.server_url)?;
|
let server_url = ClientConfig::normalize_url(&args.server_url)?;
|
||||||
@@ -822,4 +840,35 @@ mod tests {
|
|||||||
_ => panic!("Expected Accounts list command"),
|
_ => panic!("Expected Accounts list command"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cli_completions_parsing() {
|
||||||
|
let shells = [
|
||||||
|
("bash", Shell::Bash),
|
||||||
|
("zsh", Shell::Zsh),
|
||||||
|
("fish", Shell::Fish),
|
||||||
|
("powershell", Shell::PowerShell),
|
||||||
|
("elvish", Shell::Elvish),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (name, expected_shell) in shells {
|
||||||
|
let parsed = Cli::try_parse_from(&["nut", "completions", name]).unwrap();
|
||||||
|
match parsed.command {
|
||||||
|
Commands::Completions { shell } => {
|
||||||
|
assert_eq!(shell, expected_shell);
|
||||||
|
}
|
||||||
|
_ => panic!("Expected Completions command for shell {name}"),
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
let mut cmd = Cli::command();
|
||||||
|
generate(expected_shell, &mut cmd, "nut", &mut buf);
|
||||||
|
assert!(!buf.is_empty(), "Generated completion for {name} should not be empty");
|
||||||
|
let output_str = String::from_utf8(buf).expect("Completions should be valid UTF-8");
|
||||||
|
assert!(
|
||||||
|
output_str.contains("nut"),
|
||||||
|
"Completion output should contain 'nut'"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user