Skip to content

Commit

Permalink
feat: add --gituntracked option (#96)
Browse files Browse the repository at this point in the history
This will allow ignoring files which are untracked by git.

Use in conjunction with --gitignore for best effect.
  • Loading branch information
willcl-ark authored Oct 24, 2024
1 parent 8f2df53 commit 6871383
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ The following arguments are available:
| `--version` | `-V` | Print current version of mlc |
| `--ignore-path` | `-p` | Comma separated list of directories or files which shall be ignored. For example |
| `--gitignore` | `-g` | Ignore all files currently ignored by git (requires `git` binary to be available on $PATH). |
| `--gituntracked` | `-u` | Ignore all files currently untracked by git (requires `git` binary to be available on $PATH). |
| `--ignore-links` | `-i` | Comma separated list of links which shall be ignored. Use simple `?` and `*` wildcards. For example `--ignore-links "http*://crates.io*"` will skip all links to the crates.io website. See the [used lib](https://github.com/becheran/wildmatch) for more information. |
| `--markup-types` | `-t` | Comma separated list list of markup types which shall be checked [possible values: md, html] |
| `--root-dir` | `-r` | All links to the file system starting with a slash on linux or backslash on windows will use another virtual root dir. For example the link in a file `[link](/dir/other/file.md)` checked with the cli arg `--root-dir /env/another/dir` will let *mlc* check the existence of `/env/another/dir/dir/other/file.md`. |
Expand Down
13 changes: 13 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ pub fn parse_args() -> Config {
.action(ArgAction::SetTrue)
.required(false),
)
.arg(
Arg::new("gituntracked")
.long("gituntracked")
.short('u')
.value_name("GITUNTRACKED")
.help("Ignore all files untracked by git")
.action(ArgAction::SetTrue)
.required(false),
)
.get_matches();

let default_dir = format!(".{}", &MAIN_SEPARATOR);
Expand Down Expand Up @@ -175,6 +184,10 @@ pub fn parse_args() -> Config {
opt.gitignore = Some(true);
}

if matches.get_flag("gituntracked") {
opt.gituntracked = Some(true);
}

if let Some(root_dir) = matches.get_one::<String>("root-dir") {
let root_path = Path::new(
&root_dir
Expand Down
52 changes: 52 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ pub struct OptionalConfig {
pub root_dir: Option<PathBuf>,
#[serde(rename(deserialize = "gitignore"))]
pub gitignore: Option<bool>,
#[serde(rename(deserialize = "gituntracked"))]
pub gituntracked: Option<bool>,
pub throttle: Option<u32>,
}

Expand Down Expand Up @@ -92,6 +94,7 @@ Offline: {}
MatchExt: {}
RootDir: {}
Gitignore: {}
Gituntracked: {}
IgnoreLinks: {}
IgnorePath: {:?}
Throttle: {} ms",
Expand All @@ -103,6 +106,7 @@ Throttle: {} ms",
self.optional.match_file_extension.unwrap_or_default(),
root_dir_str,
self.optional.gitignore.unwrap_or_default(),
self.optional.gituntracked.unwrap_or_default(),
ignore_str.join(","),
ignore_path_str,
self.optional.throttle.unwrap_or(0)
Expand Down Expand Up @@ -157,7 +161,30 @@ fn find_git_ignored_files() -> Option<Vec<PathBuf>> {
None
}
}
fn find_git_untracked_files() -> Option<Vec<PathBuf>> {
let output = Command::new("git")
.arg("ls-files")
.arg("--others")
.arg("--exclude-standard")
.output()
.expect("Failed to execute 'git' command");

if output.status.success() {
let ignored_files = String::from_utf8(output.stdout)
.expect("Invalid UTF-8 sequence")
.lines()
.filter(|line| line.ends_with(".md") || line.ends_with(".html"))
.filter_map(|line| fs::canonicalize(Path::new(line.trim())).ok())
.collect::<Vec<_>>();
Some(ignored_files)
} else {
eprintln!(
"git ls-files command failed: {}",
String::from_utf8_lossy(&output.stderr)
);
None
}
}

fn print_helper(
link: &MarkupLink,
Expand Down Expand Up @@ -213,6 +240,16 @@ pub async fn run(config: &Config) -> Result<(), ()> {

let is_gitignore_enabled = gitignored_files.is_some();

let gituntracked_files: Option<Vec<PathBuf>> = if config.optional.gituntracked.is_some() {
let files = find_git_untracked_files();
debug!("Found gituntracked files: {:?}", files);
files
} else {
None
};

let is_gituntracked_enabled = gituntracked_files.is_some();

for link in &links {
let canonical_link_source = match fs::canonicalize(&link.source) {
Ok(path) => path,
Expand All @@ -237,6 +274,21 @@ pub async fn run(config: &Config) -> Result<(), ()> {
}
}

if is_gituntracked_enabled {
if let Some(ref gif) = gituntracked_files {
if gif.iter().any(|path| path == &canonical_link_source) {
print_helper(
link,
&"Skip".green(),
"Ignore link because it is untracked by git.",
false,
);
skipped += 1;
continue;
}
}
}

if ignore_links.iter().any(|m| m.matches(&link.target)) {
print_helper(
link,
Expand Down
2 changes: 2 additions & 0 deletions tests/end_to_end.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ async fn end_to_end() {
]),
root_dir: None,
gitignore: None,
gituntracked: None,
},
};
if let Err(e) = mlc::run(&config).await {
Expand All @@ -48,6 +49,7 @@ async fn end_to_end_different_root() {
throttle: None,
root_dir: Some(test_files),
gitignore: None,
gituntracked: None,
},
};
if let Err(e) = mlc::run(&config).await {
Expand Down

0 comments on commit 6871383

Please sign in to comment.