Skip to content

Commit 906bc6f

Browse files
committed
all filtering files per tool
1 parent 0bdead8 commit 906bc6f

File tree

10 files changed

+537
-505
lines changed

10 files changed

+537
-505
lines changed

cpp-linter-lib/examples/diff.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use cpp_linter_lib::{
2-
cli::parse_ignore,
2+
common_fs::FileFilter,
33
git::{get_diff, open_repo, parse_diff},
44
};
55
use std::error::Error;
@@ -12,9 +12,9 @@ pub fn main() -> Result<(), Box<dyn Error>> {
1212
let repo = open_repo(".")?;
1313
let diff = get_diff(&repo);
1414

15-
let extensions = vec!["cpp", "hpp", "rs"];
16-
let (ignored, not_ignored) = parse_ignore(&Vec::from_iter(["target", ".github"]));
17-
let files = parse_diff(&diff, &extensions, &ignored, &not_ignored);
15+
let extensions = vec!["cpp".to_string(), "hpp".to_string(), "rs".to_string()];
16+
let file_filter = FileFilter::new(&["target", ".github"], extensions);
17+
let files = parse_diff(&diff, &file_filter);
1818

1919
for file in &files {
2020
println!("{}", file.name.to_string_lossy());

cpp-linter-lib/examples/gh_rest_api.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::env;
22
use std::error::Error;
33

4-
use cpp_linter_lib::cli::parse_ignore;
4+
use cpp_linter_lib::common_fs::FileFilter;
55
use cpp_linter_lib::github_api::GithubApiClient;
66

77
// needed to use trait implementations (ie `get_list_of_changed_files()`)
@@ -13,12 +13,14 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
1313
env::set_var("GITHUB_REPOSITORY", "cpp-linter/cpp-linter");
1414
let client_controller = GithubApiClient::new();
1515

16-
let extensions = vec!["cpp", "hpp"];
17-
let (ignored, not_ignored) = parse_ignore(&Vec::from_iter(["target", ".github"]));
16+
let file_filter = FileFilter::new(
17+
&["target", ".github"],
18+
vec!["cpp".to_string(), "hpp".to_string()],
19+
);
1820

1921
env::set_var("CI", "true"); // needed for get_list_of_changed_files() to use REST API
2022
let files = client_controller
21-
.get_list_of_changed_files(&extensions, &ignored, &not_ignored)
23+
.get_list_of_changed_files(&file_filter)
2224
.await;
2325

2426
for file in &files {

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

+88-75
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use which::{which, which_in};
1919
use super::common_fs::FileObj;
2020
use crate::{
2121
cli::LinesChangedOnly,
22+
common_fs::FileFilter,
2223
logger::{end_log_group, start_log_group},
2324
};
2425
pub mod clang_format;
@@ -77,15 +78,17 @@ pub fn get_clang_tool_exe(name: &str, version: &str) -> Result<PathBuf, &'static
7778
}
7879

7980
#[derive(Debug, Clone)]
80-
struct ClangParams {
81-
tidy_checks: String,
82-
lines_changed_only: LinesChangedOnly,
83-
database: Option<PathBuf>,
84-
extra_args: Option<Vec<String>>,
85-
database_json: Option<CompilationDatabase>,
86-
style: String,
87-
clang_tidy_command: Option<PathBuf>,
88-
clang_format_command: Option<PathBuf>,
81+
pub struct ClangParams {
82+
pub tidy_checks: String,
83+
pub lines_changed_only: LinesChangedOnly,
84+
pub database: Option<PathBuf>,
85+
pub extra_args: Option<Vec<String>>,
86+
pub database_json: Option<CompilationDatabase>,
87+
pub style: String,
88+
pub clang_tidy_command: Option<PathBuf>,
89+
pub clang_format_command: Option<PathBuf>,
90+
pub tidy_filter: FileFilter,
91+
pub format_filter: FileFilter,
8992
}
9093

9194
/// This creates a task to run clang-tidy and clang-format on a single file.
@@ -100,104 +103,114 @@ fn analyze_single_file(
100103
file: &mut Arc<Mutex<FileObj>>,
101104
clang_params: Arc<ClangParams>,
102105
) -> (PathBuf, Vec<(log::Level, String)>) {
106+
let file_lock = file.lock().unwrap();
107+
let file_name = file_lock.name.clone();
108+
drop(file_lock);
103109
let mut logs = vec![];
104110
if let Some(tidy_cmd) = &clang_params.clang_tidy_command {
105-
let tidy_result = run_clang_tidy(
106-
&mut Command::new(tidy_cmd),
107-
file,
108-
clang_params.tidy_checks.as_str(),
109-
&clang_params.lines_changed_only,
110-
&clang_params.database,
111-
&clang_params.extra_args,
112-
&clang_params.database_json,
113-
);
114-
logs.extend(tidy_result);
111+
if clang_params
112+
.tidy_filter
113+
.is_source_or_ignored(file_name.as_path())
114+
{
115+
let tidy_result = run_clang_tidy(
116+
&mut Command::new(tidy_cmd),
117+
file,
118+
clang_params.tidy_checks.as_str(),
119+
&clang_params.lines_changed_only,
120+
&clang_params.database,
121+
&clang_params.extra_args,
122+
&clang_params.database_json,
123+
);
124+
logs.extend(tidy_result);
125+
} else {
126+
logs.push((
127+
log::Level::Info,
128+
format!(
129+
"{} not scanned due to `--ignore-tidy`",
130+
file_name.as_os_str().to_string_lossy()
131+
),
132+
))
133+
}
115134
}
116135
if let Some(format_cmd) = &clang_params.clang_format_command {
117-
let format_result = run_clang_format(
118-
&mut Command::new(format_cmd),
119-
file,
120-
clang_params.style.as_str(),
121-
&clang_params.lines_changed_only,
122-
);
123-
logs.extend(format_result);
136+
if clang_params
137+
.format_filter
138+
.is_source_or_ignored(file_name.as_path())
139+
{
140+
let format_result = run_clang_format(
141+
&mut Command::new(format_cmd),
142+
file,
143+
clang_params.style.as_str(),
144+
&clang_params.lines_changed_only,
145+
);
146+
logs.extend(format_result);
147+
} else {
148+
logs.push((
149+
log::Level::Info,
150+
format!(
151+
"{} not scanned by clang-format due to `--ignore-format`",
152+
file_name.as_os_str().to_string_lossy()
153+
),
154+
));
155+
}
124156
}
125-
let file = file.lock().unwrap();
126-
(file.name.clone(), logs)
157+
(file_name, logs)
127158
}
128159

129160
/// Runs clang-tidy and/or clang-format and returns the parsed output from each.
130161
///
131-
/// The returned list of [`FormatAdvice`] is parallel to the `files` list passed in
132-
/// here. The returned 2D list of [`TidyAdvice`] is also parallel on the first
133-
/// dimension. The second dimension is a list of notes specific to a translation unit
134-
/// (each element of `files`).
135-
///
136162
/// If `tidy_checks` is `"-*"` then clang-tidy is not executed.
137163
/// If `style` is a blank string (`""`), then clang-format is not executed.
138164
pub async fn capture_clang_tools_output(
139165
files: &mut Vec<Arc<Mutex<FileObj>>>,
140166
version: &str,
141-
tidy_checks: &str,
142-
style: &str,
143-
lines_changed_only: &LinesChangedOnly,
144-
database: Option<PathBuf>,
145-
extra_args: Option<Vec<String>>,
167+
clang_params: &mut ClangParams,
146168
) {
147169
// find the executable paths for clang-tidy and/or clang-format and show version
148170
// info as debugging output.
149-
let clang_tidy_command = if tidy_checks != "-*" {
150-
let cmd = get_clang_tool_exe("clang-tidy", version).unwrap();
151-
log::debug!(
152-
"{} --version\n{}",
153-
&cmd.to_string_lossy(),
154-
String::from_utf8_lossy(&Command::new(&cmd).arg("--version").output().unwrap().stdout)
155-
);
156-
Some(cmd)
157-
} else {
158-
None
171+
if clang_params.tidy_checks != "-*" {
172+
clang_params.clang_tidy_command = {
173+
let cmd = get_clang_tool_exe("clang-tidy", version).unwrap();
174+
log::debug!(
175+
"{} --version\n{}",
176+
&cmd.to_string_lossy(),
177+
String::from_utf8_lossy(
178+
&Command::new(&cmd).arg("--version").output().unwrap().stdout
179+
)
180+
);
181+
Some(cmd)
182+
}
159183
};
160-
let clang_format_command = if !style.is_empty() {
161-
let cmd = get_clang_tool_exe("clang-format", version).unwrap();
162-
log::debug!(
163-
"{} --version\n{}",
164-
&cmd.to_string_lossy(),
165-
String::from_utf8_lossy(&Command::new(&cmd).arg("--version").output().unwrap().stdout)
166-
);
167-
Some(cmd)
168-
} else {
169-
None
184+
if !clang_params.style.is_empty() {
185+
clang_params.clang_format_command = {
186+
let cmd = get_clang_tool_exe("clang-format", version).unwrap();
187+
log::debug!(
188+
"{} --version\n{}",
189+
&cmd.to_string_lossy(),
190+
String::from_utf8_lossy(
191+
&Command::new(&cmd).arg("--version").output().unwrap().stdout
192+
)
193+
);
194+
Some(cmd)
195+
}
170196
};
171197

172198
// parse database (if provided) to match filenames when parsing clang-tidy's stdout
173-
let database_json: Option<CompilationDatabase> = if let Some(db_path) = &database {
199+
if let Some(db_path) = &clang_params.database {
174200
if let Ok(db_str) = fs::read(db_path) {
175-
Some(
201+
clang_params.database_json = Some(
176202
serde_json::from_str::<CompilationDatabase>(
177203
String::from_utf8(db_str).unwrap().as_str(),
178204
)
179205
.unwrap(),
180206
)
181-
} else {
182-
None
183207
}
184-
} else {
185-
None
186208
};
209+
187210
let mut executors = JoinSet::new();
188211
// iterate over the discovered files and run the clang tools
189212
for file in files {
190-
let clang_params = ClangParams {
191-
tidy_checks: tidy_checks.to_string(),
192-
lines_changed_only: lines_changed_only.clone(),
193-
database: database.clone(),
194-
extra_args: extra_args.clone(),
195-
database_json: database_json.clone(),
196-
style: style.to_string(),
197-
clang_tidy_command: clang_tidy_command.clone(),
198-
clang_format_command: clang_format_command.clone(),
199-
};
200-
let arc_params = Arc::new(clang_params);
213+
let arc_params = Arc::new(clang_params.clone());
201214
let mut arc_file = Arc::clone(file);
202215
executors.spawn(async move { analyze_single_file(&mut arc_file, arc_params) });
203216
}

0 commit comments

Comments
 (0)