Skip to content

Conversation

@scotthart
Copy link
Member

Regenerate most of the .dox files for generated libraries by default whenever the generator is executed.

@gemini-code-assist
Copy link

Summary of Changes

Hello @scotthart, 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 documentation generation capabilities of the generator tool. It introduces a more granular control mechanism, allowing for the regeneration of only .dox documentation files for most client libraries by default, which streamlines the process of keeping documentation up-to-date. The changes also include minor formatting improvements across a wide range of existing documentation files and updates to Doxygen group titles for better descriptive accuracy. Additionally, new integration test configurations have been added to ensure the robustness of the generator.

Highlights

  • Refactored Documentation Generation: The generator now supports selective regeneration of documentation files, allowing for updates to .dox files without rebuilding the entire scaffold for a library.
  • Introduced ScaffoldFiles Enum: A new ScaffoldFiles enum (kAll, kDocDir) has been added to scaffold_generator.h and scaffold_generator.cc to control which parts of the scaffold are generated.
  • Conditional Doc File Regeneration: The standalone_main.cc now uses the ScaffoldFiles::kDocDir option to regenerate only specific .dox files for most services by default, with a few services explicitly omitted.
  • Documentation Formatting Cleanup: Numerous .dox files across various client libraries have been updated to remove an extraneous blank line at the beginning of Doxygen comment blocks, improving consistency.
  • Updated Doxygen Group Titles: Several options.dox files received minor title adjustments for improved clarity and accuracy (e.g., 'Cloud BigQuery' to 'BigQuery Storage API').
  • Integration Test Additions: New YAML configuration files (test2.yaml and test_deprecated.yaml) were added for integration tests, expanding test coverage for the generator.
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 Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, 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

@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 refactors the generator to regenerate most documentation files by default. This involves introducing a new ScaffoldFiles enum to control which files are generated and updating the main generator logic to call this new functionality. The bulk of the changes are formatting updates to .dox files as a result of this regeneration. My review focuses on the C++ code changes, with a couple of suggestions to improve maintainability and readability.

Comment on lines +344 to +376
std::vector<Destination> files;
if (scaffold_files == ScaffoldFiles::kDocDir) {
files = {
{"doc/environment-variables.dox", GenerateDoxygenEnvironmentPage},
{"doc/override-authentication.dox", GenerateOverrideAuthenticationPage},
{"doc/override-endpoint.dox", GenerateOverrideEndpointPage},
{"doc/override-retry-policies.dox", GenerateOverrideRetryPoliciesPage},
{"doc/options.dox", GenerateDoxygenOptionsPage},
};
} else {
MakeDirectory(destination + "quickstart/");
files = {
{"README.md", GenerateReadme},
{"BUILD.bazel", GenerateBuild},
{"CMakeLists.txt", GenerateCMakeLists},
{"doc/main.dox", GenerateDoxygenMainPage},
{"doc/environment-variables.dox", GenerateDoxygenEnvironmentPage},
{"doc/override-authentication.dox", GenerateOverrideAuthenticationPage},
{"doc/override-endpoint.dox", GenerateOverrideEndpointPage},
{"doc/override-retry-policies.dox", GenerateOverrideRetryPoliciesPage},
{"doc/options.dox", GenerateDoxygenOptionsPage},
{"quickstart/README.md", GenerateQuickstartReadme},
{"quickstart/quickstart.cc", GenerateQuickstartSkeleton},
{"quickstart/CMakeLists.txt", GenerateQuickstartCMake},
{"quickstart/Makefile", GenerateQuickstartMakefile},
{"quickstart/BUILD.bazel", GenerateQuickstartBuild},
{"quickstart/.bazelrc", GenerateQuickstartBazelrc},
};
std::ifstream is(scaffold_templates_path + kWorkspaceTemplate);
auto const contents = std::string{std::istreambuf_iterator<char>(is), {}};
std::ofstream os(destination + "quickstart/WORKSPACE.bazel");
GenerateQuickstartWorkspace(os, vars, contents);
}

