mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Add (pretty basic) config dumping and documentation help.
This commit is contained in:
40
lib/flags.cc
40
lib/flags.cc
@@ -3,6 +3,7 @@
|
||||
#include "proto.h"
|
||||
#include "utils.h"
|
||||
#include "fmt/format.h"
|
||||
#include <google/protobuf/text_format.h>
|
||||
#include <regex>
|
||||
|
||||
static FlagGroup* currentFlagGroup;
|
||||
@@ -10,6 +11,8 @@ static std::vector<Flag*> all_flags;
|
||||
static std::map<const std::string, Flag*> flags_by_name;
|
||||
|
||||
static void doHelp();
|
||||
static void doShowConfig();
|
||||
static void doDoc();
|
||||
|
||||
static FlagGroup helpGroup;
|
||||
static ActionFlag helpFlag = ActionFlag(
|
||||
@@ -17,6 +20,16 @@ static ActionFlag helpFlag = ActionFlag(
|
||||
"Shows the help.",
|
||||
doHelp);
|
||||
|
||||
static ActionFlag showConfigFlag = ActionFlag(
|
||||
{ "--show-config", "-c" },
|
||||
"Shows the currently set configuration and halts.",
|
||||
doShowConfig);
|
||||
|
||||
static ActionFlag docFlag = ActionFlag(
|
||||
{ "--doc" },
|
||||
"Shows the available configuration options.",
|
||||
doDoc);
|
||||
|
||||
FlagGroup::FlagGroup(const std::initializer_list<FlagGroup*> groups):
|
||||
_groups(groups.begin(), groups.end())
|
||||
{
|
||||
@@ -239,3 +252,30 @@ static void doHelp()
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void doShowConfig()
|
||||
{
|
||||
std::string s;
|
||||
google::protobuf::TextFormat::PrintToString(config, &s);
|
||||
std::cout << s << '\n';
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void doDoc()
|
||||
{
|
||||
const auto fields = findAllProtoFields(&config);
|
||||
for (const auto field : fields)
|
||||
{
|
||||
const std::string& path = field.first;
|
||||
const google::protobuf::FieldDescriptor* f = field.second;
|
||||
|
||||
if (f->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE)
|
||||
continue;
|
||||
|
||||
std::string helpText = f->options().GetExtension(help);
|
||||
std::cout << fmt::format("{}: {}\n", path, helpText);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
21
lib/proto.cc
21
lib/proto.cc
@@ -132,3 +132,24 @@ std::set<unsigned> iterate(const RangeProto& range)
|
||||
return set;
|
||||
}
|
||||
|
||||
std::map<std::string, const google::protobuf::FieldDescriptor*> findAllProtoFields(google::protobuf::Message* message)
|
||||
{
|
||||
std::map<std::string, const google::protobuf::FieldDescriptor*> fields;
|
||||
const auto* descriptor = message->GetDescriptor();
|
||||
|
||||
std::function<void(const google::protobuf::Descriptor*, const std::string&)> recurse =
|
||||
[&](auto* d, const auto& s) {
|
||||
for (int i=0; i<d->field_count(); i++)
|
||||
{
|
||||
const google::protobuf::FieldDescriptor* f = d->field(i);
|
||||
std::string n = s + f->name();
|
||||
if (f->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE)
|
||||
recurse(f->message_type(), n + ".");
|
||||
fields[n] = f;
|
||||
}
|
||||
};
|
||||
|
||||
recurse(descriptor, "");
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ extern void setProtoByString(google::protobuf::Message* message, const std::stri
|
||||
|
||||
extern std::set<unsigned> iterate(const RangeProto& range);
|
||||
|
||||
extern std::map<std::string, const google::protobuf::FieldDescriptor*>
|
||||
findAllProtoFields(google::protobuf::Message* message);
|
||||
|
||||
extern ConfigProto config;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,11 +28,6 @@ int mainRead(int argc, const char* argv[])
|
||||
if (!config.has_input() || !config.has_output())
|
||||
Error() << "incomplete config (did you remember to specify the format?)";
|
||||
|
||||
std::string s;
|
||||
google::protobuf::TextFormat::PrintToString(config, &s);
|
||||
std::cout << s << '\n';
|
||||
exit(0);
|
||||
|
||||
std::unique_ptr<FluxSource> fluxSource(FluxSource::create(config.input().disk()));
|
||||
std::unique_ptr<AbstractDecoder> decoder(AbstractDecoder::create(config.decoder()));
|
||||
std::unique_ptr<ImageWriter> writer(ImageWriter::create(config.output().file()));
|
||||
|
||||
@@ -98,12 +98,31 @@ static void test_range(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void test_fields(void)
|
||||
{
|
||||
TestProto proto;
|
||||
auto fields = findAllProtoFields(&proto);
|
||||
AssertThat(fields, HasLength(13));
|
||||
}
|
||||
|
||||
static void test_options(void)
|
||||
{
|
||||
TestProto proto;
|
||||
const auto* descriptor = proto.descriptor();
|
||||
const auto* field = descriptor->FindFieldByName("i64");
|
||||
const auto& options = field->options();
|
||||
const std::string s = options.GetExtension(help);
|
||||
AssertThat(s, Equals("i64"));
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
test_setting();
|
||||
test_config();
|
||||
test_load();
|
||||
test_range();
|
||||
test_fields();
|
||||
test_options();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
syntax = "proto2";
|
||||
|
||||
import "lib/common.proto";
|
||||
|
||||
message TestProto {
|
||||
message SubMessageProto {
|
||||
optional string s = 1;
|
||||
}
|
||||
|
||||
optional int64 i64 = 1;
|
||||
optional int64 i64 = 1 [(help)="i64"];
|
||||
optional int32 i32 = 2;
|
||||
optional uint64 u64 = 3;
|
||||
optional uint32 u32 = 4;
|
||||
|
||||
Reference in New Issue
Block a user