From da495b87e3ffc97d68b2e9a24ada3e9131919c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Tue, 27 Aug 2024 21:42:00 +0000 Subject: [PATCH 01/47] ok --- .config/toolbox.toml | 4 + src/config.rs | 10 ++ src/rules/never_edit.rs | 247 +++++++++++++++++++++++++++++++++++++++ tests/never_edit_test.rs | 140 ++++++++++++++++++++++ 4 files changed, 401 insertions(+) create mode 100644 src/rules/never_edit.rs create mode 100644 tests/never_edit_test.rs diff --git a/.config/toolbox.toml b/.config/toolbox.toml index a330627..94c12de 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -8,3 +8,7 @@ enabled = true [todo] enabled = true + +[neveredit] +enabled = true +paths = ["write-once.txt"] diff --git a/src/config.rs b/src/config.rs index 4969053..88ec448 100644 --- a/src/config.rs +++ b/src/config.rs @@ -12,6 +12,9 @@ pub struct Conf { #[config(nested)] pub todo: TodoConf, + + #[config(nested)] + pub neveredit: NeverEditConf, } impl Conf { @@ -38,3 +41,10 @@ pub struct TodoConf { #[config(default = false)] pub enabled: bool, } + +#[derive(Config)] +pub struct NeverEditConf { + #[config(default = false)] + pub enabled: bool, + pub paths: Vec, +} diff --git a/src/rules/never_edit.rs b/src/rules/never_edit.rs new file mode 100644 index 0000000..2f5dca7 --- /dev/null +++ b/src/rules/never_edit.rs @@ -0,0 +1,247 @@ +use crate::run::Run; +use anyhow::Context; +use log::debug; +use std::collections::{HashMap, HashSet}; +use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::path::Path; +use std::path::PathBuf; + +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; +use regex::Regex; + +use crate::diagnostic; +use crate::git; + +#[derive(Debug)] +pub enum ThenChange { + RemoteFile(String), + RepoFile(PathBuf), + MissingIf, + MissingThen, +} + +#[derive(Debug)] +pub struct IctcBlock { + pub path: PathBuf, + pub begin: Option, + pub end: Option, + pub thenchange: Option, +} + +impl IctcBlock { + fn get_range(&self) -> diagnostic::Range { + diagnostic::Range { + path: self.path.to_str().unwrap().to_string(), + start: diagnostic::Position { + line: self.begin.unwrap(), + character: 0, + }, + end: diagnostic::Position { + line: self.end.unwrap(), + character: 0, + }, + } + } +} + +lazy_static::lazy_static! { + static ref RE_BEGIN: Regex = Regex::new(r"(?i)^\s*(//|#)\s*ifchange(.*)$").unwrap(); + static ref RE_END: Regex = Regex::new(r"(?i)^\s*(//|#)\s*thenchange(.*)$").unwrap(); +} + +pub fn find_ictc_blocks(path: &PathBuf) -> anyhow::Result> { + let mut blocks: Vec = Vec::new(); + + let in_file = File::open(path).with_context(|| format!("failed to open: {:#?}", path))?; + let in_buf = BufReader::new(in_file); + + let mut block: Option = None; + + for (i, line) in lines_view(in_buf) + .context(format!("failed to read lines of text from: {:#?}", path))? + .iter() + .enumerate() + .map(|(i, line)| (i + 1, line)) + { + let line_no = Some(i as u64); + if RE_BEGIN.find(line).is_some() { + if let Some(mut block_value) = block { + // Two if blocks in a row - report problem + block_value.end = block_value.begin; + block_value.thenchange = Some(ThenChange::MissingThen); + blocks.push(block_value); + } + + block = Some(IctcBlock { + path: path.clone(), + begin: line_no, + end: None, + thenchange: None, + }); + } else if let Some(end_capture) = RE_END.captures(line) { + if let Some(mut block_value) = block { + block_value.end = line_no; + block_value.thenchange = Some(ThenChange::RepoFile(PathBuf::from( + end_capture + .get(2) + .with_context(|| "expected at least 3 captures")? + .as_str() + .trim(), + ))); + blocks.push(block_value); + block = None; + } else { + // block is None and we found a IfChange without a ThenChange + blocks.push(IctcBlock { + path: path.clone(), + begin: line_no, + end: line_no, + thenchange: Some(ThenChange::MissingIf), + }); + } + } + } + + // If we have an unclosed block - record that + if let Some(mut block_value) = block { + block_value.end = block_value.begin; + block_value.thenchange = Some(ThenChange::MissingThen); + blocks.push(block_value); + } + + Ok(blocks) +} + +pub fn ictc(run: &Run, upstream: &str) -> anyhow::Result> { + let config = &run.config.ifchange; + + if !config.enabled { + return Ok(vec![]); + } + + // Build up list of files that actually have a ifchange block - this way we can avoid + // processing git modified chunks if none are present + let all_blocks: Vec<_> = run + .paths + .par_iter() + .filter_map(|file| find_ictc_blocks(file).ok()) + .flatten() + .collect(); + + // Fast exit if we don't have any files that have ICTC blocks - saves us calling + // into git to get more information + if all_blocks.is_empty() { + return Ok(vec![]); + } + + let modified = git::modified_since(upstream, None)?; + let hunks = &modified.hunks; + + log::debug!("Modified stats, per libgit2:\n{:#?}", modified); + + // TODO(sam): this _should_ be a iter-map-collect, but unclear how to apply a reducer + // between the map and collect (there can be multiple hunks with the same path) + let mut modified_lines_by_path: HashMap> = HashMap::new(); + for h in hunks { + modified_lines_by_path + .entry(h.path.clone()) + .or_default() + .extend(h.begin..h.end); + } + let modified_lines_by_path = modified_lines_by_path; + + let mut blocks: Vec = Vec::new(); + + for block in all_blocks { + if let Some(thenchange) = &block.thenchange { + match &thenchange { + ThenChange::MissingIf | ThenChange::MissingThen => { + blocks.push(block); + } + _ => { + if let (Some(begin), Some(end)) = (block.begin, block.end) { + let block_lines = HashSet::from_iter(begin..end); + if !block_lines.is_disjoint( + modified_lines_by_path + .get(&block.path) + .unwrap_or(&HashSet::new()), + ) { + blocks.push(block); + } + } + } + } + } + } + + let blocks_by_path: HashMap<&PathBuf, &IctcBlock> = + blocks.iter().map(|b| (&b.path, b)).collect(); + + let mut diagnostics: Vec = Vec::new(); + + for block in &blocks { + if let Some(change) = &block.thenchange { + match change { + ThenChange::RemoteFile(_remote_file) => { + todo!("build support for remote file") + } + ThenChange::RepoFile(local_file) => { + // Check if the repo file exists - if it was deleted this is a warning + if !Path::new(local_file).exists() { + diagnostics.push(diagnostic::Diagnostic { + range: block.get_range(), + severity: diagnostic::Severity::Warning, + code: "if-change-file-does-not-exist".to_string(), + message: format!("ThenChange {} does not exist", local_file.display(),), + }); + } + // If target file was not changed raise issue + if blocks_by_path.get(&local_file).is_none() { + diagnostics.push(diagnostic::Diagnostic { + range: block.get_range(), + severity: diagnostic::Severity::Error, + code: "if-change-then-change-this".to_string(), + message: format!( + "Expected change in {} because {} was modified", + local_file.display(), + block.path.display(), + ), + }); + } + } + ThenChange::MissingIf => { + diagnostics.push(diagnostic::Diagnostic { + range: block.get_range(), + severity: diagnostic::Severity::Warning, + code: "if-change-mismatched".to_string(), + message: "Expected preceding IfChange tag".to_string(), + }); + } + ThenChange::MissingThen => { + diagnostics.push(diagnostic::Diagnostic { + range: block.get_range(), + severity: diagnostic::Severity::Warning, + code: "if-change-mismatched".to_string(), + message: "Expected matching ThenChange tag".to_string(), + }); + } + } + } + } + + debug!("ICTC blocks are:\n{:?}", blocks); + + Ok(diagnostics) +} + +type LinesView = Vec; + +fn lines_view(reader: R) -> anyhow::Result { + let mut ret: LinesView = LinesView::default(); + for line in reader.lines() { + let line = line?; + ret.push(line); + } + Ok(ret) +} diff --git a/tests/never_edit_test.rs b/tests/never_edit_test.rs new file mode 100644 index 0000000..456fb2c --- /dev/null +++ b/tests/never_edit_test.rs @@ -0,0 +1,140 @@ +use spectral::prelude::*; + +mod integration_testing; +use integration_testing::TestRepo; +use std::path::PathBuf; + +// use horton::rules::if_change_then_change::find_ictc_blocks; +// use horton::rules::if_change_then_change::ThenChange; + +#[test] +fn assert_missing_thenchange() { + let test_repo = TestRepo::make().unwrap(); + + test_repo.write("write_once.txt", "immutable text".as_bytes()); + test_repo.git_commit_all("create write once file"); + + { + test_repo.write("revision.foo", single_tag.as_bytes()); + let horton = test_repo.run_horton().unwrap(); + assert_that(&horton.exit_code).contains_value(0); + assert_that(&horton.stdout).contains("Expected matching ThenChange tag"); + } + + { + test_repo.write("revision.foo", multi_tag.as_bytes()); + let horton = test_repo.run_horton().unwrap(); + assert_that(&horton.exit_code).contains_value(0); + assert_that(&horton.stdout).contains("Expected matching ThenChange tag"); + } +} + +#[test] +fn assert_missing_ifchange() { + let single_tag = r#" + aaaa + bbb + cc + // ThenChange + d + "#; + + let multi_tag = r#" + aaaa + bbb + cc + // IfChange + c + // ThenChange constants.foo + d + // ThenChange constants.foo + "#; + + let test_repo = TestRepo::make().unwrap(); + + test_repo.write("constant.foo", "foo-bar".as_bytes()); + test_repo.write("revision.foo", "".as_bytes()); + test_repo.git_commit_all("create constant.foo and revision.foo"); + + { + test_repo.write("revision.foo", single_tag.as_bytes()); + let horton = test_repo.run_horton().unwrap(); + assert_that(&horton.exit_code).contains_value(0); + assert_that(&horton.stdout).contains("Expected preceding IfChange tag"); + } + + { + test_repo.write("revision.foo", multi_tag.as_bytes()); + let horton = test_repo.run_horton().unwrap(); + assert_that(&horton.exit_code).contains_value(0); + assert_that(&horton.stdout).contains("Expected preceding IfChange tag"); + } +} + +#[test] +fn assert_localfile_notfound() { + let missing_file = r#" + aaaa + bbb + // IfChange + cc + // ThenChange zee.foo + d + "#; + + let test_repo = TestRepo::make().unwrap(); + + test_repo.write("revision.foo", "".as_bytes()); + test_repo.git_commit_all("create constant.foo and revision.foo"); + + { + test_repo.write("revision.foo", missing_file.as_bytes()); + let horton = test_repo.run_horton().unwrap(); + assert_that(&horton.exit_code).contains_value(0); + assert_that(&horton.stdout).contains("ThenChange zee.foo does not exist"); + } +} + +#[test] +fn verify_find_ictc_blocks() { + let result = find_ictc_blocks(&PathBuf::from( + "tests/if_change_then_change/basic_ictc.file", + )); + assert!(result.is_ok()); + assert!(result.unwrap().len() == 1, "should find 1 ictc block"); + + let result = find_ictc_blocks(&PathBuf::from("tests/if_change_then_change/no_ictc.file")); + assert!(result.is_ok()); + assert!(result.unwrap().len() == 0, "should find no ictc block"); + + let result = find_ictc_blocks(&PathBuf::from( + "tests/if_change_then_change/multiple_ictc.file", + )); + assert!(result.is_ok()); + let list = result.unwrap(); + assert!(list.len() == 2, "should find two ictc block"); + // assert!(list[0].begin == 1, "first block should point to 2"); + let first = &list[0]; + assert_eq!(first.begin, Some(6)); + assert_eq!(first.end, Some(10)); + match &first.thenchange { + Some(ThenChange::RepoFile(path)) => { + assert_eq!(*path, PathBuf::from("foo.bar")); + } + _ => { + panic!("wrong thenchange type"); + } + }; + + let second = &list[1]; + assert_eq!(second.begin, Some(16)); + assert_eq!(second.end, Some(18)); + match &second.thenchange { + Some(ThenChange::RepoFile(path)) => { + assert_eq!(*path, PathBuf::from("path/to/file/something.else")); + } + _ => { + panic!("wrong thenchange type"); + } + }; +} From ebfc9981bab8e0a93efa77d5773b696aeea84d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 28 Aug 2024 19:07:36 +0000 Subject: [PATCH 02/47] --- .config/toolbox.toml | 8 +- .vscode/launch.json | 18 +- Cargo.toml | 2 + src/config.rs | 1 + src/diagnostic.rs | 4 +- src/git.rs | 45 ++++- src/main.rs | 96 +++++++--- src/rules/if_change_then_change.rs | 13 +- src/rules/mod.rs | 1 + src/rules/never_edit.rs | 275 +++++++---------------------- src/rules/pls_no_land.rs | 12 +- tests/alpha.foo | 3 + tests/integration_testing.rs | 2 +- tests/never_edit_test.rs | 126 +------------ 14 files changed, 218 insertions(+), 388 deletions(-) create mode 100644 tests/alpha.foo diff --git a/.config/toolbox.toml b/.config/toolbox.toml index 94c12de..c916ca5 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -1,14 +1,14 @@ # Configuration for trunk toolbox. Generate default by calling 'trunk-toolbox genconfig' [ifchange] -enabled = true +enabled = false [donotland] -enabled = true +enabled = false [todo] -enabled = true +enabled = false [neveredit] enabled = true -paths = ["write-once.txt"] +paths = ["src/rules/mod.rs"] diff --git a/.vscode/launch.json b/.vscode/launch.json index d466445..db91a2b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,8 +15,24 @@ "kind": "bin" } }, - "args": ["tests/if_change_then_change/basic_ictc.file"], + "args": ["tests/alpha.foo"], "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug cargo test toolbox", + "cargo": { + "args": ["test", "--no-run"], + "filter": { + "name": "trunk-toolbox", + "kind": "lib" + } + }, + "program": "${workspaceFolder}/target/debug/deps/output_format_test-1abc0c11be16e961", + "cwd": "${workspaceFolder}", + "stopOnEntry": false, + "sourceLanguages": ["rust"] } ] } diff --git a/Cargo.toml b/Cargo.toml index a4ebd9c..dda2c14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,8 @@ serde-sarif = "0.3.4" content_inspector = "0.2.4" rayon = "1.5.1" confique = "0.2.5" +glob = "0.3.1" +glob-match = "0.2.1" [dev-dependencies] assert_cmd = "2.0" diff --git a/src/config.rs b/src/config.rs index 88ec448..01c78e6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -46,5 +46,6 @@ pub struct TodoConf { pub struct NeverEditConf { #[config(default = false)] pub enabled: bool, + #[config(default = [])] pub paths: Vec, } diff --git a/src/diagnostic.rs b/src/diagnostic.rs index 12fe256..f74da44 100644 --- a/src/diagnostic.rs +++ b/src/diagnostic.rs @@ -28,14 +28,14 @@ pub struct Position { #[derive(Serialize)] pub struct Range { - pub path: String, pub start: Position, pub end: Position, } #[derive(Serialize)] pub struct Diagnostic { - pub range: Range, + pub path: String, + pub range: Option, pub severity: Severity, pub code: String, pub message: String, diff --git a/src/git.rs b/src/git.rs index d88e8c1..7287650 100644 --- a/src/git.rs +++ b/src/git.rs @@ -1,5 +1,5 @@ use git2::{AttrCheckFlags, AttrValue, Delta, DiffOptions, Repository}; -use std::collections::HashSet; +use std::collections::HashMap; use std::path::{Path, PathBuf}; #[derive(Debug, Clone)] @@ -13,13 +13,20 @@ pub struct Hunk { pub end: u64, } +#[derive(Debug, PartialEq, Eq, Hash)] +pub enum FileStatus { + Added, + Modified, + Deleted, +} + #[derive(Debug, Default)] -pub struct NewOrModified { +pub struct FileChanges { /// Set of modified line ranges in new/existing files pub hunks: Vec, - /// Set of new/modified files - pub paths: HashSet, + /// Map of changed files and FileStatus + pub paths: HashMap, } fn is_lfs(repo: &Repository, path: &Path) -> bool { @@ -34,7 +41,7 @@ fn is_lfs(repo: &Repository, path: &Path) -> bool { } } -pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Result { +pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Result { let path = repo_path.unwrap_or(Path::new(".")); let repo = Repository::open(path)?; @@ -72,10 +79,31 @@ pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Resul // // See https://docs.rs/git2/latest/git2/struct.Diff.html#method.foreach and the underlying API // docs at https://libgit2.org/libgit2/#HEAD/group/diff/git_diff_foreach. - let mut ret = NewOrModified::default(); + let mut ret = FileChanges::default(); let mut maybe_current_hunk: Option = None; diff.foreach( - &mut |_, _| true, + &mut |delta, _| { + if let Some(path) = delta.new_file().path() { + if !is_lfs(&repo, path) { + match delta.status() { + Delta::Added => { + ret.paths + .insert(path.to_string_lossy().to_string(), FileStatus::Added); + } + Delta::Modified => { + ret.paths + .insert(path.to_string_lossy().to_string(), FileStatus::Modified); + } + Delta::Deleted => { + ret.paths + .insert(path.to_string_lossy().to_string(), FileStatus::Deleted); + } + _ => {} + } + } + } + true + }, None, None, Some(&mut |delta, _, line| { @@ -104,7 +132,6 @@ pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Resul }) }); } else if let Some(current_hunk) = &maybe_current_hunk { - ret.paths.insert(current_hunk.path.clone()); ret.hunks.push(current_hunk.clone()); maybe_current_hunk = None; } @@ -124,7 +151,7 @@ pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Resul )?; if let Some(current_hunk) = &maybe_current_hunk { - ret.paths.insert(current_hunk.path.clone()); + // ret.paths.insert(current_hunk.path.clone()); ret.hunks.push(current_hunk.clone()); } diff --git a/src/main.rs b/src/main.rs index ca7aa90..74891a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use confique::Config; use horton::config::Conf; use horton::diagnostic; use horton::rules::if_change_then_change::ictc; +use horton::rules::never_edit::never_edit; use horton::rules::pls_no_land::pls_no_land; use horton::run::{Cli, OutputFormat, Run, Subcommands}; @@ -15,10 +16,14 @@ fn generate_line_string(original_results: &diagnostic::Diagnostics) -> String { .diagnostics .iter() .map(|d| { - format!( - "{}:{}:{}: {} ({})", - d.range.path, d.range.start.line, d.range.start.character, d.message, d.severity - ) + if let Some(range) = &d.range { + format!( + "{}:{}:{}: {} ({})", + d.path, range.start.line, range.start.character, d.message, d.severity + ) + } else { + format!("{}: {} ({})", d.path, d.message, d.severity) + } }) .collect::>() .join("\n"); @@ -34,31 +39,32 @@ fn generate_sarif_string( .diagnostics .iter() .map(|d| { + let mut location_builder = sarif::LocationBuilder::default(); + if let Some(range) = &d.range { + location_builder.physical_location( + sarif::PhysicalLocationBuilder::default() + .artifact_location( + sarif::ArtifactLocationBuilder::default() + .uri(d.path.clone()) + .build() + .unwrap(), + ) + .region( + sarif::RegionBuilder::default() + .start_line(range.start.line as i64 + 1) + .start_column(range.start.character as i64 + 1) + .end_line(range.end.line as i64 + 1) + .end_column(range.end.character as i64 + 1) + .build() + .unwrap(), + ) + .build() + .unwrap(), + ); + } sarif::ResultBuilder::default() .level(d.severity.to_string()) - .locations([sarif::LocationBuilder::default() - .physical_location( - sarif::PhysicalLocationBuilder::default() - .artifact_location( - sarif::ArtifactLocationBuilder::default() - .uri(d.range.path.clone()) - .build() - .unwrap(), - ) - .region( - sarif::RegionBuilder::default() - .start_line(d.range.start.line as i64 + 1) - .start_column(d.range.start.character as i64 + 1) - .end_line(d.range.end.line as i64 + 1) - .end_column(d.range.end.character as i64 + 1) - .build() - .unwrap(), - ) - .build() - .unwrap(), - ) - .build() - .unwrap()]) + .locations([location_builder.build().unwrap()]) .message( sarif::MessageBuilder::default() .text(d.message.clone()) @@ -68,6 +74,34 @@ fn generate_sarif_string( .rule_id(d.code.clone()) .build() .unwrap() + // sarif::ResultBuilder::default() + // .level(d.severity.to_string()) + // .locations([sarif::LocationBuilder::default() + // .physical_location( + // sarif::PhysicalLocationBuilder::default() + // .artifact_location( + // sarif::ArtifactLocationBuilder::default() + // .uri(d.range.path.clone()) + // .build() + // .unwrap(), + // ) + // .region( + // sarif::RegionBuilder::default() + // .start_line(d.range.start.line as i64 + 1) + // .start_column(d.range.start.character as i64 + 1) + // .end_line(d.range.end.line as i64 + 1) + // .end_column(d.range.end.character as i64 + 1) + // .build() + // .unwrap(), + // ) + // .build() + // .unwrap(), + // ) + // .build() + // .unwrap()]) + + // .build() + // .unwrap() }) .collect(); @@ -77,7 +111,7 @@ fn generate_sarif_string( .text(format!( "{:?} files processed in {:?}", run_context.paths.len(), - start_time.elapsed() + start_time.elapsed(), )) .build() .unwrap(), @@ -153,6 +187,12 @@ fn run() -> anyhow::Result<()> { Err(e) => return Err(e), } + let nc_result = never_edit(&run, &cli.upstream); + match nc_result { + Ok(result) => ret.diagnostics.extend(result), + Err(e) => return Err(e), + } + let mut output_string = generate_line_string(&ret); if cli.output_format == OutputFormat::Sarif { output_string = generate_sarif_string(&ret, &run, &start)?; diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index 2f5dca7..1921909 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -32,7 +32,6 @@ pub struct IctcBlock { impl IctcBlock { fn get_range(&self) -> diagnostic::Range { diagnostic::Range { - path: self.path.to_str().unwrap().to_string(), start: diagnostic::Position { line: self.begin.unwrap(), character: 0, @@ -190,7 +189,8 @@ pub fn ictc(run: &Run, upstream: &str) -> anyhow::Result anyhow::Result anyhow::Result { diagnostics.push(diagnostic::Diagnostic { - range: block.get_range(), + path: block.path.to_str().unwrap().to_string(), + range: Some(block.get_range()), severity: diagnostic::Severity::Warning, code: "if-change-mismatched".to_string(), message: "Expected preceding IfChange tag".to_string(), @@ -220,7 +222,8 @@ pub fn ictc(run: &Run, upstream: &str) -> anyhow::Result { diagnostics.push(diagnostic::Diagnostic { - range: block.get_range(), + path: block.path.to_str().unwrap().to_string(), + range: Some(block.get_range()), severity: diagnostic::Severity::Warning, code: "if-change-mismatched".to_string(), message: "Expected matching ThenChange tag".to_string(), diff --git a/src/rules/mod.rs b/src/rules/mod.rs index a0163b0..5f87d8d 100644 --- a/src/rules/mod.rs +++ b/src/rules/mod.rs @@ -1,2 +1,3 @@ pub mod if_change_then_change; +pub mod never_edit; pub mod pls_no_land; diff --git a/src/rules/never_edit.rs b/src/rules/never_edit.rs index 2f5dca7..07afeb9 100644 --- a/src/rules/never_edit.rs +++ b/src/rules/never_edit.rs @@ -1,247 +1,108 @@ +use crate::config::NeverEditConf; +use crate::git::FileStatus; use crate::run::Run; -use anyhow::Context; -use log::debug; -use std::collections::{HashMap, HashSet}; -use std::fs::File; -use std::io::{BufRead, BufReader}; -use std::path::Path; -use std::path::PathBuf; +use glob_match::glob_match; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; -use regex::Regex; use crate::diagnostic; use crate::git; -#[derive(Debug)] -pub enum ThenChange { - RemoteFile(String), - RepoFile(PathBuf), - MissingIf, - MissingThen, -} - -#[derive(Debug)] -pub struct IctcBlock { - pub path: PathBuf, - pub begin: Option, - pub end: Option, - pub thenchange: Option, -} - -impl IctcBlock { - fn get_range(&self) -> diagnostic::Range { - diagnostic::Range { - path: self.path.to_str().unwrap().to_string(), - start: diagnostic::Position { - line: self.begin.unwrap(), - character: 0, - }, - end: diagnostic::Position { - line: self.end.unwrap(), - character: 0, - }, +pub fn is_never_edit(file_path: &str, config: &NeverEditConf) -> bool { + for glob_path in &config.paths { + println!("CHecked {}", file_path); + if glob_match(glob_path, file_path) { + println!("Matched: {} with {}", glob_path, file_path); + return true; } } + false } -lazy_static::lazy_static! { - static ref RE_BEGIN: Regex = Regex::new(r"(?i)^\s*(//|#)\s*ifchange(.*)$").unwrap(); - static ref RE_END: Regex = Regex::new(r"(?i)^\s*(//|#)\s*thenchange(.*)$").unwrap(); -} - -pub fn find_ictc_blocks(path: &PathBuf) -> anyhow::Result> { - let mut blocks: Vec = Vec::new(); - - let in_file = File::open(path).with_context(|| format!("failed to open: {:#?}", path))?; - let in_buf = BufReader::new(in_file); - - let mut block: Option = None; - - for (i, line) in lines_view(in_buf) - .context(format!("failed to read lines of text from: {:#?}", path))? - .iter() - .enumerate() - .map(|(i, line)| (i + 1, line)) - { - let line_no = Some(i as u64); - if RE_BEGIN.find(line).is_some() { - if let Some(mut block_value) = block { - // Two if blocks in a row - report problem - block_value.end = block_value.begin; - block_value.thenchange = Some(ThenChange::MissingThen); - blocks.push(block_value); - } - - block = Some(IctcBlock { - path: path.clone(), - begin: line_no, - end: None, - thenchange: None, - }); - } else if let Some(end_capture) = RE_END.captures(line) { - if let Some(mut block_value) = block { - block_value.end = line_no; - block_value.thenchange = Some(ThenChange::RepoFile(PathBuf::from( - end_capture - .get(2) - .with_context(|| "expected at least 3 captures")? - .as_str() - .trim(), - ))); - blocks.push(block_value); - block = None; - } else { - // block is None and we found a IfChange without a ThenChange - blocks.push(IctcBlock { - path: path.clone(), - begin: line_no, - end: line_no, - thenchange: Some(ThenChange::MissingIf), - }); - } - } - } +pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result> { + let config = &run.config.neveredit; - // If we have an unclosed block - record that - if let Some(mut block_value) = block { - block_value.end = block_value.begin; - block_value.thenchange = Some(ThenChange::MissingThen); - blocks.push(block_value); + if !config.enabled { + return Ok(vec![]); } - Ok(blocks) -} - -pub fn ictc(run: &Run, upstream: &str) -> anyhow::Result> { - let config = &run.config.ifchange; + let mut diagnostics: Vec = Vec::new(); - if !config.enabled { - return Ok(vec![]); + if config.paths.is_empty() { + diagnostics.push(diagnostic::Diagnostic { + path: "toolbox.toml".to_string(), + range: None, + severity: diagnostic::Severity::Warning, + code: "never-edit-config".to_string(), + message: "no protected paths provided in config".to_string(), + }); + return Ok(diagnostics); } + //TODO Add warnings for any glob paths that don't resolve to an existing file or path - // Build up list of files that actually have a ifchange block - this way we can avoid - // processing git modified chunks if none are present - let all_blocks: Vec<_> = run + // Build up list of files that are being checked and are protected + let protected_files: Vec<_> = run .paths .par_iter() - .filter_map(|file| find_ictc_blocks(file).ok()) - .flatten() + .filter_map(|file| { + file.to_str().and_then(|file_str| { + if is_never_edit(file_str, config) { + Some(file_str.to_string()) + } else { + None + } + }) + }) .collect(); - // Fast exit if we don't have any files that have ICTC blocks - saves us calling - // into git to get more information - if all_blocks.is_empty() { + // Fast exit if we don't have any files changed that are protected + if protected_files.is_empty() { return Ok(vec![]); } let modified = git::modified_since(upstream, None)?; - let hunks = &modified.hunks; - log::debug!("Modified stats, per libgit2:\n{:#?}", modified); - - // TODO(sam): this _should_ be a iter-map-collect, but unclear how to apply a reducer - // between the map and collect (there can be multiple hunks with the same path) - let mut modified_lines_by_path: HashMap> = HashMap::new(); - for h in hunks { - modified_lines_by_path - .entry(h.path.clone()) - .or_default() - .extend(h.begin..h.end); - } - let modified_lines_by_path = modified_lines_by_path; - - let mut blocks: Vec = Vec::new(); - - for block in all_blocks { - if let Some(thenchange) = &block.thenchange { - match &thenchange { - ThenChange::MissingIf | ThenChange::MissingThen => { - blocks.push(block); - } - _ => { - if let (Some(begin), Some(end)) = (block.begin, block.end) { - let block_lines = HashSet::from_iter(begin..end); - if !block_lines.is_disjoint( - modified_lines_by_path - .get(&block.path) - .unwrap_or(&HashSet::new()), - ) { - blocks.push(block); - } - } - } - } - } - } - - let blocks_by_path: HashMap<&PathBuf, &IctcBlock> = - blocks.iter().map(|b| (&b.path, b)).collect(); - - let mut diagnostics: Vec = Vec::new(); - - for block in &blocks { - if let Some(change) = &block.thenchange { - match change { - ThenChange::RemoteFile(_remote_file) => { - todo!("build support for remote file") - } - ThenChange::RepoFile(local_file) => { - // Check if the repo file exists - if it was deleted this is a warning - if !Path::new(local_file).exists() { - diagnostics.push(diagnostic::Diagnostic { - range: block.get_range(), - severity: diagnostic::Severity::Warning, - code: "if-change-file-does-not-exist".to_string(), - message: format!("ThenChange {} does not exist", local_file.display(),), - }); - } - // If target file was not changed raise issue - if blocks_by_path.get(&local_file).is_none() { - diagnostics.push(diagnostic::Diagnostic { - range: block.get_range(), - severity: diagnostic::Severity::Error, - code: "if-change-then-change-this".to_string(), - message: format!( - "Expected change in {} because {} was modified", - local_file.display(), - block.path.display(), - ), - }); - } - } - ThenChange::MissingIf => { + for protected_file in &protected_files { + if let Some(status) = modified.paths.get(protected_file) { + match status { + FileStatus::Modified => { diagnostics.push(diagnostic::Diagnostic { - range: block.get_range(), - severity: diagnostic::Severity::Warning, - code: "if-change-mismatched".to_string(), - message: "Expected preceding IfChange tag".to_string(), + path: protected_file.clone(), + range: None, + severity: diagnostic::Severity::Error, + code: "never-edit-modified".to_string(), + message: format!( + "{:?} is a protected file and should not be modified", + protected_file + ), }); } - ThenChange::MissingThen => { + FileStatus::Deleted => { diagnostics.push(diagnostic::Diagnostic { - range: block.get_range(), + path: protected_file.clone(), + range: None, severity: diagnostic::Severity::Warning, - code: "if-change-mismatched".to_string(), - message: "Expected matching ThenChange tag".to_string(), + code: "never-edit-deleted".to_string(), + message: format!( + "{:?} is a protected file and should not be deleted", + protected_file + ), }); } + _ => {} } } } - debug!("ICTC blocks are:\n{:?}", blocks); + log::error!("Modified stats, per libgit2:\n{:#?}", modified.paths); - Ok(diagnostics) -} - -type LinesView = Vec; + diagnostics.push(diagnostic::Diagnostic { + path: "".to_string(), + range: None, + severity: diagnostic::Severity::Note, + code: "toolbox-perf".to_string(), + message: format!("{:?} protected files checked", protected_files.len()), + }); -fn lines_view(reader: R) -> anyhow::Result { - let mut ret: LinesView = LinesView::default(); - for line in reader.lines() { - let line = line?; - ret.push(line); - } - Ok(ret) + Ok(diagnostics) } diff --git a/src/rules/pls_no_land.rs b/src/rules/pls_no_land.rs index db3fa64..44f9279 100644 --- a/src/rules/pls_no_land.rs +++ b/src/rules/pls_no_land.rs @@ -93,8 +93,8 @@ fn pls_no_land_impl(path: &PathBuf, config: &Conf) -> anyhow::Result anyhow::Result anyhow::Result anyhow::Result, _> = modified_paths .into_iter() - .map(|path| path.into_os_string().into_string()) + .map(|file| file.path.into_os_string().into_string()) .collect(); cmd.env("RUST_LOG", "debug"); diff --git a/tests/never_edit_test.rs b/tests/never_edit_test.rs index 456fb2c..9b015b4 100644 --- a/tests/never_edit_test.rs +++ b/tests/never_edit_test.rs @@ -9,132 +9,8 @@ use std::path::PathBuf; #[test] fn assert_missing_thenchange() { - let test_repo = TestRepo::make().unwrap(); + let test_repo: TestRepo = TestRepo::make().unwrap(); test_repo.write("write_once.txt", "immutable text".as_bytes()); test_repo.git_commit_all("create write once file"); - - { - test_repo.write("revision.foo", single_tag.as_bytes()); - let horton = test_repo.run_horton().unwrap(); - assert_that(&horton.exit_code).contains_value(0); - assert_that(&horton.stdout).contains("Expected matching ThenChange tag"); - } - - { - test_repo.write("revision.foo", multi_tag.as_bytes()); - let horton = test_repo.run_horton().unwrap(); - assert_that(&horton.exit_code).contains_value(0); - assert_that(&horton.stdout).contains("Expected matching ThenChange tag"); - } -} - -#[test] -fn assert_missing_ifchange() { - let single_tag = r#" - aaaa - bbb - cc - // ThenChange - d - "#; - - let multi_tag = r#" - aaaa - bbb - cc - // IfChange - c - // ThenChange constants.foo - d - // ThenChange constants.foo - "#; - - let test_repo = TestRepo::make().unwrap(); - - test_repo.write("constant.foo", "foo-bar".as_bytes()); - test_repo.write("revision.foo", "".as_bytes()); - test_repo.git_commit_all("create constant.foo and revision.foo"); - - { - test_repo.write("revision.foo", single_tag.as_bytes()); - let horton = test_repo.run_horton().unwrap(); - assert_that(&horton.exit_code).contains_value(0); - assert_that(&horton.stdout).contains("Expected preceding IfChange tag"); - } - - { - test_repo.write("revision.foo", multi_tag.as_bytes()); - let horton = test_repo.run_horton().unwrap(); - assert_that(&horton.exit_code).contains_value(0); - assert_that(&horton.stdout).contains("Expected preceding IfChange tag"); - } -} - -#[test] -fn assert_localfile_notfound() { - let missing_file = r#" - aaaa - bbb - // IfChange - cc - // ThenChange zee.foo - d - "#; - - let test_repo = TestRepo::make().unwrap(); - - test_repo.write("revision.foo", "".as_bytes()); - test_repo.git_commit_all("create constant.foo and revision.foo"); - - { - test_repo.write("revision.foo", missing_file.as_bytes()); - let horton = test_repo.run_horton().unwrap(); - assert_that(&horton.exit_code).contains_value(0); - assert_that(&horton.stdout).contains("ThenChange zee.foo does not exist"); - } -} - -#[test] -fn verify_find_ictc_blocks() { - let result = find_ictc_blocks(&PathBuf::from( - "tests/if_change_then_change/basic_ictc.file", - )); - assert!(result.is_ok()); - assert!(result.unwrap().len() == 1, "should find 1 ictc block"); - - let result = find_ictc_blocks(&PathBuf::from("tests/if_change_then_change/no_ictc.file")); - assert!(result.is_ok()); - assert!(result.unwrap().len() == 0, "should find no ictc block"); - - let result = find_ictc_blocks(&PathBuf::from( - "tests/if_change_then_change/multiple_ictc.file", - )); - assert!(result.is_ok()); - let list = result.unwrap(); - assert!(list.len() == 2, "should find two ictc block"); - // assert!(list[0].begin == 1, "first block should point to 2"); - let first = &list[0]; - assert_eq!(first.begin, Some(6)); - assert_eq!(first.end, Some(10)); - match &first.thenchange { - Some(ThenChange::RepoFile(path)) => { - assert_eq!(*path, PathBuf::from("foo.bar")); - } - _ => { - panic!("wrong thenchange type"); - } - }; - - let second = &list[1]; - assert_eq!(second.begin, Some(16)); - assert_eq!(second.end, Some(18)); - match &second.thenchange { - Some(ThenChange::RepoFile(path)) => { - assert_eq!(*path, PathBuf::from("path/to/file/something.else")); - } - _ => { - panic!("wrong thenchange type"); - } - }; } From 7bc804440dd66edfdfad5d2bcab696e5da8ff64a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 28 Aug 2024 22:10:07 +0000 Subject: [PATCH 03/47] --- .trunk/trunk.yaml | 39 +++++++++++++++--------------- src/main.rs | 30 ++++++++++++----------- src/rules/if_change_then_change.rs | 2 +- src/rules/never_edit.rs | 7 ++---- tests/integration_testing.rs | 21 +++++++++++++--- tests/never_edit_test.rs | 34 ++++++++++++++++++++------ 6 files changed, 83 insertions(+), 50 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 96f93a8..ac578eb 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -2,7 +2,7 @@ version: 0.1 plugins: sources: - id: trunk - ref: v1.4.3 + ref: v1.6.2 uri: https://github.com/trunk-io/plugins runtimes: enabled: @@ -11,13 +11,13 @@ runtimes: - node@18.12.1 - rust@1.76.0 cli: - version: 1.20.1 + version: 1.22.3 api: address: api.trunk-staging.io:8443 tools: enabled: - - gh@2.44.1 + - gh@2.55.0 runtimes: - rust lint: @@ -33,6 +33,7 @@ lint: success_codes: [0] read_output_from: tmp_file disable_upstream: true + hold_the_line: false version_command: parse_regex: ${semver} run: trunk-toolbox --version @@ -45,22 +46,22 @@ lint: - tests/** enabled: - - shellcheck@0.9.0 - - shfmt@3.6.0 - - trunk-toolbox@0.2.0 - - checkov@3.2.26 - - trivy@0.49.1 - - trufflehog@3.68.2 - - oxipng@9.0.0 - - yamllint@1.35.1 - - git-diff-check - - taplo@0.8.1 - - actionlint@1.6.27 - - clippy@1.76.0 - - gitleaks@8.18.2 - - markdownlint@0.39.0 - - prettier@3.2.5 - - rustfmt@1.76.0 + # - shellcheck@0.10.0 + # - shfmt@3.6.0 + - trunk-toolbox@0.3.2 + # - checkov@3.2.238 + # - trivy@0.54.1 + # - trufflehog@3.81.9 + # - oxipng@9.1.2 + # - yamllint@1.35.1 + # - git-diff-check + # - taplo@0.9.3 + # - actionlint@1.7.1 + # - clippy@1.76.0 + # - gitleaks@8.18.4 + # - markdownlint@0.41.0 + # - prettier@3.3.3 + # - rustfmt@1.76.0 actions: enabled: - trunk-upgrade-available diff --git a/src/main.rs b/src/main.rs index 74891a1..a7c3bd6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,16 +39,16 @@ fn generate_sarif_string( .diagnostics .iter() .map(|d| { - let mut location_builder = sarif::LocationBuilder::default(); + let mut physical_location = sarif::PhysicalLocationBuilder::default(); + physical_location.artifact_location( + sarif::ArtifactLocationBuilder::default() + .uri(d.path.clone()) + .build() + .unwrap(), + ); + if let Some(range) = &d.range { - location_builder.physical_location( - sarif::PhysicalLocationBuilder::default() - .artifact_location( - sarif::ArtifactLocationBuilder::default() - .uri(d.path.clone()) - .build() - .unwrap(), - ) + physical_location .region( sarif::RegionBuilder::default() .start_line(range.start.line as i64 + 1) @@ -57,14 +57,16 @@ fn generate_sarif_string( .end_column(range.end.character as i64 + 1) .build() .unwrap(), - ) - .build() - .unwrap(), - ); + ); } sarif::ResultBuilder::default() .level(d.severity.to_string()) - .locations([location_builder.build().unwrap()]) + .locations([ + sarif::LocationBuilder::default() + .physical_location(physical_location.build().unwrap()) + .build() + .unwrap() + ]) .message( sarif::MessageBuilder::default() .text(d.message.clone()) diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index 1921909..008217f 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -137,7 +137,7 @@ pub fn ictc(run: &Run, upstream: &str) -> anyhow::Result bool { for glob_path in &config.paths { - println!("CHecked {}", file_path); if glob_match(glob_path, file_path) { - println!("Matched: {} with {}", glob_path, file_path); + log::info!("matched: {} with {}", glob_path, file_path); return true; } } @@ -72,7 +71,7 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result anyhow::Result, _> = modified_paths - .into_iter() - .map(|file| file.path.into_os_string().into_string()) + let files: Vec = modified_paths + .keys() + .map(|key| key.to_string()) .collect(); cmd.env("RUST_LOG", "debug"); @@ -137,7 +150,7 @@ impl TestRepo { .arg(upstream_ref) .current_dir(self.dir.path()); cmd.arg("--output-format").arg(format); - for path in strings.unwrap() { + for path in files { cmd.arg(path); } diff --git a/tests/never_edit_test.rs b/tests/never_edit_test.rs index 9b015b4..707394d 100644 --- a/tests/never_edit_test.rs +++ b/tests/never_edit_test.rs @@ -2,15 +2,35 @@ use spectral::prelude::*; mod integration_testing; use integration_testing::TestRepo; -use std::path::PathBuf; - -// use horton::rules::if_change_then_change::find_ictc_blocks; -// use horton::rules::if_change_then_change::ThenChange; #[test] -fn assert_missing_thenchange() { +fn assert_modified_locked_file() -> anyhow::Result<()> { let test_repo: TestRepo = TestRepo::make().unwrap(); - test_repo.write("write_once.txt", "immutable text".as_bytes()); - test_repo.git_commit_all("create write once file"); + test_repo.write("src/write_once.txt", "immutable text".as_bytes()); + test_repo.write("src/write_many.txt", "immutable text".as_bytes()); + test_repo.git_add_all()?; + test_repo.git_commit_all("create write once and write many file"); + + // enable and configure never_edit + let toml = r#" + [neveredit] + enabled = true + paths = ["src/foo", "src/bar/**", "**/write_once*"] +"#; + + // write to the protected file + test_repo.write("src/write_once.txt", "edit the text".as_bytes()); + test_repo.write("src/write_many.txt", "edit the text".as_bytes()); + + test_repo.set_toolbox_toml(toml); + + let horton = test_repo.run_horton()?; + + assert_that(&horton.exit_code).contains_value(0); + assert_that(&horton.stdout) + .contains("src/write_once.txt is a protected file and should not be modified"); + assert_that(&horton.stdout.contains("src/write_many.txt")).is_false(); + + Ok(()) } From 36556c5bad36debe9f63a4d35374b516c455311a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 28 Aug 2024 22:25:02 +0000 Subject: [PATCH 04/47] --- .config/toolbox.toml | 8 ++++---- README.md | 21 +++++++++++++++++++++ src/main.rs | 34 ++++------------------------------ src/rules/never_edit.rs | 3 +-- tests/alpha.foo | 3 --- 5 files changed, 30 insertions(+), 39 deletions(-) delete mode 100644 tests/alpha.foo diff --git a/.config/toolbox.toml b/.config/toolbox.toml index c916ca5..9b75bb2 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -1,14 +1,14 @@ # Configuration for trunk toolbox. Generate default by calling 'trunk-toolbox genconfig' [ifchange] -enabled = false +enabled = true [donotland] -enabled = false +enabled = true [todo] -enabled = false +enabled = true [neveredit] enabled = true -paths = ["src/rules/mod.rs"] +paths = [""] # paths to protect from modification diff --git a/README.md b/README.md index ed8f078..3e91593 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,27 @@ enum Flavor { x += 9; // why not ``` +#### never-edit + +##### What it does + +Allows you to enforce code does not get modified once checked into the repo. + +##### Why if this bad? + +If code is immutable - like database migration scripts - you want to ensure that no one edits those files +once they are checked in. This rule allows you to create restricted lists of files that cannot be edited +once added to the repo. + +##### Example + +This rule will report a violation if src/write_once.txt is modified or deleted in git given this config in toolbox.toml + +[neveredit] +enabled = true +paths = ["**/write_once*"] + + ### Disclaimer We know, we know...toolbox? That's only one step above 'UTILS', but a toolbox is a real thing, you can buy one in a store and put all kind of interesting things inside of them that make doing work a lot easier. Have you ever tried to change a wall socket without a screwdriver? We have...and it's not fun. diff --git a/src/main.rs b/src/main.rs index a7c3bd6..cfe0c82 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,34 +76,6 @@ fn generate_sarif_string( .rule_id(d.code.clone()) .build() .unwrap() - // sarif::ResultBuilder::default() - // .level(d.severity.to_string()) - // .locations([sarif::LocationBuilder::default() - // .physical_location( - // sarif::PhysicalLocationBuilder::default() - // .artifact_location( - // sarif::ArtifactLocationBuilder::default() - // .uri(d.range.path.clone()) - // .build() - // .unwrap(), - // ) - // .region( - // sarif::RegionBuilder::default() - // .start_line(d.range.start.line as i64 + 1) - // .start_column(d.range.start.character as i64 + 1) - // .end_line(d.range.end.line as i64 + 1) - // .end_column(d.range.end.character as i64 + 1) - // .build() - // .unwrap(), - // ) - // .build() - // .unwrap(), - // ) - // .build() - // .unwrap()]) - - // .build() - // .unwrap() }) .collect(); @@ -189,8 +161,10 @@ fn run() -> anyhow::Result<()> { Err(e) => return Err(e), } - let nc_result = never_edit(&run, &cli.upstream); - match nc_result { + //TODO: refactor this to use a threadpool for all the rules. using rayon::join() won't scale + //beyond two things + let ne_result = never_edit(&run, &cli.upstream); + match ne_result { Ok(result) => ret.diagnostics.extend(result), Err(e) => return Err(e), } diff --git a/src/rules/never_edit.rs b/src/rules/never_edit.rs index 67da6c0..b036c14 100644 --- a/src/rules/never_edit.rs +++ b/src/rules/never_edit.rs @@ -71,8 +71,7 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result Date: Wed, 28 Aug 2024 22:27:07 +0000 Subject: [PATCH 05/47] --- .config/toolbox.toml | 2 +- .trunk/trunk.yaml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.config/toolbox.toml b/.config/toolbox.toml index 9b75bb2..03980d2 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -11,4 +11,4 @@ enabled = true [neveredit] enabled = true -paths = [""] # paths to protect from modification +paths = ["src/rules/mod.rs"] # paths to protect from modification diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index ac578eb..344e609 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -32,8 +32,6 @@ lint: batch: true success_codes: [0] read_output_from: tmp_file - disable_upstream: true - hold_the_line: false version_command: parse_regex: ${semver} run: trunk-toolbox --version From 4cc35050823a9c88f2f328ed43d0838a2ee7c9f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 28 Aug 2024 22:31:59 +0000 Subject: [PATCH 06/47] --- .config/toolbox.toml | 2 +- .trunk/trunk.yaml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.config/toolbox.toml b/.config/toolbox.toml index 03980d2..9b75bb2 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -11,4 +11,4 @@ enabled = true [neveredit] enabled = true -paths = ["src/rules/mod.rs"] # paths to protect from modification +paths = [""] # paths to protect from modification diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 344e609..4197350 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -32,6 +32,7 @@ lint: batch: true success_codes: [0] read_output_from: tmp_file + disable_upstream: false version_command: parse_regex: ${semver} run: trunk-toolbox --version From 08aebea15f910097ec9d700306a4250396ab60f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 28 Aug 2024 22:33:24 +0000 Subject: [PATCH 07/47] --- .trunk/trunk.yaml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 4197350..c7aa315 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -45,22 +45,22 @@ lint: - tests/** enabled: - # - shellcheck@0.10.0 - # - shfmt@3.6.0 + - shellcheck@0.10.0 + - shfmt@3.6.0 - trunk-toolbox@0.3.2 - # - checkov@3.2.238 - # - trivy@0.54.1 - # - trufflehog@3.81.9 - # - oxipng@9.1.2 - # - yamllint@1.35.1 - # - git-diff-check - # - taplo@0.9.3 - # - actionlint@1.7.1 - # - clippy@1.76.0 - # - gitleaks@8.18.4 - # - markdownlint@0.41.0 - # - prettier@3.3.3 - # - rustfmt@1.76.0 + - checkov@3.2.238 + - trivy@0.54.1 + - trufflehog@3.81.9 + - oxipng@9.1.2 + - yamllint@1.35.1 + - git-diff-check + - taplo@0.9.3 + - actionlint@1.7.1 + - clippy@1.76.0 + - gitleaks@8.18.4 + - markdownlint@0.41.0 + - prettier@3.3.3 + - rustfmt@1.76.0 actions: enabled: - trunk-upgrade-available From 98ecb7e1f5a5532c37b8ee59afe7d06a7ae19451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 28 Aug 2024 22:34:25 +0000 Subject: [PATCH 08/47] --- .config/toolbox.toml | 2 +- README.md | 3 +-- src/git.rs | 1 - src/main.rs | 39 +++++++++++++++++------------------- src/rules/never_edit.rs | 4 +--- tests/integration_testing.rs | 15 +++++--------- tests/never_edit_test.rs | 2 +- 7 files changed, 27 insertions(+), 39 deletions(-) diff --git a/.config/toolbox.toml b/.config/toolbox.toml index 9b75bb2..b441993 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -11,4 +11,4 @@ enabled = true [neveredit] enabled = true -paths = [""] # paths to protect from modification +paths = [""] # paths to protect from modification diff --git a/README.md b/README.md index 3e91593..2bcb831 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ Allows you to enforce code does not get modified once checked into the repo. ##### Why if this bad? If code is immutable - like database migration scripts - you want to ensure that no one edits those files -once they are checked in. This rule allows you to create restricted lists of files that cannot be edited +once they are checked in. This rule allows you to create restricted lists of files that cannot be edited once added to the repo. ##### Example @@ -134,7 +134,6 @@ This rule will report a violation if src/write_once.txt is modified or deleted i enabled = true paths = ["**/write_once*"] - ### Disclaimer We know, we know...toolbox? That's only one step above 'UTILS', but a toolbox is a real thing, you can buy one in a store and put all kind of interesting things inside of them that make doing work a lot easier. Have you ever tried to change a wall socket without a screwdriver? We have...and it's not fun. diff --git a/src/git.rs b/src/git.rs index 7287650..47a3205 100644 --- a/src/git.rs +++ b/src/git.rs @@ -151,7 +151,6 @@ pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Resul )?; if let Some(current_hunk) = &maybe_current_hunk { - // ret.paths.insert(current_hunk.path.clone()); ret.hunks.push(current_hunk.clone()); } diff --git a/src/main.rs b/src/main.rs index cfe0c82..67bef3a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,32 +41,29 @@ fn generate_sarif_string( .map(|d| { let mut physical_location = sarif::PhysicalLocationBuilder::default(); physical_location.artifact_location( - sarif::ArtifactLocationBuilder::default() - .uri(d.path.clone()) - .build() - .unwrap(), - ); + sarif::ArtifactLocationBuilder::default() + .uri(d.path.clone()) + .build() + .unwrap(), + ); if let Some(range) = &d.range { - physical_location - .region( - sarif::RegionBuilder::default() - .start_line(range.start.line as i64 + 1) - .start_column(range.start.character as i64 + 1) - .end_line(range.end.line as i64 + 1) - .end_column(range.end.character as i64 + 1) - .build() - .unwrap(), - ); + physical_location.region( + sarif::RegionBuilder::default() + .start_line(range.start.line as i64 + 1) + .start_column(range.start.character as i64 + 1) + .end_line(range.end.line as i64 + 1) + .end_column(range.end.character as i64 + 1) + .build() + .unwrap(), + ); } sarif::ResultBuilder::default() .level(d.severity.to_string()) - .locations([ - sarif::LocationBuilder::default() - .physical_location(physical_location.build().unwrap()) - .build() - .unwrap() - ]) + .locations([sarif::LocationBuilder::default() + .physical_location(physical_location.build().unwrap()) + .build() + .unwrap()]) .message( sarif::MessageBuilder::default() .text(d.message.clone()) diff --git a/src/rules/never_edit.rs b/src/rules/never_edit.rs index b036c14..e90d72a 100644 --- a/src/rules/never_edit.rs +++ b/src/rules/never_edit.rs @@ -70,9 +70,7 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result { diff --git a/tests/integration_testing.rs b/tests/integration_testing.rs index 67d731f..f1c287e 100644 --- a/tests/integration_testing.rs +++ b/tests/integration_testing.rs @@ -89,7 +89,8 @@ impl TestRepo { // Create the directory hierarchy if needed if let Some(parent) = path.parent() { - fs::create_dir_all(parent).expect(format!("Unable to create directories for {:#?}", parent).as_str()); + fs::create_dir_all(parent) + .expect(format!("Unable to create directories for {:#?}", parent).as_str()); } fs::write(&path, data).expect(format!("Unable to write {:#?}", path).as_str()); @@ -124,11 +125,8 @@ impl TestRepo { } pub fn set_toolbox_toml(&self, config: &str) { - fs::write( - self.dir.path().join("toolbox.toml"), - config.as_bytes(), - ) - .expect("Failed to write toolbox.toml"); + fs::write(self.dir.path().join("toolbox.toml"), config.as_bytes()) + .expect("Failed to write toolbox.toml"); } pub fn run_horton_with( @@ -140,10 +138,7 @@ impl TestRepo { let modified_paths = horton::git::modified_since(upstream_ref, Some(self.dir.path()))?.paths; - let files: Vec = modified_paths - .keys() - .map(|key| key.to_string()) - .collect(); + let files: Vec = modified_paths.keys().map(|key| key.to_string()).collect(); cmd.env("RUST_LOG", "debug"); cmd.arg("--upstream") diff --git a/tests/never_edit_test.rs b/tests/never_edit_test.rs index 707394d..1b9bd9c 100644 --- a/tests/never_edit_test.rs +++ b/tests/never_edit_test.rs @@ -24,7 +24,7 @@ fn assert_modified_locked_file() -> anyhow::Result<()> { test_repo.write("src/write_many.txt", "edit the text".as_bytes()); test_repo.set_toolbox_toml(toml); - + let horton = test_repo.run_horton()?; assert_that(&horton.exit_code).contains_value(0); From db7cab6ccbe5e996751ed9f5bb918844693c0b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 28 Aug 2024 22:50:01 +0000 Subject: [PATCH 09/47] --- src/rules/never_edit.rs | 7 ++-- tests/integration_testing.rs | 15 +++++++-- tests/never_edit_test.rs | 62 ++++++++++++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 9 deletions(-) diff --git a/src/rules/never_edit.rs b/src/rules/never_edit.rs index e90d72a..7e45f2d 100644 --- a/src/rules/never_edit.rs +++ b/src/rules/never_edit.rs @@ -70,7 +70,7 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result { @@ -79,10 +79,7 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result {} diff --git a/tests/integration_testing.rs b/tests/integration_testing.rs index f1c287e..428b9bd 100644 --- a/tests/integration_testing.rs +++ b/tests/integration_testing.rs @@ -96,6 +96,16 @@ impl TestRepo { fs::write(&path, data).expect(format!("Unable to write {:#?}", path).as_str()); } + #[allow(dead_code)] + pub fn delete(&self, relpath: &str) { + let path = { + let mut path = self.dir.path().to_path_buf(); + path.push(relpath); + path + }; + fs::remove_file(&path).expect(format!("Unable to delete {:#?}", path).as_str()); + } + pub fn git_add_all(&self) -> anyhow::Result<()> { Command::new("git") .arg("add") @@ -106,6 +116,7 @@ impl TestRepo { Ok(()) } + #[allow(dead_code)] pub fn git_commit_all(&self, message: &str) { self.git_add_all().expect("add worked"); @@ -124,9 +135,9 @@ impl TestRepo { self.run_horton_with("HEAD", "sarif") } + #[allow(dead_code)] pub fn set_toolbox_toml(&self, config: &str) { - fs::write(self.dir.path().join("toolbox.toml"), config.as_bytes()) - .expect("Failed to write toolbox.toml"); + self.write(".config/toolbox.toml", config.as_bytes()); } pub fn run_horton_with( diff --git a/tests/never_edit_test.rs b/tests/never_edit_test.rs index 1b9bd9c..93889f3 100644 --- a/tests/never_edit_test.rs +++ b/tests/never_edit_test.rs @@ -28,9 +28,67 @@ fn assert_modified_locked_file() -> anyhow::Result<()> { let horton = test_repo.run_horton()?; assert_that(&horton.exit_code).contains_value(0); - assert_that(&horton.stdout) - .contains("src/write_once.txt is a protected file and should not be modified"); + assert_that(&horton.stdout).contains("file is protected and should not be modified"); assert_that(&horton.stdout.contains("src/write_many.txt")).is_false(); Ok(()) } + +#[test] +fn assert_deleted_locked_file() -> anyhow::Result<()> { + let test_repo: TestRepo = TestRepo::make().unwrap(); + + test_repo.write("src/locked/file.txt", "immutable text".as_bytes()); + test_repo.write("src/editable.txt", "mutable text".as_bytes()); + test_repo.git_add_all()?; + test_repo.git_commit_all("create locked and editable files"); + + // enable and configure never_edit + let toml = r#" + [neveredit] + enabled = true + paths = ["src/locked/**"] +"#; + + // write to the protected file + test_repo.delete("src/locked/file.txt"); + + test_repo.set_toolbox_toml(toml); + + let horton = test_repo.run_horton()?; + + assert_that(&horton.exit_code).contains_value(0); + assert_that(&horton.stdout).contains("file is protected and should not be deleted"); + assert_that(&horton.stdout).contains("src/locked/file.txt"); + + Ok(()) +} + +#[test] +fn honor_disabled_in_config() -> anyhow::Result<()> { + let test_repo: TestRepo = TestRepo::make().unwrap(); + + test_repo.write("src/locked/file.txt", "immutable text".as_bytes()); + test_repo.git_add_all()?; + test_repo.git_commit_all("create locked and editable files"); + + // enable and configure never_edit + let toml = r#" + [neveredit] + enabled = false + paths = ["src/locked/**"] +"#; + + // write to the protected file + test_repo.delete("src/locked/file.txt"); + + test_repo.set_toolbox_toml(toml); + + let horton = test_repo.run_horton()?; + + assert_that(&horton.exit_code).contains_value(0); + assert_that(&horton.stdout.contains("src/locked/file.txt")).is_false(); + assert_that(&horton.stdout).contains("1 files processed"); + + Ok(()) +} From 7e04a75f849a98218d7e09ab09c3b8d2daf382ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 28 Aug 2024 22:51:19 +0000 Subject: [PATCH 10/47] --- .vscode/launch.json | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index db91a2b..d466445 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,24 +15,8 @@ "kind": "bin" } }, - "args": ["tests/alpha.foo"], + "args": ["tests/if_change_then_change/basic_ictc.file"], "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug cargo test toolbox", - "cargo": { - "args": ["test", "--no-run"], - "filter": { - "name": "trunk-toolbox", - "kind": "lib" - } - }, - "program": "${workspaceFolder}/target/debug/deps/output_format_test-1abc0c11be16e961", - "cwd": "${workspaceFolder}", - "stopOnEntry": false, - "sourceLanguages": ["rust"] } ] } From 1361cc0c58e6c54a0de68184bf2cb0e2e2b5a6ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Thu, 29 Aug 2024 16:58:13 +0000 Subject: [PATCH 11/47] --- .config/toolbox.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/toolbox.toml b/.config/toolbox.toml index b441993..b6d8e17 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -7,7 +7,7 @@ enabled = true enabled = true [todo] -enabled = true +enabled = false [neveredit] enabled = true From c1115ac74cdba9ac9a65534ed933d3e683fcfde4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Thu, 29 Aug 2024 16:59:34 +0000 Subject: [PATCH 12/47] --- .gitignore | 4 - Cargo.lock | 1437 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1437 insertions(+), 4 deletions(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index 088ba6b..f2e972d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,5 @@ # will have compiled files and executables /target/ -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - # These are backup files generated by rustfmt **/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..21aeb66 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1437 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" + +[[package]] +name = "assert_cmd" +version = "2.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00ad3f3a942eee60335ab4342358c161ee296829e0d16ff42fc1d6cb07815467" +dependencies = [ + "anstyle", + "bstr", + "doc-comment", + "predicates 3.1.0", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bstr" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.0", +] + +[[package]] +name = "clap_derive" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "confique" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c37945ed2efccb10339a12eea282a5af9ebac77720d088723b2bbbdc44eca964" +dependencies = [ + "confique-macro", + "json5", + "serde", + "serde_yaml", + "toml", +] + +[[package]] +name = "confique-macro" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3821efdaaab3c5297054a90201cc3afa2061fc6ba2bc5d2fa558b850a7dabefe" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "content_inspector" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder_macro" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +dependencies = [ + "derive_builder_core", + "syn 1.0.109", +] + +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "function_name" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef632c665dc6e2b99ffa4d913f7160bd902c4d3e4cb732d81dc3d221f848512" +dependencies = [ + "function_name-proc-macro", +] + +[[package]] +name = "function_name-proc-macro" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "569d2238870f92cff64fc810013b61edaf446ebcfba36b649b96bc5b4078328a" +dependencies = [ + "proc-macro-crate", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "git2" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1" +dependencies = [ + "bitflags 1.3.2", + "libc", + "libgit2-sys", + "log", + "url", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "glob-match" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "jobserver" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +dependencies = [ + "libc", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libgit2-sys" +version = "0.14.2+1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f3d95f6b51075fe9810a7ae22c7095f12b98005ab364d8544797a825ce946a4" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libz-sys" +version = "1.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + +[[package]] +name = "num" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" +dependencies = [ + "num-integer", + "num-traits", + "rand", + "rustc-serialize", +] + +[[package]] +name = "num-complex" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656" +dependencies = [ + "num-traits", + "rustc-serialize", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", + "rustc-serialize", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pest_meta" +version = "2.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "pkg-config" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" + +[[package]] +name = "predicates" +version = "2.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" +dependencies = [ + "difflib", + "float-cmp", + "itertools", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" +dependencies = [ + "anstyle", + "difflib", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" + +[[package]] +name = "predicates-tree" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rayon" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rustc-serialize" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401" + +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "schemafy_core" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bec29dddcfe60f92f3c0d422707b8b56473983ef0481df8d5236ed3ab8fdf24" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "schemafy_lib" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af3d87f1df246a9b7e2bfd1f4ee5f88e48b11ef9cfc62e63f0dead255b1a6f5f" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "schemafy_core", + "serde", + "serde_derive", + "serde_json", + "syn 1.0.109", + "uriparse", +] + +[[package]] +name = "serde" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-sarif" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51eda7853590f74ef6f8b9d868f20679f2072b4b86c8970d5ce320b42d457198" +dependencies = [ + "anyhow", + "derive_builder", + "prettyplease", + "proc-macro2", + "quote", + "schemafy_lib", + "serde", + "serde_json", + "strum", + "strum_macros", + "syn 1.0.109", + "thiserror", +] + +[[package]] +name = "serde_derive" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_json" +version = "1.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "spectral" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3c15181f4b14e52eeaac3efaeec4d2764716ce9c86da0c934c3e318649c5ba" +dependencies = [ + "num", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "termtree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" + +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "trunk-toolbox" +version = "0.0.0" +dependencies = [ + "anyhow", + "assert_cmd", + "clap", + "confique", + "content_inspector", + "env_logger", + "function_name", + "git2", + "glob", + "glob-match", + "lazy_static", + "log", + "predicates 2.1.5", + "rayon", + "regex", + "serde", + "serde-sarif", + "serde_json", + "spectral", + "tempfile", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" + +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" From 8b0cd34057310bba6143ad4822870821b39d0351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 30 Aug 2024 00:49:25 +0000 Subject: [PATCH 13/47] --- .config/toolbox.toml | 6 +++--- src/rules/never_edit.rs | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/.config/toolbox.toml b/.config/toolbox.toml index b6d8e17..f32ad26 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -1,14 +1,14 @@ # Configuration for trunk toolbox. Generate default by calling 'trunk-toolbox genconfig' [ifchange] -enabled = true +enabled = false [donotland] -enabled = true +enabled = false [todo] enabled = false [neveredit] enabled = true -paths = [""] # paths to protect from modification +paths = [] # paths to protect from modification diff --git a/src/rules/never_edit.rs b/src/rules/never_edit.rs index 7e45f2d..b45f849 100644 --- a/src/rules/never_edit.rs +++ b/src/rules/never_edit.rs @@ -1,6 +1,7 @@ use crate::config::NeverEditConf; use crate::git::FileStatus; use crate::run::Run; +use glob::glob; use glob_match::glob_match; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; @@ -37,7 +38,41 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result { + for entry in paths { + match entry { + Ok(_path) => { + matches_something = true; + break; + } + Err(e) => println!("Error reading path: {:?}", e), + } + } + if !matches_something { + diagnostics.push(diagnostic::Diagnostic { + path: "toolbox.toml".to_string(), + range: None, + severity: diagnostic::Severity::Warning, + code: "never-edit-bad-config".to_string(), + message: format!("{:?} does not protect any existing files", glob_path), + }); + } + } + Err(_e) => { + diagnostics.push(diagnostic::Diagnostic { + path: "toolbox.toml".to_string(), + range: None, + severity: diagnostic::Severity::Warning, + code: "never-edit-bad-config".to_string(), + message: format!("{:?} is not a valid glob pattern", glob_path), + }); + } + } + } // Build up list of files that are being checked and are protected let protected_files: Vec<_> = run @@ -56,7 +91,7 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result Date: Fri, 30 Aug 2024 00:52:18 +0000 Subject: [PATCH 14/47] --- tests/never_edit_test.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/never_edit_test.rs b/tests/never_edit_test.rs index 93889f3..16f2e11 100644 --- a/tests/never_edit_test.rs +++ b/tests/never_edit_test.rs @@ -92,3 +92,23 @@ fn honor_disabled_in_config() -> anyhow::Result<()> { Ok(()) } + +#[test] +fn warn_for_config_not_protecting_anything() -> anyhow::Result<()> { + let test_repo: TestRepo = TestRepo::make().unwrap(); + + // enable and configure never_edit + let toml = r#" + [neveredit] + enabled = true + paths = ["bad_path/**"] +"#; + test_repo.set_toolbox_toml(toml); + + let horton: integration_testing::HortonOutput = test_repo.run_horton()?; + + assert_that(&horton.exit_code).contains_value(0); + assert_that(&horton.stdout).contains("does not protect any existing files"); + + Ok(()) +} From fdefdba980ab72bd5575376517e1b3050529b01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 30 Aug 2024 01:03:43 +0000 Subject: [PATCH 15/47] --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2bcb831..14eb502 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Keeps you from accidentally commiting code to a repository that is experimental, Valid triggers for this rule are: DONOTLAND, DO-NOT-LAND, DO_NOT_LAND, donotland, do-not-land, do_not_land -##### Why if this bad? +##### Why is this bad? Anything you intentionally don't want in your repo should really not be there. This lets you flag the code you are writing to do testing without worrying that you'll forget you dropped it in your files before pushing your Pull Request. @@ -76,7 +76,7 @@ By default, this rule is disabled and must be enabled with: enabled = true ``` -##### Why if this bad? +##### Why is this bad? TODOs should be treated like any other lint issue. Sometimes you need to land code that still has these issues, but you want to keep track of them and avoid them when possible. @@ -93,7 +93,7 @@ uploadResultsSync(); Allows you to enforce code synchronization. Often, we have code in one file that is reliant on code in another loosely - say an enum has 4 options and you want to make sure consumers of that enum are kept in sync as new enums are added. This rule will make sure the code is updated in both places when a modification occurs to the code block. -##### Why if this bad? +##### Why is this bad? If code has baked-in assumptions that are not enforced through a check - then they can easily get out of sync. This rule allows you to encode that dependency and ensure all related code is updated when a modification occurs. @@ -120,7 +120,7 @@ x += 9; // why not Allows you to enforce code does not get modified once checked into the repo. -##### Why if this bad? +##### Why is this bad? If code is immutable - like database migration scripts - you want to ensure that no one edits those files once they are checked in. This rule allows you to create restricted lists of files that cannot be edited From 6b42b192093ca249a77046bbbc4c573f4cb33d98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 30 Aug 2024 18:39:37 +0000 Subject: [PATCH 16/47] --- .config/toolbox.toml | 2 +- .trunk/trunk.yaml | 3 ++- src/main.rs | 35 +++++++++++++++++++++++---- src/rules/never_edit.rs | 53 ++++++++++++++++++++++------------------- src/run.rs | 6 +++++ 5 files changed, 68 insertions(+), 31 deletions(-) diff --git a/.config/toolbox.toml b/.config/toolbox.toml index f32ad26..e65da9c 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -11,4 +11,4 @@ enabled = false [neveredit] enabled = true -paths = [] # paths to protect from modification +paths = ["bldddah"] # paths to protect from modification diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index c7aa315..b8736b3 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -27,12 +27,13 @@ lint: files: [ALL] commands: - name: lint - run: ${workspace}/toolbox-latest --upstream=${upstream-ref} --results=${tmpfile} ${target} + run: ${workspace}/toolbox-latest --upstream=${upstream-ref} --cache-dir=${cachedir} --results=${tmpfile} ${target} output: sarif batch: true success_codes: [0] read_output_from: tmp_file disable_upstream: false + direct_configs: [toolbox.toml] version_command: parse_regex: ${semver} run: trunk-toolbox --version diff --git a/src/main.rs b/src/main.rs index 67bef3a..f8e388b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ use horton::rules::pls_no_land::pls_no_land; use horton::run::{Cli, OutputFormat, Run, Subcommands}; use serde_sarif::sarif; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::time::Instant; fn generate_line_string(original_results: &diagnostic::Diagnostics) -> String { @@ -117,6 +117,23 @@ fn generate_sarif_string( Ok(sarif) } +fn find_toolbox_toml() -> Option { + let files = [ + "toolbox.toml", + ".config/toolbox.toml", + ".trunk/config/toolbox.toml", + ".trunk/configs/toolbox.toml", + ]; + + for file in &files { + if Path::new(file).exists() { + return Some(file.to_string()); + } + } + + None +} + fn run() -> anyhow::Result<()> { let start = Instant::now(); let cli: Cli = Cli::parse(); @@ -128,12 +145,18 @@ fn run() -> anyhow::Result<()> { let mut ret = diagnostic::Diagnostics::default(); + let toolbox_toml: String = match find_toolbox_toml() { + Some(file) => file, + None => { + eprintln!("Toolbox cannot run: toolbox.toml is required"); + std::process::exit(1); + } + }; + println!("{}", toolbox_toml); + let config = Conf::builder() .env() - .file("toolbox.toml") - .file(".config/toolbox.toml") - .file(".trunk/config/toolbox.toml") - .file(".trunk/configs/toolbox.toml") + .file(&toolbox_toml) .load() .unwrap_or_else(|err| { eprintln!("Toolbox cannot run: {}", err); @@ -143,6 +166,8 @@ fn run() -> anyhow::Result<()> { let run = Run { paths: cli.files.into_iter().map(PathBuf::from).collect(), config, + config_path: toolbox_toml, + is_upstream: cli.cache_dir.ends_with("-upstream"), }; let (pls_no_land_result, ictc_result): (Result<_, _>, Result<_, _>) = diff --git a/src/rules/never_edit.rs b/src/rules/never_edit.rs index b45f849..6e96aa8 100644 --- a/src/rules/never_edit.rs +++ b/src/rules/never_edit.rs @@ -28,9 +28,11 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result = Vec::new(); - if config.paths.is_empty() { + // We only emit config issues for the current run (not the upstream) so we can guarantee + // that config issues get reported and not conceiled by HTL + if config.paths.is_empty() && !run.is_upstream { diagnostics.push(diagnostic::Diagnostic { - path: "toolbox.toml".to_string(), + path: run.config_path.clone(), range: None, severity: diagnostic::Severity::Warning, code: "never-edit-config".to_string(), @@ -39,38 +41,41 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result { - for entry in paths { - match entry { - Ok(_path) => { - matches_something = true; - break; + // We only report diagnostic issues for config when not running as upstream + if !run.is_upstream { + for glob_path in &config.paths { + let mut matches_something = false; + match glob(glob_path) { + Ok(paths) => { + for entry in paths { + match entry { + Ok(_path) => { + matches_something = true; + break; + } + Err(e) => println!("Error reading path: {:?}", e), } - Err(e) => println!("Error reading path: {:?}", e), + } + if !matches_something { + diagnostics.push(diagnostic::Diagnostic { + path: run.config_path.clone(), + range: None, + severity: diagnostic::Severity::Warning, + code: "never-edit-bad-config".to_string(), + message: format!("{:?} does not protect any existing files", glob_path), + }); } } - if !matches_something { + Err(_e) => { diagnostics.push(diagnostic::Diagnostic { - path: "toolbox.toml".to_string(), + path: run.config_path.clone(), range: None, severity: diagnostic::Severity::Warning, code: "never-edit-bad-config".to_string(), - message: format!("{:?} does not protect any existing files", glob_path), + message: format!("{:?} is not a valid glob pattern", glob_path), }); } } - Err(_e) => { - diagnostics.push(diagnostic::Diagnostic { - path: "toolbox.toml".to_string(), - range: None, - severity: diagnostic::Severity::Warning, - code: "never-edit-bad-config".to_string(), - message: format!("{:?} is not a valid glob pattern", glob_path), - }); - } } } diff --git a/src/run.rs b/src/run.rs index b1a4862..58a9028 100644 --- a/src/run.rs +++ b/src/run.rs @@ -39,6 +39,10 @@ pub struct Cli { #[clap(long, default_value = "sarif")] pub output_format: OutputFormat, + #[clap(long, default_value = "")] + /// optional cache directory location + pub cache_dir: String, + #[clap(long)] /// optional path to write results to pub results: Option, @@ -54,4 +58,6 @@ pub enum Subcommands { pub struct Run { pub paths: HashSet, pub config: Conf, + pub is_upstream: bool, + pub config_path: String, } From cc817f4ca7354d14d25aa6e1755be06fb677e1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 30 Aug 2024 18:41:57 +0000 Subject: [PATCH 17/47] update --- .config/toolbox.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.config/toolbox.toml b/.config/toolbox.toml index e65da9c..b4def01 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -10,5 +10,5 @@ enabled = false enabled = false [neveredit] -enabled = true -paths = ["bldddah"] # paths to protect from modification +enabled = false +paths = [] From 9ab0e15821cfa9edf01a73c5e467ccdaa83b229a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 30 Aug 2024 18:46:51 +0000 Subject: [PATCH 18/47] --- Cargo.lock | 383 +++++++++++++++++++++++++++++------------------------ Cargo.toml | 8 +- 2 files changed, 212 insertions(+), 179 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 21aeb66..23a63e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,77 +14,79 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "assert_cmd" -version = "2.0.13" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00ad3f3a942eee60335ab4342358c161ee296829e0d16ff42fc1d6cb07815467" +checksum = "dc1835b7f27878de8525dc71410b5a31cdcc5f230aed5ba5df968e09c201b23d" dependencies = [ "anstyle", "bstr", "doc-comment", - "predicates 3.1.0", + "libc", + "predicates 3.1.2", "predicates-core", "predicates-tree", "wait-timeout", @@ -103,21 +105,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -130,9 +126,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", "regex-automata", @@ -141,12 +137,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -157,9 +154,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.0" +version = "4.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" +checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" dependencies = [ "clap_builder", "clap_derive", @@ -167,39 +164,39 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.0" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.0", + "strsim 0.11.1", ] [[package]] name = "clap_derive" -version = "4.5.0" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "confique" @@ -237,9 +234,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] @@ -265,9 +262,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-common" @@ -369,9 +366,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "env_logger" @@ -394,19 +391,19 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "float-cmp" @@ -470,11 +467,11 @@ dependencies = [ [[package]] name = "git2" -version = "0.15.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ - "bitflags 1.3.2", + "bitflags", "libc", "libgit2-sys", "log", @@ -495,9 +492,9 @@ checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -514,6 +511,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -547,14 +550,20 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", "hashbrown", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.10.5" @@ -566,15 +575,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -592,21 +601,21 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libgit2-sys" -version = "0.14.2+1.5.1" +version = "0.17.0+1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f3d95f6b51075fe9810a7ae22c7095f12b98005ab364d8544797a825ce946a4" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" dependencies = [ "cc", "libc", @@ -616,9 +625,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.15" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" dependencies = [ "cc", "libc", @@ -628,21 +637,21 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "normalize-line-endings" @@ -697,9 +706,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -720,9 +729,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -741,9 +750,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.7" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -752,9 +761,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.7" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" dependencies = [ "pest", "pest_generator", @@ -762,22 +771,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.7" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "pest_meta" -version = "2.7.7" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" dependencies = [ "once_cell", "pest", @@ -786,9 +795,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "predicates" @@ -806,9 +815,9 @@ dependencies = [ [[package]] name = "predicates" -version = "3.1.0" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" +checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" dependencies = [ "anstyle", "difflib", @@ -817,15 +826,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" +checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" [[package]] name = "predicates-tree" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" dependencies = [ "predicates-core", "termtree", @@ -852,18 +861,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -898,9 +907,9 @@ checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] name = "rayon" -version = "1.8.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -927,9 +936,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -939,9 +948,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -950,9 +959,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "rustc-serialize" @@ -962,28 +971,28 @@ checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ - "bitflags 2.4.2", + "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schemafy_core" @@ -1014,9 +1023,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.196" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] @@ -1043,31 +1052,32 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_yaml" -version = "0.9.31" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ "indexmap", "itoa", @@ -1087,6 +1097,12 @@ dependencies = [ "digest", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "spectral" version = "0.6.0" @@ -1104,9 +1120,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" @@ -1140,9 +1156,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" dependencies = [ "proc-macro2", "quote", @@ -1151,14 +1167,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1178,29 +1195,29 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -1272,9 +1289,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] @@ -1287,9 +1304,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unsafe-libyaml" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "uriparse" @@ -1303,9 +1320,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -1314,9 +1331,9 @@ dependencies = [ [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "vcpkg" @@ -1326,9 +1343,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wait-timeout" @@ -1357,11 +1374,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -1379,15 +1396,25 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", @@ -1396,42 +1423,48 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index dda2c14..0b12b4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,15 +17,15 @@ path = "src/lib.rs" anyhow = "1.0.64" clap = { version = "4.0.8", features = ["derive"] } env_logger = "0.9.1" -git2 = { version = "0.15", default-features = false } +git2 = { version = "0.19", default-features = false } lazy_static = "1.4.0" log = "0.4.17" -regex = "1.6.0" -serde = { version = "1.0.145", features = ["derive"] } +regex = "1.10.6" +serde = { version = "1.0.209", features = ["derive"] } serde_json = "1.0.85" serde-sarif = "0.3.4" content_inspector = "0.2.4" -rayon = "1.5.1" +rayon = "1.10.0" confique = "0.2.5" glob = "0.3.1" glob-match = "0.2.1" From c0cce449c2cf2fac6506a333f36a461bdaa99e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 30 Aug 2024 18:47:37 +0000 Subject: [PATCH 19/47] ok --- Cargo.lock | 30 +++++------------------------- Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23a63e8..730c6cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,7 +86,7 @@ dependencies = [ "bstr", "doc-comment", "libc", - "predicates 3.1.2", + "predicates", "predicates-core", "predicates-tree", "wait-timeout", @@ -564,15 +564,6 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.11" @@ -799,20 +790,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" -[[package]] -name = "predicates" -version = "2.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" -dependencies = [ - "difflib", - "float-cmp", - "itertools", - "normalize-line-endings", - "predicates-core", - "regex", -] - [[package]] name = "predicates" version = "3.1.2" @@ -821,7 +798,10 @@ checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" dependencies = [ "anstyle", "difflib", + "float-cmp", + "normalize-line-endings", "predicates-core", + "regex", ] [[package]] @@ -1253,7 +1233,7 @@ dependencies = [ "glob-match", "lazy_static", "log", - "predicates 2.1.5", + "predicates", "rayon", "regex", "serde", diff --git a/Cargo.toml b/Cargo.toml index 0b12b4f..0d6d11e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ glob-match = "0.2.1" [dev-dependencies] assert_cmd = "2.0" function_name = "0.2.0" -predicates = "2.1" +predicates = "3.1.2" spectral = "0.6.0" tempfile = "3.3.0" From 6af0d5a510edf9ffb3518ac472853b214323d481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 30 Aug 2024 18:57:09 +0000 Subject: [PATCH 20/47] --- .trunk/trunk.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index b8736b3..3d92e7d 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -50,7 +50,6 @@ lint: - shfmt@3.6.0 - trunk-toolbox@0.3.2 - checkov@3.2.238 - - trivy@0.54.1 - trufflehog@3.81.9 - oxipng@9.1.2 - yamllint@1.35.1 From 168bb45a61e74215e980b5d4a948d154599a784a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 30 Aug 2024 19:01:08 +0000 Subject: [PATCH 21/47] --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 14eb502..43812b4 100644 --- a/README.md +++ b/README.md @@ -130,9 +130,11 @@ once added to the repo. This rule will report a violation if src/write_once.txt is modified or deleted in git given this config in toolbox.toml +```toml [neveredit] enabled = true paths = ["**/write_once*"] +``` ### Disclaimer From 11b893997811d381d7d25d89291fd64a8e00f8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 30 Aug 2024 19:17:21 +0000 Subject: [PATCH 22/47] --- src/main.rs | 7 +------ src/rules/pls_no_land.rs | 10 +++++++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index f8e388b..7a4023b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -118,12 +118,7 @@ fn generate_sarif_string( } fn find_toolbox_toml() -> Option { - let files = [ - "toolbox.toml", - ".config/toolbox.toml", - ".trunk/config/toolbox.toml", - ".trunk/configs/toolbox.toml", - ]; + let files = ["toolbox.toml", ".config/toolbox.toml"]; for file in &files { if Path::new(file).exists() { diff --git a/src/rules/pls_no_land.rs b/src/rules/pls_no_land.rs index 44f9279..e6669c0 100644 --- a/src/rules/pls_no_land.rs +++ b/src/rules/pls_no_land.rs @@ -1,7 +1,6 @@ // trunk-ignore-all(trunk-toolbox/do-not-land,trunk-toolbox/todo) extern crate regex; -use crate::config::Conf; use crate::diagnostic; use crate::run::Run; use anyhow::Context; @@ -45,7 +44,7 @@ pub fn pls_no_land(run: &Run) -> anyhow::Result> { let results: Result, _> = run .paths .par_iter() - .map(|path| pls_no_land_impl(path, &run.config)) + .map(|path| pls_no_land_impl(path, run)) .collect(); match results { @@ -54,7 +53,9 @@ pub fn pls_no_land(run: &Run) -> anyhow::Result> { } } -fn pls_no_land_impl(path: &PathBuf, config: &Conf) -> anyhow::Result> { +fn pls_no_land_impl(path: &PathBuf, run: &Run) -> anyhow::Result> { + let config = &run.config; + if is_binary_file(path).unwrap_or(true) { log::debug!("Ignoring binary file {}", path.display()); return Ok(vec![]); @@ -88,8 +89,11 @@ fn pls_no_land_impl(path: &PathBuf, config: &Conf) -> anyhow::Result Date: Fri, 30 Aug 2024 20:04:48 +0000 Subject: [PATCH 23/47] --- src/main.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7a4023b..24a1826 100644 --- a/src/main.rs +++ b/src/main.rs @@ -140,14 +140,12 @@ fn run() -> anyhow::Result<()> { let mut ret = diagnostic::Diagnostics::default(); + // If not configuration file is provided the default config will be used + // some parts of toolbo can run with the default config let toolbox_toml: String = match find_toolbox_toml() { Some(file) => file, - None => { - eprintln!("Toolbox cannot run: toolbox.toml is required"); - std::process::exit(1); - } + None => "no_config_found.toml".to_string(), }; - println!("{}", toolbox_toml); let config = Conf::builder() .env() From 093cfa4be7d03290b8ec20b6fd84a6f3b64a0307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 4 Sep 2024 23:02:20 +0000 Subject: [PATCH 24/47] support remote ICTC --- Cargo.lock | 1 + Cargo.toml | 1 + src/diagnostic.rs | 8 +- src/git.rs | 22 ++ src/main.rs | 8 +- src/rules/if_change_then_change.rs | 373 ++++++++++++------ .../basic_ictc_remote.file | 23 ++ tests/if_change_then_change_test.rs | 27 +- 8 files changed, 330 insertions(+), 133 deletions(-) create mode 100644 tests/if_change_then_change/basic_ictc_remote.file diff --git a/Cargo.lock b/Cargo.lock index 730c6cf..dca23d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1241,6 +1241,7 @@ dependencies = [ "serde_json", "spectral", "tempfile", + "url", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0d6d11e..045360e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ rayon = "1.10.0" confique = "0.2.5" glob = "0.3.1" glob-match = "0.2.1" +url = "2.5.2" [dev-dependencies] assert_cmd = "2.0" diff --git a/src/diagnostic.rs b/src/diagnostic.rs index f74da44..3fd2295 100644 --- a/src/diagnostic.rs +++ b/src/diagnostic.rs @@ -1,7 +1,7 @@ use serde::Serialize; use std::fmt; -#[derive(Serialize)] +#[derive(Clone, Serialize)] pub enum Severity { Error, Warning, @@ -20,19 +20,19 @@ impl fmt::Display for Severity { } } -#[derive(Serialize)] +#[derive(Clone, Serialize)] pub struct Position { pub line: u64, pub character: u64, } -#[derive(Serialize)] +#[derive(Clone, Serialize)] pub struct Range { pub start: Position, pub end: Position, } -#[derive(Serialize)] +#[derive(Clone, Serialize)] pub struct Diagnostic { pub path: String, pub range: Option, diff --git a/src/git.rs b/src/git.rs index 47a3205..8f94fa9 100644 --- a/src/git.rs +++ b/src/git.rs @@ -1,6 +1,7 @@ use git2::{AttrCheckFlags, AttrValue, Delta, DiffOptions, Repository}; use std::collections::HashMap; use std::path::{Path, PathBuf}; +use std::process::Command; #[derive(Debug, Clone)] pub struct Hunk { @@ -156,3 +157,24 @@ pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Resul Ok(ret) } + +fn clone(repo_url: &str, destination: &Path) -> Result<(), String> { + let output = Command::new("git") + .args(&[ + "clone", + "--no-checkout", + "--depth=1", + "--bare", + "--filter=blob:none", + repo_url, + destination.to_str().unwrap(), + ]) + .output() + .expect("Failed to execute git command"); + + if output.status.success() { + Ok(()) + } else { + Err(String::from_utf8_lossy(&output.stderr).to_string()) + } +} diff --git a/src/main.rs b/src/main.rs index 24a1826..6ce9d8f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use clap::Parser; use confique::Config; use horton::config::Conf; use horton::diagnostic; -use horton::rules::if_change_then_change::ictc; +use horton::rules::if_change_then_change::Ictc; use horton::rules::never_edit::never_edit; use horton::rules::pls_no_land::pls_no_land; use horton::run::{Cli, OutputFormat, Run, Subcommands}; @@ -163,8 +163,10 @@ fn run() -> anyhow::Result<()> { is_upstream: cli.cache_dir.ends_with("-upstream"), }; - let (pls_no_land_result, ictc_result): (Result<_, _>, Result<_, _>) = - rayon::join(|| pls_no_land(&run), || ictc(&run, &cli.upstream)); + let (pls_no_land_result, ictc_result): (Result<_, _>, Result<_, _>) = rayon::join( + || pls_no_land(&run), + || Ictc::new(&run, &cli.upstream).run(), + ); match pls_no_land_result { Ok(result) => ret.diagnostics.extend(result), diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index 008217f..be75491 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -4,8 +4,8 @@ use log::debug; use std::collections::{HashMap, HashSet}; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::path::Path; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; +use url::Url; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use regex::Regex; @@ -13,19 +13,56 @@ use regex::Regex; use crate::diagnostic; use crate::git; +#[derive(Debug)] +pub struct RemoteLocation { + pub repo: String, + pub path: String, + pub lock_hash: String, +} + +impl RemoteLocation { + pub fn new(entry: &str) -> Self { + let parts: Vec<&str> = entry.split_whitespace().collect(); + if parts.len() < 2 { + panic!("Entry must contain at least two parts separated by space"); + } + + let path_parts: Vec<&str> = parts[1].splitn(2, '#').collect(); + let path = path_parts[0].to_string(); + let lock_hash = if path_parts.len() > 1 { + path_parts[1].to_string() + } else { + String::new() + }; + + Self { + repo: parts[0].to_string(), + path, + lock_hash, + } + } +} + #[derive(Debug)] pub enum ThenChange { - RemoteFile(String), + RemoteFile(RemoteLocation), RepoFile(PathBuf), MissingIf, MissingThen, } +#[derive(Debug)] +pub enum IfChange { + RemoteFile(RemoteLocation), + RepoFile(PathBuf), +} + #[derive(Debug)] pub struct IctcBlock { pub path: PathBuf, pub begin: Option, pub end: Option, + pub ifchange: Option, pub thenchange: Option, } @@ -49,137 +86,133 @@ lazy_static::lazy_static! { static ref RE_END: Regex = Regex::new(r"(?i)^\s*(//|#)\s*thenchange(.*)$").unwrap(); } -pub fn find_ictc_blocks(path: &PathBuf) -> anyhow::Result> { - let mut blocks: Vec = Vec::new(); - - let in_file = File::open(path).with_context(|| format!("failed to open: {:#?}", path))?; - let in_buf = BufReader::new(in_file); - - let mut block: Option = None; - - for (i, line) in lines_view(in_buf) - .context(format!("failed to read lines of text from: {:#?}", path))? - .iter() - .enumerate() - .map(|(i, line)| (i + 1, line)) - { - let line_no = Some(i as u64); - if RE_BEGIN.find(line).is_some() { - if let Some(mut block_value) = block { - // Two if blocks in a row - report problem - block_value.end = block_value.begin; - block_value.thenchange = Some(ThenChange::MissingThen); - blocks.push(block_value); - } +pub struct Ictc<'a> { + run: &'a Run, + upstream: String, + diagnostics: Vec, +} - block = Some(IctcBlock { - path: path.clone(), - begin: line_no, - end: None, - thenchange: None, - }); - } else if let Some(end_capture) = RE_END.captures(line) { - if let Some(mut block_value) = block { - block_value.end = line_no; - block_value.thenchange = Some(ThenChange::RepoFile(PathBuf::from( - end_capture - .get(2) - .with_context(|| "expected at least 3 captures")? - .as_str() - .trim(), - ))); - blocks.push(block_value); - block = None; - } else { - // block is None and we found a IfChange without a ThenChange - blocks.push(IctcBlock { - path: path.clone(), - begin: line_no, - end: line_no, - thenchange: Some(ThenChange::MissingIf), - }); - } +impl<'a> Ictc<'a> { + pub fn new(run: &'a Run, upstream: &str) -> Self { + Self { + run, + upstream: upstream.to_string(), + diagnostics: Vec::new(), } } - // If we have an unclosed block - record that - if let Some(mut block_value) = block { - block_value.end = block_value.begin; - block_value.thenchange = Some(ThenChange::MissingThen); - blocks.push(block_value); - } - - Ok(blocks) -} + pub fn run(&mut self) -> anyhow::Result> { + let config = &self.run.config.ifchange; -pub fn ictc(run: &Run, upstream: &str) -> anyhow::Result> { - let config = &run.config.ifchange; + if !config.enabled { + return Ok(vec![]); + } - if !config.enabled { - return Ok(vec![]); - } + // Build up list of files that actually have a ifchange block - this way we can avoid + // processing git modified chunks if none are present + let all_blocks: Vec<_> = self + .run + .paths + .par_iter() + .filter_map(|file| find_ictc_blocks(file).ok()) + .flatten() + .collect(); - // Build up list of files that actually have a ifchange block - this way we can avoid - // processing git modified chunks if none are present - let all_blocks: Vec<_> = run - .paths - .par_iter() - .filter_map(|file| find_ictc_blocks(file).ok()) - .flatten() - .collect(); - - // Fast exit if we don't have any files that have ICTC blocks - saves us calling - // into git to get more information - if all_blocks.is_empty() { - return Ok(vec![]); - } + // Fast exit if we don't have any files that have ICTC blocks - saves us calling + // into git to get more information + if all_blocks.is_empty() { + return Ok(vec![]); + } - let modified = git::modified_since(upstream, None)?; - let hunks = &modified.hunks; + let modified = git::modified_since(&self.upstream, None)?; + let hunks = &modified.hunks; - log::trace!("modified stats, per libgit2:\n{:#?}", modified); + log::trace!("modified stats, per libgit2:\n{:#?}", modified); - // TODO(sam): this _should_ be a iter-map-collect, but unclear how to apply a reducer - // between the map and collect (there can be multiple hunks with the same path) - let mut modified_lines_by_path: HashMap> = HashMap::new(); - for h in hunks { - modified_lines_by_path - .entry(h.path.clone()) - .or_default() - .extend(h.begin..h.end); - } - let modified_lines_by_path = modified_lines_by_path; + // TODO(sam): this _should_ be a iter-map-collect, but unclear how to apply a reducer + // between the map and collect (there can be multiple hunks with the same path) + let mut modified_lines_by_path: HashMap> = HashMap::new(); + for h in hunks { + modified_lines_by_path + .entry(h.path.clone()) + .or_default() + .extend(h.begin..h.end); + } + let modified_lines_by_path = modified_lines_by_path; - let mut blocks: Vec = Vec::new(); + let mut blocks: Vec = Vec::new(); - for block in all_blocks { - if let Some(thenchange) = &block.thenchange { - match &thenchange { - ThenChange::MissingIf | ThenChange::MissingThen => { - blocks.push(block); + for block in all_blocks { + if let Some(thenchange) = &block.thenchange { + match &thenchange { + ThenChange::MissingIf | ThenChange::MissingThen => { + blocks.push(block); + } + _ => { + if let (Some(begin), Some(end)) = (block.begin, block.end) { + let block_lines = HashSet::from_iter(begin..end); + if !block_lines.is_disjoint( + modified_lines_by_path + .get(&block.path) + .unwrap_or(&HashSet::new()), + ) { + blocks.push(block); + } + } + } } - _ => { - if let (Some(begin), Some(end)) = (block.begin, block.end) { - let block_lines = HashSet::from_iter(begin..end); - if !block_lines.is_disjoint( - modified_lines_by_path - .get(&block.path) - .unwrap_or(&HashSet::new()), - ) { - blocks.push(block); + } + } + + let blocks_by_path: HashMap<&PathBuf, &IctcBlock> = + blocks.iter().map(|b| (&b.path, b)).collect(); + + for block in &blocks { + if let Some(change) = &block.ifchange { + match change { + IfChange::RemoteFile(remote) => { + // remote file should be in form of + // {REMOTE_REPO} {REMOTE_PATH}#{LOCK_HASH} + if self.ifchange_remote(&remote, &block) { + // if it's ok we will keep processing the rest of the rule + self.thenchange(&block, &blocks_by_path); } } + _ => self.thenchange(&block, &blocks_by_path), } } } + + debug!("ICTC blocks are:\n{:?}", blocks); + + Ok(self.diagnostics.clone()) } - let blocks_by_path: HashMap<&PathBuf, &IctcBlock> = - blocks.iter().map(|b| (&b.path, b)).collect(); + fn build_or_get_remote_repo( + &mut self, + remote: &RemoteLocation, + block: &IctcBlock, + ) -> Result { + Err(block_diagnostic( + block, + diagnostic::Severity::Warning, + "if-change-cannot-reach-remote", + format!("IfChange cannot access remote repo at {}", remote.repo).as_str(), + )) + } - let mut diagnostics: Vec = Vec::new(); + fn ifchange_remote(&mut self, remote: &RemoteLocation, block: &IctcBlock) -> bool { + // get path to clone of remote repo. + match self.build_or_get_remote_repo(remote, block) { + Ok(path) => { + println!("repo is cloned shallow at {:?}", path); + true + } + Err(_e) => false, + } + } - for block in &blocks { + fn thenchange(&mut self, block: &IctcBlock, blocks_by_path: &HashMap<&PathBuf, &IctcBlock>) { if let Some(change) = &block.thenchange { match change { ThenChange::RemoteFile(_remote_file) => { @@ -188,7 +221,7 @@ pub fn ictc(run: &Run, upstream: &str) -> anyhow::Result { // Check if the repo file exists - if it was deleted this is a warning if !Path::new(local_file).exists() { - diagnostics.push(diagnostic::Diagnostic { + self.diagnostics.push(diagnostic::Diagnostic { path: block.path.to_str().unwrap().to_string(), range: Some(block.get_range()), severity: diagnostic::Severity::Warning, @@ -198,7 +231,7 @@ pub fn ictc(run: &Run, upstream: &str) -> anyhow::Result anyhow::Result { - diagnostics.push(diagnostic::Diagnostic { + self.diagnostics.push(diagnostic::Diagnostic { path: block.path.to_str().unwrap().to_string(), range: Some(block.get_range()), severity: diagnostic::Severity::Warning, @@ -221,21 +254,113 @@ pub fn ictc(run: &Run, upstream: &str) -> anyhow::Result { - diagnostics.push(diagnostic::Diagnostic { - path: block.path.to_str().unwrap().to_string(), - range: Some(block.get_range()), - severity: diagnostic::Severity::Warning, - code: "if-change-mismatched".to_string(), - message: "Expected matching ThenChange tag".to_string(), - }); + self.diagnostics.push(block_diagnostic( + block, + diagnostic::Severity::Warning, + "if-change-mismatched", + "Expected matching ThenChange tag", + )); } } } } +} + +pub fn block_diagnostic( + block: &IctcBlock, + sev: diagnostic::Severity, + code: &str, + msg: &str, +) -> diagnostic::Diagnostic { + diagnostic::Diagnostic { + path: block.path.to_str().unwrap().to_string(), + range: Some(block.get_range()), + severity: sev, + code: code.to_string(), + message: msg.to_string(), + } +} + +pub fn find_ictc_blocks(path: &PathBuf) -> anyhow::Result> { + let mut blocks: Vec = Vec::new(); + + let in_file = File::open(path).with_context(|| format!("failed to open: {:#?}", path))?; + let in_buf = BufReader::new(in_file); + + let mut block: Option = None; + + for (i, line) in lines_view(in_buf) + .context(format!("failed to read lines of text from: {:#?}", path))? + .iter() + .enumerate() + .map(|(i, line)| (i + 1, line)) + { + let line_no = Some(i as u64); + if let Some(begin_capture) = RE_BEGIN.captures(line) { + if let Some(mut block_value) = block { + // Two if blocks in a row - report problem + block_value.end = block_value.begin; + block_value.thenchange = Some(ThenChange::MissingThen); + blocks.push(block_value); + } - debug!("ICTC blocks are:\n{:?}", blocks); + // get the content of the second capture group which should be either a remote file or blank + let source_trigger = begin_capture + .get(2) + .with_context(|| "expected at least 3 captures")? + .as_str() + .trim(); - Ok(diagnostics) + let ifchange = if source_trigger.is_empty() { + None + } else if source_trigger.contains(" ") { + // If the source trigger has a space in the middle then its in the format of a remote repo file + Some(IfChange::RemoteFile(RemoteLocation::new(source_trigger))) + } else { + // Looks like a file path but it doesn't exist + Some(IfChange::RepoFile(PathBuf::from(source_trigger))) + }; + + block = Some(IctcBlock { + path: path.clone(), + begin: line_no, + end: None, + ifchange, + thenchange: None, + }); + } else if let Some(end_capture) = RE_END.captures(line) { + if let Some(mut block_value) = block { + block_value.end = line_no; + block_value.thenchange = Some(ThenChange::RepoFile(PathBuf::from( + end_capture + .get(2) + .with_context(|| "expected at least 3 captures")? + .as_str() + .trim(), + ))); + blocks.push(block_value); + block = None; + } else { + // block is None and we found a IfChange without a ThenChange + blocks.push(IctcBlock { + path: path.clone(), + begin: line_no, + end: line_no, + ifchange: None, + thenchange: Some(ThenChange::MissingIf), + }); + } + } + } + + // If we have an unclosed block - record that + if let Some(mut block_value) = block { + block_value.end = block_value.begin; + block_value.thenchange = Some(ThenChange::MissingThen); + blocks.push(block_value); + } + + Ok(blocks) } type LinesView = Vec; diff --git a/tests/if_change_then_change/basic_ictc_remote.file b/tests/if_change_then_change/basic_ictc_remote.file new file mode 100644 index 0000000..a8caaf3 --- /dev/null +++ b/tests/if_change_then_change/basic_ictc_remote.file @@ -0,0 +1,23 @@ +Lorem ipsum odor amet, consectetuer adipiscing elit. Ornare elit nostra sit metus arcu maximus conubia. Nullam nec elit justo aenean penatibus. Vestibulum cras euismod orci morbi phasellus luctus, sit tincidunt dictum. Hendrerit fringilla augue morbi vel pharetra per fames. Nostra elit mi auctor suspendisse congue. Aptent magnis molestie dui integer turpis quam accumsan? Aenean quis lobortis per tristique mi. + +Platea platea donec duis gravida dapibus. Sodales iaculis eu pharetra finibus magna orci condimentum. Habitant nascetur praesent lobortis etiam vestibulum sollicitudin magna. Augue fames laoreet rutrum vel leo donec hendrerit senectus. Senectus malesuada efficitur suscipit; platea ipsum placerat. Bibendum platea mattis nullam feugiat lorem nibh augue. Nullam aliquet libero non mollis ridiculus blandit. Nisl lacus porta justo eu enim euismod facilisi curabitur tortor. Donec augue nunc aliquam ullamcorper faucibus arcu imperdiet suspendisse. + +Fusce sem sem volutpat phasellus congue quisque ante libero dictumst. Aposuere urna cubilia mi vitae felis velit. Aenean netus habitant molestie blandit pellentesque laoreet. Et est sed; cubilia adipiscing morbi suspendisse ac etiam. Amet facilisi ultrices vulputate arcu, inceptos taciti arcu. Mi malesuada eget sagittis morbi nisl nisi nunc platea. Ac convallis conubia, a urna auctor consectetur eu proin purus. Sollicitudin mollis natoque molestie morbi vulputate nascetur ante posuere phasellus. Neque finibus vestibulum class porttitor nullam tempor massa dis fusce. Netus ornare facilisi nisi molestie tortor. +// IfChange github.com:eslint/eslint.git LICENSE +Mus facilisis scelerisque quam semper metus orci gravida interdum mattis. Primis semper aliquet blandit condimentum pretium mus. Fames finibus torquent interdum vitae eu. At condimentum a eros turpis mus eros. Diam at interdum euismod conubia dapibus finibus fames adipiscing? Laoreet ut vehicula metus risus eros mollis mauris habitant. Mi elit ante; ullamcorper faucibus dictumst felis ac mattis. Nascetur arcu varius libero convallis penatibus aenean nunc. Molestie velit magnis turpis potenti massa suspendisse. + +Mollis ad litora adipiscing orci mi curae, vitae ipsum auctor. Malesuada aliquam tincidunt senectus justo volutpat elit taciti. Tortor massa malesuada pulvinar; eleifend vivamus sem enim. Nostra iaculis elit fusce dui rutrum sit nulla convallis. Semper pulvinar tellus magnis sociosqu nunc primis aliquam aptent. Nulla lobortis ridiculus dui ante libero sed. Gravida ut eros massa; hendrerit iaculis nisl. Ex dapibus ornare primis duis bibendum; in et cubilia. +// ThenChange +Feugiat conubia sem potenti nec sed elementum torquent. Turpis consequat orci scelerisque; nunc purus arcu hac eu. Dapibus arcu nascetur mi posuere dictum adipiscing. Sed ex lobortis commodo elit facilisis fusce. Varius senectus mattis est tortor; proin ex. Ridiculus curabitur mattis senectus euismod primis ac. Felis dictum suspendisse fringilla sit varius. Nunc risus nullam magna laoreet fusce hendrerit sed sollicitudin. Maecenas eu id mollis felis id suspendisse. Posuere nisl velit egestas porttitor lectus curae. + +Lacus eleifend euismod leo mauris blandit dapibus faucibus. Neque non lectus vel class dapibus per adipiscing pulvinar. Vehicula risus vulputate commodo tincidunt vivamus pretium. Ultricies lectus neque vestibulum primis augue justo vivamus. Ridiculus maximus id mollis facilisis fermentum nulla sapien; vitae montes. Etiam tempus conubia maecenas habitant nec. Nam platea turpis inceptos sapien tristique. Libero maximus porta hac donec scelerisque tempus. Scelerisque velit blandit per tempus ipsum. + +Posuere maximus himenaeos, ut aenean gravida auctor. Nulla ullamcorper fusce sodales; iaculis ac habitasse lacus. Turpis est augue gravida; gravida proin senectus mollis inceptos. Vulputate risus risus tempus class nam aenean erat. Mattis tempor commodo leo felis class natoque egestas imperdiet dis. Vestibulum tristique class posuere nibh iaculis. Sem rhoncus elit pellentesque facilisis auctor. Sodales rhoncus faucibus adipiscing phasellus magnis volutpat placerat magna. + +Eros laoreet porttitor porta etiam metus. Tempus eget integer cras sed non vitae hendrerit scelerisque. Pharetra pulvinar ex semper donec diam dolor. Curabitur vel vitae cubilia curabitur mollis nostra himenaeos. Habitasse volutpat fusce euismod enim bibendum magna. Ac eget bibendum semper lectus class duis gravida metus dictumst. Consequat erat praesent dis netus platea condimentum gravida. Ex platea ipsum ullamcorper duis egestas ullamcorper suscipit mauris vitae. + +Semper finibus enim praesent tempus malesuada at elementum. Sem congue fusce litora, iaculis viverra aenean curabitur semper. In lectus ut libero vehicula curabitur conubia sodales. Pellentesque magna diam ridiculus; netus ad accumsan convallis mattis. Erat euismod feugiat posuere diam hendrerit. Imperdiet himenaeos varius efficitur at nibh interdum. Eros feugiat convallis gravida sodales tincidunt rutrum semper blandit. Nostra varius condimentum per suspendisse, dignissim morbi placerat ridiculus donec. Libero parturient massa mi nascetur volutpat tristique nibh. + +Porttitor magna litora tortor nibh aliquam sit ipsum. Tempor mi leo dolor egestas feugiat risus ultrices? Sit eu tellus suspendisse lacus nulla magna cras fusce. Nulla et venenatis potenti nullam felis laoreet. Nulla magna tellus platea urna laoreet. Vitae venenatis litora, turpis ridiculus cursus facilisi. Dis augue taciti faucibus fermentum a montes cras. Gravida platea vivamus luctus penatibus conubia orci adipiscing aptent enim. Parturient ligula nam etiam quisque dolor non quisque fermentum. + +Odio nascetur suspendisse convallis semper tincidunt mi. Turpis aenean vehicula taciti gravida dapibus suscipit, netus mattis. Aenean diam sagittis elit; nisl ut commodo neque ornare nam. Donec metus cubilia neque per malesuada sit per hendrerit. Ridiculus hac risus lacinia pulvinar mattis? Eleifend torquent fermentum semper nibh duis amet facilisis porta. diff --git a/tests/if_change_then_change_test.rs b/tests/if_change_then_change_test.rs index 0e9cb27..651c886 100644 --- a/tests/if_change_then_change_test.rs +++ b/tests/if_change_then_change_test.rs @@ -5,7 +5,7 @@ use integration_testing::TestRepo; use std::path::PathBuf; use horton::rules::if_change_then_change::find_ictc_blocks; -use horton::rules::if_change_then_change::ThenChange; +use horton::rules::if_change_then_change::{IfChange, ThenChange}; fn assert_no_expected_changes(before: &str, after: &str) -> anyhow::Result<()> { let test_repo = TestRepo::make().unwrap(); @@ -348,7 +348,7 @@ fn assert_localfile_notfound() { } #[test] -fn verify_find_ictc_blocks() { +fn find_local_ictc_blocks() { let result = find_ictc_blocks(&PathBuf::from( "tests/if_change_then_change/basic_ictc.file", )); @@ -390,3 +390,26 @@ fn verify_find_ictc_blocks() { } }; } + +#[test] +fn find_repo_ictc_blocks() { + let result = find_ictc_blocks(&PathBuf::from( + "tests/if_change_then_change/basic_ictc_remote.file", + )); + assert!(result.is_ok()); + + let list = result.unwrap(); + assert!(list.len() == 1, "should find 1 ictc block"); + + let first = &list[0]; + assert_eq!(first.begin, Some(6)); + assert_eq!(first.end, Some(10)); + match &first.ifchange { + Some(IfChange::RemoteFile(path)) => { + assert_that(path).contains("github.com:eslint/eslint.git LICENSE"); + } + _ => { + panic!("wrong ifchange type"); + } + }; +} From 0a58cb2d6dd2178f264df8bc95195ca4bcc84f6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 11 Sep 2024 23:06:28 +0000 Subject: [PATCH 25/47] --- Cargo.lock | 1 + Cargo.toml | 1 + src/git.rs | 4 +- src/rules/if_change_then_change.rs | 30 ++++++++++++- tests/if_change_then_change_test.rs | 65 +++++++++++++++++++++++++++-- 5 files changed, 93 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dca23d3..2ee408b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1239,6 +1239,7 @@ dependencies = [ "serde", "serde-sarif", "serde_json", + "sha2", "spectral", "tempfile", "url", diff --git a/Cargo.toml b/Cargo.toml index 045360e..cf700c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ confique = "0.2.5" glob = "0.3.1" glob-match = "0.2.1" url = "2.5.2" +sha2 = "0.10.8" [dev-dependencies] assert_cmd = "2.0" diff --git a/src/git.rs b/src/git.rs index 8f94fa9..c882813 100644 --- a/src/git.rs +++ b/src/git.rs @@ -158,7 +158,7 @@ pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Resul Ok(ret) } -fn clone(repo_url: &str, destination: &Path) -> Result<(), String> { +pub fn clone(repo_url: &str, destination: &str) -> Result<(), String> { let output = Command::new("git") .args(&[ "clone", @@ -167,7 +167,7 @@ fn clone(repo_url: &str, destination: &Path) -> Result<(), String> { "--bare", "--filter=blob:none", repo_url, - destination.to_str().unwrap(), + destination, ]) .output() .expect("Failed to execute git command"); diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index be75491..7a893c3 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -1,7 +1,10 @@ use crate::run::Run; use anyhow::Context; use log::debug; +use sha2::{Digest, Sha256}; + use std::collections::{HashMap, HashSet}; +use std::env; use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; @@ -13,7 +16,7 @@ use regex::Regex; use crate::diagnostic; use crate::git; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct RemoteLocation { pub repo: String, pub path: String, @@ -41,6 +44,15 @@ impl RemoteLocation { lock_hash, } } + + pub fn repo_hash(&self) -> String { + let mut hasher = Sha256::new(); + hasher.update(self.repo.to_string()); + let result = hasher.finalize(); + let hash_string = format!("{:x}", result); + let hash_string = &hash_string[..32]; // Get the first 32 characters + return hash_string.to_string(); + } } #[derive(Debug)] @@ -188,11 +200,25 @@ impl<'a> Ictc<'a> { Ok(self.diagnostics.clone()) } - fn build_or_get_remote_repo( + pub fn build_or_get_remote_repo( &mut self, remote: &RemoteLocation, block: &IctcBlock, ) -> Result { + let current_dir = env::current_dir().expect("Failed to get current directory"); + let repo_dir = current_dir.join(remote.repo_hash()); + + git::clone(remote.repo.as_str(), repo_dir.to_str().unwrap()) + .map_err(|e| { + block_diagnostic( + block, + diagnostic::Severity::Warning, + "if-change-clone-failed", + format!("Failed to clone remote repo at {}: {}", remote.repo, e).as_str(), + ) + }) + .unwrap_or_default(); + Err(block_diagnostic( block, diagnostic::Severity::Warning, diff --git a/tests/if_change_then_change_test.rs b/tests/if_change_then_change_test.rs index 651c886..a598bc0 100644 --- a/tests/if_change_then_change_test.rs +++ b/tests/if_change_then_change_test.rs @@ -1,11 +1,16 @@ +use confique::{Config, Partial}; +use horton::config::confique_partial_if_change_conf::PartialIfChangeConf; +use horton::config::Conf; +use horton::run::Run; use spectral::prelude::*; mod integration_testing; use integration_testing::TestRepo; +use std::collections::HashSet; use std::path::PathBuf; -use horton::rules::if_change_then_change::find_ictc_blocks; -use horton::rules::if_change_then_change::{IfChange, ThenChange}; +use horton::rules::if_change_then_change::{find_ictc_blocks, IctcBlock}; +use horton::rules::if_change_then_change::{Ictc, IfChange, RemoteLocation, ThenChange}; fn assert_no_expected_changes(before: &str, after: &str) -> anyhow::Result<()> { let test_repo = TestRepo::make().unwrap(); @@ -405,11 +410,63 @@ fn find_repo_ictc_blocks() { assert_eq!(first.begin, Some(6)); assert_eq!(first.end, Some(10)); match &first.ifchange { - Some(IfChange::RemoteFile(path)) => { - assert_that(path).contains("github.com:eslint/eslint.git LICENSE"); + Some(IfChange::RemoteFile(remote)) => { + assert_that(&remote.repo).contains("github.com:eslint/eslint.git"); + assert_that(&remote.path).contains("LICENSE"); } _ => { panic!("wrong ifchange type"); } }; } + +#[test] +fn clone_cache_remote_repo() { + type PartialConf = ::Partial; + let mut config = Conf::from_partial(PartialConf::default_values()).unwrap(); + + let run: Run = Run { + paths: HashSet::new(), + config, + is_upstream: false, + config_path: "fake/config/path".to_string(), + }; + + let remote = RemoteLocation { + repo: "git@github.com:eslint/eslint.git".to_string(), + path: "LICENSE".to_string(), + lock_hash: "".to_string(), + }; + + let block = IctcBlock { + path: PathBuf::from("tests/if_change_then_change/basic_ictc_remote.file"), + begin: Some(6), + end: Some(10), + ifchange: Some(IfChange::RemoteFile(remote.clone())), + thenchange: Some(ThenChange::RepoFile(PathBuf::from("foo.bar"))), + }; + + let mut ictc = Ictc::new(&run, "no-upstream"); + ictc.build_or_get_remote_repo(&remote, &block); + + // let result: Result, anyhow::Error> = find_ictc_blocks(&PathBuf::from( + // "tests/if_change_then_change/basic_ictc_remote.file", + // )); + // assert!(result.is_ok()); + + // let list = result.unwrap(); + // assert!(list.len() == 1, "should find 1 ictc block"); + + // let first = &list[0]; + // assert_eq!(first.begin, Some(6)); + // assert_eq!(first.end, Some(10)); + // match &first.ifchange { + // Some(IfChange::RemoteFile(remote)) => { + // assert_that(&remote.repo).contains("github.com:eslint/eslint.git"); + // assert_that(&remote.path).contains("LICENSE"); + // } + // _ => { + // panic!("wrong ifchange type"); + // } + // }; +} From 6699fa15de47ac5050d30bbc413bc2601d342c51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 18 Sep 2024 20:48:26 +0000 Subject: [PATCH 26/47] --- src/git.rs | 45 ++++++++++++++++--- src/rules/if_change_then_change.rs | 70 ++++++++++++++++++++--------- tests/if_change_then_change_test.rs | 4 +- 3 files changed, 92 insertions(+), 27 deletions(-) diff --git a/src/git.rs b/src/git.rs index c882813..63651ad 100644 --- a/src/git.rs +++ b/src/git.rs @@ -2,6 +2,7 @@ use git2::{AttrCheckFlags, AttrValue, Delta, DiffOptions, Repository}; use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::process::Command; +use std::process::Output as ProcessOutput; #[derive(Debug, Clone)] pub struct Hunk { @@ -30,6 +31,22 @@ pub struct FileChanges { pub paths: HashMap, } +pub struct Output { + pub status: std::process::ExitStatus, + pub stdout: String, + pub stderr: String, +} + +impl Output { + pub fn new(po: ProcessOutput) -> Self { + Self { + status: po.status, + stdout: String::from_utf8_lossy(&po.stdout).to_string(), + stderr: String::from_utf8_lossy(&po.stderr).to_string(), + } + } +} + fn is_lfs(repo: &Repository, path: &Path) -> bool { // "filter" is the primary LFS attribute, see gitattributes(5) // FILE_THEN_INDEX checks working tree then index; mimics git itself @@ -158,7 +175,7 @@ pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Resul Ok(ret) } -pub fn clone(repo_url: &str, destination: &str) -> Result<(), String> { +pub fn clone(repo_url: &str, destination: &str) -> Output { let output = Command::new("git") .args(&[ "clone", @@ -172,9 +189,25 @@ pub fn clone(repo_url: &str, destination: &str) -> Result<(), String> { .output() .expect("Failed to execute git command"); - if output.status.success() { - Ok(()) - } else { - Err(String::from_utf8_lossy(&output.stderr).to_string()) - } + Output::new(output) +} + +pub fn status(dir: &str) -> Output { + let output = Command::new("git") + .args(&["status", "--porcelain"]) + .current_dir(dir) + .output() + .expect("Failed to execute git command"); + + Output::new(output) +} + +pub fn dir_inside_git_repo(dir: &str) -> bool { + let output = Command::new("git") + .args(&["rev-parse", "--is-inside-work-tree"]) + .current_dir(dir) + .output() + .expect("Failed to execute git command"); + + output.status.success() } diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index 7a893c3..842084b 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -45,9 +45,26 @@ impl RemoteLocation { } } + fn extract_repo_name(repo_url: &str) -> Option { + if repo_url.contains("github.com") { + let re = Regex::new(r"^git@github\.com:[\w\.-]+/(?P[\w\.-]+)\.git$").unwrap(); + if let Some(captures) = re.captures(repo_url) { + return Some(captures["name"].to_string()); + } + } + None + } + + pub fn repo_dir(&self) -> String { + if let Some(repo_name) = Self::extract_repo_name(&self.repo) { + return format!("{}-{}", repo_name, &self.repo_hash()); + } + self.repo_hash() + } + pub fn repo_hash(&self) -> String { let mut hasher = Sha256::new(); - hasher.update(self.repo.to_string()); + hasher.update(repo.to_string()); let result = hasher.finalize(); let hash_string = format!("{:x}", result); let hash_string = &hash_string[..32]; // Get the first 32 characters @@ -205,26 +222,39 @@ impl<'a> Ictc<'a> { remote: &RemoteLocation, block: &IctcBlock, ) -> Result { - let current_dir = env::current_dir().expect("Failed to get current directory"); - let repo_dir = current_dir.join(remote.repo_hash()); - - git::clone(remote.repo.as_str(), repo_dir.to_str().unwrap()) - .map_err(|e| { - block_diagnostic( - block, - diagnostic::Severity::Warning, - "if-change-clone-failed", - format!("Failed to clone remote repo at {}: {}", remote.repo, e).as_str(), + let current_dir: PathBuf = env::current_dir().expect("Failed to get current directory"); + let repo_path = current_dir.join(remote.repo_hash()); + + let repo_dir = repo_path.to_str().unwrap(); + + // Check if repo_dir exists + if repo_path.exists() { + if !git::dir_inside_git_repo(repo_dir) { + // must delete repo and try again + std::fs::remove_dir_all(repo_dir) + .expect("Failed to remove repository and its contents"); + } else { + return Ok(repo_path); + } + } + + let result = git::clone(remote.repo.as_str(), repo_dir); + if result.status.success() { + return Ok(repo_path); + } + + Err({ + block_diagnostic( + block, + diagnostic::Severity::Warning, + "if-change-clone-failed", + format!( + "Failed to clone remote repo at {}: {}", + remote.repo, result.stderr ) - }) - .unwrap_or_default(); - - Err(block_diagnostic( - block, - diagnostic::Severity::Warning, - "if-change-cannot-reach-remote", - format!("IfChange cannot access remote repo at {}", remote.repo).as_str(), - )) + .as_str(), + ) + }) } fn ifchange_remote(&mut self, remote: &RemoteLocation, block: &IctcBlock) -> bool { diff --git a/tests/if_change_then_change_test.rs b/tests/if_change_then_change_test.rs index a598bc0..389e773 100644 --- a/tests/if_change_then_change_test.rs +++ b/tests/if_change_then_change_test.rs @@ -447,7 +447,9 @@ fn clone_cache_remote_repo() { }; let mut ictc = Ictc::new(&run, "no-upstream"); - ictc.build_or_get_remote_repo(&remote, &block); + let result = ictc.build_or_get_remote_repo(&remote, &block); + + assert!(result.is_ok(), "clone on remote repo failed"); // let result: Result, anyhow::Error> = find_ictc_blocks(&PathBuf::from( // "tests/if_change_then_change/basic_ictc_remote.file", From 187ce7aa5f5d4db06958b27820b9b4ed76bdde87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 18 Sep 2024 20:49:05 +0000 Subject: [PATCH 27/47] --- src/rules/if_change_then_change.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index 842084b..c7dd52f 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -64,7 +64,7 @@ impl RemoteLocation { pub fn repo_hash(&self) -> String { let mut hasher = Sha256::new(); - hasher.update(repo.to_string()); + hasher.update(self.repo.to_string()); let result = hasher.finalize(); let hash_string = format!("{:x}", result); let hash_string = &hash_string[..32]; // Get the first 32 characters From 97d052493ba514cf4d83b87762ffcd5f6c6da30a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 18 Sep 2024 23:57:49 +0000 Subject: [PATCH 28/47] --- Cargo.lock | 138 ++++++++++++++++++++++++++++ Cargo.toml | 1 + src/git.rs | 48 +++++++++- src/main.rs | 2 +- src/rules/if_change_then_change.rs | 86 +++++++++++++---- src/rules/never_edit.rs | 4 +- src/rules/pls_no_land.rs | 2 +- src/run.rs | 8 +- tests/if_change_then_change_test.rs | 8 +- 9 files changed, 265 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ee408b..b7e8a54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,6 +21,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.15" @@ -135,6 +150,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "cc" version = "1.1.15" @@ -152,6 +173,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + [[package]] name = "clap" version = "4.5.16" @@ -232,6 +267,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cpufeatures" version = "0.2.13" @@ -532,6 +573,29 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -579,6 +643,15 @@ dependencies = [ "libc", ] +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "json5" version = "0.4.1" @@ -1223,6 +1296,7 @@ version = "0.0.0" dependencies = [ "anyhow", "assert_cmd", + "chrono", "clap", "confique", "content_inspector", @@ -1338,6 +1412,61 @@ dependencies = [ "libc", ] +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.76", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.76", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + [[package]] name = "winapi" version = "0.3.9" @@ -1369,6 +1498,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index cf700c9..f14ddd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ glob = "0.3.1" glob-match = "0.2.1" url = "2.5.2" sha2 = "0.10.8" +chrono = "0.4.38" [dev-dependencies] assert_cmd = "2.0" diff --git a/src/git.rs b/src/git.rs index 63651ad..9bc474a 100644 --- a/src/git.rs +++ b/src/git.rs @@ -1,3 +1,4 @@ +use chrono::{DateTime, FixedOffset}; use git2::{AttrCheckFlags, AttrValue, Delta, DiffOptions, Repository}; use std::collections::HashMap; use std::path::{Path, PathBuf}; @@ -37,6 +38,11 @@ pub struct Output { pub stderr: String, } +pub struct Commit { + pub hash: String, + pub date: DateTime, +} + impl Output { pub fn new(po: ProcessOutput) -> Self { Self { @@ -175,16 +181,15 @@ pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Resul Ok(ret) } -pub fn clone(repo_url: &str, destination: &str) -> Output { +pub fn clone(repo_url: &str, destination: &PathBuf) -> Output { let output = Command::new("git") .args(&[ "clone", "--no-checkout", - "--depth=1", "--bare", "--filter=blob:none", repo_url, - destination, + destination.to_str().unwrap(), ]) .output() .expect("Failed to execute git command"); @@ -192,7 +197,7 @@ pub fn clone(repo_url: &str, destination: &str) -> Output { Output::new(output) } -pub fn status(dir: &str) -> Output { +pub fn status(dir: &PathBuf) -> Output { let output = Command::new("git") .args(&["status", "--porcelain"]) .current_dir(dir) @@ -202,7 +207,7 @@ pub fn status(dir: &str) -> Output { Output::new(output) } -pub fn dir_inside_git_repo(dir: &str) -> bool { +pub fn dir_inside_git_repo(dir: &PathBuf) -> bool { let output = Command::new("git") .args(&["rev-parse", "--is-inside-work-tree"]) .current_dir(dir) @@ -211,3 +216,36 @@ pub fn dir_inside_git_repo(dir: &str) -> bool { output.status.success() } + +pub fn last_commit(dir: &PathBuf, file: &str) -> Result { + let result = Command::new("git") + .args(&[ + "--no-pager", + "log", + "-1", + "--pretty=format:%H%n%ci", + "--", + file, + ]) + .current_dir(dir) + .output() + .expect("Failed to execute git command"); + + let output = Output::new(result); + + if output.status.success() { + if output.stdout.is_empty() { + return Err("No file history found".to_string()); + } else { + let mut lines: std::str::Lines<'_> = output.stdout.lines(); + let hash = lines.next().ok_or("Missing hash").unwrap(); + let date_str = lines.next().ok_or("Missing date").unwrap(); + + return Ok(Commit { + hash: hash.to_string(), + date: DateTime::parse_from_str(date_str, "%Y-%m-%d %H:%M:%S %z").unwrap(), + }); + } + } + Err(output.stderr) +} diff --git a/src/main.rs b/src/main.rs index 6ce9d8f..df7326a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -160,7 +160,7 @@ fn run() -> anyhow::Result<()> { paths: cli.files.into_iter().map(PathBuf::from).collect(), config, config_path: toolbox_toml, - is_upstream: cli.cache_dir.ends_with("-upstream"), + cache_dir: cli.cache_dir.clone(), }; let (pls_no_land_result, ictc_result): (Result<_, _>, Result<_, _>) = rayon::join( diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index c7dd52f..d8e69f8 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -55,14 +55,7 @@ impl RemoteLocation { None } - pub fn repo_dir(&self) -> String { - if let Some(repo_name) = Self::extract_repo_name(&self.repo) { - return format!("{}-{}", repo_name, &self.repo_hash()); - } - self.repo_hash() - } - - pub fn repo_hash(&self) -> String { + fn repo_hash(&self) -> String { let mut hasher = Sha256::new(); hasher.update(self.repo.to_string()); let result = hasher.finalize(); @@ -70,6 +63,26 @@ impl RemoteLocation { let hash_string = &hash_string[..32]; // Get the first 32 characters return hash_string.to_string(); } + + pub fn repo_dir_name(&self) -> String { + if let Some(repo_name) = Self::extract_repo_name(&self.repo) { + return format!("{}-{}", repo_name, &self.repo_hash()); + } + self.repo_hash() + } + + pub fn local_dir(&self, run: &Run) -> PathBuf { + let mut cache_dir = PathBuf::from(run.cache_dir.clone()); + + if !cache_dir.exists() { + // put the cache in the temp directory + cache_dir = env::temp_dir(); + if !cache_dir.exists() { + cache_dir = env::current_dir().expect("Failed to get current directory"); + } + } + cache_dir.join(self.repo_dir_name()) + } } #[derive(Debug)] @@ -222,23 +235,20 @@ impl<'a> Ictc<'a> { remote: &RemoteLocation, block: &IctcBlock, ) -> Result { - let current_dir: PathBuf = env::current_dir().expect("Failed to get current directory"); - let repo_path = current_dir.join(remote.repo_hash()); - - let repo_dir = repo_path.to_str().unwrap(); + let repo_path = remote.local_dir(&self.run); // Check if repo_dir exists if repo_path.exists() { - if !git::dir_inside_git_repo(repo_dir) { + if !git::dir_inside_git_repo(&repo_path) { // must delete repo and try again - std::fs::remove_dir_all(repo_dir) + std::fs::remove_dir_all(&repo_path) .expect("Failed to remove repository and its contents"); } else { return Ok(repo_path); } } - let result = git::clone(remote.repo.as_str(), repo_dir); + let result = git::clone(remote.repo.as_str(), &repo_path); if result.status.success() { return Ok(repo_path); } @@ -257,14 +267,54 @@ impl<'a> Ictc<'a> { }) } - fn ifchange_remote(&mut self, remote: &RemoteLocation, block: &IctcBlock) -> bool { + pub fn ifchange_remote(&mut self, remote: &RemoteLocation, block: &IctcBlock) -> bool { // get path to clone of remote repo. match self.build_or_get_remote_repo(remote, block) { Ok(path) => { println!("repo is cloned shallow at {:?}", path); - true + // now check if the remote file has changed since the marker + let lc = git::last_commit(&remote.local_dir(&self.run), &remote.path); + match lc { + Ok(commit) => { + println!("last commit: {}", commit.hash); + + if remote.lock_hash.is_empty() { + // No lock hash was provided - recommend a diagnostic fix that includes the desired hash + self.diagnostics.push(block_diagnostic( + block, + diagnostic::Severity::Error, + "if-change-update-lock-hash", + format!("Lock hash for IfChange needed; should be {}", commit.hash) + .as_str(), + )); + return false; + } + // If the lock hash matches the last commit hash - then nothing to do + if commit.hash == remote.lock_hash { + // nothing changed - all good + return false; + } + true + } + Err(e) => { + self.diagnostics.push(block_diagnostic( + block, + diagnostic::Severity::Error, + "if-change-git-error", + format!( + "Failed to get last commit of remote file {}: {}", + remote.path, e + ) + .as_str(), + )); + false + } + } + } + Err(diag) => { + self.diagnostics.push(diag); + false } - Err(_e) => false, } } diff --git a/src/rules/never_edit.rs b/src/rules/never_edit.rs index 6e96aa8..28aa7ec 100644 --- a/src/rules/never_edit.rs +++ b/src/rules/never_edit.rs @@ -30,7 +30,7 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result anyhow::Result anyhow::Result, pub config: Conf, - pub is_upstream: bool, pub config_path: String, + pub cache_dir: String, +} + +impl Run { + pub fn is_upstream(&self) -> bool { + self.cache_dir.ends_with("-upstream") + } } diff --git a/tests/if_change_then_change_test.rs b/tests/if_change_then_change_test.rs index 389e773..9ba91ed 100644 --- a/tests/if_change_then_change_test.rs +++ b/tests/if_change_then_change_test.rs @@ -428,7 +428,7 @@ fn clone_cache_remote_repo() { let run: Run = Run { paths: HashSet::new(), config, - is_upstream: false, + cache_dir: "".to_string(), config_path: "fake/config/path".to_string(), }; @@ -443,13 +443,13 @@ fn clone_cache_remote_repo() { begin: Some(6), end: Some(10), ifchange: Some(IfChange::RemoteFile(remote.clone())), - thenchange: Some(ThenChange::RepoFile(PathBuf::from("foo.bar"))), + thenchange: Some(ThenChange::RepoFile(PathBuf::from("f2oo.bar"))), }; let mut ictc = Ictc::new(&run, "no-upstream"); - let result = ictc.build_or_get_remote_repo(&remote, &block); + let result = ictc.ifchange_remote(&remote, &block); - assert!(result.is_ok(), "clone on remote repo failed"); + assert!(result, "clone on remote repo failed"); // let result: Result, anyhow::Error> = find_ictc_blocks(&PathBuf::from( // "tests/if_change_then_change/basic_ictc_remote.file", From 9e274d57777950712468b645ad2f24749bbb37d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 20 Sep 2024 00:07:35 +0000 Subject: [PATCH 29/47] --- .config/toolbox.toml | 2 +- .trunk/trunk.yaml | 2 +- Cargo.lock | 247 +++++++++++++++++++++++++++- Cargo.toml | 3 +- log4rs.yaml | 21 +++ logs/toolbox.log | 0 src/diagnostic.rs | 10 +- src/main.rs | 13 +- src/rules/if_change_then_change.rs | 197 ++++++++++++++++------ src/rules/never_edit.rs | 6 + src/rules/pls_no_land.rs | 2 + tests/if_change_then_change_test.rs | 114 ++++++++++--- 12 files changed, 535 insertions(+), 82 deletions(-) create mode 100644 log4rs.yaml create mode 100644 logs/toolbox.log diff --git a/.config/toolbox.toml b/.config/toolbox.toml index b4def01..239e483 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -1,7 +1,7 @@ # Configuration for trunk toolbox. Generate default by calling 'trunk-toolbox genconfig' [ifchange] -enabled = false +enabled = true [donotland] enabled = false diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 3d92e7d..8a430f9 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -39,7 +39,7 @@ lint: run: trunk-toolbox --version environment: - name: PATH - list: ["${linter}"] + list: ["${linter}", "${env.PATH}"] ignore: - linters: [trunk-toolbox] paths: diff --git a/Cargo.lock b/Cargo.lock index b7e8a54..3e1b11f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,6 +91,12 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "assert_cmd" version = "2.0.16" @@ -156,6 +162,12 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cc" version = "1.1.15" @@ -352,6 +364,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_builder" version = "0.12.0" @@ -383,6 +406,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "destructure_traitobject" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7" + [[package]] name = "difflib" version = "0.4.0" @@ -506,6 +535,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "git2" version = "0.19.0" @@ -705,11 +745,58 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +dependencies = [ + "serde", +] + +[[package]] +name = "log-mdc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" + +[[package]] +name = "log4rs" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0816135ae15bd0391cf284eab37e6e3ee0a6ee63d2ceeb659862bd8d0a984ca6" +dependencies = [ + "anyhow", + "arc-swap", + "chrono", + "derivative", + "fnv", + "humantime", + "libc", + "log", + "log-mdc", + "once_cell", + "parking_lot", + "rand 0.8.5", + "serde", + "serde-value", + "serde_json", + "serde_yaml", + "thiserror", + "thread-id", + "typemap-ors", + "winapi", +] [[package]] name = "memchr" @@ -745,7 +832,7 @@ checksum = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" dependencies = [ "num-integer", "num-traits", - "rand", + "rand 0.4.6", "rustc-serialize", ] @@ -806,6 +893,38 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -863,6 +982,15 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "predicates" version = "3.1.2" @@ -943,6 +1071,27 @@ dependencies = [ "winapi", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_core" version = "0.3.1" @@ -958,6 +1107,15 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rayon" version = "1.10.0" @@ -987,6 +1145,15 @@ dependencies = [ "rand_core 0.3.1", ] +[[package]] +name = "redox_syscall" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.10.6" @@ -1074,6 +1241,12 @@ dependencies = [ "uriparse", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.209" @@ -1103,6 +1276,16 @@ dependencies = [ "thiserror", ] +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.209" @@ -1156,6 +1339,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + [[package]] name = "spectral" version = "0.6.0" @@ -1266,6 +1455,16 @@ dependencies = [ "syn 2.0.76", ] +[[package]] +name = "thread-id" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe8f25bbdd100db7e1d34acf7fd2dc59c4bf8f7483f505eaa7d4f12f76cc0ea" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -1307,6 +1506,7 @@ dependencies = [ "glob-match", "lazy_static", "log", + "log4rs", "predicates", "rayon", "regex", @@ -1319,6 +1519,15 @@ dependencies = [ "url", ] +[[package]] +name = "typemap-ors" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a68c24b707f02dd18f1e4ccceb9d49f2058c2fb86384ef9972592904d7a28867" +dependencies = [ + "unsafe-any-ors", +] + [[package]] name = "typenum" version = "1.17.0" @@ -1358,6 +1567,15 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +[[package]] +name = "unsafe-any-ors" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a303d30665362d9680d7d91d78b23f5f899504d4f08b3c4cf08d055d87c0ad" +dependencies = [ + "destructure_traitobject", +] + [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -1412,6 +1630,12 @@ dependencies = [ "libc", ] +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.93" @@ -1588,3 +1812,24 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.76", +] diff --git a/Cargo.toml b/Cargo.toml index f14ddd6..c456376 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ clap = { version = "4.0.8", features = ["derive"] } env_logger = "0.9.1" git2 = { version = "0.19", default-features = false } lazy_static = "1.4.0" -log = "0.4.17" +log = "0.4.22" regex = "1.10.6" serde = { version = "1.0.209", features = ["derive"] } serde_json = "1.0.85" @@ -32,6 +32,7 @@ glob-match = "0.2.1" url = "2.5.2" sha2 = "0.10.8" chrono = "0.4.38" +log4rs = "1.3.0" [dev-dependencies] assert_cmd = "2.0" diff --git a/log4rs.yaml b/log4rs.yaml new file mode 100644 index 0000000..287c0f8 --- /dev/null +++ b/log4rs.yaml @@ -0,0 +1,21 @@ +appenders: + stdout: + kind: console + + # Appender for the step strategy + file: + kind: file + path: logs/toolbox.log + encoder: + pattern: "{d(%Y-%m-%d %H:%M:%S)} | {({l}):5.5} | {f}:{L} — {m}{n}" + +root: + level: debug + appenders: + - stdout + +loggers: + step: + level: trace + appenders: + - file diff --git a/logs/toolbox.log b/logs/toolbox.log new file mode 100644 index 0000000..e69de29 diff --git a/src/diagnostic.rs b/src/diagnostic.rs index 3fd2295..99c9b79 100644 --- a/src/diagnostic.rs +++ b/src/diagnostic.rs @@ -20,18 +20,23 @@ impl fmt::Display for Severity { } } -#[derive(Clone, Serialize)] +#[derive(Debug, Clone, Serialize)] pub struct Position { pub line: u64, pub character: u64, } -#[derive(Clone, Serialize)] +#[derive(Debug, Clone, Serialize)] pub struct Range { pub start: Position, pub end: Position, } +#[derive(Clone, Serialize)] +pub struct Replacement { + pub deleted_region: Range, + pub inserted_content: String, +} #[derive(Clone, Serialize)] pub struct Diagnostic { pub path: String, @@ -39,6 +44,7 @@ pub struct Diagnostic { pub severity: Severity, pub code: String, pub message: String, + pub replacements: Option>, } #[derive(Serialize, Default)] diff --git a/src/main.rs b/src/main.rs index df7326a..ca99b42 100644 --- a/src/main.rs +++ b/src/main.rs @@ -201,7 +201,18 @@ fn run() -> anyhow::Result<()> { } fn main() { - env_logger::init(); + match log4rs::init_file("log4rs.yaml", Default::default()) { + Ok(_) => { + // Initialization succeeded + println!("Logging initialized successfully."); + } + Err(e) => { + // Initialization failed + eprintln!("Failed to initialize logging: {}", e); + // error!("Failed to initialize logging: {}", e); + // Handle the error, e.g., fallback to a default logger or exit + } + } match run() { Ok(_) => (), diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index d8e69f8..ac7e19b 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -8,24 +8,41 @@ use std::env; use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; -use url::Url; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use regex::Regex; -use crate::diagnostic; +use crate::diagnostic::{Diagnostic, Position, Range, Replacement, Severity}; use crate::git; +#[derive(Debug, Clone)] +pub struct TextBlock { + pub location: Range, + pub text: String, +} + #[derive(Debug, Clone)] pub struct RemoteLocation { pub repo: String, pub path: String, pub lock_hash: String, + // content and location specifying this remote location in the original file + pub block: TextBlock, } impl RemoteLocation { - pub fn new(entry: &str) -> Self { - let parts: Vec<&str> = entry.split_whitespace().collect(); + pub fn new(line: &str, block: &IctcBlock) -> Self { + let capture = RE_BEGIN.captures(line).unwrap(); + + // get the content of the second capture group which must be a remote file + let rule = capture + .get(2) + .with_context(|| "expected at least 3 captures") + .unwrap() + .as_str() + .trim(); + + let parts: Vec<&str> = rule.split_whitespace().collect(); if parts.len() < 2 { panic!("Entry must contain at least two parts separated by space"); } @@ -38,10 +55,28 @@ impl RemoteLocation { String::new() }; + // Calculate where in the string 'line' the string 'rule' appears + let rule_position = line.find(rule).expect("Rule not found in line") as u64; + + let block = TextBlock { + location: Range { + start: Position { + line: block.begin.unwrap(), + character: rule_position, + }, + end: Position { + line: block.begin.unwrap(), + character: rule_position + rule.len() as u64, + }, + }, + text: rule.to_string(), + }; + Self { repo: parts[0].to_string(), path, lock_hash, + block, } } @@ -83,6 +118,41 @@ impl RemoteLocation { } cache_dir.join(self.repo_dir_name()) } + + pub fn get_replacement_for_hash(&self, new_hash: &str) -> Replacement { + if self.lock_hash.is_empty() { + // nothing to delete - just an insertion + // find insertion point which is at the end of the file name + Replacement { + deleted_region: Range { + start: Position { + line: self.block.location.start.line, + character: self.block.location.end.character, + }, + end: Position { + line: self.block.location.start.line, + character: self.block.location.end.character, + }, + }, + inserted_content: format!("#{}", new_hash), + } + } else { + // find the location of the original hash and replace it with the new hash + Replacement { + deleted_region: Range { + start: Position { + line: self.block.location.start.line, + character: self.block.location.end.character - self.lock_hash.len() as u64, + }, + end: Position { + line: self.block.location.start.line, + character: self.block.location.end.character, + }, + }, + inserted_content: new_hash.to_string(), + } + } + } } #[derive(Debug)] @@ -109,13 +179,13 @@ pub struct IctcBlock { } impl IctcBlock { - fn get_range(&self) -> diagnostic::Range { - diagnostic::Range { - start: diagnostic::Position { + fn get_range(&self) -> Range { + Range { + start: Position { line: self.begin.unwrap(), character: 0, }, - end: diagnostic::Position { + end: Position { line: self.end.unwrap(), character: 0, }, @@ -131,7 +201,7 @@ lazy_static::lazy_static! { pub struct Ictc<'a> { run: &'a Run, upstream: String, - diagnostics: Vec, + pub diagnostics: Vec, } impl<'a> Ictc<'a> { @@ -143,7 +213,7 @@ impl<'a> Ictc<'a> { } } - pub fn run(&mut self) -> anyhow::Result> { + pub fn run(&mut self) -> anyhow::Result> { let config = &self.run.config.ifchange; if !config.enabled { @@ -225,7 +295,7 @@ impl<'a> Ictc<'a> { } } - debug!("ICTC blocks are:\n{:?}", blocks); + log::trace!("ICTC blocks are:\n{:?}", blocks); Ok(self.diagnostics.clone()) } @@ -234,7 +304,7 @@ impl<'a> Ictc<'a> { &mut self, remote: &RemoteLocation, block: &IctcBlock, - ) -> Result { + ) -> Result { let repo_path = remote.local_dir(&self.run); // Check if repo_dir exists @@ -248,6 +318,8 @@ impl<'a> Ictc<'a> { } } + log::debug!("cloning {:?} at {:?}", remote.repo.as_str(), repo_path); + let result = git::clone(remote.repo.as_str(), &repo_path); if result.status.success() { return Ok(repo_path); @@ -256,7 +328,7 @@ impl<'a> Ictc<'a> { Err({ block_diagnostic( block, - diagnostic::Severity::Warning, + Severity::Warning, "if-change-clone-failed", format!( "Failed to clone remote repo at {}: {}", @@ -276,30 +348,55 @@ impl<'a> Ictc<'a> { let lc = git::last_commit(&remote.local_dir(&self.run), &remote.path); match lc { Ok(commit) => { - println!("last commit: {}", commit.hash); - if remote.lock_hash.is_empty() { // No lock hash was provided - recommend a diagnostic fix that includes the desired hash - self.diagnostics.push(block_diagnostic( - block, - diagnostic::Severity::Error, - "if-change-update-lock-hash", - format!("Lock hash for IfChange needed; should be {}", commit.hash) - .as_str(), - )); + let message = + format!("Hash for IfChange needed; should be {}", commit.hash); + let diagnostic = Diagnostic { + path: block.path.to_str().unwrap().to_string(), + range: Some(block.get_range()), + severity: Severity::Warning, + code: "if-change-update-lock-hash".to_string(), + message: message.clone(), + replacements: Some(vec![ + remote.get_replacement_for_hash(&commit.hash) + ]), + }; + + self.diagnostics.push(diagnostic); return false; } // If the lock hash matches the last commit hash - then nothing to do if commit.hash == remote.lock_hash { // nothing changed - all good return false; + } else { + // commit hash has changed - must confirm we changed the code inside + // and also add an autofix diag to move the hash lock marker + + let message = format!( + "Remote file changed - hash should be updated to {}", + commit.hash + ); + let diagnostic = Diagnostic { + path: block.path.to_str().unwrap().to_string(), + range: Some(block.get_range()), + severity: Severity::Warning, + code: "if-change-remote-updated-new-hash".to_string(), + message: message.clone(), + replacements: Some(vec![ + remote.get_replacement_for_hash(&commit.hash) + ]), + }; + + self.diagnostics.push(diagnostic); + return true; } - true } Err(e) => { self.diagnostics.push(block_diagnostic( block, - diagnostic::Severity::Error, + Severity::Error, "if-change-git-error", format!( "Failed to get last commit of remote file {}: {}", @@ -327,42 +424,45 @@ impl<'a> Ictc<'a> { ThenChange::RepoFile(local_file) => { // Check if the repo file exists - if it was deleted this is a warning if !Path::new(local_file).exists() { - self.diagnostics.push(diagnostic::Diagnostic { + self.diagnostics.push(Diagnostic { path: block.path.to_str().unwrap().to_string(), range: Some(block.get_range()), - severity: diagnostic::Severity::Warning, + severity: Severity::Warning, code: "if-change-file-does-not-exist".to_string(), message: format!("ThenChange {} does not exist", local_file.display(),), + replacements: None, }); } // If target file was not changed raise issue if blocks_by_path.get(&local_file).is_none() { - self.diagnostics.push(diagnostic::Diagnostic { + self.diagnostics.push(Diagnostic { path: block.path.to_str().unwrap().to_string(), range: Some(block.get_range()), - severity: diagnostic::Severity::Error, + severity: Severity::Error, code: "if-change-then-change-this".to_string(), message: format!( "Expected change in {} because {} was modified", local_file.display(), block.path.display(), ), + replacements: None, }); } } ThenChange::MissingIf => { - self.diagnostics.push(diagnostic::Diagnostic { + self.diagnostics.push(Diagnostic { path: block.path.to_str().unwrap().to_string(), range: Some(block.get_range()), - severity: diagnostic::Severity::Warning, + severity: Severity::Warning, code: "if-change-mismatched".to_string(), message: "Expected preceding IfChange tag".to_string(), + replacements: None, }); } ThenChange::MissingThen => { self.diagnostics.push(block_diagnostic( block, - diagnostic::Severity::Warning, + Severity::Warning, "if-change-mismatched", "Expected matching ThenChange tag", )); @@ -372,18 +472,14 @@ impl<'a> Ictc<'a> { } } -pub fn block_diagnostic( - block: &IctcBlock, - sev: diagnostic::Severity, - code: &str, - msg: &str, -) -> diagnostic::Diagnostic { - diagnostic::Diagnostic { +pub fn block_diagnostic(block: &IctcBlock, sev: Severity, code: &str, msg: &str) -> Diagnostic { + Diagnostic { path: block.path.to_str().unwrap().to_string(), range: Some(block.get_range()), severity: sev, code: code.to_string(), message: msg.to_string(), + replacements: None, } } @@ -417,23 +513,24 @@ pub fn find_ictc_blocks(path: &PathBuf) -> anyhow::Result> { .as_str() .trim(); - let ifchange = if source_trigger.is_empty() { + let mut ib = IctcBlock { + path: path.clone(), + begin: line_no, + end: None, + ifchange: None, + thenchange: None, + }; + + ib.ifchange = if source_trigger.is_empty() { None } else if source_trigger.contains(" ") { // If the source trigger has a space in the middle then its in the format of a remote repo file - Some(IfChange::RemoteFile(RemoteLocation::new(source_trigger))) + Some(IfChange::RemoteFile(RemoteLocation::new(line, &ib))) } else { // Looks like a file path but it doesn't exist Some(IfChange::RepoFile(PathBuf::from(source_trigger))) }; - - block = Some(IctcBlock { - path: path.clone(), - begin: line_no, - end: None, - ifchange, - thenchange: None, - }); + block = Some(ib); } else if let Some(end_capture) = RE_END.captures(line) { if let Some(mut block_value) = block { block_value.end = line_no; @@ -479,3 +576,7 @@ fn lines_view(reader: R) -> anyhow::Result { } Ok(ret) } + +// IfChange git@github.com:eslint/eslint.git LICENSE +// Content inside here +// ThenChange diff --git a/src/rules/never_edit.rs b/src/rules/never_edit.rs index 28aa7ec..ef24274 100644 --- a/src/rules/never_edit.rs +++ b/src/rules/never_edit.rs @@ -37,6 +37,7 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result anyhow::Result anyhow::Result anyhow::Result { @@ -120,6 +124,7 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result {} @@ -133,6 +138,7 @@ pub fn never_edit(run: &Run, upstream: &str) -> anyhow::Result anyhow::Result anyhow::Result anyhow::Result<()> { @@ -421,9 +422,9 @@ fn find_repo_ictc_blocks() { } #[test] -fn clone_cache_remote_repo() { +fn remote_repo_insert_hash_fix() { type PartialConf = ::Partial; - let mut config = Conf::from_partial(PartialConf::default_values()).unwrap(); + let config = Conf::from_partial(PartialConf::default_values()).unwrap(); let run: Run = Run { paths: HashSet::new(), @@ -436,6 +437,19 @@ fn clone_cache_remote_repo() { repo: "git@github.com:eslint/eslint.git".to_string(), path: "LICENSE".to_string(), lock_hash: "".to_string(), + block: TextBlock { + location: Range { + start: Position { + line: 1, + character: 1, + }, + end: Position { + line: 1, + character: 2, + }, + }, + text: "git@github.com:eslint/eslint.git LICENSE".to_string(), + }, }; let block = IctcBlock { @@ -447,28 +461,74 @@ fn clone_cache_remote_repo() { }; let mut ictc = Ictc::new(&run, "no-upstream"); - let result = ictc.ifchange_remote(&remote, &block); - - assert!(result, "clone on remote repo failed"); - - // let result: Result, anyhow::Error> = find_ictc_blocks(&PathBuf::from( - // "tests/if_change_then_change/basic_ictc_remote.file", - // )); - // assert!(result.is_ok()); - - // let list = result.unwrap(); - // assert!(list.len() == 1, "should find 1 ictc block"); - - // let first = &list[0]; - // assert_eq!(first.begin, Some(6)); - // assert_eq!(first.end, Some(10)); - // match &first.ifchange { - // Some(IfChange::RemoteFile(remote)) => { - // assert_that(&remote.repo).contains("github.com:eslint/eslint.git"); - // assert_that(&remote.path).contains("LICENSE"); - // } - // _ => { - // panic!("wrong ifchange type"); - // } - // }; + ictc.ifchange_remote(&remote, &block); + assert!(ictc.diagnostics.len() == 1, "should have 1 diagnostic"); + + let diag = ictc.diagnostics.get(0).unwrap(); + let replacements = diag + .replacements + .as_ref() + .expect("should have replacements"); + let replacement = replacements + .get(0) + .expect("should have at least one replacement"); + + assert_that(&replacement.inserted_content).starts_with("#"); +} + +#[test] +fn remote_repo_update_hash() { + type PartialConf = ::Partial; + let config = Conf::from_partial(PartialConf::default_values()).unwrap(); + + let run: Run = Run { + paths: HashSet::new(), + config, + cache_dir: "".to_string(), + config_path: "fake/config/path".to_string(), + }; + + let remote = RemoteLocation { + repo: "git@github.com:eslint/eslint.git".to_string(), + path: "LICENSE".to_string(), + lock_hash: "ABCDEFG".to_string(), + block: TextBlock { + location: Range { + start: Position { + line: 1, + character: 1, + }, + end: Position { + line: 1, + character: 47, + }, + }, + text: "git@github.com:eslint/eslint.git LICENSE#ABCDEFG".to_string(), + }, + }; + + let block = IctcBlock { + path: PathBuf::from("tests/if_change_then_change/basic_ictc_remote.file"), + begin: Some(6), + end: Some(10), + ifchange: Some(IfChange::RemoteFile(remote.clone())), + thenchange: Some(ThenChange::RepoFile(PathBuf::from("f2oo.bar"))), + }; + + let mut ictc = Ictc::new(&run, "no-upstream"); + ictc.ifchange_remote(&remote, &block); + assert!(ictc.diagnostics.len() == 1, "should have 1 diagnostic"); + + let diag = ictc.diagnostics.get(0).unwrap(); + let replacements = diag + .replacements + .as_ref() + .expect("should have replacements"); + let replacement = replacements + .get(0) + .expect("should have at least one replacement"); + + assert_that(&replacement.deleted_region.start.character).is_equal_to(40); + assert_that(&replacement.deleted_region.end.character).is_equal_to(47); + assert_that(&replacement.inserted_content.len()).is_equal_to(40); } From 8e976030453bbbbdcee47124012c774c1470c771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 20 Sep 2024 00:08:30 +0000 Subject: [PATCH 30/47] --- logs/toolbox.log | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 logs/toolbox.log diff --git a/logs/toolbox.log b/logs/toolbox.log deleted file mode 100644 index e69de29..0000000 From d5ac97bdd16f23bad4cec318f3de85d2a1a76e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 20 Sep 2024 22:53:26 +0000 Subject: [PATCH 31/47] --- logs/toolbox.log | 0 src/diagnostic.rs | 87 +++++++++++++++++++++++++++++ src/main.rs | 37 +----------- src/rules/if_change_then_change.rs | 20 ++++--- tests/if_change_then_change_test.rs | 6 ++ 5 files changed, 106 insertions(+), 44 deletions(-) create mode 100644 logs/toolbox.log diff --git a/logs/toolbox.log b/logs/toolbox.log new file mode 100644 index 0000000..e69de29 diff --git a/src/diagnostic.rs b/src/diagnostic.rs index 99c9b79..0209e02 100644 --- a/src/diagnostic.rs +++ b/src/diagnostic.rs @@ -1,4 +1,5 @@ use serde::Serialize; +use serde_sarif::sarif; use std::fmt; #[derive(Clone, Serialize)] @@ -58,3 +59,89 @@ impl Diagnostics { Ok(as_string) } } + +impl Diagnostic { + pub fn to_sarif(&self) -> sarif::Result { + let mut physical_location = sarif::PhysicalLocationBuilder::default(); + physical_location.artifact_location( + sarif::ArtifactLocationBuilder::default() + .uri(self.path.clone()) + .build() + .unwrap(), + ); + + if let Some(range) = &self.range { + physical_location.region( + sarif::RegionBuilder::default() + .start_line(range.start.line as i64 + 1) + .start_column(range.start.character as i64 + 1) + .end_line(range.end.line as i64 + 1) + .end_column(range.end.character as i64 + 1) + .build() + .unwrap(), + ); + } + + let fixes = if let Some(replacements) = &self.replacements { + let mut fixes = Vec::new(); + for replacement in replacements { + fixes.push(replacement.to_fix(self)); + } + Some(fixes) + } else { + None + }; + + sarif::ResultBuilder::default() + .level(self.severity.to_string()) + .locations([sarif::LocationBuilder::default() + .physical_location(physical_location.build().unwrap()) + .build() + .unwrap()]) + .fixes(fixes.unwrap_or_default()) + .message( + sarif::MessageBuilder::default() + .text(self.message.clone()) + .build() + .unwrap(), + ) + .rule_id(self.code.clone()) + .build() + .unwrap() + } +} + +impl Replacement { + pub fn to_fix(&self, diag: &Diagnostic) -> sarif::Fix { + sarif::FixBuilder::default() + .artifact_changes([sarif::ArtifactChangeBuilder::default() + .artifact_location( + sarif::ArtifactLocationBuilder::default() + .uri(diag.path.clone()) + .build() + .unwrap(), + ) + .replacements(vec![sarif::ReplacementBuilder::default() + .deleted_region( + sarif::RegionBuilder::default() + .start_line(self.deleted_region.start.line as i64) + .start_column(self.deleted_region.start.character as i64 + 1) + .end_line(self.deleted_region.end.line as i64) + .end_column(self.deleted_region.end.character as i64 + 1) + .build() + .unwrap(), + ) + .inserted_content( + sarif::ArtifactContentBuilder::default() + .text(self.inserted_content.clone()) + .build() + .unwrap(), + ) + .build() + .unwrap()]) + .build() + .unwrap()]) + .build() + .unwrap() + } +} diff --git a/src/main.rs b/src/main.rs index ca99b42..c5c8d75 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,42 +38,7 @@ fn generate_sarif_string( let mut results: Vec = original_results .diagnostics .iter() - .map(|d| { - let mut physical_location = sarif::PhysicalLocationBuilder::default(); - physical_location.artifact_location( - sarif::ArtifactLocationBuilder::default() - .uri(d.path.clone()) - .build() - .unwrap(), - ); - - if let Some(range) = &d.range { - physical_location.region( - sarif::RegionBuilder::default() - .start_line(range.start.line as i64 + 1) - .start_column(range.start.character as i64 + 1) - .end_line(range.end.line as i64 + 1) - .end_column(range.end.character as i64 + 1) - .build() - .unwrap(), - ); - } - sarif::ResultBuilder::default() - .level(d.severity.to_string()) - .locations([sarif::LocationBuilder::default() - .physical_location(physical_location.build().unwrap()) - .build() - .unwrap()]) - .message( - sarif::MessageBuilder::default() - .text(d.message.clone()) - .build() - .unwrap(), - ) - .rule_id(d.code.clone()) - .build() - .unwrap() - }) + .map(|d| d.to_sarif()) .collect(); let r = sarif::ResultBuilder::default() diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index ac7e19b..05fb559 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -346,12 +346,14 @@ impl<'a> Ictc<'a> { println!("repo is cloned shallow at {:?}", path); // now check if the remote file has changed since the marker let lc = git::last_commit(&remote.local_dir(&self.run), &remote.path); + match lc { Ok(commit) => { + let truncated_hash = &commit.hash[..10]; if remote.lock_hash.is_empty() { // No lock hash was provided - recommend a diagnostic fix that includes the desired hash let message = - format!("Hash for IfChange needed; should be {}", commit.hash); + format!("Hash for IfChange required; should be {}", truncated_hash); let diagnostic = Diagnostic { path: block.path.to_str().unwrap().to_string(), range: Some(block.get_range()), @@ -359,7 +361,7 @@ impl<'a> Ictc<'a> { code: "if-change-update-lock-hash".to_string(), message: message.clone(), replacements: Some(vec![ - remote.get_replacement_for_hash(&commit.hash) + remote.get_replacement_for_hash(truncated_hash) ]), }; @@ -367,17 +369,15 @@ impl<'a> Ictc<'a> { return false; } // If the lock hash matches the last commit hash - then nothing to do - if commit.hash == remote.lock_hash { + if commit.hash.starts_with(&remote.lock_hash) { // nothing changed - all good return false; } else { // commit hash has changed - must confirm we changed the code inside // and also add an autofix diag to move the hash lock marker - let message = format!( - "Remote file changed - hash should be updated to {}", - commit.hash - ); + let message = + format!("Remote file changed; new hash is {}", truncated_hash); let diagnostic = Diagnostic { path: block.path.to_str().unwrap().to_string(), range: Some(block.get_range()), @@ -385,7 +385,7 @@ impl<'a> Ictc<'a> { code: "if-change-remote-updated-new-hash".to_string(), message: message.clone(), replacements: Some(vec![ - remote.get_replacement_for_hash(&commit.hash) + remote.get_replacement_for_hash(&truncated_hash) ]), }; @@ -580,3 +580,7 @@ fn lines_view(reader: R) -> anyhow::Result { // IfChange git@github.com:eslint/eslint.git LICENSE // Content inside here // ThenChange + +// IfChange git@github.com:eslint/eslint.git LICENSE#ABCDEF +// Content inside here +// ThenChange diff --git a/tests/if_change_then_change_test.rs b/tests/if_change_then_change_test.rs index 4fb2435..c369358 100644 --- a/tests/if_change_then_change_test.rs +++ b/tests/if_change_then_change_test.rs @@ -531,4 +531,10 @@ fn remote_repo_update_hash() { assert_that(&replacement.deleted_region.start.character).is_equal_to(40); assert_that(&replacement.deleted_region.end.character).is_equal_to(47); assert_that(&replacement.inserted_content.len()).is_equal_to(40); + + let sarif = diag.to_sarif(); + assert!( + sarif.fixes.as_ref().map_or(0, |fixes| fixes.len()) == 1, + "should have 1 fix" + ); } From f950a81e9a7dd1fc634a72c2a4499d2f257dd314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 20 Sep 2024 23:19:54 +0000 Subject: [PATCH 32/47] --- logs/toolbox.log | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 logs/toolbox.log diff --git a/logs/toolbox.log b/logs/toolbox.log deleted file mode 100644 index e69de29..0000000 From 3b3c813962ef1eb04206d6d0f2218d67a065b944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Mon, 23 Sep 2024 22:07:34 +0000 Subject: [PATCH 33/47] --- .config/toolbox.toml | 6 +++--- logs/toolbox.log | 0 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 logs/toolbox.log diff --git a/.config/toolbox.toml b/.config/toolbox.toml index 239e483..fb0f57d 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -1,13 +1,13 @@ # Configuration for trunk toolbox. Generate default by calling 'trunk-toolbox genconfig' [ifchange] -enabled = true +enabled = false [donotland] -enabled = false +enabled = true [todo] -enabled = false +enabled = true [neveredit] enabled = false diff --git a/logs/toolbox.log b/logs/toolbox.log new file mode 100644 index 0000000..e69de29 From f58e1fdafeebce9d566f87c8aaef0608af9e8e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Tue, 24 Sep 2024 22:42:51 +0000 Subject: [PATCH 34/47] --- .config/toolbox.toml | 24 +++--- .gitignore | 2 + .trunk/config/toolbox.toml | 129 +++++++++++++++++++++++++++++ .trunk/trunk.yaml | 12 ++- kd | 3 + log4rs.yaml | 2 +- loop | 32 +++++++ src/config.rs | 2 + src/git.rs | 10 +-- src/main.rs | 12 ++- src/rules/if_change_then_change.rs | 23 +++-- src/rules/mod.rs | 1 + src/rules/pls_no_land.rs | 13 +++ src/run.rs | 6 ++ toolbox-latest | 6 +- 15 files changed, 237 insertions(+), 40 deletions(-) create mode 100644 .trunk/config/toolbox.toml create mode 100755 kd create mode 100755 loop diff --git a/.config/toolbox.toml b/.config/toolbox.toml index fb0f57d..84d0292 100644 --- a/.config/toolbox.toml +++ b/.config/toolbox.toml @@ -1,14 +1,10 @@ -# Configuration for trunk toolbox. Generate default by calling 'trunk-toolbox genconfig' - -[ifchange] -enabled = false - -[donotland] -enabled = true - -[todo] -enabled = true - -[neveredit] -enabled = false -paths = [] +# DwFjL +# KLP84 +# yAc2Y +# omMC1 +# EeVq5 +# mt0wO +# mUbgN +# BAXwB +# lpx6R +# 3GHhC diff --git a/.gitignore b/.gitignore index f2e972d..a0099e8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ # These are backup files generated by rustfmt **/*.rs.bk + +toolbox.log \ No newline at end of file diff --git a/.trunk/config/toolbox.toml b/.trunk/config/toolbox.toml new file mode 100644 index 0000000..1452e42 --- /dev/null +++ b/.trunk/config/toolbox.toml @@ -0,0 +1,129 @@ +# Configuration for trunk toolbox. Generate default by calling 'trunk-toolbox genconfig' + +[ifchange] +enabled = false + +[donotland] +enabled = true + +[todo] +enabled = true +sleep_for = 1000 + +[neveredit] +enabled = false +paths = [] + +# nothing here +# Ih2LF +# HNcvh +# GhbHo +# G3VuQ +# 3GSLq +# V4Vbn +# igeowh +# waKtV +# xmNcG +# jri2U +# MCrN5 +# Es8bb +# CtWae +# vD0hL +# uIcIA +# dAhJY +# UpV5q +# d510D +# 5N2mW +# yyMc6 +# UgNzZ +# Tl8le +# F3X6m +# doyGg +# YEODp +# 3aeYX +# DBpfO +# 5d6b9 +# C4tO8 +# d9kna +# 06L1E +# WiLBC +# PYeCQ +# 3Ce46 +# haeio +# 24ITN +# BIedu +# NYwIK +# QGP3e +# S5VZ5 +# BK6iu +# 0jdCV +# ajFuW +# 0hC3l +# Uw8bT +# lJ2dO +# itODb +# WjXJK +# EDdXj +# iTLQs +# Fkk5m +# jTy2F +# yT905 +# paH0c +# lnG2a +# BscVm +# M4UOi +# oktmU +# 7dJXy +# kKZV3 +# wHzpI +# D16vj +# bviZa +# pY9vU +# sR1LG +# U8X09 +# OSC80 +# JvkOa +# ey612 +# EJIXp +# kNUBw +# tgvkr +# 1YLS1 +# 8HBIf +# pUTTW +# ON9Qw +# RM66a +# z6XHy +# Xc1DF +# 9Giat +# OZ0ot +# XJe6m +# TSRNL +# 0e2Mn +# lvnx3 +# itv6h +# qU9P0 +# GH6kJ +# TKW9R +# Upvlo +# alL22 +# HuT2P +# VSG9J +# MWQfC +# DtCJ7 +# BGlku +# WTG7d +# TnNBF +# BCNaD +# 6zppq +# 5QlIb +# pNwcE +# Wjmyh +# hAJqi +# sQz83 +# uAtyp +# EgNWX +# lWt5H +# iigey +# 1MmEr +# zPRO9 +# DYEkD diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 8a430f9..71e7499 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -30,16 +30,24 @@ lint: run: ${workspace}/toolbox-latest --upstream=${upstream-ref} --cache-dir=${cachedir} --results=${tmpfile} ${target} output: sarif batch: true + cache_results: true + cache_ttl: 2000ms success_codes: [0] read_output_from: tmp_file - disable_upstream: false - direct_configs: [toolbox.toml] + # disable_upstream: false version_command: parse_regex: ${semver} run: trunk-toolbox --version + direct_configs: [toolbox.toml, log4rs.yaml] + affects_cache: + - toolbox.toml environment: - name: PATH list: ["${linter}", "${env.PATH}"] + - name: debug_path + value: "${workspace}/target/debug/trunk-toolbox" + - name: release_path + value: "${workspace}/target/release/trunk-toolbox" ignore: - linters: [trunk-toolbox] paths: diff --git a/kd b/kd new file mode 100755 index 0000000..ecbb51f --- /dev/null +++ b/kd @@ -0,0 +1,3 @@ +#!/bin/bash + +/home/eli/Github/trunk/bazel-bin/trunk/cli/cli daemon shutdown diff --git a/log4rs.yaml b/log4rs.yaml index 287c0f8..681c930 100644 --- a/log4rs.yaml +++ b/log4rs.yaml @@ -5,7 +5,7 @@ appenders: # Appender for the step strategy file: kind: file - path: logs/toolbox.log + path: toolbox.log encoder: pattern: "{d(%Y-%m-%d %H:%M:%S)} | {({l}):5.5} | {f}:{L} — {m}{n}" diff --git a/loop b/loop new file mode 100755 index 0000000..6cba6b0 --- /dev/null +++ b/loop @@ -0,0 +1,32 @@ +#!/bin/bash + +# Ensure the tester directory exists +mkdir -p tester + +# Function to generate a random 30-character filename +generate_random_filename() { + tr -dc A-Za-z0-9 >.trunk/config/toolbox.toml + +done + +echo "Completed 100 iterations successfully." diff --git a/src/config.rs b/src/config.rs index 01c78e6..7c1e2ea 100644 --- a/src/config.rs +++ b/src/config.rs @@ -40,6 +40,8 @@ pub struct PlsNotLandConf { pub struct TodoConf { #[config(default = false)] pub enabled: bool, + #[config(default = 0)] + pub sleep_for: u64, } #[derive(Config)] diff --git a/src/git.rs b/src/git.rs index 9bc474a..1ab28ca 100644 --- a/src/git.rs +++ b/src/git.rs @@ -183,13 +183,13 @@ pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Resul pub fn clone(repo_url: &str, destination: &PathBuf) -> Output { let output = Command::new("git") - .args(&[ + .args([ "clone", "--no-checkout", "--bare", "--filter=blob:none", repo_url, - destination.to_str().unwrap(), + destination.to_string_lossy().as_ref(), ]) .output() .expect("Failed to execute git command"); @@ -199,7 +199,7 @@ pub fn clone(repo_url: &str, destination: &PathBuf) -> Output { pub fn status(dir: &PathBuf) -> Output { let output = Command::new("git") - .args(&["status", "--porcelain"]) + .args(["status", "--porcelain"]) .current_dir(dir) .output() .expect("Failed to execute git command"); @@ -209,7 +209,7 @@ pub fn status(dir: &PathBuf) -> Output { pub fn dir_inside_git_repo(dir: &PathBuf) -> bool { let output = Command::new("git") - .args(&["rev-parse", "--is-inside-work-tree"]) + .args(["rev-parse", "--is-inside-work-tree"]) .current_dir(dir) .output() .expect("Failed to execute git command"); @@ -219,7 +219,7 @@ pub fn dir_inside_git_repo(dir: &PathBuf) -> bool { pub fn last_commit(dir: &PathBuf, file: &str) -> Result { let result = Command::new("git") - .args(&[ + .args([ "--no-pager", "log", "-1", diff --git a/src/main.rs b/src/main.rs index c5c8d75..51426a6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,9 @@ use horton::rules::never_edit::never_edit; use horton::rules::pls_no_land::pls_no_land; use horton::run::{Cli, OutputFormat, Run, Subcommands}; +use log::debug; use serde_sarif::sarif; +use std::env; use std::path::{Path, PathBuf}; use std::time::Instant; @@ -45,9 +47,10 @@ fn generate_sarif_string( .message( sarif::MessageBuilder::default() .text(format!( - "{:?} files processed in {:?}", + "{:?} files processed in {:?}\n{:?}", run_context.paths.len(), start_time.elapsed(), + run_context.paths )) .build() .unwrap(), @@ -166,10 +169,13 @@ fn run() -> anyhow::Result<()> { } fn main() { - match log4rs::init_file("log4rs.yaml", Default::default()) { + let current_dir = env::current_dir().expect("Failed to get current directory"); + let log_config_path = current_dir.join("log4rs.yaml"); + + match log4rs::init_file(&log_config_path, Default::default()) { Ok(_) => { // Initialization succeeded - println!("Logging initialized successfully."); + debug!("logging initialized successfullly {:?}", log_config_path); } Err(e) => { // Initialization failed diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index 05fb559..7f28d97 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -1,6 +1,5 @@ use crate::run::Run; use anyhow::Context; -use log::debug; use sha2::{Digest, Sha256}; use std::collections::{HashMap, HashSet}; @@ -92,11 +91,11 @@ impl RemoteLocation { fn repo_hash(&self) -> String { let mut hasher = Sha256::new(); - hasher.update(self.repo.to_string()); + hasher.update(&self.repo); let result = hasher.finalize(); let hash_string = format!("{:x}", result); let hash_string = &hash_string[..32]; // Get the first 32 characters - return hash_string.to_string(); + hash_string.to_string() } pub fn repo_dir_name(&self) -> String { @@ -285,12 +284,12 @@ impl<'a> Ictc<'a> { IfChange::RemoteFile(remote) => { // remote file should be in form of // {REMOTE_REPO} {REMOTE_PATH}#{LOCK_HASH} - if self.ifchange_remote(&remote, &block) { + if self.ifchange_remote(remote, block) { // if it's ok we will keep processing the rest of the rule - self.thenchange(&block, &blocks_by_path); + self.thenchange(block, &blocks_by_path); } } - _ => self.thenchange(&block, &blocks_by_path), + _ => self.thenchange(block, &blocks_by_path), } } } @@ -305,7 +304,7 @@ impl<'a> Ictc<'a> { remote: &RemoteLocation, block: &IctcBlock, ) -> Result { - let repo_path = remote.local_dir(&self.run); + let repo_path = remote.local_dir(self.run); // Check if repo_dir exists if repo_path.exists() { @@ -345,7 +344,7 @@ impl<'a> Ictc<'a> { Ok(path) => { println!("repo is cloned shallow at {:?}", path); // now check if the remote file has changed since the marker - let lc = git::last_commit(&remote.local_dir(&self.run), &remote.path); + let lc = git::last_commit(&remote.local_dir(self.run), &remote.path); match lc { Ok(commit) => { @@ -371,7 +370,7 @@ impl<'a> Ictc<'a> { // If the lock hash matches the last commit hash - then nothing to do if commit.hash.starts_with(&remote.lock_hash) { // nothing changed - all good - return false; + false } else { // commit hash has changed - must confirm we changed the code inside // and also add an autofix diag to move the hash lock marker @@ -385,12 +384,12 @@ impl<'a> Ictc<'a> { code: "if-change-remote-updated-new-hash".to_string(), message: message.clone(), replacements: Some(vec![ - remote.get_replacement_for_hash(&truncated_hash) + remote.get_replacement_for_hash(truncated_hash) ]), }; self.diagnostics.push(diagnostic); - return true; + true } } Err(e) => { @@ -523,7 +522,7 @@ pub fn find_ictc_blocks(path: &PathBuf) -> anyhow::Result> { ib.ifchange = if source_trigger.is_empty() { None - } else if source_trigger.contains(" ") { + } else if source_trigger.contains(' ') { // If the source trigger has a space in the middle then its in the format of a remote repo file Some(IfChange::RemoteFile(RemoteLocation::new(line, &ib))) } else { diff --git a/src/rules/mod.rs b/src/rules/mod.rs index 5f87d8d..a6c2f9f 100644 --- a/src/rules/mod.rs +++ b/src/rules/mod.rs @@ -1,3 +1,4 @@ +// lets change this file as well pub mod if_change_then_change; pub mod never_edit; pub mod pls_no_land; diff --git a/src/rules/pls_no_land.rs b/src/rules/pls_no_land.rs index cb1db4f..c35ec60 100644 --- a/src/rules/pls_no_land.rs +++ b/src/rules/pls_no_land.rs @@ -4,6 +4,7 @@ extern crate regex; use crate::diagnostic; use crate::run::Run; use anyhow::Context; +use log::warn; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use regex::Regex; use std::fs::File; @@ -11,6 +12,9 @@ use std::io::Read; use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; +use std::thread::sleep; +use std::time::Duration; + lazy_static::lazy_static! { static ref DNL_RE: Regex = Regex::new(r"(?i)(DO[\s_-]*NOT[\s_-]*LAND)").unwrap(); static ref TODO_RE: Regex = Regex::new(r"(?i)(TODO|FIXME)(\W+.*)?$").unwrap(); @@ -56,6 +60,15 @@ pub fn pls_no_land(run: &Run) -> anyhow::Result> { fn pls_no_land_impl(path: &PathBuf, run: &Run) -> anyhow::Result> { let config = &run.config; + if config.todo.enabled && config.todo.sleep_for > 0 { + // test code to force the todo rule to run slowly per file + warn!( + "sleeping inside pls_no_land for {:?}ms", + config.todo.sleep_for + ); + sleep(Duration::from_millis(config.todo.sleep_for)); + } + if is_binary_file(path).unwrap_or(true) { log::debug!("Ignoring binary file {}", path.display()); return Ok(vec![]); diff --git a/src/run.rs b/src/run.rs index 5f5dd05..0612df9 100644 --- a/src/run.rs +++ b/src/run.rs @@ -67,3 +67,9 @@ impl Run { self.cache_dir.ends_with("-upstream") } } + +// # hello +// $hioewh +// jgrhogweo +// ewighiowehioegioh +// efwhewo diff --git a/toolbox-latest b/toolbox-latest index fe8c080..cc8746d 100755 --- a/toolbox-latest +++ b/toolbox-latest @@ -1,8 +1,8 @@ #!/bin/bash -# Define the paths -release_path="./target/release/trunk-toolbox" -debug_path="./target/debug/trunk-toolbox" +# Define the paths. Don't override in case it's being passed in by trunk check +release_path="${release_path:-./target/release/trunk-toolbox}" +debug_path="${debug_path:-./target/debug/trunk-toolbox}" fallback_path="trunk-toolbox" # Check if the release and debug files exist From 4c1253561363086fa3b5f9a85797cf9bafa1f978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 25 Sep 2024 00:15:27 +0000 Subject: [PATCH 35/47] --- .config/toolbox.toml | 10 ---- .trunk/config/toolbox.toml | 114 +------------------------------------ .trunk/trunk.yaml | 3 +- bar.config | 1 + foo.config | 1 + log4rs.yaml | 4 +- loop | 6 +- src/main.rs | 59 ++++++++++++++----- src/rules/pls_no_land.rs | 18 +++--- src/run.rs | 6 -- 10 files changed, 64 insertions(+), 158 deletions(-) delete mode 100644 .config/toolbox.toml create mode 100644 bar.config create mode 100644 foo.config diff --git a/.config/toolbox.toml b/.config/toolbox.toml deleted file mode 100644 index 84d0292..0000000 --- a/.config/toolbox.toml +++ /dev/null @@ -1,10 +0,0 @@ -# DwFjL -# KLP84 -# yAc2Y -# omMC1 -# EeVq5 -# mt0wO -# mUbgN -# BAXwB -# lpx6R -# 3GHhC diff --git a/.trunk/config/toolbox.toml b/.trunk/config/toolbox.toml index 1452e42..1e87643 100644 --- a/.trunk/config/toolbox.toml +++ b/.trunk/config/toolbox.toml @@ -8,122 +8,10 @@ enabled = true [todo] enabled = true -sleep_for = 1000 +sleep_for = 5000 [neveredit] enabled = false paths = [] # nothing here -# Ih2LF -# HNcvh -# GhbHo -# G3VuQ -# 3GSLq -# V4Vbn -# igeowh -# waKtV -# xmNcG -# jri2U -# MCrN5 -# Es8bb -# CtWae -# vD0hL -# uIcIA -# dAhJY -# UpV5q -# d510D -# 5N2mW -# yyMc6 -# UgNzZ -# Tl8le -# F3X6m -# doyGg -# YEODp -# 3aeYX -# DBpfO -# 5d6b9 -# C4tO8 -# d9kna -# 06L1E -# WiLBC -# PYeCQ -# 3Ce46 -# haeio -# 24ITN -# BIedu -# NYwIK -# QGP3e -# S5VZ5 -# BK6iu -# 0jdCV -# ajFuW -# 0hC3l -# Uw8bT -# lJ2dO -# itODb -# WjXJK -# EDdXj -# iTLQs -# Fkk5m -# jTy2F -# yT905 -# paH0c -# lnG2a -# BscVm -# M4UOi -# oktmU -# 7dJXy -# kKZV3 -# wHzpI -# D16vj -# bviZa -# pY9vU -# sR1LG -# U8X09 -# OSC80 -# JvkOa -# ey612 -# EJIXp -# kNUBw -# tgvkr -# 1YLS1 -# 8HBIf -# pUTTW -# ON9Qw -# RM66a -# z6XHy -# Xc1DF -# 9Giat -# OZ0ot -# XJe6m -# TSRNL -# 0e2Mn -# lvnx3 -# itv6h -# qU9P0 -# GH6kJ -# TKW9R -# Upvlo -# alL22 -# HuT2P -# VSG9J -# MWQfC -# DtCJ7 -# BGlku -# WTG7d -# TnNBF -# BCNaD -# 6zppq -# 5QlIb -# pNwcE -# Wjmyh -# hAJqi -# sQz83 -# uAtyp -# EgNWX -# lWt5H -# iigey -# 1MmEr -# zPRO9 -# DYEkD diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 71e7499..0571710 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -31,10 +31,9 @@ lint: output: sarif batch: true cache_results: true - cache_ttl: 2000ms success_codes: [0] read_output_from: tmp_file - # disable_upstream: false + disable_upstream: false version_command: parse_regex: ${semver} run: trunk-toolbox --version diff --git a/bar.config b/bar.config new file mode 100644 index 0000000..e5b9ba0 --- /dev/null +++ b/bar.config @@ -0,0 +1 @@ +SameSame \ No newline at end of file diff --git a/foo.config b/foo.config new file mode 100644 index 0000000..e5b9ba0 --- /dev/null +++ b/foo.config @@ -0,0 +1 @@ +SameSame \ No newline at end of file diff --git a/log4rs.yaml b/log4rs.yaml index 681c930..49330f3 100644 --- a/log4rs.yaml +++ b/log4rs.yaml @@ -1,5 +1,7 @@ appenders: stdout: + encoder: + pattern: "{d(%H:%M:%S)} | {({l}):5.5} | {f}:{L} | {m}{n}" kind: console # Appender for the step strategy @@ -7,7 +9,7 @@ appenders: kind: file path: toolbox.log encoder: - pattern: "{d(%Y-%m-%d %H:%M:%S)} | {({l}):5.5} | {f}:{L} — {m}{n}" + pattern: "{d(%H:%M:%S)} | {({l}):5.5} | {f}:{L} | {m}{n}" root: level: debug diff --git a/loop b/loop index 6cba6b0..a0de832 100755 --- a/loop +++ b/loop @@ -17,15 +17,15 @@ generate_random_content() { # Loop 100 times for i in {1..100}; do echo "Running trunk check (Iteration ${i})" - /home/eli/Github/trunk/bazel-bin/trunk/cli/cli check + /home/eli/Github/trunk/bazel-bin/trunk/cli/cli check -n # Check if the command was successful if [[ $? -ne 0 ]]; then echo "Command failed on iteration ${i}" fi - random_content=$(generate_random_content) - echo "${random_content}" >>.trunk/config/toolbox.toml + # random_content=$(generate_random_content) + # echo "${random_content}" >>.trunk/config/toolbox.toml done diff --git a/src/main.rs b/src/main.rs index 51426a6..741fe69 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,12 +7,19 @@ use horton::rules::never_edit::never_edit; use horton::rules::pls_no_land::pls_no_land; use horton::run::{Cli, OutputFormat, Run, Subcommands}; -use log::debug; +use log::{debug, warn}; use serde_sarif::sarif; use std::env; use std::path::{Path, PathBuf}; use std::time::Instant; +use log::LevelFilter; +use log4rs::{ + append::console::ConsoleAppender, + config::{Appender, Root}, + encode::pattern::PatternEncoder, +}; + fn generate_line_string(original_results: &diagnostic::Diagnostics) -> String { return original_results .diagnostics @@ -47,10 +54,15 @@ fn generate_sarif_string( .message( sarif::MessageBuilder::default() .text(format!( - "{:?} files processed in {:?}\n{:?}", + "{:?} files processed in {:?} files:[{}]", run_context.paths.len(), start_time.elapsed(), - run_context.paths + run_context + .paths + .iter() + .map(|p| p.to_string_lossy()) + .collect::>() + .join(", ") )) .build() .unwrap(), @@ -168,21 +180,40 @@ fn run() -> anyhow::Result<()> { Ok(()) } +fn init_default_logger() { + // Create a console appender for stdout + let stdout = ConsoleAppender::builder() + .encoder(Box::new(PatternEncoder::new( + "{d(%H:%M:%S)} | {({l}):5.5} | {f}:{L} | {m}{n}", + ))) + .build(); + + // Build the log4rs configuration + let config = log4rs::Config::builder() + .appender(Appender::builder().build("stdout", Box::new(stdout))) + .build(Root::builder().appender("stdout").build(LevelFilter::Debug)) + .expect("Failed to build log4rs configuration"); + + log4rs::init_config(config).unwrap(); +} + fn main() { + // initialize logging from file if log4rs.yaml exists let current_dir = env::current_dir().expect("Failed to get current directory"); let log_config_path = current_dir.join("log4rs.yaml"); - - match log4rs::init_file(&log_config_path, Default::default()) { - Ok(_) => { - // Initialization succeeded - debug!("logging initialized successfullly {:?}", log_config_path); - } - Err(e) => { - // Initialization failed - eprintln!("Failed to initialize logging: {}", e); - // error!("Failed to initialize logging: {}", e); - // Handle the error, e.g., fallback to a default logger or exit + if log_config_path.exists() { + match log4rs::init_file(&log_config_path, Default::default()) { + Ok(_) => { + // Initialization succeeded + debug!("logging initialized - {:?}", log_config_path); + } + Err(e) => { + init_default_logger(); + warn!("Falling back to default logging setup. override with valid 'log4rs.yaml' file, {}", e); + } } + } else { + init_default_logger(); } match run() { diff --git a/src/rules/pls_no_land.rs b/src/rules/pls_no_land.rs index c35ec60..d63698e 100644 --- a/src/rules/pls_no_land.rs +++ b/src/rules/pls_no_land.rs @@ -60,15 +60,6 @@ pub fn pls_no_land(run: &Run) -> anyhow::Result> { fn pls_no_land_impl(path: &PathBuf, run: &Run) -> anyhow::Result> { let config = &run.config; - if config.todo.enabled && config.todo.sleep_for > 0 { - // test code to force the todo rule to run slowly per file - warn!( - "sleeping inside pls_no_land for {:?}ms", - config.todo.sleep_for - ); - sleep(Duration::from_millis(config.todo.sleep_for)); - } - if is_binary_file(path).unwrap_or(true) { log::debug!("Ignoring binary file {}", path.display()); return Ok(vec![]); @@ -78,6 +69,15 @@ fn pls_no_land_impl(path: &PathBuf, run: &Run) -> anyhow::Result 0 { + // test code to force the todo rule to run slowly per file + warn!( + "sleeping inside TODO rule for {:?}ms", + config.todo.sleep_for + ); + sleep(Duration::from_millis(config.todo.sleep_for)); + } + let in_file = File::open(path).with_context(|| format!("failed to open: {:#?}", path))?; let mut in_buf = BufReader::new(in_file); diff --git a/src/run.rs b/src/run.rs index 0612df9..5f5dd05 100644 --- a/src/run.rs +++ b/src/run.rs @@ -67,9 +67,3 @@ impl Run { self.cache_dir.ends_with("-upstream") } } - -// # hello -// $hioewh -// jgrhogweo -// ewighiowehioegioh -// efwhewo From abf3007ba60ac16173e2a8eda5c2245065c40264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 25 Sep 2024 00:18:51 +0000 Subject: [PATCH 36/47] --- bar.config | 1 - foo.config | 1 - 2 files changed, 2 deletions(-) delete mode 100644 bar.config delete mode 100644 foo.config diff --git a/bar.config b/bar.config deleted file mode 100644 index e5b9ba0..0000000 --- a/bar.config +++ /dev/null @@ -1 +0,0 @@ -SameSame \ No newline at end of file diff --git a/foo.config b/foo.config deleted file mode 100644 index e5b9ba0..0000000 --- a/foo.config +++ /dev/null @@ -1 +0,0 @@ -SameSame \ No newline at end of file From 632e93245a20eb78ce3d84eb6ffeeb7697ddeb78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 25 Sep 2024 00:20:27 +0000 Subject: [PATCH 37/47] --- .trunk/trunk.yaml | 2 +- loop | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 0571710..649501e 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -37,7 +37,7 @@ lint: version_command: parse_regex: ${semver} run: trunk-toolbox --version - direct_configs: [toolbox.toml, log4rs.yaml] + direct_configs: [toolbox.toml] # // , log4rs.yaml] affects_cache: - toolbox.toml environment: diff --git a/loop b/loop index a0de832..01a7075 100755 --- a/loop +++ b/loop @@ -17,7 +17,7 @@ generate_random_content() { # Loop 100 times for i in {1..100}; do echo "Running trunk check (Iteration ${i})" - /home/eli/Github/trunk/bazel-bin/trunk/cli/cli check -n + trunk check --filter=trunk-toolbox # Check if the command was successful if [[ $? -ne 0 ]]; then From 32872ac4ef52d88945cc84d27e7fea034025268a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Thu, 26 Sep 2024 22:30:41 +0000 Subject: [PATCH 38/47] --- .trunk/config/toolbox.toml | 2 +- .trunk/trunk.yaml | 18 ++++++++++-------- loop | 4 ++-- rd | 4 ++++ 4 files changed, 17 insertions(+), 11 deletions(-) create mode 100755 rd diff --git a/.trunk/config/toolbox.toml b/.trunk/config/toolbox.toml index 1e87643..951784c 100644 --- a/.trunk/config/toolbox.toml +++ b/.trunk/config/toolbox.toml @@ -8,7 +8,7 @@ enabled = true [todo] enabled = true -sleep_for = 5000 +sleep_for = 2000 [neveredit] enabled = false diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 649501e..6d224c0 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -11,13 +11,13 @@ runtimes: - node@18.12.1 - rust@1.76.0 cli: - version: 1.22.3 + version: 1.22.6-beta.12 api: address: api.trunk-staging.io:8443 tools: enabled: - - gh@2.55.0 + - gh@2.57.0 runtimes: - rust lint: @@ -31,6 +31,7 @@ lint: output: sarif batch: true cache_results: true + cache_ttl: 3000ms success_codes: [0] read_output_from: tmp_file disable_upstream: false @@ -53,19 +54,20 @@ lint: - tests/** enabled: + - osv-scanner@1.8.5 - shellcheck@0.10.0 - shfmt@3.6.0 - - trunk-toolbox@0.3.2 - - checkov@3.2.238 - - trufflehog@3.81.9 + - trunk-toolbox@0.4.1 + - checkov@3.2.255 + - trufflehog@3.82.5 - oxipng@9.1.2 - yamllint@1.35.1 - git-diff-check - taplo@0.9.3 - - actionlint@1.7.1 + - actionlint@1.7.2 - clippy@1.76.0 - - gitleaks@8.18.4 - - markdownlint@0.41.0 + - gitleaks@8.19.2 + - markdownlint@0.42.0 - prettier@3.3.3 - rustfmt@1.76.0 actions: diff --git a/loop b/loop index 01a7075..add7777 100755 --- a/loop +++ b/loop @@ -15,10 +15,10 @@ generate_random_content() { } # Loop 100 times -for i in {1..100}; do +for i in {1..1000}; do echo "Running trunk check (Iteration ${i})" trunk check --filter=trunk-toolbox - + # trunk check --filter=trunk-toolbox # Check if the command was successful if [[ $? -ne 0 ]]; then echo "Command failed on iteration ${i}" diff --git a/rd b/rd new file mode 100755 index 0000000..15f9d89 --- /dev/null +++ b/rd @@ -0,0 +1,4 @@ +#!/bin/bash + +trunk daemon launch --log-file=/dev/stdout +# /home/eli/Github/trunk/bazel-bin/trunk/cli/cli daemon launch --log-file=/dev/stdout From e8617f028893caee2b82254e54b3918be2044cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 9 Oct 2024 23:33:20 +0000 Subject: [PATCH 39/47] --- .trunk/trunk.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 6d224c0..acb3473 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -2,7 +2,7 @@ version: 0.1 plugins: sources: - id: trunk - ref: v1.6.2 + ref: v1.6.3 uri: https://github.com/trunk-io/plugins runtimes: enabled: @@ -11,13 +11,13 @@ runtimes: - node@18.12.1 - rust@1.76.0 cli: - version: 1.22.6-beta.12 + version: 1.22.6 api: address: api.trunk-staging.io:8443 tools: enabled: - - gh@2.57.0 + - gh@2.58.0 runtimes: - rust lint: @@ -38,7 +38,7 @@ lint: version_command: parse_regex: ${semver} run: trunk-toolbox --version - direct_configs: [toolbox.toml] # // , log4rs.yaml] + direct_configs: [toolbox.toml, log4rs.yaml] affects_cache: - toolbox.toml environment: @@ -54,19 +54,19 @@ lint: - tests/** enabled: - - osv-scanner@1.8.5 + - osv-scanner@1.9.0 - shellcheck@0.10.0 - shfmt@3.6.0 - trunk-toolbox@0.4.1 - - checkov@3.2.255 - - trufflehog@3.82.5 + - checkov@3.2.257 + - trufflehog@3.82.7 - oxipng@9.1.2 - yamllint@1.35.1 - git-diff-check - taplo@0.9.3 - - actionlint@1.7.2 + - actionlint@1.7.3 - clippy@1.76.0 - - gitleaks@8.19.2 + - gitleaks@8.20.1 - markdownlint@0.42.0 - prettier@3.3.3 - rustfmt@1.76.0 From 66764d6537917287026f99849599c0605c27a847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 9 Oct 2024 23:36:05 +0000 Subject: [PATCH 40/47] --- .trunk/trunk.yaml | 2 +- kd | 3 --- loop | 32 -------------------------------- rd | 4 ---- src/git.rs | 2 +- 5 files changed, 2 insertions(+), 41 deletions(-) delete mode 100755 kd delete mode 100755 loop delete mode 100755 rd diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index acb3473..9675f10 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -31,7 +31,7 @@ lint: output: sarif batch: true cache_results: true - cache_ttl: 3000ms + cache_ttl: 6h success_codes: [0] read_output_from: tmp_file disable_upstream: false diff --git a/kd b/kd deleted file mode 100755 index ecbb51f..0000000 --- a/kd +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -/home/eli/Github/trunk/bazel-bin/trunk/cli/cli daemon shutdown diff --git a/loop b/loop deleted file mode 100755 index add7777..0000000 --- a/loop +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -# Ensure the tester directory exists -mkdir -p tester - -# Function to generate a random 30-character filename -generate_random_filename() { - tr -dc A-Za-z0-9 >.trunk/config/toolbox.toml - -done - -echo "Completed 100 iterations successfully." diff --git a/rd b/rd deleted file mode 100755 index 15f9d89..0000000 --- a/rd +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -trunk daemon launch --log-file=/dev/stdout -# /home/eli/Github/trunk/bazel-bin/trunk/cli/cli daemon launch --log-file=/dev/stdout diff --git a/src/git.rs b/src/git.rs index 1ab28ca..62bf318 100644 --- a/src/git.rs +++ b/src/git.rs @@ -181,7 +181,7 @@ pub fn modified_since(upstream: &str, repo_path: Option<&Path>) -> anyhow::Resul Ok(ret) } -pub fn clone(repo_url: &str, destination: &PathBuf) -> Output { +pub fn clone(repo_url: &str, destination: &Path) -> Output { let output = Command::new("git") .args([ "clone", From 491f3805b3ab9f41cfdb368c955fb4ed420bba29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Wed, 9 Oct 2024 23:41:35 +0000 Subject: [PATCH 41/47] --- .trunk/config/toolbox.toml | 5 ++--- src/config.rs | 2 -- src/rules/mod.rs | 1 - src/rules/pls_no_land.rs | 9 --------- 4 files changed, 2 insertions(+), 15 deletions(-) diff --git a/.trunk/config/toolbox.toml b/.trunk/config/toolbox.toml index 951784c..6e22ae2 100644 --- a/.trunk/config/toolbox.toml +++ b/.trunk/config/toolbox.toml @@ -4,11 +4,10 @@ enabled = false [donotland] -enabled = true +enabled = false [todo] -enabled = true -sleep_for = 2000 +enabled = false [neveredit] enabled = false diff --git a/src/config.rs b/src/config.rs index 7c1e2ea..01c78e6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -40,8 +40,6 @@ pub struct PlsNotLandConf { pub struct TodoConf { #[config(default = false)] pub enabled: bool, - #[config(default = 0)] - pub sleep_for: u64, } #[derive(Config)] diff --git a/src/rules/mod.rs b/src/rules/mod.rs index a6c2f9f..5f87d8d 100644 --- a/src/rules/mod.rs +++ b/src/rules/mod.rs @@ -1,4 +1,3 @@ -// lets change this file as well pub mod if_change_then_change; pub mod never_edit; pub mod pls_no_land; diff --git a/src/rules/pls_no_land.rs b/src/rules/pls_no_land.rs index d63698e..2298a0e 100644 --- a/src/rules/pls_no_land.rs +++ b/src/rules/pls_no_land.rs @@ -69,15 +69,6 @@ fn pls_no_land_impl(path: &PathBuf, run: &Run) -> anyhow::Result 0 { - // test code to force the todo rule to run slowly per file - warn!( - "sleeping inside TODO rule for {:?}ms", - config.todo.sleep_for - ); - sleep(Duration::from_millis(config.todo.sleep_for)); - } - let in_file = File::open(path).with_context(|| format!("failed to open: {:#?}", path))?; let mut in_buf = BufReader::new(in_file); From f22cf0849d40258c421790d7ca57a8b9e8dd6541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Mon, 28 Oct 2024 22:49:42 +0000 Subject: [PATCH 42/47] --- .trunk/trunk.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 9675f10..61b0ddc 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -30,11 +30,12 @@ lint: run: ${workspace}/toolbox-latest --upstream=${upstream-ref} --cache-dir=${cachedir} --results=${tmpfile} ${target} output: sarif batch: true - cache_results: true + cache_results: false cache_ttl: 6h success_codes: [0] read_output_from: tmp_file disable_upstream: false + max_concurrency: 1 version_command: parse_regex: ${semver} run: trunk-toolbox --version From e1f2837eeddf368b63ad6b55370835b703895db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Fri, 15 Nov 2024 22:55:47 +0000 Subject: [PATCH 43/47] merge --- .trunk/trunk.yaml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index c26fc2f..84c531c 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -58,15 +58,9 @@ lint: - osv-scanner@1.9.0 - shellcheck@0.10.0 - shfmt@3.6.0 -<<<<<<< HEAD - - trunk-toolbox@0.4.1 - - checkov@3.2.257 - - trufflehog@3.82.7 -======= - - trunk-toolbox@0.3.2 + - trunk-toolbox@0.5.4 - checkov@3.2.238 - trufflehog@3.81.9 ->>>>>>> main - oxipng@9.1.2 - yamllint@1.35.1 - git-diff-check From adbf14d3c46be87989b086b35e4ea1f7cb36ca26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Mon, 18 Nov 2024 22:15:31 +0000 Subject: [PATCH 44/47] merge --- src/rules/if_change_then_change.rs | 165 ++--------------------------- 1 file changed, 11 insertions(+), 154 deletions(-) diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index 816ec0a..af8221c 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -1,27 +1,17 @@ use crate::run::Run; use anyhow::Context; -<<<<<<< HEAD use sha2::{Digest, Sha256}; -======= use log::{debug, trace, warn}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use regex::Regex; ->>>>>>> main use std::collections::{HashMap, HashSet}; use std::env; use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; -<<<<<<< HEAD -use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; -use regex::Regex; - use crate::diagnostic::{Diagnostic, Position, Range, Replacement, Severity}; -======= -use crate::diagnostic; ->>>>>>> main use crate::git; #[derive(Debug, Clone)] @@ -226,9 +216,20 @@ impl<'a> Ictc<'a> { let config = &self.run.config.ifchange; if !config.enabled { + trace!("'ifchange' is disabled"); + return Ok(vec![]); + } + + if run.is_upstream() { + trace!("'if-change' rule doesn't run on upstream"); return Ok(vec![]); } + debug!( + "scanning {} files for if_change_then_change", + run.paths.len() + ); + // Build up list of files that actually have a ifchange block - this way we can avoid // processing git modified chunks if none are present let all_blocks: Vec<_> = self @@ -582,150 +583,6 @@ pub fn find_ictc_blocks(path: &PathBuf) -> anyhow::Result> { Ok(blocks) } -<<<<<<< HEAD -======= -pub fn ictc(run: &Run, upstream: &str) -> anyhow::Result> { - let config = &run.config.ifchange; - - if !config.enabled { - trace!("'ifchange' is disabled"); - return Ok(vec![]); - } - - if run.is_upstream() { - trace!("'if-change' rule doesn't run on upstream"); - return Ok(vec![]); - } - - debug!( - "scanning {} files for if_change_then_change", - run.paths.len() - ); - - // Build up list of files that actually have a ifchange block - this way we can avoid - // processing git modified chunks if none are present - let all_blocks: Vec<_> = run - .paths - .par_iter() - .filter_map(|file| find_ictc_blocks(file).ok()) - .flatten() - .collect(); - - // Fast exit if we don't have any files that have ICTC blocks - saves us calling - // into git to get more information - if all_blocks.is_empty() { - return Ok(vec![]); - } - - let modified = git::modified_since(upstream, None)?; - let hunks = &modified.hunks; - - log::trace!("modified stats, per libgit2:\n{:#?}", modified); - - // TODO(sam): this _should_ be a iter-map-collect, but unclear how to apply a reducer - // between the map and collect (there can be multiple hunks with the same path) - let mut modified_lines_by_path: HashMap> = HashMap::new(); - for h in hunks { - modified_lines_by_path - .entry(h.path.clone()) - .or_default() - .extend(h.begin..h.end); - } - let modified_lines_by_path = modified_lines_by_path; - - let mut blocks: Vec = Vec::new(); - - for block in all_blocks { - if let Some(thenchange) = &block.thenchange { - match &thenchange { - ThenChange::MissingIf | ThenChange::MissingThen => { - blocks.push(block); - } - _ => { - if let (Some(begin), Some(end)) = (block.begin, block.end) { - let block_lines = HashSet::from_iter(begin..end); - if !block_lines.is_disjoint( - modified_lines_by_path - .get(&block.path) - .unwrap_or(&HashSet::new()), - ) { - blocks.push(block); - } - } - } - } - } - } - - let blocks_by_path: HashMap<&PathBuf, &IctcBlock> = - blocks.iter().map(|b| (&b.path, b)).collect(); - - let mut diagnostics: Vec = Vec::new(); - - for block in &blocks { - if let Some(change) = &block.thenchange { - match change { - ThenChange::RemoteFile(_remote_file) => { - todo!("build support for remote file") - } - ThenChange::RepoFile(local_file) => { - // Check if the repo file exists - if it was deleted this is a warning - if !Path::new(local_file).exists() { - diagnostics.push(diagnostic::Diagnostic { - path: block.path.to_str().unwrap().to_string(), - range: Some(block.get_range()), - severity: diagnostic::Severity::Warning, - code: "if-change-file-does-not-exist".to_string(), - message: format!("ThenChange {} does not exist", local_file.display(),), - replacements: None, - }); - } - // If target file was not changed raise issue - if blocks_by_path.get(&local_file).is_none() { - diagnostics.push(diagnostic::Diagnostic { - path: block.path.to_str().unwrap().to_string(), - range: Some(block.get_range()), - severity: diagnostic::Severity::Error, - code: "if-change-then-change-this".to_string(), - message: format!( - "Expected change in {} because {} was modified", - local_file.display(), - block.path.display(), - ), - replacements: None, - }); - } - } - ThenChange::MissingIf => { - diagnostics.push(diagnostic::Diagnostic { - path: block.path.to_str().unwrap().to_string(), - range: Some(block.get_range()), - severity: diagnostic::Severity::Warning, - code: "if-change-mismatched".to_string(), - message: "Expected preceding IfChange tag".to_string(), - replacements: None, - }); - } - ThenChange::MissingThen => { - diagnostics.push(diagnostic::Diagnostic { - path: block.path.to_str().unwrap().to_string(), - range: Some(block.get_range()), - severity: diagnostic::Severity::Warning, - code: "if-change-mismatched".to_string(), - message: "Expected matching ThenChange tag".to_string(), - replacements: None, - }); - } - } - } - } - - trace!("ICTC blocks are:\n{:?}", blocks); - - Ok(diagnostics) -} - ->>>>>>> main type LinesView = Vec; fn lines_view(reader: R) -> anyhow::Result { From adeb56f4385f5271476b517ebf127bdeed665630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Mon, 18 Nov 2024 22:17:55 +0000 Subject: [PATCH 45/47] merge --- .trunk/trunk.yaml | 2 -- src/git.rs | 4 ---- src/main.rs | 3 --- src/rules/pls_no_land.rs | 4 ---- 4 files changed, 13 deletions(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 84c531c..bedb77e 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -30,8 +30,6 @@ lint: run: ${workspace}/toolbox-latest --upstream=${upstream-ref} --cache-dir=${cachedir} --results=${tmpfile} ${target} output: sarif batch: true - cache_results: false - cache_ttl: 6h success_codes: [0] read_output_from: tmp_file cache_results: true diff --git a/src/git.rs b/src/git.rs index 53aae0d..f369646 100644 --- a/src/git.rs +++ b/src/git.rs @@ -5,11 +5,7 @@ use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::process::Command; use std::process::Output as ProcessOutput; -<<<<<<< HEAD - -======= use std::sync::Mutex; ->>>>>>> main #[derive(Debug, Clone)] pub struct Hunk { pub path: PathBuf, diff --git a/src/main.rs b/src/main.rs index cbcedce..57d6334 100644 --- a/src/main.rs +++ b/src/main.rs @@ -214,10 +214,7 @@ fn main() { } } else { init_default_logger(); -<<<<<<< HEAD -======= debug!("using default built-in logging setup - no log4rs.yaml found"); ->>>>>>> main } match run() { diff --git a/src/rules/pls_no_land.rs b/src/rules/pls_no_land.rs index c09ccc9..42794f1 100644 --- a/src/rules/pls_no_land.rs +++ b/src/rules/pls_no_land.rs @@ -4,11 +4,7 @@ extern crate regex; use crate::diagnostic; use crate::run::Run; use anyhow::Context; -<<<<<<< HEAD -use log::warn; -======= use log::{debug, trace}; ->>>>>>> main use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use regex::Regex; use std::fs::File; From fe0e66867158da559159631c64e8051a6540bfbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Mon, 18 Nov 2024 22:44:33 +0000 Subject: [PATCH 46/47] --- .trunk/config/toolbox.toml | 1 - Cargo.lock | 729 ++++++++++++---------------- src/rules/if_change_then_change.rs | 8 +- src/rules/pls_no_land.rs | 3 - tests/if_change_then_change_test.rs | 3 +- 5 files changed, 320 insertions(+), 424 deletions(-) diff --git a/.trunk/config/toolbox.toml b/.trunk/config/toolbox.toml index 6d8d134..b4def01 100644 --- a/.trunk/config/toolbox.toml +++ b/.trunk/config/toolbox.toml @@ -12,4 +12,3 @@ enabled = false [neveredit] enabled = false paths = [] - diff --git a/Cargo.lock b/Cargo.lock index 814860c..4b77368 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,9 +38,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -53,78 +53,43 @@ dependencies = [ [[package]] name = "anstyle" -<<<<<<< HEAD -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" - -[[package]] -name = "anstyle-parse" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" -======= -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" ->>>>>>> main dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -<<<<<<< HEAD -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" -dependencies = [ - "windows-sys 0.52.0", -======= version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ "windows-sys 0.59.0", ->>>>>>> main ] [[package]] name = "anstyle-wincon" -<<<<<<< HEAD -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -======= version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", "windows-sys 0.59.0", ->>>>>>> main ] [[package]] name = "anyhow" -<<<<<<< HEAD -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" -======= -version = "1.0.91" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" ->>>>>>> main +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arc-swap" @@ -161,15 +126,9 @@ dependencies = [ [[package]] name = "autocfg" -<<<<<<< HEAD -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" -======= version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" ->>>>>>> main [[package]] name = "bitflags" @@ -188,9 +147,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" dependencies = [ "memchr", "regex-automata", @@ -211,15 +170,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -<<<<<<< HEAD -version = "1.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" -======= -version = "1.1.31" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" ->>>>>>> main +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ "jobserver", "libc", @@ -248,15 +201,9 @@ dependencies = [ [[package]] name = "clap" -<<<<<<< HEAD -version = "4.5.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" -======= -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" ->>>>>>> main +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -264,15 +211,9 @@ dependencies = [ [[package]] name = "clap_builder" -<<<<<<< HEAD -version = "4.5.15" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" -======= -version = "4.5.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" ->>>>>>> main +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -282,43 +223,27 @@ dependencies = [ [[package]] name = "clap_derive" -<<<<<<< HEAD -version = "4.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" -======= version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" ->>>>>>> main dependencies = [ "heck 0.5.0", "proc-macro2", "quote", -<<<<<<< HEAD - "syn 2.0.76", -======= - "syn 2.0.85", ->>>>>>> main + "syn 2.0.87", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "colorchoice" -<<<<<<< HEAD -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" -======= version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" ->>>>>>> main [[package]] name = "confique" @@ -362,15 +287,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -<<<<<<< HEAD -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" -======= -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" ->>>>>>> main +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] @@ -509,6 +428,17 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "doc-comment" version = "0.3.3" @@ -552,9 +482,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "float-cmp" @@ -654,15 +584,9 @@ checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d" [[package]] name = "hashbrown" -<<<<<<< HEAD -version = "0.14.5" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -======= -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" ->>>>>>> main +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "heck" @@ -723,6 +647,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -731,25 +773,30 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "indexmap" -<<<<<<< HEAD -version = "2.4.0" +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" -======= +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" ->>>>>>> main dependencies = [ "equivalent", "hashbrown", @@ -778,15 +825,9 @@ dependencies = [ [[package]] name = "js-sys" -<<<<<<< HEAD -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" -======= version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" ->>>>>>> main dependencies = [ "wasm-bindgen", ] @@ -810,15 +851,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -<<<<<<< HEAD -version = "0.2.158" +version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" -======= -version = "0.2.161" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" ->>>>>>> main +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" [[package]] name = "libgit2-sys" @@ -850,6 +885,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "lock_api" version = "0.4.12" @@ -1030,38 +1071,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "ordered-float" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" -dependencies = [ - "num-traits", -] - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - [[package]] name = "percent-encoding" version = "2.3.1" @@ -1070,15 +1079,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -<<<<<<< HEAD -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" -======= version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" ->>>>>>> main dependencies = [ "memchr", "thiserror", @@ -1087,15 +1090,9 @@ dependencies = [ [[package]] name = "pest_derive" -<<<<<<< HEAD -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" -======= version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" ->>>>>>> main dependencies = [ "pest", "pest_generator", @@ -1103,38 +1100,22 @@ dependencies = [ [[package]] name = "pest_generator" -<<<<<<< HEAD -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" -======= version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" ->>>>>>> main dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", -<<<<<<< HEAD - "syn 2.0.76", -======= - "syn 2.0.85", ->>>>>>> main + "syn 2.0.87", ] [[package]] name = "pest_meta" -<<<<<<< HEAD -version = "2.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" -======= version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" ->>>>>>> main dependencies = [ "once_cell", "pest", @@ -1143,15 +1124,9 @@ dependencies = [ [[package]] name = "pkg-config" -<<<<<<< HEAD -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" -======= version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" ->>>>>>> main [[package]] name = "ppv-lite86" @@ -1213,15 +1188,9 @@ dependencies = [ [[package]] name = "proc-macro2" -<<<<<<< HEAD -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -======= version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" ->>>>>>> main dependencies = [ "unicode-ident", ] @@ -1324,30 +1293,18 @@ dependencies = [ [[package]] name = "redox_syscall" -<<<<<<< HEAD -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" -======= version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" ->>>>>>> main dependencies = [ "bitflags", ] [[package]] name = "regex" -<<<<<<< HEAD -version = "1.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" -======= version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" ->>>>>>> main dependencies = [ "aho-corasick", "memchr", @@ -1357,15 +1314,9 @@ dependencies = [ [[package]] name = "regex-automata" -<<<<<<< HEAD -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -======= -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" ->>>>>>> main +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1374,15 +1325,9 @@ dependencies = [ [[package]] name = "regex-syntax" -<<<<<<< HEAD -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" -======= version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" ->>>>>>> main [[package]] name = "rustc-serialize" @@ -1392,15 +1337,9 @@ checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401" [[package]] name = "rustix" -<<<<<<< HEAD -version = "0.38.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" -======= -version = "0.38.38" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" ->>>>>>> main +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags", "errno", @@ -1411,15 +1350,9 @@ dependencies = [ [[package]] name = "rustversion" -<<<<<<< HEAD -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" -======= version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" ->>>>>>> main [[package]] name = "ryu" @@ -1462,15 +1395,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -<<<<<<< HEAD -version = "1.0.209" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" -======= -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" ->>>>>>> main +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -1507,36 +1434,20 @@ dependencies = [ [[package]] name = "serde_derive" -<<<<<<< HEAD -version = "1.0.209" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.76", -======= -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", ->>>>>>> main + "syn 2.0.87", ] [[package]] name = "serde_json" -<<<<<<< HEAD -version = "1.0.127" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" -======= -version = "1.0.132" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" ->>>>>>> main +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -1545,11 +1456,6 @@ dependencies = [ ] [[package]] -<<<<<<< HEAD -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -======= name = "serde_spanned" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1562,7 +1468,6 @@ dependencies = [ name = "serde_yaml" version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" ->>>>>>> main checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ "indexmap", @@ -1604,6 +1509,12 @@ dependencies = [ "num", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "strsim" version = "0.10.0" @@ -1648,15 +1559,9 @@ dependencies = [ [[package]] name = "syn" -<<<<<<< HEAD -version = "2.0.76" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" -======= -version = "2.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" ->>>>>>> main +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -1664,16 +1569,21 @@ dependencies = [ ] [[package]] -name = "tempfile" -<<<<<<< HEAD -version = "3.12.0" +name = "synstructure" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" -======= -version = "3.13.0" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "tempfile" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" ->>>>>>> main +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -1699,38 +1609,22 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -<<<<<<< HEAD -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" -======= -version = "1.0.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" ->>>>>>> main +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -<<<<<<< HEAD -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.76", -======= -version = "1.0.65" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", ->>>>>>> main + "syn 2.0.87", ] [[package]] @@ -1744,20 +1638,15 @@ dependencies = [ ] [[package]] -name = "tinyvec" -version = "1.8.0" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "tinyvec_macros", + "displaydoc", + "zerovec", ] -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "toml" version = "0.5.11" @@ -1852,33 +1741,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" -[[package]] -name = "unicode-bidi" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" - [[package]] name = "unicode-ident" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" -[[package]] -name = "unicode-normalization" -<<<<<<< HEAD -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -======= -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" ->>>>>>> main -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-segmentation" version = "1.12.0" @@ -1894,25 +1762,10 @@ dependencies = [ "destructure_traitobject", ] -[[package]] -<<<<<<< HEAD -name = "unsafe-any-ors" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a303d30665362d9680d7d91d78b23f5f899504d4f08b3c4cf08d055d87c0ad" -dependencies = [ - "destructure_traitobject", -] - [[package]] name = "unsafe-libyaml" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -======= -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" ->>>>>>> main checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] @@ -1927,15 +1780,27 @@ dependencies = [ [[package]] name = "url" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -1971,15 +1836,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -<<<<<<< HEAD -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" -======= version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" ->>>>>>> main dependencies = [ "cfg-if", "once_cell", @@ -1988,40 +1847,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -<<<<<<< HEAD -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" -======= version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" ->>>>>>> main dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", -<<<<<<< HEAD - "syn 2.0.76", -======= - "syn 2.0.85", ->>>>>>> main + "syn 2.0.87", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -<<<<<<< HEAD -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" -======= version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" ->>>>>>> main dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2029,38 +1872,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -<<<<<<< HEAD -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.76", -======= version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", ->>>>>>> main + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -<<<<<<< HEAD -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" -======= version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" ->>>>>>> main [[package]] name = "winapi" @@ -2185,8 +2012,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -<<<<<<< HEAD -======= name = "winnow" version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2196,7 +2021,42 @@ dependencies = [ ] [[package]] ->>>>>>> main +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure", +] + +[[package]] name = "zerocopy" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2214,9 +2074,48 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", -<<<<<<< HEAD - "syn 2.0.76", -======= - "syn 2.0.85", ->>>>>>> main + "syn 2.0.87", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", ] diff --git a/src/rules/if_change_then_change.rs b/src/rules/if_change_then_change.rs index af8221c..4ac4aba 100644 --- a/src/rules/if_change_then_change.rs +++ b/src/rules/if_change_then_change.rs @@ -220,14 +220,14 @@ impl<'a> Ictc<'a> { return Ok(vec![]); } - if run.is_upstream() { + if self.run.is_upstream() { trace!("'if-change' rule doesn't run on upstream"); return Ok(vec![]); } debug!( "scanning {} files for if_change_then_change", - run.paths.len() + self.run.paths.len() ); // Build up list of files that actually have a ifchange block - this way we can avoid @@ -302,11 +302,12 @@ impl<'a> Ictc<'a> { } _ => self.thenchange(block, &blocks_by_path), } + } else { + self.thenchange(block, &blocks_by_path); } } log::trace!("ICTC blocks are:\n{:?}", blocks); - Ok(self.diagnostics.clone()) } @@ -460,6 +461,7 @@ impl<'a> Ictc<'a> { } } ThenChange::MissingIf => { + trace!("MissingIf processing..."); self.diagnostics.push(Diagnostic { path: block.path.to_str().unwrap().to_string(), range: Some(block.get_range()), diff --git a/src/rules/pls_no_land.rs b/src/rules/pls_no_land.rs index 42794f1..86cced3 100644 --- a/src/rules/pls_no_land.rs +++ b/src/rules/pls_no_land.rs @@ -12,9 +12,6 @@ use std::io::Read; use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; -use std::thread::sleep; -use std::time::Duration; - lazy_static::lazy_static! { static ref DNL_RE: Regex = Regex::new(r"(?i)(DO[\s_-]*NOT[\s_-]*LAND)").unwrap(); static ref TODO_RE: Regex = Regex::new(r"(?i)(TODO|FIXME)(\W+.*)?$").unwrap(); diff --git a/tests/if_change_then_change_test.rs b/tests/if_change_then_change_test.rs index 457fba3..5b5c0d6 100644 --- a/tests/if_change_then_change_test.rs +++ b/tests/if_change_then_change_test.rs @@ -1,5 +1,4 @@ use confique::{Config, Partial}; -use horton::config::confique_partial_if_change_conf::PartialIfChangeConf; use horton::config::Conf; use horton::diagnostic::{Position, Range}; use horton::run::Run; @@ -564,7 +563,7 @@ fn remote_repo_update_hash() { assert_that(&replacement.deleted_region.start.character).is_equal_to(40); assert_that(&replacement.deleted_region.end.character).is_equal_to(47); - assert_that(&replacement.inserted_content.len()).is_equal_to(40); + assert_that(&replacement.inserted_content.len()).is_equal_to(10); let sarif = diag.to_sarif(); assert!( From 7fbb6071411de00d20e7d6a43fac73f9d0d71c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEli?= Date: Mon, 18 Nov 2024 22:59:33 +0000 Subject: [PATCH 47/47] --- .trunk/trunk.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index bedb77e..6639303 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -56,7 +56,7 @@ lint: - osv-scanner@1.9.0 - shellcheck@0.10.0 - shfmt@3.6.0 - - trunk-toolbox@0.5.4 + - trunk-toolbox@0.5.3 - checkov@3.2.238 - trufflehog@3.81.9 - oxipng@9.1.2