Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions .lychee.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# .lychee.yaml
exclude:
- "https://www.gnu.org/software/libc/"
1 change: 1 addition & 0 deletions .mise/tasks/check-links.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

find . -type f -name "*.md" \
-not -path "*/node_modules/*" \
-not -path "*/CHANGELOG.md" \
-not -path "*/target/*" \
-not -path "*/docs/*" \
-not -path "*/.*/*" \
Expand Down
11 changes: 11 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ cargo_metadata = "0.23"
calm_io = "0.1"
camino = { version = "1", features = ["serde1"] }
clap = "4"
clap_complete = "4"
chrono = "0.4"
ci_info = "0.14"
comfy-table = { version = "7", features = ["custom_styling"] }
Expand Down Expand Up @@ -187,6 +188,7 @@ buildstructor = { workspace = true }
calm_io = { workspace = true }
camino = { workspace = true }
clap = { workspace = true, features = ["color", "derive", "env"] }
clap_complete = { workspace = true }
chrono = { workspace = true }
console = { workspace = true }
derive-getters = { workspace = true }
Expand Down Expand Up @@ -263,6 +265,7 @@ speculoos = { workspace = true }
tower-test = { workspace = true }
tracing-test = { workspace = true }
temp-env = { version = "0.3", features = ["async_closure"] }
which = { workspace = true }

# For sputnik, run tests with debug_assertions disabled. This is necessary because telemetry is not sent if
# debug_assertions is enabled, and the tests rely on telemetry being sent to mock APIs.
Expand Down
2 changes: 2 additions & 0 deletions docs/source/_sidebar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ items:
href: ./commands/api-key
- label: cloud
href: ./commands/cloud
- label: completion
href: ./commands/completion
- label: config
href: ./commands/config
- label: connector
Expand Down
91 changes: 91 additions & 0 deletions docs/source/commands/completion.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
title: Rover completion Commands

Check warning on line 2 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L2

Use title casing for page titles. ```suggestion title: Rover Completion Commands ```
subtitle: Generate shell completion scripts for bash and zsh
description: Generate shell completion scripts to enable tab completion for Rover commands in bash and zsh shells.
---

Rover provides shell completion support for bash and zsh, enabling tab completion for Rover commands and their options. This makes it easier to discover available commands and options while working in the terminal.

## Generating completion scripts

### `completion bash`

The `completion bash` command generates a bash completion script:

```

Check warning on line 15 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L15

Specify the example's programming language for syntax highlighting. ```suggestion ```bash ```
rover completion bash
```

This outputs a bash completion script to `stdout`. To enable bash completion, save the output to a file and source it in your shell configuration:

```bash
# Save the completion script
rover completion bash > ~/.rover-completion.bash

# Add to your ~/.bashrc or ~/.bash_profile
echo "source ~/.rover-completion.bash" >> ~/.bashrc

# Reload your shell configuration
source ~/.bashrc # or restart your terminal
```

You'll now have tab completion for Rover commands.

Check notice on line 32 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L32

Favor the present tense. ```suggestion You now have tab completion for Rover commands. ```

### `completion zsh`

The `completion zsh` command generates a zsh completion script:

```

Check warning on line 38 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L38

Specify the example's programming language for syntax highlighting. ```suggestion ```bash ```
rover completion zsh
```

This outputs a zsh completion script to `stdout`. To enable zsh completion, save the output to a file and source it in your shell configuration:

```zsh
# Save the completion script
rover completion zsh > ~/.rover-completion.zsh

# Add to your ~/.zshrc
echo "source ~/.rover-completion.zsh" >> ~/.zshrc

# Reload your shell configuration
source ~/.zshrc # or restart your terminal
```

You'll now have tab completion for Rover commands.

Check notice on line 55 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L55

Favor the present tense. ```suggestion You now have tab completion for Rover commands. ```

Alternatively, you can use zsh's completion system by placing the script in your `fpath`:

```zsh
# Create completion directory if it doesn't exist
mkdir -p /usr/local/share/zsh/site-functions

# Save the completion script to fpath
rover completion zsh > /usr/local/share/zsh/site-functions/_rover

