Skip to content

feat: expose library crate for programmatic API access#214

Open
geofflittle wants to merge 6 commits intogoogleworkspace:mainfrom
geofflittle:feat/library-crate
Open

feat: expose library crate for programmatic API access#214
geofflittle wants to merge 6 commits intogoogleworkspace:mainfrom
geofflittle:feat/library-crate

Conversation

@geofflittle
Copy link

Description

Adds a library crate (lib.rs) so that gws can be used as a Rust dependency for programmatic access to Google Workspace APIs — without shelling out to the binary.

Addresses #211.

Two coupling points previously prevented a clean lib/bin split:

  1. config_dir() lived in the CLI-only auth_commands module but was called by 6 library modules (accounts, credential_store, oauth_config, auth, discovery)
  2. Model Armor sanitization types (SanitizeMode, SanitizeConfig, SanitizationResult, sanitize_text()) lived in helpers/modelarmor but were used by executor

This PR extracts both into standalone modules (config.rs, sanitize.rs), creates lib.rs re-exporting library-worthy modules, and adds a [lib] section to Cargo.toml. The original call sites delegate to the new modules, so all existing code paths are unchanged.

Also moves parse_service_and_version() from main.rs to services.rs so it is accessible from both crate roots.

Zero behavior changes to the binary. All existing tests pass.

Dry Run Output:

N/A — structural refactor, no new CLI commands or API requests

Checklist:

  • My code follows the AGENTS.md guidelines (no generated google-* crates).
  • I have run cargo fmt --all to format the code perfectly.
  • I have run cargo clippy -- -D warnings and resolved all warnings.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have provided a Changeset file (e.g. via pnpx changeset) to document my changes.

Notes

  • cargo clippy -- -D warnings is clean for all new/modified code. There is 1 pre-existing should_implement_trait warning in formatter.rs:55 (unrelated to this PR).
  • New integration tests (tests/lib_integration.rs) verify the library surface: RestDescription deserialization, resolve_service(), GwsError, validate_api_identifier().
  • The #![allow(dead_code)] on lib.rs suppresses warnings for pub(crate) modules that are only used by the binary target (dual compilation — same .rs files compiled for both targets).

@geofflittle geofflittle requested a review from jpoehnelt as a code owner March 5, 2026 22:15
@changeset-bot
Copy link

changeset-bot bot commented Mar 5, 2026

🦋 Changeset detected

Latest commit: 0a078bd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@googleworkspace/cli Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@google-cla
Copy link

google-cla bot commented Mar 5, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the gws project by introducing a dedicated library crate. This change allows developers to integrate gws's core functionalities directly into their Rust applications, moving beyond its previous CLI-only usage. The refactoring involved extracting shared utilities like configuration directory resolution and Model Armor sanitization into independent modules, thereby reducing coupling and improving the overall modularity and reusability of the codebase.

Highlights

  • Library Crate Exposure: A new library crate (lib.rs) has been added to allow programmatic access to the gws functionality, enabling its use as a Rust dependency without relying on the CLI binary.
  • Code Refactoring for Modularity: The config_dir() function, previously coupled with CLI-only auth_commands, has been extracted into a new standalone src/config.rs module. Similarly, Model Armor sanitization types (SanitizeMode, SanitizeConfig, SanitizationResult, sanitize_text()) were moved from helpers/modelarmor to a new src/sanitize.rs module.
  • Improved Service Parsing: The parse_service_and_version() function has been relocated from main.rs to services.rs, making it accessible to both the binary and the new library crate.
  • No Behavioral Changes: This refactor introduces no changes to the existing binary's behavior, ensuring backward compatibility. All existing tests continue to pass.
  • New Integration Tests: New integration tests (tests/lib_integration.rs) have been added to specifically verify the exposed library surface, including RestDescription deserialization, resolve_service(), GwsError, and validate_api_identifier().
