Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sanitise input data #200

Merged
merged 48 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
bed9892
Remove create_output_folder() function
alexdewar Aug 7, 2023
50505e1
Use std::filesystem::path cf. std::string in a few places
alexdewar Aug 8, 2023
2700324
Drop support for v1 config files
alexdewar Aug 8, 2023
358c762
load_configuration(): Remove some indentation
alexdewar Aug 8, 2023
a2fd569
Make separate function for rebasing paths
alexdewar Aug 8, 2023
c66c0b8
Put new functions for loading JSON into configuration.cpp
alexdewar Aug 8, 2023
d9a8ab8
Add ConfigurationError class and use in a few places
alexdewar Aug 8, 2023
100ffd7
Remove unused field
alexdewar Aug 8, 2023
d1cc571
Clean up and add extra error checking to config file loading
alexdewar Aug 8, 2023
f480522
Remove superfluous helper functions
alexdewar Aug 9, 2023
2597d32
Fix: Seemingly MSVC isn't happy about casting filesystem::paths to st…
alexdewar Aug 9, 2023
9a1188c
Move some functions out of configuration.cpp to program.cpp
alexdewar Aug 9, 2023
3efc2be
Put functionality related to command-line args in own cpp file
alexdewar Aug 9, 2023
0d1f803
Move some parsing functions into configuration_parsing.cpp
alexdewar Aug 9, 2023
3d72290
Put configuration parsing helper function defs into own header
alexdewar Aug 9, 2023
edc505d
Rename some functions and mark noexcept
alexdewar Aug 9, 2023
04eab1e
Remove unused API version functionality
alexdewar Aug 9, 2023
a7ee4b5
Move version.h.in to src/HealthGPS
alexdewar Aug 9, 2023
7ff7cc1
Build most console functionality as lib for testability
alexdewar Aug 9, 2023
c6306a1
Spelling
alexdewar Aug 11, 2023
3934a7f
Add JSON (de)serialisation code for Interval<> class
alexdewar Aug 11, 2023
3111772
Make SettingsInfo.age_range an IntegerInterval
alexdewar Aug 11, 2023
35b93a2
Base OptionalRange on Interval class and rename
alexdewar Aug 11, 2023
9557033
Add tests for some config code
alexdewar Aug 11, 2023
efd97bf
Merge remote-tracking branch 'origin/main' into sanitise_input_data
alexdewar Aug 11, 2023
9f5eaec
Fix typo
alexdewar Aug 14, 2023
6180f36
Allow for parsing JSON objects to any map type with Identifier as key
alexdewar Aug 14, 2023
babf513
Use default comparators cf. custom operator==
alexdewar Aug 14, 2023
f5f55f4
Add test for load_interventions
alexdewar Aug 14, 2023
3191348
Make active intervention into an optional type
alexdewar Aug 14, 2023
4c9ee02
Add final tests for config code
alexdewar Aug 15, 2023
5625e26
MSVC resources file should live in HealthGPS.Console/
alexdewar Aug 15, 2023
d4f531e
Remove unused var
alexdewar Aug 15, 2023
d5c2aa7
Use different get_to overload in a couple of places
alexdewar Aug 15, 2023
d19cdd8
Explicitly convert to string to appease MSVC
alexdewar Aug 15, 2023
c1b6636
Fix: Appease g++ v11 by not using structured bindings
alexdewar Aug 15, 2023
9d9801d
Fix narrowing warning on MSVC
alexdewar Aug 15, 2023
7deec87
Fix: Interval class's members should be default-initialised
alexdewar Aug 16, 2023
aafadfb
Fix/suppress bugprone-exception-escape clang-tidy warning
alexdewar Aug 16, 2023
6f19143
Fix: Use absolute cf. weakly canonical paths in rebase_valid_path()
alexdewar Aug 16, 2023
cbd23d7
Fix docstring warnings and rename a couple of args
alexdewar Aug 16, 2023
a592a1b
Add docstrings to poco.h
alexdewar Aug 16, 2023
26f1b31
Remove unused function definition
alexdewar Aug 16, 2023
6438589
Add file-level documentation for several headers
alexdewar Aug 16, 2023
0157f76
range parameter doesn't need a default value
alexdewar Aug 17, 2023
c9e3b2d
Revert "range parameter doesn't need a default value"
jamesturner246 Aug 18, 2023
72d6519
Remove special-casing for std::optional<Interval<T>>
alexdewar Aug 21, 2023
00fc19f
Merge branch 'main' into sanitise_input_data
alexdewar Aug 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions src/HealthGPS.Console/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ find_package(TBB CONFIG REQUIRED)
find_path(RAPIDCSV_INCLUDE_DIRS "rapidcsv.h")
find_package(Threads REQUIRED)

