AsmGrader 0.0.0
Loading...
Searching...
No Matches
program_options.hpp
Go to the documentation of this file.
1#pragma once
2
5
7#include "common/expected.hpp"
8#include "program/program.hpp"
10#include "version.hpp"
11
12#include <fmt/base.h>
13#include <fmt/compile.h>
14#include <fmt/format.h>
15#include <libassert/assert.hpp>
16
17#include <algorithm>
18#include <exception>
19#include <filesystem>
20#include <optional>
21#include <regex>
22#include <stdexcept>
23#include <string>
24#include <string_view>
25#include <tuple>
26#include <type_traits>
27
28namespace asmgrader {
29
31{
32
33 // ###### Argument fields
34
46 std::string assignment_name;
47
52
54
55 // TODO: Premit simplified execution of individual files in prof mode. Has to be mutually excusive with some
56 // other opts
57
58 // Student version only
59 std::optional<std::string> file_name;
60
61 // PROFESSOR_VERSION only
62 std::string file_matcher = std::string{DEFAULT_FILE_MATCHER};
63 std::filesystem::path database_path = DEFAULT_DATABASE_PATH;
64 std::filesystem::path search_path = DEFAULT_SEARCH_PATH;
65
66 // ###### Argument defaults
67
68 static constexpr std::string_view DEFAULT_DATABASE_PATH = "students.csv";
69 static constexpr std::string_view DEFAULT_SEARCH_PATH = ".";
72
73 static Expected<void, std::string> ensure_file_exists(const std::filesystem::path& path,
74 fmt::format_string<std::string> fmt) {
75 if (!std::filesystem::exists(path)) {
76 return (fmt::format(fmt, path.string()) + " does not exist");
77 }
78
79 return {};
80 }
81
82 static Expected<void, std::string> ensure_is_regular_file(const std::filesystem::path& path,
83 fmt::format_string<std::string> fmt) {
84 TRY(ensure_file_exists(path, fmt));
85
86 if (!std::filesystem::is_regular_file(path)) {
87 return (fmt::format(fmt, path.string()) + " is not a regular file");
88 }
89
90 return {};
91 }
92
93 [[maybe_unused]] static Expected<void, std::string> ensure_is_directory(const std::filesystem::path& path,
94 fmt::format_string<std::string> fmt) {
95 TRY(ensure_file_exists(path, fmt));
96
97 if (!std::filesystem::is_directory(path)) {
98 return (fmt::format(fmt, path.string()) + " is not a directory");
99 }
100
101 return {};
102 }
103
106 // Assume that all enumerators have valid values except for verbosity
107 // which we will just clamp to [MIN, MAX]
108
109 constexpr auto MAX_VERBOSITY = VerbosityLevel::Max;
110 constexpr auto MIN_VERBOSITY = VerbosityLevel{};
111
112 verbosity = std::clamp(verbosity, MIN_VERBOSITY, MAX_VERBOSITY);
113
114 // Ensure that the matcher is a valid RegEx
115 try {
116 std::ignore = std::regex{file_matcher};
117 } catch (std::exception& ex) {
118 return (fmt::format("File matcher {:?} is invalid. {}", file_matcher, ex.what()));
119 }
120
121 TRY(ensure_is_directory(search_path, "Search path {:?}"));
122
123 // The CLI should verify that the specified assignment is valid
124 // We'll check here just in case and return an error if it's not
125 auto assignment = TRYE(GlobalRegistrar::get().get_assignment(assignment_name),
126 fmt::format("Error locating assignment {}", assignment_name));
127
128 if (APP_MODE != AppMode::Professor) {
129 // TODO: A more friendly diagnostic for non-existant file
130 std::string exec_file_name = file_name.value_or(assignment.get().get_exec_path());
131
132 TRY(ensure_is_regular_file(exec_file_name, "File to run tests on {:?}"));
133 TRY(Program::check_is_elf(exec_file_name));
134 }
135
136 // Only check the database path if it's not the default
137 // non-existance will be handled properly in ProfessorApp
139 TRY(ensure_is_regular_file(database_path, "Database file {:?}"));
140 }
141
142 return {};
143 }
144};
145
146} // namespace asmgrader
147
148template <>
150{
151 auto format(const ::asmgrader::ProgramOptions& from, fmt::format_context& ctx) const {
152 // TODO: Enums -> strings
153
154 ctx.advance_to(
155 fmt::format_to(ctx.out(), "{{verbosity={}, assignment={}, stop_opt={}, color_opt={}, file_name={}",
156 fmt::underlying(from.verbosity), from.assignment_name, fmt::underlying(from.stop_option),
157 fmt::underlying(from.colorize_option), from.file_name));
158
159 if (asmgrader::APP_MODE == asmgrader::AppMode::Professor) {
160 return fmt::format_to(ctx.out(), " file_matcher={}, database_path={}, search_path={}", from.file_matcher,
161 from.database_path, from.search_path);
162 }
163
164 return ctx.out() = '}';
165 }
166};
static constexpr auto DEFAULT_REGEX
Definition assignment_file_searcher.hpp:18
std::variant wrapper for a partial implementation of C++23's expected type
Definition expected.hpp:34
static GlobalRegistrar & get() noexcept
Safe global singleton pattern (first intro. by Scott Meyers for C++, I think)
Definition global_registrar.cpp:11
static Expected< void, std::string > check_is_elf(const std::filesystem::path &path)
Definition program.cpp:53
#define TRY(val)
If the supplied argument is an error (unexpected) type, then propegate it up the call stack....
Definition error_types.hpp:46
#define TRYE(val, e)
Definition error_types.hpp:42
Definition asm_buffer.hpp:19
Definition debug.hpp:9
Definition program_options.hpp:31
std::filesystem::path database_path
Definition program_options.hpp:63
VerbosityLevel
See Description of Levels for an explaination of each of the levels. Max is just used as a sentinal f...
Definition program_options.hpp:37
std::string file_matcher
Definition program_options.hpp:62
static Expected< void, std::string > ensure_is_directory(const std::filesystem::path &path, fmt::format_string< std::string > fmt)
Definition program_options.hpp:93
StopOpt
Never = stop only on fatal errors FirstError = stop completely on the first error encountered EachTes...
Definition program_options.hpp:51
static constexpr auto DEFAULT_VERBOSITY_LEVEL
Definition program_options.hpp:71
std::string assignment_name
Definition program_options.hpp:46
enum asmgrader::ProgramOptions::VerbosityLevel verbosity
Expected< void, std::string > validate()
Verify that all fields are valid.
Definition program_options.hpp:105
enum asmgrader::ProgramOptions::ColorizeOpt colorize_option
static Expected< void, std::string > ensure_is_regular_file(const std::filesystem::path &path, fmt::format_string< std::string > fmt)
Definition program_options.hpp:82
std::optional< std::string > file_name
Definition program_options.hpp:59
static Expected< void, std::string > ensure_file_exists(const std::filesystem::path &path, fmt::format_string< std::string > fmt)
Definition program_options.hpp:73
ColorizeOpt
Definition program_options.hpp:53
std::filesystem::path search_path
Definition program_options.hpp:64
static constexpr std::string_view DEFAULT_SEARCH_PATH
Definition program_options.hpp:69
static constexpr std::string_view DEFAULT_FILE_MATCHER
Definition program_options.hpp:70
static constexpr std::string_view DEFAULT_DATABASE_PATH
Definition program_options.hpp:68
enum asmgrader::ProgramOptions::StopOpt stop_option
auto format(const ::asmgrader::ProgramOptions &from, fmt::format_context &ctx) const
Definition program_options.hpp:151