From f779fabc98ad00f975bdbe4df9bc99eccb4e0485 Mon Sep 17 00:00:00 2001 From: Bortlesboat Date: Thu, 5 Mar 2026 13:20:49 -0500 Subject: [PATCH] feat: add [MANUAL] notation for steps requiring human interaction --- .changeset/feat-manual-notation.md | 5 +++++ src/auth_commands.rs | 10 +++++----- src/error.rs | 6 +++--- src/setup.rs | 10 +++++----- 4 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 .changeset/feat-manual-notation.md diff --git a/.changeset/feat-manual-notation.md b/.changeset/feat-manual-notation.md new file mode 100644 index 0000000..1bdf2ba --- /dev/null +++ b/.changeset/feat-manual-notation.md @@ -0,0 +1,5 @@ +--- +"@googleworkspace/cli": minor +--- + +Add [MANUAL] notation to help text and runtime messages for steps requiring human interaction diff --git a/src/auth_commands.rs b/src/auth_commands.rs index b5a5bb8..cf0535c 100644 --- a/src/auth_commands.rs +++ b/src/auth_commands.rs @@ -133,7 +133,7 @@ fn token_cache_path() -> PathBuf { pub async fn handle_auth_command(args: &[String]) -> Result<(), GwsError> { const USAGE: &str = concat!( "Usage: gws auth [options]\n\n", - " login Authenticate via OAuth2 (opens browser)\n", + " login [MANUAL] Authenticate via OAuth2 (opens browser for consent)\n", " --account EMAIL Associate credentials with a specific account\n", " --readonly Request read-only scopes\n", " --full Request all scopes incl. pubsub + cloud-platform\n", @@ -141,7 +141,7 @@ pub async fn handle_auth_command(args: &[String]) -> Result<(), GwsError> { " --scopes Comma-separated custom scopes\n", " -s, --services Comma-separated service names to limit scope picker\n", " (e.g. -s drive,gmail,sheets)\n", - " setup Configure GCP project + OAuth client (requires gcloud)\n", + " setup [MANUAL] Configure GCP project + OAuth client (requires gcloud)\n", " --project Use a specific GCP project\n", " status Show current authentication state\n", " export Print decrypted credentials to stdout\n", @@ -203,7 +203,7 @@ impl yup_oauth2::authenticator_delegate::InstalledFlowDelegate for CliFlowDelega } else { url.to_string() }; - eprintln!("Open this URL in your browser to authenticate:\n"); + eprintln!("[MANUAL] Open this URL in your browser to authenticate:\n"); eprintln!(" {display_url}\n"); Ok(String::new()) }) @@ -508,8 +508,8 @@ fn resolve_client_credentials() -> Result<(String, String, Option), GwsE format!( "No OAuth client configured.\n\n\ Either:\n \ - 1. Run `gws auth setup` to configure a GCP project and OAuth client\n \ - 2. Download client_secret.json from Google Cloud Console and save it to:\n \ + 1. [MANUAL] Run `gws auth setup` (interactive wizard, opens browser)\n \ + 2. [MANUAL] Download client_secret.json from Google Cloud Console and save it to:\n \ {}\n \ 3. Set env vars: GOOGLE_WORKSPACE_CLI_CLIENT_ID and GOOGLE_WORKSPACE_CLI_CLIENT_SECRET", crate::oauth_config::client_config_path().display() diff --git a/src/error.rs b/src/error.rs index 25cc9f5..c68e350 100644 --- a/src/error.rs +++ b/src/error.rs @@ -111,11 +111,11 @@ pub fn print_error_json(err: &GwsError) { { if reason == "accessNotConfigured" { eprintln!(); - eprintln!("💡 API not enabled for your GCP project."); + eprintln!("💡 [MANUAL] API not enabled for your GCP project."); if let Some(url) = enable_url { - eprintln!(" Enable it at: {url}"); + eprintln!(" [MANUAL] Enable it at: {url}"); } else { - eprintln!(" Visit the GCP Console → APIs & Services → Library to enable the required API."); + eprintln!(" [MANUAL] Visit the GCP Console → APIs & Services → Library to enable the required API."); } eprintln!(" After enabling, wait a few seconds and retry your command."); } diff --git a/src/setup.rs b/src/setup.rs index 5df88cc..bfb3f46 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -921,7 +921,7 @@ fn stage_account(ctx: &mut SetupContext) -> Result { .unwrap() .suspend() .map_err(|e| GwsError::Validation(format!("TUI error: {e}")))?; - eprintln!(" → Opening browser for login..."); + eprintln!(" → [MANUAL] Opening browser for login..."); gcloud_auth_login()?; let acct = get_gcloud_account()?.ok_or_else(|| { GwsError::Auth("Authentication failed — no active account".to_string()) @@ -1285,21 +1285,21 @@ fn manual_oauth_instructions(project_id: &str) -> String { format!( concat!( - "OAuth client creation requires manual setup in the Google Cloud Console.\n\n", + "[MANUAL] OAuth client creation requires manual setup in the Google Cloud Console.\n\n", "Follow these steps:\n\n", - "1. Configure the OAuth consent screen (if not already done):\n", + "1. [MANUAL] Configure the OAuth consent screen (if not already done):\n", " {consent_url}\n", " → User Type: External\n", " → App name: gws CLI (or your preferred name)\n", " → Support email: your Google account email\n", " → Save and continue through all screens\n\n", - "2. Create an OAuth client ID:\n", + "2. [MANUAL] Create an OAuth client ID:\n", " {creds_url}\n", " → Click 'Create Credentials' → 'OAuth client ID'\n", " → Application type: Desktop app\n", " → Name: gws CLI (or your preferred name)\n", " → Click 'Create'\n\n", - "3. Copy the Client ID and Client Secret shown in the dialog.\n\n", + "3. [MANUAL] Copy the Client ID and Client Secret shown in the dialog.\n\n", "4. Provide the credentials to gws using one of these methods:\n\n", " Option A — Environment variables (recommended for CI/scripts):\n", " export GOOGLE_WORKSPACE_CLI_CLIENT_ID=\"\"\n",