Skip to content

Commit 5309a22

Browse files
authored
feat(generator): more discoverable generated options (googleapis#10210)
This creates a new page and Doxygen group to host the generated options for each library. The options are automatically added to this group, so they are easier to discover.
1 parent e5d5309 commit 5309a22

296 files changed

Lines changed: 5957 additions & 1113 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

doc/contributor/howto-guide-adding-generated-libraries.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ were written by a robot:
236236
- `google/cloud/${library}/README.md`
237237
- `google/cloud/${library}/quickstart/README.md`
238238
- `google/cloud/${library}/doc/main.dox`
239+
- `google/cloud/${library}/doc/options.dox`
239240

240241
The Cloud documentation links (`cloud.google.com/*/docs/*`) in these files are
241242
not always valid. Find the correct urls and update the links.

generator/integration_tests/golden/golden_kitchen_sink_options.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,38 @@ namespace cloud {
3131
namespace golden {
3232
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
3333

34-
/// Option to use with `google::cloud::Options`.
34+
/**
35+
* Use with `google::cloud::Options` to configure the retry policy.
36+
*
37+
* @ingroup generator-integration_tests-golden-options
38+
*/
3539
struct GoldenKitchenSinkRetryPolicyOption {
3640
using Type = std::shared_ptr<GoldenKitchenSinkRetryPolicy>;
3741
};
3842

39-
/// Option to use with `google::cloud::Options`.
43+
/**
44+
* Use with `google::cloud::Options` to configure the backoff policy.
45+
*
46+
* @ingroup generator-integration_tests-golden-options
47+
*/
4048
struct GoldenKitchenSinkBackoffPolicyOption {
4149
using Type = std::shared_ptr<BackoffPolicy>;
4250
};
4351

44-
/// Option to use with `google::cloud::Options`.
52+
/**
53+
* Use with `google::cloud::Options` to configure which operations are retried.
54+
*
55+
* @ingroup generator-integration_tests-golden-options
56+
*/
4557
struct GoldenKitchenSinkConnectionIdempotencyPolicyOption {
4658
using Type = std::shared_ptr<GoldenKitchenSinkConnectionIdempotencyPolicy>;
4759
};
4860

61+
/**
62+
* The options applicable to GoldenKitchenSink.
63+
*
64+
* @ingroup generator-integration_tests-golden-options
65+
*/
4966
using GoldenKitchenSinkPolicyOptionList =
5067
OptionList<GoldenKitchenSinkRetryPolicyOption,
5168
GoldenKitchenSinkBackoffPolicyOption,

generator/integration_tests/golden/golden_thing_admin_options.h

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,48 @@ namespace cloud {
3131
namespace golden {
3232
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
3333

34-
/// Option to use with `google::cloud::Options`.
34+
/**
35+
* Use with `google::cloud::Options` to configure the retry policy.
36+
*
37+
* @ingroup generator-integration_tests-golden-options
38+
*/
3539
struct GoldenThingAdminRetryPolicyOption {
3640
using Type = std::shared_ptr<GoldenThingAdminRetryPolicy>;
3741
};
3842

39-
/// Option to use with `google::cloud::Options`.
43+
/**
44+
* Use with `google::cloud::Options` to configure the backoff policy.
45+
*
46+
* @ingroup generator-integration_tests-golden-options
47+
*/
4048
struct GoldenThingAdminBackoffPolicyOption {
4149
using Type = std::shared_ptr<BackoffPolicy>;
4250
};
4351

44-
/// Option to use with `google::cloud::Options`.
45-
struct GoldenThingAdminPollingPolicyOption {
46-
using Type = std::shared_ptr<PollingPolicy>;
47-
};
48-
49-
/// Option to use with `google::cloud::Options`.
52+
/**
53+
* Use with `google::cloud::Options` to configure which operations are retried.
54+
*
55+
* @ingroup generator-integration_tests-golden-options
56+
*/
5057
struct GoldenThingAdminConnectionIdempotencyPolicyOption {
5158
using Type = std::shared_ptr<GoldenThingAdminConnectionIdempotencyPolicy>;
5259
};
5360

61+
/**
62+
* Use with `google::cloud::Options` to configure the long-running operations
63+
* polling policy.
64+
*
65+
* @ingroup generator-integration_tests-golden-options
66+
*/
67+
struct GoldenThingAdminPollingPolicyOption {
68+
using Type = std::shared_ptr<PollingPolicy>;
69+
};
70+
71+
/**
72+
* The options applicable to GoldenThingAdmin.
73+
*
74+
* @ingroup generator-integration_tests-golden-options
75+
*/
5476
using GoldenThingAdminPolicyOptionList =
5577
OptionList<GoldenThingAdminRetryPolicyOption,
5678
GoldenThingAdminBackoffPolicyOption,

generator/internal/descriptor_utils.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,8 @@ VarsDictionary CreateServiceVars(
846846
google::protobuf::ServiceDescriptor const& descriptor,
847847
std::vector<std::pair<std::string, std::string>> const& initial_values) {
848848
VarsDictionary vars(initial_values.begin(), initial_values.end());
849+
vars["product_options_page"] = absl::StrCat(
850+
absl::StrReplaceAll(vars["product_path"], {{"/", "-"}}), "options");
849851
vars["additional_pb_header_paths"] = FormatAdditionalPbHeaderPaths(vars);
850852
vars["class_comment_block"] =
851853
FormatClassCommentsFromServiceComments(descriptor);

generator/internal/options_generator.cc

Lines changed: 66 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -56,36 +56,72 @@ Status OptionsGenerator::GenerateHeader() {
5656
auto result = HeaderOpenNamespaces();
5757
if (!result.ok()) return result;
5858

59-
HeaderPrint({// clang-format off
60-
{"\n"
61-
"/// Option to use with `google::cloud::Options`.\n"
62-
"struct $retry_policy_name$Option {\n"
63-
" using Type = std::shared_ptr<$retry_policy_name$>;\n"
64-
"};\n"
65-
"\n"
66-
"/// Option to use with `google::cloud::Options`.\n"
67-
"struct $service_name$BackoffPolicyOption {\n"
68-
" using Type = std::shared_ptr<BackoffPolicy>;\n"
69-
"};\n"},
70-
{[this]{return HasLongrunningMethod();},
71-
"\n"
72-
"/// Option to use with `google::cloud::Options`.\n"
73-
"struct $service_name$PollingPolicyOption {\n"
74-
" using Type = std::shared_ptr<PollingPolicy>;\n"
75-
"};\n", ""},
76-
{"\n"
77-
"/// Option to use with `google::cloud::Options`.\n"
78-
"struct $idempotency_class_name$Option {\n"
79-
" using Type = std::shared_ptr<$idempotency_class_name$>;\n"
80-
"};\n"},
81-
{"\n"
82-
"using $service_name$PolicyOptionList =\n"
83-
" OptionList<$service_name$RetryPolicyOption,\n"
84-
" $service_name$BackoffPolicyOption,\n"},
85-
{[this]{return HasLongrunningMethod();},
86-
" $service_name$PollingPolicyOption,\n", ""},
87-
{" $idempotency_class_name$Option>;\n"}});
88-
// clang-format on
59+
HeaderPrint(
60+
R"""(
61+
/**
62+
* Use with `google::cloud::Options` to configure the retry policy.
63+
*
64+
* @ingroup $product_options_page$
65+
*/
66+
struct $retry_policy_name$Option {
67+
using Type = std::shared_ptr<$retry_policy_name$>;
68+
};
69+
70+
/**
71+
* Use with `google::cloud::Options` to configure the backoff policy.
72+
*
73+
* @ingroup $product_options_page$
74+
*/
75+
struct $service_name$BackoffPolicyOption {
76+
using Type = std::shared_ptr<BackoffPolicy>;
77+
};
78+
79+
/**
80+
* Use with `google::cloud::Options` to configure which operations are retried.
81+
*
82+
* @ingroup $product_options_page$
83+
*/
84+
struct $idempotency_class_name$Option {
85+
using Type = std::shared_ptr<$idempotency_class_name$>;
86+
};
87+
)""");
88+
89+
if (HasLongrunningMethod()) {
90+
HeaderPrint(R"""(
91+
/**
92+
* Use with `google::cloud::Options` to configure the long-running operations
93+
* polling policy.
94+
*
95+
* @ingroup $product_options_page$
96+
*/
97+
struct $service_name$PollingPolicyOption {
98+
using Type = std::shared_ptr<PollingPolicy>;
99+
};
100+
101+
/**
102+
* The options applicable to $service_name$.
103+
*
104+
* @ingroup $product_options_page$
105+
*/
106+
using $service_name$PolicyOptionList =
107+
OptionList<$service_name$RetryPolicyOption,
108+
$service_name$BackoffPolicyOption,
109+
$service_name$PollingPolicyOption,
110+
$idempotency_class_name$Option>;
111+
)""");
112+
} else {
113+
HeaderPrint(R"""(
114+
/**
115+
* The options applicable to $service_name$.
116+
*
117+
* @ingroup $product_options_page$
118+
*/
119+
using $service_name$PolicyOptionList =
120+
OptionList<$service_name$RetryPolicyOption,
121+
$service_name$BackoffPolicyOption,
122+
$idempotency_class_name$Option>;
123+
)""");
124+
}
89125

90126
HeaderCloseNamespaces();
91127
// close header guard

generator/internal/scaffold_generator.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "generator/internal/scaffold_generator.h"
1616
#include "google/cloud/internal/absl_str_join_quiet.h"
17+
#include "google/cloud/internal/absl_str_replace_quiet.h"
1718
#include "google/cloud/internal/filesystem.h"
1819
#include "google/cloud/log.h"
1920
#include "absl/strings/str_split.h"
@@ -82,6 +83,8 @@ std::map<std::string, std::string> ScaffoldVars(
8283
auto const library = LibraryName(service);
8384
vars["copyright_year"] = service.initial_copyright_year();
8485
vars["library"] = library;
86+
vars["product_options_page"] = absl::StrCat(
87+
absl::StrReplaceAll(service.product_path(), {{"/", "-"}}), "options");
8588
vars["site_root"] = SiteRoot(service);
8689
vars["library_prefix"] = experimental ? "experimental-" : "";
8790
vars["doxygen_version_suffix"] = experimental ? " (Experimental)" : "";
@@ -117,6 +120,7 @@ void GenerateScaffold(
117120
{"BUILD.bazel", GenerateBuild},
118121
{"CMakeLists.txt", GenerateCMakeLists},
119122
{"doc/main.dox", GenerateDoxygenMainPage},
123+
{"doc/options.dox", GenerateDoxygenOptionsPage},
120124
{"quickstart/README.md", GenerateQuickstartReadme},
121125
{"quickstart/quickstart.cc", GenerateQuickstartSkeleton},
122126
{"quickstart/CMakeLists.txt", GenerateQuickstartCMake},
@@ -641,6 +645,24 @@ can override the default policies.
641645
printer.Print(variables, kText);
642646
}
643647

648+
void GenerateDoxygenOptionsPage(
649+
std::ostream& os, std::map<std::string, std::string> const& variables) {
650+
auto constexpr kText = R"""(/*!
651+
@defgroup $product_options_page$ $title$ Configuration Options
652+
653+
This library uses the same mechanism (`google::cloud::Options`) and the common
654+
[options](@ref options) as all other C++ client libraries for its configuration.
655+
Some `*Option` classes, which are only used in this library, are documented in
656+
this page.
657+
658+
@see @ref options - for an overview of client library configuration.
659+
*/
660+
)""";
661+
google::protobuf::io::OstreamOutputStream output(&os);
662+
google::protobuf::io::Printer printer(&output, '$');
663+
printer.Print(variables, kText);
664+
}
665+
644666
void GenerateQuickstartReadme(
645667
std::ostream& os, std::map<std::string, std::string> const& variables) {
646668
auto constexpr kText =

generator/internal/scaffold_generator.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ void GenerateCMakeLists(std::ostream& os,
6060
std::map<std::string, std::string> const& variables);
6161
void GenerateDoxygenMainPage(
6262
std::ostream& os, std::map<std::string, std::string> const& variables);
63+
void GenerateDoxygenOptionsPage(
64+
std::ostream& os, std::map<std::string, std::string> const& variables);
6365
void GenerateQuickstartReadme(
6466
std::ostream& os, std::map<std::string, std::string> const& variables);
6567
void GenerateQuickstartSkeleton(

generator/internal/scaffold_generator_test.cc

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ char const* const kHierarchy[] = {
4747

4848
TEST(ScaffoldGeneratorTest, LibraryName) {
4949
google::cloud::cpp::generator::ServiceConfiguration service;
50-
service.set_product_path("google/cloud/test");
50+
service.set_product_path("google/cloud/test/");
5151
EXPECT_EQ("test", LibraryName(service));
5252

5353
service.set_product_path("google/cloud/test/v1");
@@ -112,7 +112,7 @@ class ScaffoldGenerator : public ::testing::Test {
112112
)""";
113113

114114
google::cloud::cpp::generator::ServiceConfiguration service;
115-
service.set_product_path("google/cloud/test");
115+
service.set_product_path("google/cloud/test/");
116116
service.set_service_proto_path("google/cloud/test/v1/service.proto");
117117
service.set_initial_copyright_year("2034");
118118
service_ = std::move(service);
@@ -131,15 +131,17 @@ class ScaffoldGenerator : public ::testing::Test {
131131
TEST_F(ScaffoldGenerator, Vars) {
132132
auto const ga = ScaffoldVars(path(), service(), false);
133133
EXPECT_THAT(
134-
ga, AllOf(Contains(Pair("title", "Test Only API")),
135-
Contains(Pair("description",
136-
"Provides a placeholder to write this test.")),
137-
Contains(Pair("library", "test")),
138-
Contains(Pair("copyright_year", "2034")),
139-
Contains(Pair("library_prefix", "")),
140-
Contains(Pair("doxygen_version_suffix", "")),
141-
Contains(Pair("construction", "")),
142-
Contains(Pair("status", HasSubstr("**GA**")))));
134+
ga,
135+
AllOf(Contains(Pair("title", "Test Only API")),
136+
Contains(Pair("description",
137+
"Provides a placeholder to write this test.")),
138+
Contains(Pair("library", "test")),
139+
Contains(Pair("product_options_page", "google-cloud-test-options")),
140+
Contains(Pair("copyright_year", "2034")),
141+
Contains(Pair("library_prefix", "")),
142+
Contains(Pair("doxygen_version_suffix", "")),
143+
Contains(Pair("construction", "")),
144+
Contains(Pair("status", HasSubstr("**GA**")))));
143145

144146
auto const experimental = ScaffoldVars(path(), service(), true);
145147
EXPECT_THAT(
@@ -148,6 +150,7 @@ TEST_F(ScaffoldGenerator, Vars) {
148150
Contains(Pair("description",
149151
"Provides a placeholder to write this test.")),
150152
Contains(Pair("library", "test")),
153+
Contains(Pair("product_options_page", "google-cloud-test-options")),
151154
Contains(Pair("copyright_year", "2034")),
152155
Contains(Pair("library_prefix", "experimental-")),
153156
Contains(Pair("doxygen_version_suffix", " (Experimental)")),
@@ -242,6 +245,16 @@ to Provides a placeholder to write this test.
242245
EXPECT_THAT(actual, HasSubstr("**GA**"));
243246
}
244247

248+
TEST_F(ScaffoldGenerator, DoxygenOptionsPage) {
249+
auto const vars = ScaffoldVars(path(), service(), false);
250+
std::ostringstream os;
251+
GenerateDoxygenOptionsPage(os, vars);
252+
auto const actual = std::move(os).str();
253+
EXPECT_THAT(actual, HasSubstr(R"""(
254+
@defgroup google-cloud-test-options Test Only API Configuration Options
255+
)"""));
256+
}
257+
245258
TEST_F(ScaffoldGenerator, QuickstartReadme) {
246259
auto const vars = ScaffoldVars(path(), service(), false);
247260
std::ostringstream os;

google/cloud/accessapproval/access_approval_options.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,38 @@ namespace cloud {
3131
namespace accessapproval {
3232
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
3333

34-
/// Option to use with `google::cloud::Options`.
34+
/**
35+
* Use with `google::cloud::Options` to configure the retry policy.
36+
*
37+
* @ingroup google-cloud-accessapproval-options
38+
*/
3539
struct AccessApprovalRetryPolicyOption {
3640
using Type = std::shared_ptr<AccessApprovalRetryPolicy>;
3741
};
3842

39-
/// Option to use with `google::cloud::Options`.
43+
/**
44+
* Use with `google::cloud::Options` to configure the backoff policy.
45+
*
46+
* @ingroup google-cloud-accessapproval-options
47+
*/
4048
struct AccessApprovalBackoffPolicyOption {
4149
using Type = std::shared_ptr<BackoffPolicy>;
4250
};
4351

44-
/// Option to use with `google::cloud::Options`.
52+
/**
53+
* Use with `google::cloud::Options` to configure which operations are retried.
54+
*
55+
* @ingroup google-cloud-accessapproval-options
56+
*/
4557
struct AccessApprovalConnectionIdempotencyPolicyOption {
4658
using Type = std::shared_ptr<AccessApprovalConnectionIdempotencyPolicy>;
4759
};
4860

61+
/**
62+
* The options applicable to AccessApproval.
63+
*
64+
* @ingroup google-cloud-accessapproval-options
65+
*/
4966
using AccessApprovalPolicyOptionList =
5067
OptionList<AccessApprovalRetryPolicyOption,
5168
AccessApprovalBackoffPolicyOption,

0 commit comments

Comments
 (0)