Choose a reason for hiding this comment

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

medium

There is code duplication in this if-else block. The list of documentation files to be generated (environment-variables.dox, override-authentication.dox, etc.) is present in both the if branch (lines 347-351) and the else branch (lines 360-364). To improve maintainability and avoid potential inconsistencies in the future, consider extracting this common list of files into a separate variable and using it in both branches.

Comment on lines +240 to +254
if (!service.omit_client() &&
!std::any_of(kOmittedDocDirs.begin(), kOmittedDocDirs.end(),
[&](auto s) {
// TODO(#15652): Remove when service is turned down.
if (absl::StartsWith(service.product_path(),
"google/cloud/pubsublite")) {
return false;
}
return absl::StartsWith(service.product_path(), s);
})) {
GenerateScaffold(
scaffold_vars, generator_args.scaffold_templates_path,
generator_args.output_path, service,
google::cloud::generator_internal::ScaffoldFiles::kDocDir);
}

Choose a reason for hiding this comment

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

medium

The logic within this if condition, particularly the lambda passed to std::any_of, is a bit complex due to the special handling for pubsublite. To improve readability, I suggest separating the general check against kOmittedDocDirs from the special case logic for pubsublite.

      bool omit_doc_dir = std::any_of(
          kOmittedDocDirs.begin(), kOmittedDocDirs.end(),
          [&](auto s) { return absl::StartsWith(service.product_path(), s); });
      // TODO(#15652): Remove when service is turned down.
      if (absl::StartsWith(service.product_path(), "google/cloud/pubsublite")) {
        omit_doc_dir = false;
      }
      if (!service.omit_client() && !omit_doc_dir) {
        GenerateScaffold(
            scaffold_vars, generator_args.scaffold_templates_path,
            generator_args.output_path, service,
            google::cloud::generator_internal::ScaffoldFiles::kDocDir);
      }

mpeddada1
mpeddada1 previously approved these changes Oct 22, 2025
Copy link
Collaborator

@mpeddada1 mpeddada1 left a comment

Choose a reason for hiding this comment

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

@scotthart what command did we need to run to regenerate these doc files?

@codecov
Copy link

codecov bot commented Oct 22, 2025

Codecov Report

❌ Patch coverage is 0% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.10%. Comparing base (04f7a48) to head (d93c262).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
generator/internal/scaffold_generator.cc 0.00% 14 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #15653      +/-   ##
==========================================
- Coverage   93.11%   93.10%   -0.01%     
==========================================
  Files        2433     2433              
  Lines      223810   223817       +7     
==========================================
- Hits       208400   208387      -13     
- Misses      15410    15430      +20     

☔ 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.

#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/match.h"
#include <google/protobuf/compiler/command_line_interface.h>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Also to double check my understanding, is there were the doc generation logic lives?

Copy link
Member Author

Choose a reason for hiding this comment

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

The dox file templates are generated from calling GenerateScaffold. Additional content is injected when update-library-landing-dox.sh is invoked.

Comment on lines +236 to +239
static constexpr std::array<char const*, 4> kOmittedDocDirs = {
"google/cloud/bigtable", "google/cloud/compute",
"google/cloud/pubsub", "google/cloud/spanner"};

Copy link
Collaborator

Choose a reason for hiding this comment

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

Would you provide some context into why these modules are being excluded?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added comments to document the rationale.


io::log_h2 "Running doxygen landing-page updates:"
time {
features::libraries | xargs -P "$(nproc)" -n 1 ci/generate-markdown/update-library-landing-dox.sh
Copy link
Collaborator

Choose a reason for hiding this comment

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

qq: is this where we hook doc generation to the generator?

Copy link
Member Author

Choose a reason for hiding this comment

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

Producing the final .dox files is a 2 stage process. The generator produces the dox file with markers for the start/end injection points. This script modified the dox file to inject the information between the injection points. line 80 is the invocation of the generator that produces the dox files.

@scotthart scotthart merged commit 1cbff5a into googleapis:main Oct 23, 2025
66 of 67 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants