Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Include untracked files with --gitignore option #96

Merged
merged 1 commit into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

#### Arch Linux

You can install from the [official repositories](https://archlinux.org/packages/extra/x86_64/markuplinkchecker/) using [pacman](https://wiki.archlinux.org/title/pacman):

Check warning on line 46 in README.md

View workflow job for this annotation

GitHub Actions / test_own_readme

link checker warning

https://wiki.archlinux.org/title/pacman. Request was redirected to https://wiki.archlinux.org/title/Pacman

```bash
pacman -S markuplinkchecker
Expand All @@ -69,7 +69,7 @@
args: ./README.md
```

The action does uses [GitHub workflow commands](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions) to highlight broken links:

Check warning on line 72 in README.md

View workflow job for this annotation

GitHub Actions / test_own_readme

link checker warning


![annotation](./docs/FailingAnnotation.PNG)

Expand Down Expand Up @@ -127,6 +127,7 @@
| `--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
Loading