# Reload completions (or restart your terminal)
compinit
```

## Using completion

Once enabled, you can use tab completion to:

- Complete command names: Type `rover ` and press `Tab` to see available commands

Check notice on line 74 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L74

Include ending punctuation for list items that are complete sentences. ```suggestion - Complete command names: Type `rover ` and press `Tab` to see available commands. ```
- Complete subcommands: Type `rover graph ` and press `Tab` to see available graph subcommands

Check notice on line 75 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L75

Include ending punctuation for list items that are complete sentences. ```suggestion - Complete subcommands: Type `rover graph ` and press `Tab` to see available graph subcommands. ```
- Complete options: Type `rover graph publish ` and press `Tab` to see available options and flags

Check notice on line 76 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L76

Include ending punctuation for list items that are complete sentences. ```suggestion - Complete options: Type `rover graph publish ` and press `Tab` to see available options and flags. ```

## Testing completion

To verify that completion is working correctly:

1. Open a new terminal or reload your shell configuration
2. Type `rover ` (with a space) and press `Tab` - you should see a list of available commands

Check notice on line 83 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L83

Favor the active voice and present tense. Avoid 'should' to maintain an authoritative tone. Include ending punctuation. ```suggestion 2. Type `rover ` (with a space) and press `Tab`. A list of available commands appears. ```
3. Type `rover gra` and press `Tab` - it should autocomplete to `rover graph`

Check notice on line 84 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L84

Favor the active voice and present tense. Avoid 'should'. Include ending punctuation. ```suggestion 3. Type `rover gra` and press `Tab`. The command autocompletes to `rover graph`. ```
4. Continue typing `rover graph ` and press `Tab` - you should see available subcommands like `check`, `publish`, `fetch`, etc.

Check notice on line 85 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L85

Favor the active voice and present tense. Avoid 'should'. Use the Oxford comma. ```suggestion 4. Continue typing `rover graph ` and press `Tab`. Available subcommands appear, such as `check`, `publish`, and `fetch`. ```

If completion isn't working, ensure that:
- You've reloaded your shell configuration or opened a new terminal

Check notice on line 88 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L88

Include ending punctuation for list items that are complete sentences. ```suggestion - You've reloaded your shell configuration or opened a new terminal. ```
- The completion script file exists and is readable

Check notice on line 89 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L89

Include ending punctuation for list items that are complete sentences. ```suggestion - The completion script file exists and is readable. ```
- For bash: The script is being sourced in your `~/.bashrc` or `~/.bash_profile`

Check notice on line 90 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L90

Include ending punctuation for list items that are complete sentences. ```suggestion - For bash: The script is being sourced in your `~/.bashrc` or `~/.bash_profile`. ```
- For zsh: The script is being sourced in your `~/.zshrc` or is in your `fpath`

Check notice on line 91 in docs/source/commands/completion.mdx

View check run for this annotation

Apollo Librarian / AI Style Review

docs/source/commands/completion.mdx#L91

