-
Notifications
You must be signed in to change notification settings - Fork 114
Expand file tree
/
Copy pathcli_options.rs
More file actions
237 lines (208 loc) · 7.14 KB
/
cli_options.rs
File metadata and controls
237 lines (208 loc) · 7.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
use crate::LoggingLevel;
use crate::logging::LoggingKind;
use bpaf::Bpaf;
use pglt_configuration::ConfigurationPathHint;
use pglt_diagnostics::Severity;
use std::fmt::{Display, Formatter};
use std::path::PathBuf;
use std::str::FromStr;
/// Global options applied to all commands
#[derive(Debug, Clone, Bpaf)]
pub struct CliOptions {
/// Set the formatting mode for markup: "off" prints everything as plain text, "force" forces the formatting of markup using ANSI even if the console output is determined to be incompatible
#[bpaf(long("colors"), argument("off|force"))]
pub colors: Option<ColorsArg>,
/// Connect to a running instance of the daemon server.
#[bpaf(long("use-server"), switch, fallback(false))]
pub use_server: bool,
/// Skip connecting to the database and only run checks that don't require a database connection.
#[bpaf(long("skip-db"), switch, fallback(false))]
pub skip_db: bool,
/// Print additional diagnostics, and some diagnostics show more information. Also, print out what files were processed and which ones were modified.
#[bpaf(long("verbose"), switch, fallback(false))]
pub verbose: bool,
/// Set the file path to the configuration file, or the directory path to find `pglt.jsonc`.
/// If used, it disables the default configuration file resolution.
#[bpaf(long("config-path"), argument("PATH"), optional)]
pub config_path: Option<String>,
/// Cap the amount of diagnostics displayed. When `none` is provided, the limit is lifted.
#[bpaf(
long("max-diagnostics"),
argument("none|<NUMBER>"),
fallback(MaxDiagnostics::default()),
display_fallback
)]
pub max_diagnostics: MaxDiagnostics,
/// Skip over files containing syntax errors instead of emitting an error diagnostic.
#[bpaf(long("skip-errors"), switch)]
pub skip_errors: bool,
/// Silence errors that would be emitted in case no files were processed during the execution of the command.
#[bpaf(long("no-errors-on-unmatched"), switch)]
pub no_errors_on_unmatched: bool,
/// Tell PgLT to exit with an error code if some diagnostics emit warnings.
#[bpaf(long("error-on-warnings"), switch)]
pub error_on_warnings: bool,
/// Allows to change how diagnostics and summary are reported.
#[bpaf(
long("reporter"),
argument("json|json-pretty|github|junit|summary|gitlab"),
fallback(CliReporter::default())
)]
pub reporter: CliReporter,
#[bpaf(
long("log-level"),
argument("none|debug|info|warn|error"),
fallback(LoggingLevel::default()),
display_fallback
)]
/// The level of logging. In order, from the most verbose to the least verbose: debug, info, warn, error.
///
/// The value `none` won't show any logging.
pub log_level: LoggingLevel,
/// How the log should look like.
#[bpaf(
long("log-kind"),
argument("pretty|compact|json"),
fallback(LoggingKind::default()),
display_fallback
)]
pub log_kind: LoggingKind,
#[bpaf(
long("diagnostic-level"),
argument("info|warn|error"),
fallback(Severity::default()),
display_fallback
)]
/// The level of diagnostics to show. In order, from the lowest to the most important: info, warn, error. Passing `--diagnostic-level=error` will cause PgLT to print only diagnostics that contain only errors.
pub diagnostic_level: Severity,
}
impl CliOptions {
/// Computes the [ConfigurationPathHint] based on the options passed by the user
pub(crate) fn as_configuration_path_hint(&self) -> ConfigurationPathHint {
match self.config_path.as_ref() {
None => ConfigurationPathHint::default(),
Some(path) => ConfigurationPathHint::FromUser(PathBuf::from(path)),
}
}
}
#[derive(Debug, Clone)]
pub enum ColorsArg {
Off,
Force,
}
impl FromStr for ColorsArg {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"off" => Ok(Self::Off),
"force" => Ok(Self::Force),
_ => Err(format!(
"value {s:?} is not valid for the --colors argument"
)),
}
}
}
#[derive(Debug, Default, Clone)]
pub enum CliReporter {
/// The default reporter
#[default]
Default,
/// Diagnostics are printed for GitHub workflow commands
GitHub,
/// Diagnostics and summary are printed in JUnit format
Junit,
/// Reports linter diagnostics using the [GitLab Code Quality report](https://docs.gitlab.com/ee/ci/testing/code_quality.html#implement-a-custom-tool).
GitLab,
}
impl CliReporter {
pub(crate) const fn is_default(&self) -> bool {
matches!(self, Self::Default)
}
}
impl FromStr for CliReporter {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"github" => Ok(Self::GitHub),
"junit" => Ok(Self::Junit),
"gitlab" => Ok(Self::GitLab),
_ => Err(format!(
"value {s:?} is not valid for the --reporter argument"
)),
}
}
}
impl Display for CliReporter {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
CliReporter::Default => f.write_str("default"),
CliReporter::GitHub => f.write_str("github"),
CliReporter::Junit => f.write_str("junit"),
CliReporter::GitLab => f.write_str("gitlab"),
}
}
}
#[derive(Debug, Clone, Copy, Bpaf)]
pub enum MaxDiagnostics {
None,
Limit(u32),
}
impl MaxDiagnostics {
pub fn ok(&self) -> Option<u32> {
match self {
MaxDiagnostics::None => None,
MaxDiagnostics::Limit(value) => Some(*value),
}
}
}
impl Default for MaxDiagnostics {
fn default() -> Self {
Self::Limit(20)
}
}
impl Display for MaxDiagnostics {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
MaxDiagnostics::None => {
write!(f, "none")
}
MaxDiagnostics::Limit(value) => {
write!(f, "{value}")
}
}
}
}
impl FromStr for MaxDiagnostics {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"none" => Ok(MaxDiagnostics::None),
_ => {
if let Ok(value) = s.parse::<u32>() {
Ok(MaxDiagnostics::Limit(value))
} else {
Err(format!(
"Invalid value provided. Provide 'none' to lift the limit, or a number between 0 and {}.",
u32::MAX
))
}
}
}
}
}
impl From<MaxDiagnostics> for u64 {
fn from(value: MaxDiagnostics) -> Self {
match value {
MaxDiagnostics::None => u64::MAX,
MaxDiagnostics::Limit(value) => value as u64,
}
}
}
impl From<MaxDiagnostics> for u32 {
fn from(value: MaxDiagnostics) -> Self {
match value {
MaxDiagnostics::None => u32::MAX,
MaxDiagnostics::Limit(value) => value,
}
}
}