add_executable(HealthGPS.Console "")
target_compile_features(HealthGPS.Console PUBLIC cxx_std_${CMAKE_CXX_STANDARD})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why no target_compile_features(HealthGPS.Console PUBLIC cxx_std_${CMAKE_CXX_STANDARD})?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's redundant because targets are already built using ${CMAKE_CXX_STANDARD} anyway.


configure_file("version.h.in" "version.h" ESCAPE_QUOTES)
include_directories(${CMAKE_CURRENT_BINARY_DIR})

target_sources(HealthGPS.Console
PRIVATE
add_executable(HealthGPS.Console "program.cpp")
add_library(HealthGPS.LibConsole STATIC
"command_options.cpp"
"command_options.h"
"configuration.cpp"
"configuration.h"
"configuration_parsing.cpp"
"configuration_parsing.h"
"configuration_parsing_helpers.h"
"csvparser.cpp"
"csvparser.h"
"event_monitor.cpp"
Expand All @@ -27,7 +26,6 @@ target_sources(HealthGPS.Console
"jsonparser.cpp"
"jsonparser.h"
"model_info.h"
"options.h"
"resource.h"
"result_writer.h"
"riskmodel.h"
Expand All @@ -40,7 +38,21 @@ if(WIN32)
target_sources(HealthGPS.Console PRIVATE versioninfo.rc)
endif(WIN32)

target_include_directories(HealthGPS.LibConsole PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

target_link_libraries(HealthGPS.Console
PRIVATE
HealthGPS.Core
HealthGPS.Datastore
HealthGPS.LibConsole
HealthGPS
fmt::fmt
Threads::Threads
cxxopts::cxxopts
nlohmann_json::nlohmann_json
TBB::tbb)

target_link_libraries(HealthGPS.LibConsole
PRIVATE
HealthGPS.Core
HealthGPS.Datastore
Expand All @@ -56,4 +68,4 @@ if(WIN32)
install(IMPORTED_RUNTIME_ARTIFACTS fmt::fmt)
endif()

set(ROOT_NAMESPACE hgps)
set(ROOT_NAMESPACE hgps)
96 changes: 96 additions & 0 deletions src/HealthGPS.Console/command_options.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include "command_options.h"
#include "version.h"

#include <fmt/color.h>

#include <iostream>

namespace host {

cxxopts::Options create_options() {
cxxopts::Options options("HealthGPS.Console", "Health-GPS microsimulation for policy options.");
options.add_options()("f,file", "Configuration file full name.", cxxopts::value<std::string>())(
"s,storage", "Path to root folder of the data storage.", cxxopts::value<std::string>())(
"j,jobid", "The batch execution job identifier.",
cxxopts::value<int>())("verbose", "Print more information about progress",
cxxopts::value<bool>()->default_value("false"))(
"help", "Help about this application.")("version", "Print the application version number.");

return options;
}

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() << std::endl;
cmd.success = false;
return cmd;
}

if (result.count("version")) {
fmt::print("Version {}\n\n", PROJECT_VERSION);
cmd.success = false;
return cmd;
}

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

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());
}
}

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;
}

if (result.count("storage")) {
cmd.storage_folder = result["storage"].as<std::string>();
if (cmd.storage_folder.is_relative()) {
cmd.storage_folder = std::filesystem::absolute(cmd.storage_folder);
fmt::print("File storage folder.: {}\n", cmd.storage_folder.string());
}
}

if (!fs::exists(cmd.storage_folder)) {
fmt::print(fg(fmt::color::red), "\nFile storage folder: {} not found.\n",
cmd.storage_folder.string());
cmd.exit_code = EXIT_FAILURE;
}

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.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;
}

return cmd;
}
} // namespace host
43 changes: 43 additions & 0 deletions src/HealthGPS.Console/command_options.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @file
* @brief Functionality for parsing console application's command-line arguments
*/
#pragma once
#include <cxxopts.hpp>

#include <filesystem>

namespace host {
/// @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{};

/// @brief The back-end storage full path argument value
std::filesystem::path storage_folder{};

/// @brief Indicates whether the application logging is verbose
bool verbose{};

/// @brief The batch job identifier value, optional.
int job_id{};
};

/// @brief Creates the command-line interface (CLI) options
/// @return Health-GPS CLI options
cxxopts::Options create_options();

/// @brief Parses the command-line interface (CLI) arguments
/// @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[]);

} // namespace host
Loading