Skip to content

Commit 7ee69a7

Browse files
committed
Add a value name hint to Flag
A flag created with `Flag::StringFlag("instance-name")` produces a synopsis like "--instance-name=NAME" by default. Callers can customize it further with the ValueNameHintMethod. Assisted-by: Gemini
1 parent ba2435d commit 7ee69a7

3 files changed

Lines changed: 50 additions & 1 deletion

File tree

base/cvd/cuttlefish/flag_parser/flag.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@
3030

3131
#include "absl/cleanup/cleanup.h"
3232
#include "absl/log/check.h"
33+
#include "absl/strings/ascii.h"
3334
#include "absl/strings/str_cat.h"
3435
#include "absl/strings/str_join.h"
3536
#include "absl/strings/str_replace.h"
37+
#include "absl/strings/str_split.h"
3638
#include "absl/strings/strip.h"
3739

3840
#include "cuttlefish/common/libs/utils/contains.h"
@@ -57,6 +59,15 @@ bool MatchNormalized(std::string_view str1, std::string_view str2) {
5759
return n1 == n2;
5860
}
5961

62+
std::string DefaultValueNameHint(std::string_view name) {
63+
std::vector<std::string_view> parts =
64+
absl::StrSplit(name, absl::ByAnyChar("-_"), absl::SkipEmpty());
65+
if (parts.empty()) {
66+
return "VAL";
67+
}
68+
return absl::AsciiStrToUpper(parts.back());
69+
}
70+
6071
} // namespace
6172

6273
Flag Flag::StringFlag(std::string name) {
@@ -80,6 +91,14 @@ Flag& Flag::Help(std::string help) & {
8091
}
8192
Flag Flag::Help(std::string help) && { return std::move(Help(help)); }
8293

94+
Flag& Flag::ValueNameHint(std::string value_name_hint) & {
95+
value_name_hint_ = std::move(value_name_hint);
96+
return *this;
97+
}
98+
Flag Flag::ValueNameHint(std::string value_name_hint) && {
99+
return std::move(ValueNameHint(value_name_hint));
100+
}
101+
83102
Flag& Flag::Getter(std::function<std::string()> getter) & {
84103
getter_ = std::move(getter);
85104
return *this;
@@ -111,7 +130,7 @@ std::string Flag::Synopsis() const {
111130
for (const std::string& alias : aliases_) {
112131
switch (style_) {
113132
case Flag::Style::String:
114-
options.emplace_back(absl::StrCat("--", alias, "=VAL"));
133+
options.emplace_back(absl::StrCat("--", alias, "=", value_name_hint_));
115134
break;
116135
case Flag::Style::Bool:
117136
options.emplace_back("--[no]" + alias);
@@ -127,6 +146,7 @@ std::string Flag::CurrentValue() const { return getter_(); }
127146

128147
Flag::Flag(std::string name, Flag::Style style) : style_(style) {
129148
ValidateAlias(name);
149+
value_name_hint_ = DefaultValueNameHint(name);
130150
aliases_.emplace_back(std::move(name));
131151
}
132152

base/cvd/cuttlefish/flag_parser/flag.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ class Flag {
4040
/* Set help text, visible in the class ostream writer method. Optional. */
4141
Flag& Help(std::string) &;
4242
Flag Help(std::string) &&;
43+
/* Set the value name hint used in the synopsis. Optional. */
44+
Flag& ValueNameHint(std::string) &;
45+
Flag ValueNameHint(std::string) &&;
4346
/* Set a loader that displays the current value in help text. Optional. */
4447
Flag& Getter(std::function<std::string()>) &;
4548
Flag Getter(std::function<std::string()>) &&;
@@ -86,6 +89,7 @@ class Flag {
8689
std::vector<std::string> aliases_;
8790
Style style_;
8891
std::string help_;
92+
std::string value_name_hint_ = "VAL";
8993
std::function<std::string()> getter_ = []() { return ""; };
9094
std::function<Result<void>(std::string_view value)> setter_;
9195
std::vector<std::function<Result<void>()>> validators_;

base/cvd/cuttlefish/flag_parser/flag_test.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,29 @@ TEST(FlagParser, EndOfOptionMark) {
8484
ASSERT_TRUE(flag);
8585
}
8686

87+
TEST(FlagParser, ValueNameHint_Customized) {
88+
auto flag = Flag::StringFlag("myflag").ValueNameHint("myvalue");
89+
EXPECT_EQ(flag.Synopsis(), "--myflag=myvalue");
90+
}
91+
92+
TEST(FlagParser, ValueNameHint_CustomizedWithAlias) {
93+
auto flag = Flag::StringFlag("myflag").Alias("mf").ValueNameHint("myvalue");
94+
EXPECT_EQ(flag.Synopsis(), "--myflag=myvalue, --mf=myvalue");
95+
}
96+
97+
TEST(FlagParser, ValueNameHint_DefaultDerived) {
98+
auto flag = Flag::StringFlag("myflag");
99+
EXPECT_EQ(flag.Synopsis(), "--myflag=MYFLAG");
100+
}
101+
102+
TEST(FlagParser, ValueNameHint_DefaultDerivedDashed) {
103+
auto flag = Flag::StringFlag("verbosity-level");
104+
EXPECT_EQ(flag.Synopsis(), "--verbosity-level=LEVEL");
105+
}
106+
107+
TEST(FlagParser, ValueNameHint_DefaultDerivedSnaked) {
108+
auto flag = Flag::StringFlag("verbosity_level");
109+
EXPECT_EQ(flag.Synopsis(), "--verbosity_level=LEVEL");
110+
}
111+
87112
} // namespace cuttlefish

0 commit comments

Comments
 (0)