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 "proto.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
#include <google/protobuf/text_format.h>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
static FlagGroup* currentFlagGroup;
|
static FlagGroup* currentFlagGroup;
|
||||||
@@ -10,6 +11,8 @@ static std::vector<Flag*> all_flags;
|
|||||||
static std::map<const std::string, Flag*> flags_by_name;
|
static std::map<const std::string, Flag*> flags_by_name;
|
||||||
|
|
||||||
static void doHelp();
|
static void doHelp();
|
||||||
|
static void doShowConfig();
|
||||||
|
static void doDoc();
|
||||||
|
|
||||||
static FlagGroup helpGroup;
|
static FlagGroup helpGroup;
|
||||||
static ActionFlag helpFlag = ActionFlag(
|
static ActionFlag helpFlag = ActionFlag(
|
||||||
@@ -17,6 +20,16 @@ static ActionFlag helpFlag = ActionFlag(
|
|||||||
"Shows the help.",
|
"Shows the help.",
|
||||||
doHelp);
|
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):
|
FlagGroup::FlagGroup(const std::initializer_list<FlagGroup*> groups):
|
||||||
_groups(groups.begin(), groups.end())
|
_groups(groups.begin(), groups.end())
|
||||||
{
|
{
|
||||||
@@ -239,3 +252,30 @@ static void doHelp()
|
|||||||
}
|
}
|
||||||
exit(0);
|
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;
|
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::set<unsigned> iterate(const RangeProto& range);
|
||||||
|
|
||||||
|
extern std::map<std::string, const google::protobuf::FieldDescriptor*>
|
||||||
|
findAllProtoFields(google::protobuf::Message* message);
|
||||||
|
|
||||||
extern ConfigProto config;
|
extern ConfigProto config;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -28,11 +28,6 @@ int mainRead(int argc, const char* argv[])
|
|||||||
if (!config.has_input() || !config.has_output())
|
if (!config.has_input() || !config.has_output())
|
||||||
Error() << "incomplete config (did you remember to specify the format?)";
|
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<FluxSource> fluxSource(FluxSource::create(config.input().disk()));
|
||||||
std::unique_ptr<AbstractDecoder> decoder(AbstractDecoder::create(config.decoder()));
|
std::unique_ptr<AbstractDecoder> decoder(AbstractDecoder::create(config.decoder()));
|
||||||
std::unique_ptr<ImageWriter> writer(ImageWriter::create(config.output().file()));
|
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[])
|
int main(int argc, const char* argv[])
|
||||||
{
|
{
|
||||||
test_setting();
|
test_setting();
|
||||||
test_config();
|
test_config();
|
||||||
test_load();
|
test_load();
|
||||||
test_range();
|
test_range();
|
||||||
|
test_fields();
|
||||||
|
test_options();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
syntax = "proto2";
|
syntax = "proto2";
|
||||||
|
|
||||||
|
import "lib/common.proto";
|
||||||
|
|
||||||
message TestProto {
|
message TestProto {
|
||||||
message SubMessageProto {
|
message SubMessageProto {
|
||||||
optional string s = 1;
|
optional string s = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
optional int64 i64 = 1;
|
optional int64 i64 = 1 [(help)="i64"];
|
||||||
optional int32 i32 = 2;
|
optional int32 i32 = 2;
|
||||||
optional uint64 u64 = 3;
|
optional uint64 u64 = 3;
|
||||||
optional uint32 u32 = 4;
|
optional uint32 u32 = 4;
|
||||||
|
|||||||
Reference in New Issue
Block a user