Changelog
  • .changeset/add-library-crate.md
    • Added a new changeset file documenting the addition of the library crate and the associated refactoring.
  • Cargo.toml
    • Added a [lib] section to define the new gws library crate, pointing to src/lib.rs.
  • src/accounts.rs
    • Updated the call to config_dir() to reference the newly created crate::config module.
  • src/auth.rs
    • Updated the call to config_dir() to reference the newly created crate::config module.
  • src/auth_commands.rs
    • Removed the implementation of config_dir(), now delegating its call to crate::config::config_dir().
  • src/config.rs
    • Added a new module containing the config_dir() function, centralizing configuration directory logic.
  • src/credential_store.rs
    • Updated all calls to config_dir() to reference the newly created crate::config module.
  • src/discovery.rs
    • Updated the call to config_dir() to reference the newly created crate::config module.
  • src/executor.rs
    • Updated references to Model Armor sanitization types and functions to use the new crate::sanitize module.
  • src/helpers/modelarmor.rs
    • Removed the original definitions of Model Armor sanitization types and functions, now re-exporting them from crate::sanitize.
  • src/lib.rs
    • Added a new library crate file, re-exporting public modules to expose the programmatic API.
  • src/main.rs
    • Imported the new config and sanitize modules and updated the call to parse_service_and_version to use the services module.
  • src/mcp_server.rs
    • Updated all calls to parse_service_and_version to use the services module.
  • src/oauth_config.rs
    • Updated the call to config_dir() to reference the newly created crate::config module.
  • src/sanitize.rs
    • Added a new module containing Model Armor sanitization types and functions, previously in helpers/modelarmor.rs.
  • src/services.rs
    • Moved the parse_service_and_version() function from main.rs to this module.
  • tests/lib_integration.rs
    • Added new integration tests to verify the functionality exposed by the library crate.
Activity
  • The pull request author confirmed that the code adheres to AGENTS.md guidelines, cargo fmt --all was run, and cargo clippy -- -D warnings passed (with one pre-existing warning noted).
  • Tests were added to prove the feature works, specifically new integration tests for the library surface.
  • A Changeset file was provided to document the changes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Generative AI Prohibited Use Policy, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively refactors the codebase to expose a library crate, which is a great step towards making gws more reusable. The extraction of configuration and sanitization logic into their own modules is clean and well-executed. I have one suggestion to make the new library API for SanitizeMode more idiomatic.

@geofflittle
Copy link
Author

I have signed the CLA — https://cla.developers.google.com/ shows it under g.little712@gmail.com / geofflittle.

@geofflittle
Copy link
Author

Removed the Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> trailer that was failing the CLA check — that email can't sign a CLA. Force-pushed with a clean commit.

@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively refactors the codebase to expose a library crate, enabling programmatic use of gws. The separation of concerns is well-executed by extracting shared logic into new modules like config.rs and sanitize.rs. The new library structure in lib.rs and the corresponding Cargo.toml changes are correct. I've identified one critical security vulnerability in the new sanitize.rs module related to input validation, which I've detailed in a specific comment.

@codecov
Copy link

codecov bot commented Mar 6, 2026

Codecov Report

❌ Patch coverage is 72.24670% with 63 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.32%. Comparing base (dd3fc90) to head (0a078bd).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/sanitize.rs 60.00% 32 Missing ⚠️
src/services.rs 47.61% 22 Missing ⚠️
src/executor.rs 50.00% 3 Missing ⚠️
src/main.rs 0.00% 3 Missing ⚠️
src/auth.rs 0.00% 1 Missing ⚠️
src/config.rs 94.73% 1 Missing ⚠️
src/discovery.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #214      +/-   ##
==========================================
+ Coverage   59.09%   59.32%   +0.23%     
==========================================
  Files          36       38       +2     
  Lines       12953    13039      +86     
==========================================
+ Hits         7654     7736      +82     
- Misses       5299     5303       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a well-executed refactoring that successfully exposes a library crate for programmatic API access. The modularization of config and sanitize logic is clean, and the introduction of lib.rs provides a clear API surface. I have one high-severity comment regarding argument parsing that should be addressed to ensure consistent behavior.

@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully refactors the codebase to expose a library crate, which is a great step for enabling programmatic use of gws. The changes are well-structured, moving shared logic into new config and sanitize modules and creating a lib.rs entry point.

I have one critical piece of feedback regarding a behavioral change. The logic for overriding the configuration directory via the GOOGLE_WORKSPACE_CLI_CONFIG_DIR environment variable has been unintentionally restricted to test builds only. This is a breaking change for users of the binary, as this is a documented feature. My review comment includes a suggestion to fix this.

