diff --git a/crates/prek/src/cli/mod.rs b/crates/prek/src/cli/mod.rs index 91de4f36..651054f7 100644 --- a/crates/prek/src/cli/mod.rs +++ b/crates/prek/src/cli/mod.rs @@ -202,9 +202,9 @@ pub(crate) struct GlobalArgs { #[derive(Debug, Subcommand)] pub(crate) enum Command { - /// Install the prek git hook. + /// Install prek as a git hook under the `.git/hooks/` directory. Install(InstallArgs), - /// Create hook environments for all hooks used in the config file. + /// Create environments for all hooks used in the config file. /// /// This command does not install the git hook. To install the git hook along with the hook environments in one command, use `prek install --install-hooks`. InstallHooks(InstallHooksArgs), @@ -212,17 +212,15 @@ pub(crate) enum Command { Run(Box), /// List available hooks. List(ListArgs), - /// Show file identification tags. - Identify(IdentifyArgs), - /// Uninstall the prek git hook. + /// Uninstall prek from git hooks. Uninstall(UninstallArgs), - /// Validate `.pre-commit-config.yaml` files. + /// Validate configuration files (prek.toml or .pre-commit-config.yaml). ValidateConfig(ValidateConfigArgs), /// Validate `.pre-commit-hooks.yaml` files. ValidateManifest(ValidateManifestArgs), - /// Produce a sample `.pre-commit-config.yaml` file. + /// Produce a sample configuration file (prek.toml or .pre-commit-config.yaml). SampleConfig(SampleConfigArgs), - /// Auto-update pre-commit config to the latest repos' versions. + /// Auto-update the `rev` field of repositories in the config file to the latest version. #[command(alias = "autoupdate")] AutoUpdate(AutoUpdateArgs), /// Manage the prek cache. @@ -234,19 +232,18 @@ pub(crate) enum Command { #[command(hide = true)] Clean, /// Install hook script in a directory intended for use with `git config init.templateDir`. - #[command(alias = "init-templatedir")] + #[command(alias = "init-templatedir", hide = true)] InitTemplateDir(InitTemplateDirArgs), /// Try the pre-commit hooks in the current repo. TryRepo(Box), - /// The implementation of the `pre-commit` hook. + /// The implementation of the prek hook script that is installed in the `.git/hooks/` directory. #[command(hide = true)] HookImpl(HookImplArgs), + /// Utility commands. + Util(UtilNamespace), /// `prek` self management. #[command(name = "self")] Self_(SelfNamespace), - /// Generate shell completion scripts. - #[command(hide = true)] - GenerateShellCompletion(GenerateShellCompletionArgs), } #[derive(Debug, Args)] @@ -287,7 +284,7 @@ pub(crate) struct InstallArgs { #[arg(short = 'f', long)] pub(crate) overwrite: bool, - /// Create hook environments for all hooks used in the config file. + /// Create environments for all hooks used in the config file. #[arg(long)] pub(crate) install_hooks: bool, @@ -304,7 +301,7 @@ pub(crate) struct InstallArgs { #[arg(short = 't', long = "hook-type", value_name = "HOOK_TYPE", value_enum)] pub(crate) hook_types: Vec, - /// Allow a missing `pre-commit` configuration file. + /// Allow a missing configuration file. #[arg(long)] pub(crate) allow_missing_config: bool, } @@ -713,6 +710,24 @@ pub(crate) struct CacheNamespace { pub(crate) command: CacheCommand, } +#[derive(Debug, Args)] +pub(crate) struct UtilNamespace { + #[command(subcommand)] + pub(crate) command: UtilCommand, +} + +#[derive(Debug, Subcommand)] +pub(crate) enum UtilCommand { + /// Show file identification tags. + Identify(IdentifyArgs), + /// Install hook script in a directory intended for use with `git config init.templateDir`. + #[command(alias = "init-templatedir")] + InitTemplateDir(InitTemplateDirArgs), + /// Generate shell completion scripts. + #[command(hide = true)] + GenerateShellCompletion(GenerateShellCompletionArgs), +} + #[derive(Debug, Subcommand)] pub(crate) enum CacheCommand { /// Show the location of the prek cache. diff --git a/crates/prek/src/main.rs b/crates/prek/src/main.rs index b6e07624..332802df 100644 --- a/crates/prek/src/main.rs +++ b/crates/prek/src/main.rs @@ -19,7 +19,9 @@ use tracing_subscriber::util::SubscriberInitExt; use tracing_subscriber::{EnvFilter, Layer}; use crate::cleanup::cleanup; -use crate::cli::{CacheCommand, CacheNamespace, Cli, Command, ExitStatus}; +use crate::cli::{ + CacheCommand, CacheNamespace, Cli, Command, ExitStatus, UtilCommand, UtilNamespace, +}; #[cfg(feature = "self-update")] use crate::cli::{SelfCommand, SelfNamespace, SelfUpdateArgs}; use crate::printer::Printer; @@ -299,11 +301,6 @@ async fn run(cli: Cli) -> Result { ) .await } - Command::Identify(args) => { - show_settings!(args); - - cli::identify(&args.paths, args.output_format, printer) - } Command::HookImpl(args) => { show_settings!(args); @@ -381,6 +378,38 @@ async fn run(cli: Cli) -> Result { ) .await } + Command::Util(UtilNamespace { command }) => match command { + UtilCommand::Identify(args) => { + show_settings!(args); + + cli::identify(&args.paths, args.output_format, printer) + } + UtilCommand::InitTemplateDir(args) => { + show_settings!(args); + + cli::init_template_dir( + &store, + args.directory, + cli.globals.config, + args.hook_types, + args.no_allow_missing_config, + cli.globals.refresh, + printer, + ) + .await + } + UtilCommand::GenerateShellCompletion(args) => { + show_settings!(args); + + let mut command = Cli::command(); + let bin_name = command + .get_bin_name() + .unwrap_or_else(|| command.get_name()) + .to_owned(); + clap_complete::generate(args.shell, &mut command, bin_name, &mut std::io::stdout()); + Ok(ExitStatus::Success) + } + }, #[cfg(feature = "self-update")] Command::Self_(SelfNamespace { command: @@ -409,18 +438,6 @@ async fn run(cli: Cli) -> Result { anyhow::bail!("{msg}"); } - - Command::GenerateShellCompletion(args) => { - show_settings!(args); - - let mut command = Cli::command(); - let bin_name = command - .get_bin_name() - .unwrap_or_else(|| command.get_name()) - .to_owned(); - clap_complete::generate(args.shell, &mut command, bin_name, &mut std::io::stdout()); - Ok(ExitStatus::Success) - } Command::InitTemplateDir(args) => { show_settings!(args); diff --git a/crates/prek/tests/identify.rs b/crates/prek/tests/identify.rs index 7e954e4f..e2951659 100644 --- a/crates/prek/tests/identify.rs +++ b/crates/prek/tests/identify.rs @@ -18,6 +18,7 @@ fn identify_text_with_missing_paths() -> anyhow::Result<()> { context.filters(), context .command() + .arg("util") .arg("identify") .arg(".") .arg("hello.py") @@ -50,6 +51,7 @@ fn identify_json_with_missing_paths() -> anyhow::Result<()> { context.filters(), context .command() + .arg("util") .arg("identify") .arg("--output-format") .arg("json") diff --git a/crates/prek/tests/install.rs b/crates/prek/tests/install.rs index 8d51bc3a..f73ec84f 100644 --- a/crates/prek/tests/install.rs +++ b/crates/prek/tests/install.rs @@ -459,6 +459,44 @@ fn init_template_dir() -> anyhow::Result<()> { Ok(()) } +/// Tests `prek util init-template-dir` works. +#[test] +fn util_init_template_dir() { + let context = TestContext::new(); + context.init_project(); + + cmd_snapshot!(context.filters(), context.command().arg("util").arg("init-templatedir").arg(".git"), @r#" + success: true + exit_code: 0 + ----- stdout ----- + prek installed at `.git/hooks/pre-commit` + + ----- stderr ----- + warning: git config `init.templateDir` not set to the target directory, try `git config --global init.templateDir '.git'` + "#); + + insta::with_settings!( + { filters => context.filters() }, + { + assert_snapshot!(context.read(".git/hooks/pre-commit"), @r#" + #!/bin/sh + # File generated by prek: https://github.com/j178/prek + # ID: 182c10f181da4464a3eec51b83331688 + + HERE="$(cd "$(dirname "$0")" && pwd)" + PREK="[CURRENT_EXE]" + + # Check if the full path to prek is executable, otherwise fallback to PATH + if [ ! -x "$PREK" ]; then + PREK="prek" + fi + + exec "$PREK" hook-impl --hook-dir "$HERE" --script-version 4 --hook-type=pre-commit --skip-on-missing-config -- "$@" + "#); + } + ); +} + /// Tests `prek init-template-dir` in a non-git repository. #[test] fn init_template_dir_non_git_repo() { diff --git a/crates/prek/tests/run.rs b/crates/prek/tests/run.rs index ca25ea0a..1f6fdb6f 100644 --- a/crates/prek/tests/run.rs +++ b/crates/prek/tests/run.rs @@ -2164,23 +2164,22 @@ fn selectors_completion() -> Result<()> { // Unrelated non-project dir should not appear in subdir suggestions cwd.child("scratch").create_dir_all()?; - cmd_snapshot!(context.filters(), context.run().env("COMPLETE", "fish").arg("--").arg("prek").arg(""), @r" + cmd_snapshot!(context.filters(), context.run().env("COMPLETE", "fish").arg("--").arg("prek").arg(""), @" success: true exit_code: 0 ----- stdout ----- - install Install the prek git hook - install-hooks Create hook environments for all hooks used in the config file + install Install prek as a git hook under the `.git/hooks/` directory + install-hooks Create environments for all hooks used in the config file run Run hooks list List available hooks - identify Show file identification tags - uninstall Uninstall the prek git hook - validate-config Validate `.pre-commit-config.yaml` files + uninstall Uninstall prek from git hooks + validate-config Validate configuration files (prek.toml or .pre-commit-config.yaml) validate-manifest Validate `.pre-commit-hooks.yaml` files - sample-config Produce a sample `.pre-commit-config.yaml` file - auto-update Auto-update pre-commit config to the latest repos' versions + sample-config Produce a sample configuration file (prek.toml or .pre-commit-config.yaml) + auto-update Auto-update the `rev` field of repositories in the config file to the latest version cache Manage the prek cache - init-template-dir Install hook script in a directory intended for use with `git config init.templateDir` try-repo Try the pre-commit hooks in the current repo + util Utility commands self `prek` self management app/ app: diff --git a/docs/cli.md b/docs/cli.md index ecd604fc..f7cb8e14 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -12,25 +12,24 @@ prek [OPTIONS] [HOOK|PROJECT]... [COMMAND]

Commands

-
prek install

Install the prek git hook

-
prek install-hooks

Create hook environments for all hooks used in the config file

+
prek install

Install prek as a git hook under the .git/hooks/ directory

+
prek install-hooks

Create environments for all hooks used in the config file

prek run

Run hooks

prek list

List available hooks

-
prek identify

Show file identification tags

-
prek uninstall

Uninstall the prek git hook

-
prek validate-config

Validate .pre-commit-config.yaml files

+
prek uninstall

Uninstall prek from git hooks

+
prek validate-config

Validate configuration files (prek.toml or .pre-commit-config.yaml)

prek validate-manifest

Validate .pre-commit-hooks.yaml files

-
prek sample-config

Produce a sample .pre-commit-config.yaml file

-
prek auto-update

Auto-update pre-commit config to the latest repos' versions

+
prek sample-config

Produce a sample configuration file (prek.toml or .pre-commit-config.yaml)

+
prek auto-update

Auto-update the rev field of repositories in the config file to the latest version

prek cache

Manage the prek cache

-
prek init-template-dir

Install hook script in a directory intended for use with git config init.templateDir

prek try-repo

Try the pre-commit hooks in the current repo

+
prek util

Utility commands

prek self

prek self management

## prek install -Install the prek git hook +Install prek as a git hook under the `.git/hooks/` directory

Usage

@@ -58,7 +57,7 @@ prek install [OPTIONS] [HOOK|PROJECT]...

Options

-
--allow-missing-config

Allow a missing pre-commit configuration file

+
--allow-missing-config

Allow a missing configuration file

--cd, -C dir

Change to directory before running

--color color

Whether to use color in output

May also be set with the PREK_COLOR environment variable.

[default: auto]

Possible values:

@@ -84,7 +83,7 @@ prek install [OPTIONS] [HOOK|PROJECT]...
  • pre-push
  • pre-rebase
  • prepare-commit-msg
  • -
    --install-hooks

    Create hook environments for all hooks used in the config file

    +
    --install-hooks

    Create environments for all hooks used in the config file

    --log-file log-file

    Write trace logs to the specified file. If not specified, trace logs will be written to $PREK_HOME/prek.log

    --no-progress

    Hide all progress outputs.

    For example, spinners or progress bars.

    @@ -112,7 +111,7 @@ prek install [OPTIONS] [HOOK|PROJECT]... ## prek install-hooks -Create hook environments for all hooks used in the config file. +Create environments for all hooks used in the config file. This command does not install the git hook. To install the git hook along with the hook environments in one command, use `prek install --install-hooks`. @@ -370,50 +369,9 @@ prek list [OPTIONS] [HOOK|PROJECT]...
    --version, -V

    Display the prek version

    -## prek identify - -Show file identification tags - -

    Usage

    - -``` -prek identify [OPTIONS] [PATH]... -``` - -

    Arguments

    - -
    PATH

    The path(s) to the file(s) to identify

    -
    - -

    Options

    - -
    --cd, -C dir

    Change to directory before running

    -
    --color color

    Whether to use color in output

    -

    May also be set with the PREK_COLOR environment variable.

    [default: auto]

    Possible values:

    -
      -
    • auto: Enables colored output only when the output is going to a terminal or TTY with support
    • -
    • always: Enables colored output regardless of the detected environment
    • -
    • never: Disables colored output
    • -
    --config, -c config

    Path to alternate config file

    -
    --help, -h

    Display the concise help for this command

    -
    --log-file log-file

    Write trace logs to the specified file. If not specified, trace logs will be written to $PREK_HOME/prek.log

    -
    --no-progress

    Hide all progress outputs.

    -

    For example, spinners or progress bars.

    -
    --output-format output-format

    The output format

    -

    [default: text]

    Possible values:

    -
      -
    • text
    • -
    • json
    • -
    --quiet, -q

    Use quiet output.

    -

    Repeating this option, e.g., -qq, will enable a silent mode in which prek will write no output to stdout.

    -

    May also be set with the PREK_QUIET environment variable.

    --refresh

    Refresh all cached data

    -
    --verbose, -v

    Use verbose output

    -
    --version, -V

    Display the prek version

    -
    - ## prek uninstall -Uninstall the prek git hook +Uninstall prek from git hooks

    Usage

    @@ -459,7 +417,7 @@ prek uninstall [OPTIONS] ## prek validate-config -Validate `.pre-commit-config.yaml` files +Validate configuration files (prek.toml or .pre-commit-config.yaml)

    Usage

    @@ -531,7 +489,7 @@ prek validate-manifest [OPTIONS] [MANIFEST]... ## prek sample-config -Produce a sample `.pre-commit-config.yaml` file +Produce a sample configuration file (prek.toml or .pre-commit-config.yaml)

    Usage

    @@ -569,7 +527,7 @@ prek sample-config [OPTIONS] ## prek auto-update -Auto-update pre-commit config to the latest repos' versions +Auto-update the `rev` field of repositories in the config file to the latest version

    Usage

    @@ -749,58 +707,6 @@ prek cache size [OPTIONS]
    --version, -V

    Display the prek version

    -## prek init-template-dir - -Install hook script in a directory intended for use with `git config init.templateDir` - -

    Usage

    - -``` -prek init-template-dir [OPTIONS] -``` - -

    Arguments

    - -
    DIRECTORY

    The directory in which to write the hook script

    -
    - -

    Options

    - -
    --cd, -C dir

    Change to directory before running

    -
    --color color

    Whether to use color in output

    -

    May also be set with the PREK_COLOR environment variable.

    [default: auto]

    Possible values:

    -
      -
    • auto: Enables colored output only when the output is going to a terminal or TTY with support
    • -
    • always: Enables colored output regardless of the detected environment
    • -
    • never: Disables colored output
    • -
    --config, -c config

    Path to alternate config file

    -
    --help, -h

    Display the concise help for this command

    -
    --hook-type, -t hook-type

    Which hook type(s) to install.

    -

    Specifies which git hook stage(s) you want to install the hook script for. Can be specified multiple times to install hooks for multiple stages.

    -

    If not specified, uses default_install_hook_types from the config file, or defaults to pre-commit if that is also not set.

    -

    Possible values:

    -
      -
    • commit-msg
    • -
    • post-checkout
    • -
    • post-commit
    • -
    • post-merge
    • -
    • post-rewrite
    • -
    • pre-commit
    • -
    • pre-merge-commit
    • -
    • pre-push
    • -
    • pre-rebase
    • -
    • prepare-commit-msg
    • -
    --log-file log-file

    Write trace logs to the specified file. If not specified, trace logs will be written to $PREK_HOME/prek.log

    -
    --no-allow-missing-config

    Assume cloned repos should have a pre-commit config

    -
    --no-progress

    Hide all progress outputs.

    -

    For example, spinners or progress bars.

    -
    --quiet, -q

    Use quiet output.

    -

    Repeating this option, e.g., -qq, will enable a silent mode in which prek will write no output to stdout.

    -

    May also be set with the PREK_QUIET environment variable.

    --refresh

    Refresh all cached data

    -
    --verbose, -v

    Use verbose output

    -
    --version, -V

    Display the prek version

    -
    - ## prek try-repo Try the pre-commit hooks in the current repo @@ -891,6 +797,115 @@ prek try-repo [OPTIONS] [HOOK|PROJECT]...
    --version, -V

    Display the prek version

    +## prek util + +Utility commands + +

    Usage

    + +``` +prek util [OPTIONS] +``` + +

    Commands

    + +
    prek util identify

    Show file identification tags

    +
    prek util init-template-dir

    Install hook script in a directory intended for use with git config init.templateDir

    +
    + +### prek util identify + +Show file identification tags + +

    Usage

    + +``` +prek util identify [OPTIONS] [PATH]... +``` + +

    Arguments

    + +
    PATH

    The path(s) to the file(s) to identify

    +
    + +

    Options

    + +
    --cd, -C dir

    Change to directory before running

    +
    --color color

    Whether to use color in output

    +

    May also be set with the PREK_COLOR environment variable.

    [default: auto]

    Possible values:

    +
      +
    • auto: Enables colored output only when the output is going to a terminal or TTY with support
    • +
    • always: Enables colored output regardless of the detected environment
    • +
    • never: Disables colored output
    • +
    --config, -c config

    Path to alternate config file

    +
    --help, -h

    Display the concise help for this command

    +
    --log-file log-file

    Write trace logs to the specified file. If not specified, trace logs will be written to $PREK_HOME/prek.log

    +
    --no-progress

    Hide all progress outputs.

    +

    For example, spinners or progress bars.

    +
    --output-format output-format

    The output format

    +

    [default: text]

    Possible values:

    +
      +
    • text
    • +
    • json
    • +
    --quiet, -q

    Use quiet output.

    +

    Repeating this option, e.g., -qq, will enable a silent mode in which prek will write no output to stdout.

    +

    May also be set with the PREK_QUIET environment variable.

    --refresh

    Refresh all cached data

    +
    --verbose, -v

    Use verbose output

    +
    --version, -V

    Display the prek version

    +
    + +### prek util init-template-dir + +Install hook script in a directory intended for use with `git config init.templateDir` + +

    Usage

    + +``` +prek util init-template-dir [OPTIONS] +``` + +

    Arguments

    + +
    DIRECTORY

    The directory in which to write the hook script

    +
    + +

    Options

    + +
    --cd, -C dir

    Change to directory before running

    +
    --color color

    Whether to use color in output

    +

    May also be set with the PREK_COLOR environment variable.

    [default: auto]

    Possible values:

    +
      +
    • auto: Enables colored output only when the output is going to a terminal or TTY with support
    • +
    • always: Enables colored output regardless of the detected environment
    • +
    • never: Disables colored output
    • +
    --config, -c config

    Path to alternate config file

    +
    --help, -h

    Display the concise help for this command

    +
    --hook-type, -t hook-type

    Which hook type(s) to install.

    +

    Specifies which git hook stage(s) you want to install the hook script for. Can be specified multiple times to install hooks for multiple stages.

    +

    If not specified, uses default_install_hook_types from the config file, or defaults to pre-commit if that is also not set.

    +

    Possible values:

    +
      +
    • commit-msg
    • +
    • post-checkout
    • +
    • post-commit
    • +
    • post-merge
    • +
    • post-rewrite
    • +
    • pre-commit
    • +
    • pre-merge-commit
    • +
    • pre-push
    • +
    • pre-rebase
    • +
    • prepare-commit-msg
    • +
    --log-file log-file

    Write trace logs to the specified file. If not specified, trace logs will be written to $PREK_HOME/prek.log

    +
    --no-allow-missing-config

    Assume cloned repos should have a pre-commit config

    +
    --no-progress

    Hide all progress outputs.

    +

    For example, spinners or progress bars.

    +
    --quiet, -q

    Use quiet output.

    +

    Repeating this option, e.g., -qq, will enable a silent mode in which prek will write no output to stdout.

    +

    May also be set with the PREK_QUIET environment variable.

    --refresh

    Refresh all cached data

    +
    --verbose, -v

    Use verbose output

    +
    --version, -V

    Display the prek version

    +
    + ## prek self `prek` self management diff --git a/docs/configuration.md b/docs/configuration.md index e7ece65d..82e5a982 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -918,7 +918,7 @@ File-type filters based on [`identify`](https://pre-commit.com/#filtering-files- !!! tip - Use [`prek identify `](cli.md#prek-identify) to see how prek tags a file when you’re troubleshooting `types` filters. + Use [`prek util identify `](cli.md#prek-util-identify) to see how prek tags a file when you’re troubleshooting `types` filters. Compared to regex-only filtering (`files` / `exclude`), tag-based filtering is often easier and more robust: