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