Include ending punctuation for list items that are complete sentences. ```suggestion - For zsh: The script is being sourced in your `~/.zshrc` or is in your `fpath`. ```
4 changes: 4 additions & 0 deletions docs/source/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ There are a few additional installation methods maintained by the community:
1. [Homebrew](https://formulae.brew.sh/formula/rover#default)
2. [Nix](https://search.nixos.org/packages?channel=unstable&show=rover&from=0&size=50&sort=relevance&type=packages&query=rover)

## Next steps

After installing Rover, you can set up shell completion for bash or zsh to enable tab completion for Rover commands. See the [completion command documentation](./commands/completion) for instructions.

## Connecting to GraphOS

After you install Rover, you should authenticate it with [GraphOS](/graphos/), because many of its commands communicate with GraphOS.
Expand Down
4 changes: 4 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ impl Rover {
match &self.command {
Command::Init(command) => command.run(self.get_client_config()?).await,
Command::Cloud(command) => command.run(self.get_client_config()?).await,
Command::Completion(command) => command.run(),
Command::Config(command) => command.run(self.get_client_config()?).await,
#[cfg(feature = "composition-js")]
Command::Connector(command) => {
Expand Down Expand Up @@ -392,6 +393,9 @@ pub enum Command {
#[cfg(feature = "composition-js")]
Connector(command::Connector),

/// Generate shell completion scripts
Completion(command::Completion),

/// Configuration profile commands
Config(command::Config),

Expand Down
17 changes: 17 additions & 0 deletions src/command/completion/bash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use clap::{CommandFactory, Parser};
use clap_complete::{generate, shells::Bash as BashShell};
use serde::Serialize;

use crate::{RoverOutput, RoverResult, cli::Rover};

#[derive(Debug, Serialize, Parser)]
pub struct Bash {}

impl Bash {
pub fn run(&self) -> RoverResult<RoverOutput> {
let mut cmd = Rover::command();
let name = "rover".to_string();
generate(BashShell, &mut cmd, &name, &mut std::io::stdout());
Ok(RoverOutput::EmptySuccess)
}
}
31 changes: 31 additions & 0 deletions src/command/completion/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
mod bash;
mod zsh;

use clap::Parser;
use serde::Serialize;

use crate::{RoverOutput, RoverResult};

#[derive(Debug, Serialize, Parser)]
pub struct Completion {
#[clap(subcommand)]
command: Command,
}

#[derive(Debug, Serialize, Parser)]
enum Command {
/// Generate bash completion script
Bash(bash::Bash),

/// Generate zsh completion script
Zsh(zsh::Zsh),
}

impl Completion {
pub fn run(&self) -> RoverResult<RoverOutput> {
match &self.command {
Command::Bash(command) => command.run(),
Command::Zsh(command) => command.run(),
}
}
}
17 changes: 17 additions & 0 deletions src/command/completion/zsh.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use clap::{CommandFactory, Parser};
use clap_complete::{generate, shells::Zsh as ZshShell};
use serde::Serialize;

use crate::{RoverOutput, RoverResult, cli::Rover};

#[derive(Debug, Serialize, Parser)]
pub struct Zsh {}

impl Zsh {
pub fn run(&self) -> RoverResult<RoverOutput> {
let mut cmd = Rover::command();
let name = "rover".to_string();
generate(ZshShell, &mut cmd, &name, &mut std::io::stdout());
Ok(RoverOutput::EmptySuccess)
}
}
2 changes: 2 additions & 0 deletions src/command/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod api_key;
mod cloud;
mod completion;
mod config;
#[cfg(feature = "composition-js")]
pub mod connector;
Expand All @@ -25,6 +26,7 @@ mod update;

pub use api_key::ApiKeys;
pub use cloud::Cloud;
pub use completion::Completion;
pub use config::Config;
#[cfg(feature = "composition-js")]
pub use connector::Connector;
Expand Down
5 changes: 3 additions & 2 deletions tests/e2e/config/auth.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use assert_cmd::cargo::cargo_bin_cmd;
use predicates::prelude::*;
use rstest::rstest;

#[rstest]
#[ignore]
fn e2e_test_rover_auth_help() {
let mut cmd = assert_cmd::cargo::cargo_bin_cmd!("rover");
let mut cmd = cargo_bin_cmd!("rover");
cmd.arg("config")
.arg("auth")
.arg("--help")
Expand All @@ -15,7 +16,7 @@ fn e2e_test_rover_auth_help() {
#[rstest]
#[ignore]
fn e2e_test_rover_auth_fail_empty_api_key() {
let mut cmd = assert_cmd::cargo::cargo_bin_cmd!("rover");
let mut cmd = cargo_bin_cmd!("rover");
let result = cmd.arg("config").arg("auth").write_stdin("").assert();
result.stderr(predicate::str::contains("empty"));
}
7 changes: 4 additions & 3 deletions tests/e2e/config/clear.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::convert::TryFrom;

use assert_cmd::cargo::cargo_bin_cmd;
use camino::Utf8PathBuf;
use houston::{Config, Profile};
use predicates::prelude::*;
Expand All @@ -19,7 +20,7 @@ fn e2e_test_rover_config_clear() {
Profile::set_api_key(CUSTOM_PROFILE, &config, CUSTOM_API_KEY).unwrap();

// when one is added
let mut cmd = assert_cmd::cargo::cargo_bin_cmd!("rover");
let mut cmd = cargo_bin_cmd!("rover");
let result = cmd
.env(RoverEnvKey::ConfigHome.to_string(), &temp_dir)
.arg("config")
Expand All @@ -28,7 +29,7 @@ fn e2e_test_rover_config_clear() {
result.stdout(predicate::str::contains(CUSTOM_PROFILE));

// and then removed via `config clear`
let mut cmd = assert_cmd::cargo::cargo_bin_cmd!("rover");
let mut cmd = cargo_bin_cmd!("rover");
let result = cmd
.env(RoverEnvKey::ConfigHome.to_string(), &temp_dir)
.arg("config")
Expand All @@ -37,7 +38,7 @@ fn e2e_test_rover_config_clear() {
result.stderr("Successfully cleared all configuration.\n");

// then we should have no profiles
let mut cmd = assert_cmd::cargo::cargo_bin_cmd!("rover");
let mut cmd = cargo_bin_cmd!("rover");
let result = cmd
.arg("config")
.env(RoverEnvKey::ConfigHome.to_string(), &temp_dir)
Expand Down
5 changes: 3 additions & 2 deletions tests/e2e/config/list.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::convert::TryFrom;

use assert_cmd::cargo::cargo_bin_cmd;
use camino::Utf8PathBuf;
use houston::{Config, Profile};
use predicates::prelude::*;
Expand All @@ -14,7 +15,7 @@ const CUSTOM_API_KEY: &str = "custom-api-key";
#[ignore]
fn e2e_test_rover_config_list_empty() {
let temp_dir = Utf8PathBuf::try_from(TempDir::new().unwrap().path().to_path_buf()).unwrap();
let mut cmd = assert_cmd::cargo::cargo_bin_cmd!("rover");
let mut cmd = cargo_bin_cmd!("rover");
let result = cmd
.arg("config")
.env(RoverEnvKey::ConfigHome.to_string(), &temp_dir)
Expand All @@ -30,7 +31,7 @@ fn e2e_test_rover_config_list_one_profile() {
let config = Config::new(Some(temp_dir.clone()).as_ref(), None).unwrap();
Profile::set_api_key(CUSTOM_PROFILE, &config, CUSTOM_API_KEY).unwrap();

let mut cmd = assert_cmd::cargo::cargo_bin_cmd!("rover");
let mut cmd = cargo_bin_cmd!("rover");
let result = cmd
.env(RoverEnvKey::ConfigHome.to_string(), &temp_dir)
.arg("config")
Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/config/whoami.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use assert_cmd::cargo::cargo_bin_cmd;
use rstest::rstest;
use serde::Deserialize;
use serde_json::Value;
Expand All @@ -24,7 +25,7 @@ fn e2e_test_rover_config_whoami() {
.tempfile()
.expect("Could not create output file");

let mut cmd = assert_cmd::cargo::cargo_bin_cmd!("rover");
let mut cmd = cargo_bin_cmd!("rover");
cmd.args([
"config",
"whoami",
Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/dev.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{env, process::Command, time::Duration};

use assert_cmd::cargo;
use mime::APPLICATION_JSON;
use portpicker::pick_unused_port;
use reqwest::{Client, header::CONTENT_TYPE};
Expand All @@ -21,7 +22,7 @@ const ROVER_DEV_TIMEOUT: Duration = Duration::from_secs(45);
#[once]
#[allow(clippy::zombie_processes)]
fn run_rover_dev(run_subgraphs_retail_supergraph: &RetailSupergraph) -> String {
let mut cmd = Command::new(assert_cmd::cargo::cargo_bin!("rover"));
let mut cmd = Command::new(cargo::cargo_bin!("rover"));
let port = pick_unused_port().expect("No ports free");
let router_url = format!("http://localhost:{port}");
let client = Client::new();
Expand Down
Loading