-
Notifications
You must be signed in to change notification settings - Fork 388
docs: document all environment variables and enable CONFIG_DIR override #222
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@googleworkspace/cli": patch | ||
| --- | ||
|
|
||
| Document all environment variables and enable GOOGLE_WORKSPACE_CLI_CONFIG_DIR in release builds |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,35 @@ | ||
| # OAuth Client Credentials | ||
| # Create these at https://console.cloud.google.com/apis/credentials | ||
| GOOGLE_WORKSPACE_CLI_CLIENT_ID= | ||
| GOOGLE_WORKSPACE_CLI_CLIENT_SECRET= | ||
| # gws — Google Workspace CLI | ||
| # Copy this file to .env and uncomment the variables you need. | ||
| # All variables are optional. See README.md for details. | ||
|
|
||
| # Authentication | ||
| # Path to a service account JSON key file or user credentials | ||
| # ── Authentication ──────────────────────────────────────────────── | ||
| # Pre-obtained OAuth2 access token (highest priority; bypasses all credential loading) | ||
| # GOOGLE_WORKSPACE_CLI_TOKEN= | ||
|
|
||
| # Path to OAuth credentials JSON (user or service account) | ||
| # GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE= | ||
|
|
||
| # Impersonation (Domain-Wide Delegation) | ||
| # Email address of the user to impersonate when using a service account | ||
| # Default account email for multi-account usage (overridden by --account flag) | ||
| # GOOGLE_WORKSPACE_CLI_ACCOUNT= | ||
|
|
||
| # Email of user to impersonate via Domain-Wide Delegation (service accounts only) | ||
| # GOOGLE_WORKSPACE_CLI_IMPERSONATED_USER= | ||
|
|
||
| # Model Armor Sanitization | ||
| # Default template resource name for --sanitize | ||
| # GOOGLE_WORKSPACE_CLI_SANITIZE_TEMPLATE=projects/my-project/locations/us-central1/templates/my-template | ||
| # Sanitization mode: 'warn' (default) or 'block' | ||
| # ── OAuth Client ────────────────────────────────────────────────── | ||
| # OAuth client ID and secret (alternative to saving client_secret.json) | ||
| # GOOGLE_WORKSPACE_CLI_CLIENT_ID= | ||
| # GOOGLE_WORKSPACE_CLI_CLIENT_SECRET= | ||
|
|
||
| # ── Configuration ───────────────────────────────────────────────── | ||
| # Override the config directory (default: ~/.config/gws) | ||
| # GOOGLE_WORKSPACE_CLI_CONFIG_DIR= | ||
|
|
||
| # ── Model Armor (response sanitization) ────────────────────────── | ||
| # Default Model Armor template (overridden by --sanitize flag) | ||
| # GOOGLE_WORKSPACE_CLI_SANITIZE_TEMPLATE= | ||
| # Sanitization mode: warn (default) or block | ||
| # GOOGLE_WORKSPACE_CLI_SANITIZE_MODE=warn | ||
|
|
||
| # ── Helpers ─────────────────────────────────────────────────────── | ||
| # GCP project ID fallback for gmail watch and events subscribe (overridden by --project) | ||
| # GOOGLE_WORKSPACE_PROJECT_ID= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| # Code Review Style Guide | ||
|
|
||
| ## Project Architecture | ||
|
|
||
| `gws` is a Rust CLI that dynamically generates commands from Google Discovery Documents at runtime. It does NOT use generated Rust crates (`google-drive3`, etc.) for API interaction. Do not suggest adding API-specific crates to `Cargo.toml`. | ||
|
|
||
| ## Security: Trusted vs Untrusted Inputs | ||
|
|
||
| This CLI is frequently invoked by AI/LLM agents. CLI arguments may be adversarial. | ||
|
|
||
| - **CLI arguments (untrusted)** — Must validate paths against traversal (`../../`), reject control characters, percent-encode URL path segments, and use `reqwest .query()` for query parameters. Validators: `validate_safe_output_dir()`, `validate_safe_dir_path()`, `encode_path_segment()`, `validate_resource_name()`. | ||
| - **Environment variables (trusted)** — Set by the user in their shell profile, `.env` file, or deployment config. Do NOT flag missing path validation on environment variable values. This is consistent with `XDG_CONFIG_HOME`, `CARGO_HOME`, etc. | ||
|
|
||
| ## Test Coverage | ||
|
|
||
| The `codecov/patch` check requires new/modified lines to be covered by tests. Prefer extracting testable helper functions over embedding logic in `main`/`run`. Tests should cover both happy paths and rejection paths (e.g., pass `../../.ssh` and assert `Err`). | ||
|
|
||
| ## Changesets | ||
|
|
||
| Every PR must include a `.changeset/<name>.md` file. Use `patch` for fixes/chores, `minor` for features, `major` for breaking changes. | ||
|
|
||
| ## Code Style | ||
|
|
||
| - Rust: `cargo clippy -- -D warnings` must pass. `cargo fmt` enforced via pre-commit hook. | ||
| - Node.js: Use `pnpm` not `npm`. | ||
| - OAuth scope strings in test code will trigger "restricted/sensitive scope" warnings — these are expected and should be ignored. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -92,7 +92,6 @@ const READONLY_SCOPES: &[&str] = &[ | |||||||||||||||||||||
| ]; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| pub fn config_dir() -> PathBuf { | ||||||||||||||||||||||
| #[cfg(test)] | ||||||||||||||||||||||
| if let Ok(dir) = std::env::var("GOOGLE_WORKSPACE_CLI_CONFIG_DIR") { | ||||||||||||||||||||||
| return PathBuf::from(dir); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
jpoehnelt marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
95
to
97
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While the
Although other environment variables like
Suggested change
|
||||||||||||||||||||||
|
|
@@ -266,7 +265,7 @@ async fn handle_login(args: &[String]) -> Result<(), GwsError> { | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Determine scopes: explicit flags > interactive TUI > defaults | ||||||||||||||||||||||
| let mut scopes = resolve_scopes( | ||||||||||||||||||||||
| let scopes = resolve_scopes( | ||||||||||||||||||||||
| &filtered_args, | ||||||||||||||||||||||
| project_id.as_deref(), | ||||||||||||||||||||||
| services_filter.as_ref(), | ||||||||||||||||||||||
|
|
@@ -277,7 +276,7 @@ async fn handle_login(args: &[String]) -> Result<(), GwsError> { | |||||||||||||||||||||
| // gmail.metadata blocks query parameters like `q`, and is redundant | ||||||||||||||||||||||
| // when broader scopes (gmail.modify, gmail.readonly, mail.google.com) | ||||||||||||||||||||||
| // are already included. | ||||||||||||||||||||||
| let scopes = filter_redundant_restrictive_scopes(scopes); | ||||||||||||||||||||||
| let mut scopes = filter_redundant_restrictive_scopes(scopes); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| let secret = yup_oauth2::ApplicationSecret { | ||||||||||||||||||||||
| client_id: client_id.clone(), | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.