Skip to content
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
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::path::Path;
use std::path::{Path, PathBuf};

use clap::Parser;
use rustc_hash::FxHashSet;

use crate::git::{get_added_files, get_lfs_files};
use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::{hook_filenames, parse_hook_args};
use crate::hooks::run_concurrent_file_checks;
use crate::run::INTERNAL_CONCURRENCY;

Expand All @@ -17,13 +18,17 @@ struct Args {
enforce_all: bool,
#[arg(long = "maxkb", default_value = "500")]
max_kb: u64,
#[arg(value_name = "FILENAMES")]
filenames: Vec<PathBuf>,
}

pub(crate) async fn check_added_large_files(
hook: &Hook,
filenames: &[&Path],
) -> anyhow::Result<(i32, Vec<u8>)> {
let args = Args::try_parse_from(hook.entry.expect_direct().split_with_args(&hook.args)?)?;
let args: Args = parse_hook_args(hook)?;
let all_filenames = hook_filenames(&args.filenames, filenames).collect::<Vec<_>>();
let filenames = all_filenames.as_slice();

let candidate_filenames;
let filenames = if args.enforce_all {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ use rustc_hash::FxHashSet;

use crate::git;
use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::{FilenamesArgs, hook_filenames, parse_hook_args};

pub(crate) async fn check_case_conflict(
hook: &Hook,
filenames: &[&Path],
) -> Result<(i32, Vec<u8>)> {
let args: FilenamesArgs = parse_hook_args(hook)?;
let filenames = hook_filenames(&args.filenames, filenames).collect::<Vec<_>>();
let work_dir = hook.work_dir();

// Get all files in the repo.
Expand All @@ -25,7 +28,7 @@ pub(crate) async fn check_case_conflict(
// Get relevant files (filenames + added files) and include their parent directories.
let added = git::get_added_files(work_dir).await?;
let mut relevant_files_with_dirs: FxHashSet<&Path> = FxHashSet::default();
for filename in filenames {
for filename in &filenames {
insert_path_and_parents(&mut relevant_files_with_dirs, filename);
}
for path in &added {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::shebangs::{
file_has_shebang, git_index_stage_output, matching_git_index_paths_by_executable_bit,
};
use crate::hooks::pre_commit_hooks::{FilenamesArgs, hook_filenames, parse_hook_args};
use crate::hooks::run_concurrent_file_checks;
use crate::run::INTERNAL_CONCURRENCY;
use rustc_hash::FxHashSet;
Expand All @@ -16,6 +17,8 @@ pub(crate) async fn check_executables_have_shebangs(
hook: &Hook,
filenames: &[&Path],
) -> Result<(i32, Vec<u8>), anyhow::Error> {
let args: FilenamesArgs = parse_hook_args(hook)?;
let filenames = hook_filenames(&args.filenames, filenames).collect::<Vec<_>>();
if filenames.is_empty() {
return Ok((0, Vec::new()));
}
Expand All @@ -34,10 +37,10 @@ pub(crate) async fn check_executables_have_shebangs(
let (code, output) = if tracks_executable_bit {
// core.fileMode=true means the platform honors the executable bit, so trust the FS metadata.
// The `executables-have-shebangs` hook already restricts inputs to executable text files (`types: [text, executable]`).
os_check_shebangs(file_base, filenames).await?
os_check_shebangs(file_base, &filenames).await?
} else {
// If on win32 use git to check executable bit
git_check_shebangs(file_base, filenames).await?
git_check_shebangs(file_base, &filenames).await?
};

Ok((code, output))
Expand Down
4 changes: 3 additions & 1 deletion crates/prek/src/hooks/pre_commit_hooks/check_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ use rustc_hash::FxHashSet;
use serde::{Deserialize, Deserializer};

use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::{FilenamesArgs, hook_filenames, parse_hook_args};
use crate::hooks::run_concurrent_file_checks;
use crate::run::INTERNAL_CONCURRENCY;

pub(crate) async fn check_json(hook: &Hook, filenames: &[&Path]) -> Result<(i32, Vec<u8>)> {
let args: FilenamesArgs = parse_hook_args(hook)?;
run_concurrent_file_checks(
filenames.iter().copied(),
hook_filenames(&args.filenames, filenames),
*INTERNAL_CONCURRENCY,
|filename| check_file(hook.project().relative_path(), filename),
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::io::Write;
use std::path::Path;
use std::path::{Path, PathBuf};

use anyhow::Result;
use clap::Parser;
use tokio::io::AsyncBufReadExt;

use crate::git::get_git_dir;
use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::{hook_filenames, parse_hook_args};
use crate::hooks::run_concurrent_file_checks;
use crate::run::INTERNAL_CONCURRENCY;

Expand All @@ -22,21 +23,23 @@ const SEPARATOR_PATTERNS: &[&[u8]] = &[b"======= ", b"=======\r\n", b"=======\n"
struct Args {
#[arg(long)]
assume_in_merge: bool,
#[arg(value_name = "FILENAMES")]
filenames: Vec<PathBuf>,
}

pub(crate) async fn check_merge_conflict(
hook: &Hook,
filenames: &[&Path],
) -> Result<(i32, Vec<u8>)> {
let args = Args::try_parse_from(hook.entry.expect_direct().split_with_args(&hook.args)?)?;
let args: Args = parse_hook_args(hook)?;

// Check if we're in a merge state or assuming merge
if !args.assume_in_merge && !is_in_merge().await? {
return Ok((0, Vec::new()));
}

run_concurrent_file_checks(
filenames.iter().copied(),
hook_filenames(&args.filenames, filenames),
*INTERNAL_CONCURRENCY,
|filename| check_file(hook.project().relative_path(), filename),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::shebangs::{
file_has_shebang, git_index_stage_output, matching_git_index_paths_by_executable_bit,
};
use crate::hooks::pre_commit_hooks::{FilenamesArgs, hook_filenames, parse_hook_args};
use crate::hooks::run_concurrent_file_checks;
use crate::run::INTERNAL_CONCURRENCY;
use rustc_hash::FxHashSet;
Expand All @@ -15,13 +16,15 @@ pub(crate) async fn check_shebang_scripts_are_executable(
hook: &Hook,
filenames: &[&Path],
) -> Result<(i32, Vec<u8>), anyhow::Error> {
let args: FilenamesArgs = parse_hook_args(hook)?;
let filenames = hook_filenames(&args.filenames, filenames).collect::<Vec<_>>();
if filenames.is_empty() {
return Ok((0, Vec::new()));
}

let file_base = hook.project().relative_path();
let stdout = git_index_stage_output(file_base).await?;
let filenames: FxHashSet<_> = filenames.iter().copied().collect();
let filenames: FxHashSet<_> = filenames.into_iter().collect();
let entries = matching_git_index_paths_by_executable_bit(&stdout, file_base, &filenames, false);

run_concurrent_file_checks(entries, *INTERNAL_CONCURRENCY, |file| async move {
Expand Down
4 changes: 3 additions & 1 deletion crates/prek/src/hooks/pre_commit_hooks/check_symlinks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ use std::path::Path;
use anyhow::Result;

use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::{FilenamesArgs, hook_filenames, parse_hook_args};
use crate::hooks::run_concurrent_file_checks;
use crate::run::INTERNAL_CONCURRENCY;

pub(crate) async fn check_symlinks(hook: &Hook, filenames: &[&Path]) -> Result<(i32, Vec<u8>)> {
let args: FilenamesArgs = parse_hook_args(hook)?;
run_concurrent_file_checks(
filenames.iter().copied(),
hook_filenames(&args.filenames, filenames),
*INTERNAL_CONCURRENCY,
|filename| check_file(hook.project().relative_path(), filename),
)
Expand Down
4 changes: 3 additions & 1 deletion crates/prek/src/hooks/pre_commit_hooks/check_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ use std::path::Path;
use anyhow::Result;

use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::{FilenamesArgs, hook_filenames, parse_hook_args};
use crate::hooks::run_concurrent_file_checks;
use crate::run::INTERNAL_CONCURRENCY;

pub(crate) async fn check_toml(hook: &Hook, filenames: &[&Path]) -> Result<(i32, Vec<u8>)> {
let args: FilenamesArgs = parse_hook_args(hook)?;
run_concurrent_file_checks(
filenames.iter().copied(),
hook_filenames(&args.filenames, filenames),
*INTERNAL_CONCURRENCY,
|filename| check_file(hook.project().relative_path(), filename),
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::BTreeSet;
use std::io::{BufRead, BufReader, Write};
use std::path::Path;
use std::path::{Path, PathBuf};
use std::sync::Arc;

use anyhow::Result;
Expand All @@ -9,6 +9,7 @@ use memchr::memmem;
use regex::bytes::{Match, Regex};

use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::{hook_filenames, parse_hook_args};
use crate::hooks::run_concurrent_file_checks;
use crate::run::INTERNAL_CONCURRENCY;

Expand All @@ -19,6 +20,8 @@ use crate::run::INTERNAL_CONCURRENCY;
struct Args {
#[arg(long = "additional-github-domain")]
additional_github_domains: Vec<String>,
#[arg(value_name = "FILENAMES")]
filenames: Vec<PathBuf>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -82,14 +85,14 @@ pub(crate) async fn check_vcs_permalinks(
hook: &Hook,
filenames: &[&Path],
) -> Result<(i32, Vec<u8>)> {
let args = Args::try_parse_from(hook.entry.expect_direct().split_with_args(&hook.args)?)?;
let args: Args = parse_hook_args(hook)?;
let matcher = Arc::new(GithubNonPermalinkMatcher::new(
args.additional_github_domains,
));

let file_base = hook.project().relative_path();
run_concurrent_file_checks(
filenames.iter().copied(),
hook_filenames(&args.filenames, filenames),
*INTERNAL_CONCURRENCY,
|filename| check_file(file_base, filename, &matcher),
)
Expand Down
4 changes: 3 additions & 1 deletion crates/prek/src/hooks/pre_commit_hooks/check_xml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ use anyhow::Result;
use xml::reader::ParserConfig;

use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::{FilenamesArgs, hook_filenames, parse_hook_args};
use crate::hooks::run_concurrent_file_checks;
use crate::run::INTERNAL_CONCURRENCY;

pub(crate) async fn check_xml(hook: &Hook, filenames: &[&Path]) -> Result<(i32, Vec<u8>)> {
let args: FilenamesArgs = parse_hook_args(hook)?;
run_concurrent_file_checks(
filenames.iter().copied(),
hook_filenames(&args.filenames, filenames),
*INTERNAL_CONCURRENCY,
|filename| check_file(hook.project().relative_path(), filename),
)
Expand Down
9 changes: 6 additions & 3 deletions crates/prek/src/hooks/pre_commit_hooks/check_yaml.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::path::Path;
use std::path::{Path, PathBuf};

use anyhow::Result;
use clap::Parser;
use serde::de::IgnoredAny;

use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::{hook_filenames, parse_hook_args};
use crate::hooks::run_concurrent_file_checks;
use crate::run::INTERNAL_CONCURRENCY;

Expand All @@ -15,16 +16,18 @@ use crate::run::INTERNAL_CONCURRENCY;
struct Args {
#[arg(long, short = 'm', alias = "multi")]
allow_multiple_documents: bool,
#[arg(value_name = "FILENAMES")]
filenames: Vec<PathBuf>,
// `--unsafe` flag is not supported yet.
// #[arg(long)]
// r#unsafe: bool,
}

pub(crate) async fn check_yaml(hook: &Hook, filenames: &[&Path]) -> Result<(i32, Vec<u8>)> {
let args = Args::try_parse_from(hook.entry.expect_direct().split_with_args(&hook.args)?)?;
let args: Args = parse_hook_args(hook)?;

run_concurrent_file_checks(
filenames.iter().copied(),
hook_filenames(&args.filenames, filenames),
*INTERNAL_CONCURRENCY,
|filename| {
check_file(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ use rustc_hash::FxHashSet;

use crate::git;
use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::{FilenamesArgs, hook_filenames, parse_hook_args};

const ORDINARY_CHANGED_ENTRY_MARKER: &str = "1";
const PERMS_LINK: u32 = 0o120_000;
const PERMS_NONEXIST: u32 = 0;

pub(crate) async fn destroyed_symlinks(hook: &Hook, filenames: &[&Path]) -> Result<(i32, Vec<u8>)> {
let args: FilenamesArgs = parse_hook_args(hook)?;
let filenames = hook_filenames(&args.filenames, filenames).collect::<Vec<_>>();
let status_output = git_status_output(hook.work_dir()).await?;
let entries = status_output
.split(|&byte| byte == b'\0')
Expand All @@ -22,7 +25,7 @@ pub(crate) async fn destroyed_symlinks(hook: &Hook, filenames: &[&Path]) -> Resu
Err(err) => Some(Err(err)),
});

let destroyed_links = find_destroyed_symlinks(hook, filenames, entries).await?;
let destroyed_links = find_destroyed_symlinks(hook, &filenames, entries).await?;
if destroyed_links.is_empty() {
return Ok((0, Vec::new()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use aho_corasick::AhoCorasick;
use anyhow::Result;

use crate::hook::Hook;
use crate::hooks::pre_commit_hooks::{FilenamesArgs, hook_filenames, parse_hook_args};
use crate::hooks::run_concurrent_file_checks;
use crate::run::INTERNAL_CONCURRENCY;

Expand Down Expand Up @@ -42,8 +43,9 @@ static PRIVATE_KEY_MATCHER: LazyLock<AhoCorasick> = LazyLock::new(|| {
});

pub(crate) async fn detect_private_key(hook: &Hook, filenames: &[&Path]) -> Result<(i32, Vec<u8>)> {
let args: FilenamesArgs = parse_hook_args(hook)?;
run_concurrent_file_checks(
filenames.iter().copied(),
hook_filenames(&args.filenames, filenames),
*INTERNAL_CONCURRENCY,
|filename| check_file(hook.project().relative_path(), filename),
)
Expand Down
13 changes: 8 additions & 5 deletions crates/prek/src/hooks/pre_commit_hooks/file_contents_sorter.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::path::Path;
use std::path::{Path, PathBuf};

use anyhow::Result;
use bstr::ByteSlice;
use clap::Parser;

use crate::hook::Hook;
use crate::hooks::run_concurrent_file_checks;
use crate::hooks::pre_commit_hooks::{parse_hook_args, run_file_checks};
use crate::run::INTERNAL_CONCURRENCY;

#[derive(Parser)]
Expand All @@ -17,17 +17,20 @@ struct Args {
ignore_case: bool,
#[arg(long, conflicts_with = "ignore_case")]
unique: bool,
#[arg(value_name = "FILENAMES")]
filenames: Vec<PathBuf>,
}

pub(crate) async fn file_contents_sorter(
hook: &Hook,
filenames: &[&Path],
) -> Result<(i32, Vec<u8>)> {
let args = Args::try_parse_from(hook.entry.expect_direct().split_with_args(&hook.args)?)?;
let args: Args = parse_hook_args(hook)?;
let file_base = hook.project().relative_path();

run_concurrent_file_checks(
filenames.iter().copied(),
run_file_checks(
&args.filenames,
filenames,
*INTERNAL_CONCURRENCY,
|filename| sort_file(file_base, filename, args.ignore_case, args.unique),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use anyhow::Result;
use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt, SeekFrom};

use crate::hook::Hook;
use crate::hooks::run_concurrent_file_checks;
use crate::hooks::pre_commit_hooks::{FilenamesArgs, parse_hook_args, run_file_checks};
use crate::run::INTERNAL_CONCURRENCY;

const UTF8_BOM: &[u8] = b"\xef\xbb\xbf";
Expand All @@ -14,8 +14,10 @@ pub(crate) async fn fix_byte_order_marker(
hook: &Hook,
filenames: &[&Path],
) -> Result<(i32, Vec<u8>)> {
run_concurrent_file_checks(
filenames.iter().copied(),
let args: FilenamesArgs = parse_hook_args(hook)?;
run_file_checks(
&args.filenames,
filenames,
*INTERNAL_CONCURRENCY,
|filename| fix_file(hook.project().relative_path(), filename),
)
Expand Down
Loading
Loading