mod common;
use anyhow::Result;
use assert_cmd::assert::OutputAssertExt;
use assert_fs::fixture::{FileWriteStr, PathChild};
use indoc::indoc;
use prek_consts::env_vars::EnvVars;
use crate::common::{TestContext, cmd_snapshot, git_cmd};
#[test]
fn basic_discovery() -> Result<()> {
let context = TestContext::new();
let cwd = context.work_dir();
context.init_project();
let config = indoc! {r"
repos:
- repo: local
hooks:
- id: show-cwd
name: Show CWD
language: python
entry: python -c 'import sys, os; print(os.getcwd()); print(sys.argv[1:])'
verbose: true
"};
context.setup_workspace(
&[
"project2",
"project3",
"nested/project4",
"project3/project5",
],
config,
)?;
context.git_add(".");
cmd_snapshot!(context.filters(), context.run(), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `nested/project4`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/nested/project4
['.pre-commit-config.yaml']
Running hooks for `project3/project5`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project5
['.pre-commit-config.yaml']
Running hooks for `project2`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
Running hooks for `project3`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project5/.pre-commit-config.yaml', '.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['nested/project4/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project5/.pre-commit-config.yaml', 'project2/.pre-commit-config.yaml']
[TEMP_DIR]/
['project3/.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().current_dir(cwd.join("project2")), @r"
success: true
exit_code: 0
----- stdout -----
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().current_dir(cwd.join("project2")).arg("--all-files"), @r"
success: true
exit_code: 0
----- stdout -----
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().current_dir(cwd.join("project3")), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project5`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project5
['.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project5/.pre-commit-config.yaml', '.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().arg("--cd").arg(cwd.join("project3")), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project5`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project5
['.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project5/.pre-commit-config.yaml', '.pre-commit-config.yaml']
----- stderr -----
");
context
.work_dir()
.child("project3/.prekignore")
.write_str("project5/\n")?;
context.git_add(".");
cmd_snapshot!(context.filters(), context.run().arg("--refresh").arg("--cd").arg(cwd.join("project3")), @r"
success: true
exit_code: 0
----- stdout -----
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['.prekignore', '.pre-commit-config.yaml', 'project5/.pre-commit-config.yaml']
----- stderr -----
");
context
.work_dir()
.child("project3/.prekignore")
.write_str("*\n")?;
context.git_add(".");
cmd_snapshot!(context.filters(), context.run().arg("--refresh").arg("--cd").arg(cwd.join("project3")), @r"
success: true
exit_code: 0
----- stdout -----
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['.prekignore', '.pre-commit-config.yaml', 'project5/.pre-commit-config.yaml']
----- stderr -----
");
Ok(())
}
#[test]
fn config_not_staged() -> Result<()> {
let context = TestContext::new();
let cwd = context.work_dir();
context.init_project();
let config = indoc! {r"
repos:
- repo: local
hooks:
- id: show-cwd
name: Show CWD
language: python
entry: python -c 'import sys, os; print(os.getcwd()); print(sys.argv[1:])'
verbose: true
"};
context.setup_workspace(
&[
"project2",
"project3",
"nested/project4",
"project3/project5",
],
config,
)?;
context.git_add(".");
let config = indoc! {r"
repos:
- repo: local
hooks:
- id: show-cwd-modified
name: Show CWD
language: python
entry: python -c 'import sys, os; print(os.getcwd()); print(sys.argv[1:])'
verbose: true
"};
context.setup_workspace(
&[
"project2",
"project3",
"nested/project4",
"project3/project5",
],
config,
)?;
cmd_snapshot!(context.filters(), context.run(), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: The following configuration files are not staged, `git add` them first:
.pre-commit-config.yaml
nested/project4/.pre-commit-config.yaml
project2/.pre-commit-config.yaml
project3/.pre-commit-config.yaml
project3/project5/.pre-commit-config.yaml
");
cmd_snapshot!(context.filters(), context.run().current_dir(cwd.join("project3")), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: The following configuration files are not staged, `git add` them first:
.pre-commit-config.yaml
project5/.pre-commit-config.yaml
");
cmd_snapshot!(context.filters(), context.run().current_dir(cwd.join("project2")), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: prek configuration file is not staged, run `git add .pre-commit-config.yaml` to stage it
");
Ok(())
}
#[test]
fn run_with_selectors() -> Result<()> {
let context = TestContext::new();
context.init_project();
let config = indoc! {r"
repos:
- repo: local
hooks:
- id: show-cwd
name: Show CWD
language: python
entry: python -c 'import sys, os; print(os.getcwd()); print(sys.argv[1:])'
verbose: true
"};
context.setup_workspace(
&[
"project2",
"project3",
"nested/project4",
"project3/project5",
],
config,
)?;
context.git_add(".");
cmd_snapshot!(context.filters(), context.run().arg("project2/"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project2`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().arg("--skip").arg("project2/"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `nested/project4`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/nested/project4
['.pre-commit-config.yaml']
Running hooks for `project3/project5`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project5
['.pre-commit-config.yaml']
Running hooks for `project3`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project5/.pre-commit-config.yaml', '.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['nested/project4/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project5/.pre-commit-config.yaml', 'project2/.pre-commit-config.yaml']
[TEMP_DIR]/
['project3/.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().arg("--skip").arg("nested/").arg("--skip").arg("project3/"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project2`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['nested/project4/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project5/.pre-commit-config.yaml', 'project2/.pre-commit-config.yaml']
[TEMP_DIR]/
['project3/.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().arg("show-cwd"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `nested/project4`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/nested/project4
['.pre-commit-config.yaml']
Running hooks for `project3/project5`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project5
['.pre-commit-config.yaml']
Running hooks for `project2`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
Running hooks for `project3`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project5/.pre-commit-config.yaml', '.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['nested/project4/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project5/.pre-commit-config.yaml', 'project2/.pre-commit-config.yaml']
[TEMP_DIR]/
['project3/.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().arg("project2:show-cwd"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project2`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().arg(".:show-cwd"), @r"
success: true
exit_code: 0
----- stdout -----
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['nested/project4/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project5/.pre-commit-config.yaml', 'project2/.pre-commit-config.yaml']
[TEMP_DIR]/
['project3/.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().arg("--skip").arg("show-cwd"), @r"
success: false
exit_code: 1
----- stdout -----
----- stderr -----
error: No hooks found after filtering with the given selectors
");
cmd_snapshot!(context.filters(), context.run().arg("--skip").arg("project2:show-cwd").arg("--skip").arg("nested:show-cwd"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `nested/project4`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/nested/project4
['.pre-commit-config.yaml']
Running hooks for `project3/project5`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project5
['.pre-commit-config.yaml']
Running hooks for `project3`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project5/.pre-commit-config.yaml', '.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['nested/project4/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project5/.pre-commit-config.yaml', 'project2/.pre-commit-config.yaml']
[TEMP_DIR]/
['project3/.pre-commit-config.yaml']
----- stderr -----
warning: selector `--skip=nested:show-cwd` did not match any hooks
");
cmd_snapshot!(context.filters(), context.run().arg("--skip").arg("non-exist"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `nested/project4`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/nested/project4
['.pre-commit-config.yaml']
Running hooks for `project3/project5`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project5
['.pre-commit-config.yaml']
Running hooks for `project2`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
Running hooks for `project3`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project5/.pre-commit-config.yaml', '.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['nested/project4/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project5/.pre-commit-config.yaml', 'project2/.pre-commit-config.yaml']
[TEMP_DIR]/
['project3/.pre-commit-config.yaml']
----- stderr -----
warning: selector `--skip=non-exist` did not match any hooks
");
cmd_snapshot!(context.filters(), context.run().arg("--skip").arg("../"), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: Invalid selector: `../`
caused by: Invalid project path: `../`
caused by: path is outside the workspace root
");
cmd_snapshot!(context.filters(), context.run().current_dir(context.work_dir().join("project2")), @r"
success: true
exit_code: 0
----- stdout -----
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
----- stderr -----
");
Ok(())
}
#[test]
fn skips() -> Result<()> {
let context = TestContext::new();
context.init_project();
let config = indoc! {r"
repos:
- repo: local
hooks:
- id: show-cwd
name: Show CWD
language: python
entry: python -c 'import sys, os; print(os.getcwd()); print(sys.argv[1:])'
verbose: true
"};
context.setup_workspace(&["project2", "project3", "project3/project4"], config)?;
context.git_add(".");
cmd_snapshot!(context.filters(), context.run().arg("--skip").arg("project2/"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project3/project4`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project4
['.pre-commit-config.yaml']
Running hooks for `project3`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project4/.pre-commit-config.yaml', '.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['project2/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project4/.pre-commit-config.yaml', 'project3/.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().env(EnvVars::PREK_SKIP, "project2/"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project3/project4`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project4
['.pre-commit-config.yaml']
Running hooks for `project3`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project4/.pre-commit-config.yaml', '.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['project2/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project4/.pre-commit-config.yaml', 'project3/.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().env(EnvVars::SKIP, "project2/"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project3/project4`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project4
['.pre-commit-config.yaml']
Running hooks for `project3`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project4/.pre-commit-config.yaml', '.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['project2/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project4/.pre-commit-config.yaml', 'project3/.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().arg("--skip").arg("project2/").env(EnvVars::PREK_SKIP, "project3/"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project3/project4`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project4
['.pre-commit-config.yaml']
Running hooks for `project3`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project4/.pre-commit-config.yaml', '.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['project2/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project4/.pre-commit-config.yaml', 'project3/.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().env(EnvVars::PREK_SKIP, "project2/").env(EnvVars::SKIP, "project3/"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project3/project4`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3/project4
['.pre-commit-config.yaml']
Running hooks for `project3`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project3
['project4/.pre-commit-config.yaml', '.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['project2/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project4/.pre-commit-config.yaml', 'project3/.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().env("PREK_SKIP", "project2/,project3/,non-exist-hook"), @r"
success: true
exit_code: 0
----- stdout -----
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['project2/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project4/.pre-commit-config.yaml', 'project3/.pre-commit-config.yaml']
----- stderr -----
warning: selector `PREK_SKIP=non-exist-hook` did not match any hooks
");
context
.work_dir()
.child("project3/.pre-commit-config.yaml")
.write_str("invalid_yaml: [")?;
context.git_add(".");
cmd_snapshot!(context.filters(), context.run(), @"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: Failed to parse `project3/.pre-commit-config.yaml`
caused by: error: line 1 column 15: unclosed bracket '['
--> <input>:1:15
|
1 | invalid_yaml: [
| ^ unclosed bracket '['
");
cmd_snapshot!(context.filters(), context.run().arg("--skip").arg("project3/"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project2`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['project2/.pre-commit-config.yaml', '.pre-commit-config.yaml', 'project3/project4/.pre-commit-config.yaml', 'project3/.pre-commit-config.yaml']
----- stderr -----
");
Ok(())
}
#[test]
fn workspace_no_projects() {
let context = TestContext::new();
context.init_project();
context.write_pre_commit_config("repos: []");
context.git_add(".");
cmd_snapshot!(context.filters(), context.run().arg("--skip").arg("."), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: No `prek.toml` or `.pre-commit-config.yaml` found in the current directory or parent directories.
hint: If you just added one, rerun your command with the `--refresh` flag to rescan the workspace.
");
}
#[test]
fn gitignore_respected() -> Result<()> {
let context = TestContext::new();
context.init_project();
let config = indoc! {r"
repos:
- repo: local
hooks:
- id: show-cwd
name: Show CWD
language: python
entry: python -c 'import sys, os; print(os.getcwd()); print(sorted(sys.argv[1:]))'
verbose: true
"};
context.setup_workspace(
&[
"src",
"node_modules/ignored", "target/ignored", ],
config,
)?;
context
.work_dir()
.child(".gitignore")
.write_str("node_modules/\ntarget/\n")?;
context.git_add(".");
cmd_snapshot!(context.filters(), context.run(), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `src`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/src
['.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['.gitignore', '.pre-commit-config.yaml', 'src/.pre-commit-config.yaml']
----- stderr -----
");
Ok(())
}
#[test]
fn nested_project_exclude_is_relative() -> Result<()> {
let context = TestContext::new();
context.init_project();
let config = indoc! {r#"
exclude: \.pre-commit-config\.yaml$|^excluded_by_project$
repos:
- repo: local
hooks:
- id: show-files
name: Show Files
language: python
entry: python -c 'import sys; print("Processing {} files".format(len(sys.argv[1:]))); [print(" - {}".format(f)) for f in sys.argv[1:]]'
pass_filenames: true
verbose: true
"#};
context.setup_workspace(&["nested"], config)?;
context
.work_dir()
.child("excluded_by_project")
.write_str("")?;
context.work_dir().child("nested/include").write_str("")?;
context
.work_dir()
.child("nested/excluded_by_project")
.write_str("")?;
context.git_add(".");
cmd_snapshot!(context.filters(), context.run().arg("--all-files"), @"
success: true
exit_code: 0
----- stdout -----
Running hooks for `nested`:
Show Files...............................................................Passed
- hook id: show-files
- duration: [TIME]
Processing 1 files
- include
Running hooks for `.`:
Show Files...............................................................Passed
- hook id: show-files
- duration: [TIME]
Processing 2 files
- nested/include
- nested/excluded_by_project
----- stderr -----
");
Ok(())
}
#[test]
fn reference_files_across_projects() -> Result<()> {
let context = TestContext::new();
context.init_project();
let config = indoc! {r"
repos:
- repo: local
hooks:
- id: echo
name: echo
language: system
entry: echo
verbose: true
"};
context.setup_workspace(&["frontend", "backend"], config)?;
let cwd = context.work_dir();
cwd.child("backend/app.py")
.write_str("print('Hello from backend')")?;
context.git_add(".");
cmd_snapshot!(context.filters(), context.run().current_dir(cwd.child("frontend")).arg("--files").arg("../backend/app.py").arg("../backend/non-exist.py"), @r"
success: true
exit_code: 0
----- stdout -----
echo.................................................(no files to check)Skipped
----- stderr -----
warning: This file does not exist and will be ignored: `../backend/non-exist.py`
");
Ok(())
}
#[test]
fn submodule_discovery() -> Result<()> {
let context = TestContext::new();
let cwd = context.work_dir();
context.init_project();
let config = indoc! {r"
repos:
- repo: local
hooks:
- id: show-cwd
name: Show CWD
language: python
entry: python -c 'import sys, os; print(os.getcwd()); print(sys.argv[1:])'
verbose: true
"};
context.setup_workspace(&["project2"], config)?;
let submodule_path = cwd.child("submodule");
let submodule_context = TestContext::new_at(submodule_path.to_path_buf());
submodule_context.init_project();
submodule_context.write_pre_commit_config(config);
submodule_context.git_add(".");
submodule_context.git_commit("Initial commit");
git_cmd(cwd)
.args(["submodule", "add", "./submodule"])
.assert()
.success();
context.git_add(".");
cmd_snapshot!(context.filters(), context.run().arg("--all-files"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project2`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['.pre-commit-config.yaml', '.gitmodules', 'project2/.pre-commit-config.yaml']
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().current_dir(&submodule_path).arg("--all-files"), @r"
success: true
exit_code: 0
----- stdout -----
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/submodule
['.pre-commit-config.yaml']
----- stderr -----
");
std::fs::remove_file(submodule_path.join(".pre-commit-config.yaml"))?;
submodule_context.git_add(".");
submodule_context.git_commit("Remove config");
cmd_snapshot!(context.filters(), context.run().current_dir(&submodule_path), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: No `prek.toml` or `.pre-commit-config.yaml` found in the current directory or parent directories.
hint: If you just added one, rerun your command with the `--refresh` flag to rescan the workspace.
");
Ok(())
}
#[test]
fn cookiecutter_template_directories_are_skipped() -> Result<()> {
let context = TestContext::new();
context.init_project();
let config = indoc! {r"
repos:
- repo: local
hooks:
- id: show-cwd
name: Show CWD
language: python
entry: python -c 'import sys, os; print(os.getcwd()); print(sys.argv[1:])'
verbose: true
"};
context.setup_workspace(&["project2", "{{cookiecutter.project_slug}}"], config)?;
context.git_add(".pre-commit-config.yaml");
context.git_add("project2/.pre-commit-config.yaml");
cmd_snapshot!(context.filters(), context.run().arg("--refresh").arg("--all-files"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `project2`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/project2
['.pre-commit-config.yaml']
Running hooks for `.`:
Show CWD.................................................................Passed
- hook id: show-cwd
- duration: [TIME]
[TEMP_DIR]/
['project2/.pre-commit-config.yaml', '.pre-commit-config.yaml']
----- stderr -----
");
Ok(())
}
#[test]
fn orphan_projects() -> Result<()> {
let context = TestContext::new();
context.init_project();
let config = indoc! {r#"
exclude: \.pre-commit-config\.yaml$
repos:
- repo: local
hooks:
- id: show-files
name: Show Files
language: python
entry: python -c 'import sys; print("Processing {} files".format(len(sys.argv[1:]))); [print(" - {}".format(f)) for f in sys.argv[1:]]'
pass_filenames: true
verbose: true
"#};
context
.work_dir()
.child("src/backend/.pre-commit-config.yaml")
.write_str(config)?;
context
.work_dir()
.child("src/.pre-commit-config.yaml")
.write_str(config)?;
context
.work_dir()
.child(".pre-commit-config.yaml")
.write_str(config)?;
context
.work_dir()
.child("src/backend/test.py")
.write_str("")?;
context.work_dir().child("src/test.py").write_str("")?;
context.work_dir().child("test.py").write_str("")?;
context.git_add(".");
cmd_snapshot!(context.filters(), context.run().arg("--all-files"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `src/backend`:
Show Files...............................................................Passed
- hook id: show-files
- duration: [TIME]
Processing 1 files
- test.py
Running hooks for `src`:
Show Files...............................................................Passed
- hook id: show-files
- duration: [TIME]
Processing 2 files
- test.py
- backend/test.py
Running hooks for `.`:
Show Files...............................................................Passed
- hook id: show-files
- duration: [TIME]
Processing 3 files
- src/test.py
- src/backend/test.py
- test.py
----- stderr -----
");
context
.work_dir()
.child("src/backend/.pre-commit-config.yaml")
.write_str(indoc! {r#"
orphan: true
exclude: \.pre-commit-config\.yaml$
repos:
- repo: local
hooks:
- id: show-files
name: Show Files
language: python
entry: python -c 'import sys; print("Processing {} files".format(len(sys.argv[1:]))); [print(" - {}".format(f)) for f in sys.argv[1:]]'
pass_filenames: true
verbose: true
"#})?;
context
.work_dir()
.child("src/.pre-commit-config.yaml")
.write_str(indoc! {r#"
orphan: true
files: ^$
exclude: \.pre-commit-config\.yaml$
repos:
- repo: local
hooks:
- id: show-files
name: Show Files
language: python
entry: python -c 'import sys; print("Processing {} files".format(len(sys.argv[1:]))); [print(" - {}".format(f)) for f in sys.argv[1:]]'
pass_filenames: true
verbose: true
"#})?;
context
.work_dir()
.child(".pre-commit-config.yaml")
.write_str(indoc! {r#"
orphan: false
exclude: \.pre-commit-config\.yaml$
repos:
- repo: local
hooks:
- id: show-files
name: Show Files
language: python
entry: python -c 'import sys; print("Processing {} files".format(len(sys.argv[1:]))); [print(" - {}".format(f)) for f in sys.argv[1:]]'
pass_filenames: true
verbose: true
"#})?;
cmd_snapshot!(context.filters(), context.run().arg("--all-files"), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `src/backend`:
Show Files...............................................................Passed
- hook id: show-files
- duration: [TIME]
Processing 1 files
- test.py
Running hooks for `src`:
Show Files...........................................(no files to check)Skipped
Running hooks for `.`:
Show Files...............................................................Passed
- hook id: show-files
- duration: [TIME]
Processing 1 files
- test.py
----- stderr -----
");
cmd_snapshot!(context.filters(), context.run().arg("--all-files").arg("--skip").arg("src/"), @r"
success: true
exit_code: 0
----- stdout -----
Show Files...............................................................Passed
- hook id: show-files
- duration: [TIME]
Processing 1 files
- test.py
----- stderr -----
");
Ok(())
}
#[test]
fn relative_repo_path_resolution() -> Result<()> {
use assert_fs::fixture::PathCreateDir;
use prek_consts::{PRE_COMMIT_CONFIG_YAML, PRE_COMMIT_HOOKS_YAML};
let context = TestContext::new();
context.init_project();
let hook_repo = context.work_dir().child("hook-repo");
hook_repo.create_dir_all()?;
git_cmd(&hook_repo).args(["init"]).assert().success();
git_cmd(&hook_repo)
.args(["config", "user.name", "Test"])
.assert()
.success();
git_cmd(&hook_repo)
.args(["config", "user.email", "test@test.com"])
.assert()
.success();
git_cmd(&hook_repo)
.args(["config", "core.autocrlf", "false"])
.assert()
.success();
hook_repo.child(PRE_COMMIT_HOOKS_YAML).write_str(indoc! {r"
- id: test-hook
name: Test Hook
entry: echo test
language: system
always_run: true
"})?;
git_cmd(&hook_repo).args(["add", "."]).assert().success();
git_cmd(&hook_repo)
.args(["commit", "--no-si", "-m", "Initial commit"])
.assert()
.success();
let output = git_cmd(&hook_repo).args(["rev-parse", "HEAD"]).output()?;
let commit_sha = String::from_utf8_lossy(&output.stdout).trim().to_string();
let subproject = context.work_dir().child("subproject");
subproject.create_dir_all()?;
subproject
.child(PRE_COMMIT_CONFIG_YAML)
.write_str(&indoc::formatdoc! {r"
repos:
- repo: ../hook-repo
rev: {commit_sha}
hooks:
- id: test-hook
always_run: true
"})?;
subproject.child("test.txt").write_str("test content")?;
context.write_pre_commit_config(indoc! {r"
repos:
- repo: local
hooks:
- id: noop
name: Noop
entry: echo noop
language: system
always_run: true
"});
context.git_add(".");
cmd_snapshot!(context.filters(), context.run(), @r"
success: true
exit_code: 0
----- stdout -----
Running hooks for `subproject`:
Test Hook................................................................Passed
Running hooks for `.`:
Noop.....................................................................Passed
----- stderr -----
");
Ok(())
}