Skip to content

Commit

Permalink
Merge pull request #483 from imperialCHEPI/refactor_parsing_args
Browse files Browse the repository at this point in the history
Refactor code for parsing command-line arguments
  • Loading branch information
alexdewar authored Aug 16, 2024
2 parents 297d88b + aa6f0be commit 0e2229f
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 69 deletions.
95 changes: 38 additions & 57 deletions src/HealthGPS.Console/command_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,75 +19,56 @@ cxxopts::Options create_options() {
return options;
}

// NOLINTNEXTLINE(modernize-avoid-c-arrays)
CommandOptions parse_arguments(cxxopts::Options &options, int &argc, char *argv[]) {
std::optional<CommandOptions> parse_arguments(cxxopts::Options &options, int argc, char **argv) {
namespace fs = std::filesystem;

CommandOptions cmd;
try {
cmd.success = true;
cmd.exit_code = EXIT_SUCCESS;
cmd.verbose = false;
auto result = options.parse(argc, argv);
if (result.count("help")) {
std::cout << options.help() << '\n';
cmd.success = false;
return cmd;
}
auto result = options.parse(argc, argv);

if (result.count("version")) {
fmt::print("Version {}\n\n", PROJECT_VERSION);
cmd.success = false;
return cmd;
}
if (result.count("help")) {
std::cout << options.help() << '\n';
return std::nullopt;
}

cmd.verbose = result["verbose"].as<bool>();
if (cmd.verbose) {
fmt::print(fg(fmt::color::dark_salmon), "Verbose output enabled\n");
}
if (result.count("version")) {
fmt::print("Version {}\n\n", PROJECT_VERSION);
return std::nullopt;
}

if (result.count("file")) {
cmd.config_file = result["file"].as<std::string>();
if (cmd.config_file.is_relative()) {
cmd.config_file = std::filesystem::absolute(cmd.config_file);
fmt::print("Configuration file..: {}\n", cmd.config_file.string());
}
}
cmd.verbose = result["verbose"].as<bool>();
if (cmd.verbose) {
fmt::print(fg(fmt::color::dark_salmon), "Verbose output enabled\n");
}

if (!fs::exists(cmd.config_file)) {
fmt::print(fg(fmt::color::red), "\nConfiguration file: {} not found.\n",
cmd.config_file.string());
cmd.exit_code = EXIT_FAILURE;
}
cmd.config_file = result["file"].as<std::string>();
if (cmd.config_file.is_relative()) {
cmd.config_file = std::filesystem::absolute(cmd.config_file);
fmt::print("Configuration file: {}\n", cmd.config_file.string());
}

if (result.count("storage")) {
auto source = result["storage"].as<std::string>();
if (!fs::exists(cmd.config_file)) {
throw std::runtime_error(
fmt::format("Configuration file: {} not found.", cmd.config_file.string()));
}

fmt::print(fmt::fg(fmt::color::yellow),
"WARNING: Path to data source specified with command-line argument. "
"This functionality is deprecatated and will be removed in future. You "
"should pass the data source via the config file.\n");
fmt::print("Data source: {}\n", source);
if (result.count("storage")) {
auto source = result["storage"].as<std::string>();

cmd.data_source = hgps::input::DataSource(std::move(source));
}
fmt::print(fmt::fg(fmt::color::yellow),
"WARNING: Path to data source specified with command-line argument. "
"This functionality is deprecated and will be removed in future. You "
"should pass the data source via the config file.\n");
fmt::print("Data source: {}\n", source);

if (result.count("jobid")) {
cmd.job_id = result["jobid"].as<int>();
if (cmd.job_id < 1) {
fmt::print(fg(fmt::color::red),
"\nJob identifier value outside range: (0 < x) given: {}.\n",
std::to_string(cmd.job_id));
cmd.exit_code = EXIT_FAILURE;
}
}
cmd.data_source = hgps::input::DataSource(std::move(source));
}

cmd.success = cmd.exit_code == EXIT_SUCCESS;
} catch (const cxxopts::exceptions::exception &ex) {
fmt::print(fg(fmt::color::red), "\nInvalid command line argument: {}.\n", ex.what());
fmt::print("\n{}\n", options.help());
cmd.success = false;
cmd.exit_code = EXIT_FAILURE;
if (result.count("jobid")) {
cmd.job_id = result["jobid"].as<int>();
if (cmd.job_id < 1) {
throw std::runtime_error(
fmt::format("Job identifier value outside range: (0 < x) given: {}.", cmd.job_id));
}
}

return cmd;
Expand Down
12 changes: 3 additions & 9 deletions src/HealthGPS.Console/command_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,8 @@
namespace hgps {
/// @brief Defines the Command Line Interface (CLI) arguments options
struct CommandOptions {
/// @brief Indicates whether the argument parsing succeed
bool success{};

/// @brief The exit code to return, in case of CLI arguments parsing failure
int exit_code{};

/// @brief The configuration file argument value
std::filesystem::path config_file{};
std::filesystem::path config_file;

/// @brief The back-end storage full path or URL argument value
std::optional<hgps::input::DataSource> data_source;
Expand All @@ -41,7 +35,7 @@ cxxopts::Options create_options();
/// @param options The valid CLI options
/// @param argc Number of input arguments
/// @param argv List of input arguments
/// @return User command-line options
CommandOptions parse_arguments(cxxopts::Options &options, int &argc, char *argv[]);
/// @return User command-line options or std::nullopt if program should exit
std::optional<CommandOptions> parse_arguments(cxxopts::Options &options, int argc, char **argv);

} // namespace hgps
18 changes: 15 additions & 3 deletions src/HealthGPS.Console/program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,23 @@ int main(int argc, char *argv[]) { // NOLINT(bugprone-exception-escape)

// Print application title and parse command line arguments
print_app_title();
auto cmd_args = parse_arguments(options, argc, argv);
if (!cmd_args.success) {
return cmd_args.exit_code;

std::optional<CommandOptions> cmd_args_opt;
try {
cmd_args_opt = parse_arguments(options, argc, argv);

// We won't get a config if e.g. the user chooses the --help option
if (!cmd_args_opt) {
return exit_application(EXIT_SUCCESS);
}
} catch (const std::exception &ex) {
fmt::print(fg(fmt::color::red), "\nInvalid command line argument: {}\n", ex.what());
fmt::print("\n{}\n", options.help());
return exit_application(EXIT_FAILURE);
}

const auto &cmd_args = cmd_args_opt.value();

// Parse inputs configuration file, *.json.
Configuration config;
try {
Expand Down

0 comments on commit 0e2229f

Please sign in to comment.