@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a well-executed refactoring that successfully exposes the gws tool as a library crate. The code is cleanly split into a new lib.rs target, with shared logic like configuration and sanitization extracted into their own modules. The addition of integration tests for the library surface is a great touch. However, I've identified a critical issue where the GOOGLE_WORKSPACE_CLI_CONFIG_DIR environment variable override has been unintentionally restricted to test builds only. This is a breaking change for users who rely on this variable and contradicts the PR's claim of zero behavior changes.

@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a well-executed refactoring to expose a library crate, which is a great architectural improvement. The changes to split out configuration and sanitization logic into their own modules are clean. The included security fix to validate sanitize template parameters against path traversal and SSRF is also a critical addition. I've found one high-severity issue related to argument parsing that could lead to confusing behavior, and I've provided a suggestion to make it more robust. Overall, this is a solid contribution.

@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a well-executed refactoring that successfully exposes a library crate for programmatic API access. The changes are logically structured, with shared functionality like configuration management and sanitization logic cleanly extracted into their own modules. The introduction of validation for sanitize template parameters is a crucial security improvement that hardens the API against path traversal and SSRF vulnerabilities. The addition of integration tests for the new library crate is also a valuable contribution that enhances the project's robustness. Overall, the code quality is high, and the changes align well with the stated goals of the pull request.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a well-executed refactoring that successfully exposes a library crate for programmatic API access. The changes are logically structured, with shared functionality like configuration management and sanitization logic cleanly extracted into their own modules. The introduction of validation for sanitize template parameters is a crucial security improvement that hardens the API against path traversal and SSRF vulnerabilities. The addition of integration tests for the new library crate is also a valuable contribution that enhances the project's robustness. Overall, the code quality is high, and the changes align well with the stated goals of the pull request.

Extract `config_dir()` into `src/config.rs` and Model Armor sanitization
types into `src/sanitize.rs` so they can be shared between the binary and
library targets without pulling in CLI-only code. Add `src/lib.rs` with
public module re-exports and `tests/lib_integration.rs` with offline tests.

Also moves `parse_service_and_version()` from `main.rs` to `services.rs`
so it is accessible from both the lib and bin crate roots.

Zero behavior changes to the binary.
Add validate_resource_name() and validate_api_identifier() checks in
build_sanitize_request_data() to prevent path traversal, query injection,
and percent-encoded bypasses in the template parameter.
…ntax

- Remove #[cfg(test)] from GOOGLE_WORKSPACE_CLI_CONFIG_DIR check in
  config_dir() so the override works in release builds.
- Handle --api-version=v3 syntax in parse_service_and_version(), not
  just --api-version v3.
@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a well-executed refactoring to expose a library crate for programmatic API access. The code is cleanly split into a library and binary, with thoughtful module organization and visibility. The changes are logical and effectively decouple the core logic from the CLI. I appreciate the simultaneous inclusion of a security enhancement to validate sanitize template parameters against path traversal and SSRF, which strengthens the tool. The addition of integration tests for the new library surface is also a great touch. Overall, this is a high-quality contribution that improves the project's structure and security.

@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a significant and well-executed refactoring to expose a library crate for programmatic access. The code has been cleanly split into library and binary targets, with shared logic extracted into new modules like config.rs and sanitize.rs. The changes are logical and follow the description.

However, I've identified a critical security vulnerability in the new sanitize.rs module. The validation for the location parameter, which is used to construct a hostname for an API call, is insufficient and could lead to a Server-Side Request Forgery (SSRF) attack. My review includes a specific comment with a suggested fix for this issue.

… template

Replace validate_api_identifier (which allows dots) with a stricter
validate_gcp_location that only permits lowercase alphanumeric and
hyphens. This prevents an attacker from injecting a dotted domain
(e.g. evil.com) into the Model Armor regional hostname.
@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully refactors the codebase to expose a library crate, enabling programmatic use of gws. The changes are well-structured, moving shared logic into new modules like config.rs and sanitize.rs and setting up a dual-target compilation with lib.rs and main.rs. A notable improvement is the addition of input validation in the sanitization logic, which effectively mitigates potential SSRF and path traversal vulnerabilities. The refactoring of functions into the services module also enhances code organization. The new integration tests for the library crate are a welcome addition. Overall, this is a high-quality contribution that improves the project's structure and security.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: auth area: core Core CLI parsing, commands, error handling, utilities area: discovery area: distribution area: http

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants