Skip to content

Commit 0fbd22d

Browse files
committed
implement positional arg files
begin pre-commit support
1 parent c7ae257 commit 0fbd22d

File tree

7 files changed

+79
-45
lines changed

7 files changed

+79
-45
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@
2525
*.code-workspace text eol=lf
2626
*.clang-tidy text eol=lf
2727
*.clang-format text eol=lf
28+
justfile text eol=lf

cpp-linter-lib/src/cli.rs

+47-36
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@ pub fn get_arg_parser() -> Command {
2828
.short('v')
2929
.default_value("info")
3030
.value_parser(["debug", "info"])
31-
.long_help(
31+
.help(
3232
"This controls the action's verbosity in the workflow's logs.
3333
This option does not affect the verbosity of resulting
34-
thread comments or file annotations.",
34+
thread comments or file annotations.\n\n",
3535
),
3636
)
3737
.arg(
3838
Arg::new("database")
3939
.long("database")
4040
.short('p')
4141
.help_heading("clang-tidy options")
42-
.long_help(
42+
.help(
4343
"The path that is used to read a compile command database.
4444
For example, it can be a CMake build directory in which a file named
4545
compile_commands.json exists (set `CMAKE_EXPORT_COMPILE_COMMANDS` to `ON`).
@@ -54,13 +54,13 @@ for an example of setting up Clang Tooling on a source tree.",
5454
.long("style")
5555
.default_value("llvm")
5656
.help_heading("clang-format options")
57-
.long_help(
57+
.help(
5858
"The style rules to use.
5959
6060
- Set this to `file` to have clang-format use the closest relative
6161
.clang-format file.
6262
- Set this to a blank string (`''`) to disable using clang-format
63-
entirely.",
63+
entirely.\n\n",
6464
),
6565
)
6666
.arg(
@@ -71,7 +71,7 @@ for an example of setting up Clang Tooling on a source tree.",
7171
"boost-*,bugprone-*,performance-*,readability-*,portability-*,modernize-*,clang-analyzer-*,cppcoreguidelines-*",
7272
)
7373
.help_heading("clang-tidy options")
74-
.long_help(
74+
.help(
7575
"A comma-separated list of globs with optional `-` prefix.
7676
Globs are processed in order of appearance in the list.
7777
Globs without `-` prefix add checks with matching names to the set,
@@ -84,7 +84,7 @@ option in a .clang-tidy file (if any).
8484
- It is also possible to rely solely on a .clang-tidy config file by
8585
specifying this option as a blank string (`''`).
8686
87-
See also clang-tidy docs for more info.",
87+
See also clang-tidy docs for more info.\n\n",
8888
),
8989
)
9090
.arg(
@@ -95,15 +95,15 @@ See also clang-tidy docs for more info.",
9595
.num_args(0..=1)
9696
.require_equals(true)
9797
.default_value("")
98-
.long_help(
98+
.help(
9999
"The desired version of the clang tools to use. Accepted options are
100100
strings which can be 8, 9, 10, 11, 12, 13, 14, 15, 16, 17.
101101
102102
- Set this option to a blank string (`''`) to use the
103103
platform's default installed version.
104104
- This value can also be a path to where the clang tools are
105105
installed (if using a custom install location). All paths specified
106-
here are converted to absolute.",
106+
here are converted to absolute.\n\n",
107107
),
108108
)
109109
.arg(
@@ -112,19 +112,19 @@ strings which can be 8, 9, 10, 11, 12, 13, 14, 15, 16, 17.
112112
.long("extensions")
113113
.value_delimiter(',')
114114
.default_value("c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx")
115-
.help_heading("source options")
116-
.long_help("A comma-separated list of file extensions to analyze."),
115+
.help_heading("Source options")
116+
.help("A comma-separated list of file extensions to analyze.\n"),
117117
)
118118
.arg(
119119
Arg::new("repo-root")
120120
.short('r')
121121
.long("repo-root")
122122
.default_value(".")
123-
.help_heading("source options")
124-
.long_help(
123+
.help_heading("Source options")
124+
.help(
125125
"The relative path to the repository root directory. This path is
126126
relative to the runner's `GITHUB_WORKSPACE` environment variable (or
127-
the current working directory if not using a CI runner).",
127+
the current working directory if not using a CI runner).\n\n",
128128
),
129129
)
130130
.arg(
@@ -133,8 +133,8 @@ the current working directory if not using a CI runner).",
133133
.long("ignore")
134134
.value_delimiter('|')
135135
.default_value(".github|target")
136-
.help_heading("source options")
137-
.long_help(
136+
.help_heading("Source options")
137+
.help(
138138
"Set this option with path(s) to ignore (or not ignore).
139139
140140
- In the case of multiple paths, you can use `|` to separate each path.
@@ -147,7 +147,7 @@ the current working directory if not using a CI runner).",
147147
- Prefix a path with `!` to explicitly not ignore it. This can be
148148
applied to a submodule's path (if desired) but not hidden directories.
149149
- Glob patterns are not supported here. All asterisk characters (`*`)
150-
are literal.",
150+
are literal.\n\n",
151151
),
152152
)
153153
.arg(
@@ -157,9 +157,9 @@ the current working directory if not using a CI runner).",
157157
.value_delimiter('|')
158158
.default_value("")
159159
.help_heading("clang-tidy options")
160-
.long_help(
160+
.help(
161161
"Similar to [`--ignore`](#-i---ignore) but applied
162-
exclusively to files analyzed by clang-tidy.",
162+
exclusively to files analyzed by clang-tidy.\n\n",
163163
),
164164
)
165165
.arg(
@@ -169,9 +169,9 @@ exclusively to files analyzed by clang-tidy.",
169169
.value_delimiter('|')
170170
.default_value("")
171171
.help_heading("clang-format options")
172-
.long_help(
172+
.help(
173173
"Similar to [`--ignore`](#-i---ignore) but applied
174-
exclusively to files analyzed by clang-format.",
174+
exclusively to files analyzed by clang-format.\n\n",
175175
),
176176
)
177177
.arg(
@@ -180,15 +180,15 @@ exclusively to files analyzed by clang-format.",
180180
.long("lines-changed-only")
181181
.value_parser(["true", "false", "diff"])
182182
.default_value("true")
183-
.help_heading("source options")
184-
.long_help(
183+
.help_heading("Source options")
184+
.help(
185185
"This controls what part of the files are analyzed.
186186
The following values are accepted:
187187
188188
- `false`: All lines in a file are analyzed.
189189
- `true`: Only lines in the diff that contain additions are analyzed.
190190
- `diff`: All lines in the diff are analyzed (including unchanged
191-
lines but not subtractions).",
191+
lines but not subtractions).\n\n",
192192
),
193193
)
194194
.arg(
@@ -198,8 +198,8 @@ The following values are accepted:
198198
.default_value_if("lines-changed-only", ArgPredicate::Equals("true".into()), "true")
199199
.default_value("false")
200200
.value_parser(FalseyValueParser::new())
201-
.help_heading("source options")
202-
.long_help(
201+
.help_heading("Source options")
202+
.help(
203203
"Set this option to false to analyze any source files in the repo.
204204
This is automatically enabled if
205205
[`--lines-changed-only`](#-l---lines-changed-only) is enabled.
@@ -210,7 +210,7 @@ This is automatically enabled if
210210
> does not not have the privilege to list the changed files for an event.
211211
>
212212
> See [Authenticating with the `GITHUB_TOKEN`](
213-
> https://docs.github.com/en/actions/reference/authentication-in-a-workflow).",
213+
> https://docs.github.com/en/actions/reference/authentication-in-a-workflow).\n\n",
214214
),
215215
)
216216
.arg(
@@ -219,7 +219,7 @@ This is automatically enabled if
219219
.short('x')
220220
.action(ArgAction::Append)
221221
.help_heading("clang-tidy options")
222-
.long_help(
222+
.help(
223223
"A string of extra arguments passed to clang-tidy for use as
224224
compiler arguments. This can be specified more than once for each
225225
additional argument. Recommend using quotes around the value and
@@ -237,7 +237,7 @@ cpp-linter --extra-arg=\"-std=c++17\" --extra-arg=\"-Wall\"
237237
.value_parser(["true", "false", "updated"])
238238
.default_value("false")
239239
.help_heading("feedback options")
240-
.long_help(
240+
.help(
241241
"Set this option to true to enable the use of thread comments as feedback.
242242
Set this to `update` to update an existing comment if one exists;
243243
the value 'true' will always delete an old comment and post a new one if necessary.
@@ -248,7 +248,7 @@ the value 'true' will always delete an old comment and post a new one if necessa
248248
> variable.
249249
>
250250
> See [Authenticating with the `GITHUB_TOKEN`](
251-
> https://docs.github.com/en/actions/reference/authentication-in-a-workflow).",
251+
> https://docs.github.com/en/actions/reference/authentication-in-a-workflow).\n\n",
252252
),
253253
)
254254
.arg(
@@ -258,13 +258,13 @@ the value 'true' will always delete an old comment and post a new one if necessa
258258
.value_parser(FalseyValueParser::new())
259259
.default_value("true")
260260
.help_heading("feedback options")
261-
.long_help(
261+
.help(
262262
"Set this option to true or false to enable or disable the use of a
263263
thread comment that basically says 'Looks Good To Me' (when all checks pass).
264264
265265
> [!important]
266266
> The [`--thread-comments`](#-g---thread-comments)
267-
> option also notes further implications.",
267+
> option also notes further implications.\n\n",
268268
),
269269
)
270270
.arg(
@@ -274,9 +274,9 @@ thread comment that basically says 'Looks Good To Me' (when all checks pass).
274274
.value_parser(FalseyValueParser::new())
275275
.default_value("false")
276276
.help_heading("feedback options")
277-
.long_help(
277+
.help(
278278
"Set this option to true or false to enable or disable the use of
279-
a workflow step summary when the run has concluded.",
279+
a workflow step summary when the run has concluded.\n\n",
280280
),
281281
)
282282
.arg(
@@ -286,11 +286,21 @@ a workflow step summary when the run has concluded.",
286286
.value_parser(FalseyValueParser::new())
287287
.default_value("true")
288288
.help_heading("feedback options")
289-
.long_help(
289+
.help(
290290
"Set this option to false to disable the use of
291-
file annotations as feedback.",
291+
file annotations as feedback.\n\n",
292292
),
293293
)
294+
.arg(
295+
Arg::new("files")
296+
.action(ArgAction::Append)
297+
.help(
298+
"An explicit path to a file.
299+
This can be specified zero or more times, resulting in a list of files.
300+
The list of files is appended to the internal list of 'not ignored' files.
301+
Further filtering can still be applied (see [Source options](#source-options)).",
302+
)
303+
)
294304
.groups([
295305
ArgGroup::new("Clang-tidy options")
296306
.args(["tidy-checks", "database", "extra-arg", "ignore-tidy"]),
@@ -301,6 +311,7 @@ file annotations as feedback.",
301311
"thread-comments", "no-lgtm", "step-summary", "file-annotations"
302312
]),
303313
])
314+
.next_line_help(true)
304315
}
305316

306317
/// Converts the parsed value of the `--extra-arg` option into an optional vector of strings.

cpp-linter-lib/src/common_fs/file_filter.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use super::FileObj;
44

55
#[derive(Debug, Clone)]
66
pub struct FileFilter {
7-
ignored: Vec<String>,
8-
not_ignored: Vec<String>,
9-
extensions: Vec<String>,
7+
pub ignored: Vec<String>,
8+
pub not_ignored: Vec<String>,
9+
pub extensions: Vec<String>,
1010
}
1111
impl FileFilter {
1212
pub fn new(ignore: &[&str], extensions: Vec<String>) -> Self {

cpp-linter-lib/src/rest_api/github_api.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,11 @@ impl RestApiClient for GithubApiClient {
191191
}
192192
}
193193

194-
async fn post_feedback(&self, files: &[Arc<Mutex<FileObj>>], user_inputs: FeedbackInput) {
194+
async fn post_feedback(
195+
&self,
196+
files: &[Arc<Mutex<FileObj>>],
197+
user_inputs: FeedbackInput,
198+
) -> u64 {
195199
let format_checks_failed = tally_format_advice(files);
196200
let tidy_checks_failed = tally_tidy_advice(files);
197201
let mut comment = None;
@@ -268,6 +272,7 @@ impl RestApiClient for GithubApiClient {
268272
}
269273
}
270274
}
275+
format_checks_failed + tidy_checks_failed
271276
}
272277
}
273278

cpp-linter-lib/src/rest_api/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pub trait RestApiClient {
124124
&self,
125125
files: &[Arc<Mutex<FileObj>>],
126126
user_inputs: FeedbackInput,
127-
) -> impl Future<Output = ()>;
127+
) -> impl Future<Output = u64>;
128128
}
129129

130130
fn make_format_comment(

cpp-linter-lib/src/run.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ pub async fn run_main(args: Vec<String>) -> i32 {
100100
.collect::<Vec<_>>();
101101
let mut file_filter = FileFilter::new(&ignore, extensions.clone());
102102
file_filter.parse_submodules();
103+
if let Some(files) = args.get_many::<Vec<String>>("files") {
104+
for list in files {
105+
file_filter
106+
.not_ignored
107+
.extend(list.iter().map(|v| v.to_string()).collect::<Vec<String>>());
108+
}
109+
}
103110

104111
let lines_changed_only = match args
105112
.get_one::<String>("lines-changed-only")
@@ -166,8 +173,11 @@ pub async fn run_main(args: Vec<String>) -> i32 {
166173
};
167174
capture_clang_tools_output(&mut arc_files, version, &mut clang_params).await;
168175
start_log_group(String::from("Posting feedback"));
169-
rest_api_client.post_feedback(&arc_files, user_inputs).await;
176+
let checks_failed = rest_api_client.post_feedback(&arc_files, user_inputs).await;
170177
end_log_group();
178+
if env::var("PRE_COMMIT").is_ok_and(|v| v == "1") {
179+
return (checks_failed > 1) as i32;
180+
}
171181
0
172182
}
173183

docs/src/main.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ mod cli_gen_lib {
9999
format!("{}\n", &cmd.get_about().unwrap().to_string().trim()).as_str(),
100100
);
101101
}
102+
out.push_str("## Arguments\n");
103+
for arg in command.get_positionals() {
104+
out.push_str(format!("\n### `{}`\n\n", arg.get_id().as_str()).as_str());
105+
if let Some(help) = arg.get_help() {
106+
out.push_str(format!("{}\n", help.to_string().trim()).as_str());
107+
}
108+
}
102109
let arg_groups = if let Some(groups) = groups_order {
103110
eprintln!("ordering groups into {:?}", groups);
104111
let mut ordered = Vec::with_capacity(command.get_groups().count());
@@ -146,9 +153,9 @@ mod cli_gen_lib {
146153
.as_str(),
147154
);
148155
}
149-
out.push_str(
150-
format!("{}\n", &arg.get_long_help().unwrap().to_string().trim()).as_str(),
151-
);
156+
if let Some(help) = &arg.get_help() {
157+
out.push_str(format!("{}\n", help.to_string().trim()).as_str());
158+
}
152159
}
153160
}
154161
out

0 commit comments

Comments
 (0)