From 1978176c22e8be009df34bff7f6cc1e6ccccd89b Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 13 Nov 2022 20:25:49 +0200 Subject: [PATCH] tools: add an utility cmd/tools/git_pre_commit_hook.vsh script That script can be used to ensure that all commited V files are vfmt-ed, i.e. it will run `v fmt -w ` on them before commiting them. To use the script in your V project, you need to be in the main folder of your project, then do the equivalent of: ```sh cp /PATH/TO_YOUR/V/cmd/tools/git_pre_commit_hook.vsh .git/hooks/pre-commit chmod 755 .git/hooks/pre-commit ``` Note: you can use this command: `git config --bool --add hooks.stopCommitOfNonVfmtedVFiles true` ... to make it just *prevent* the commiting of unformatted .v files, i.e. stop the commiting, if they are not, but *without modifying them* automatically (you will then need to run `v fmt -w` on them manually). Note 2: Git supports the option `--no-verify`, to temporarily disable all hooks. --- cmd/tools/git_pre_commit_hook.vsh | 49 +++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100755 cmd/tools/git_pre_commit_hook.vsh diff --git a/cmd/tools/git_pre_commit_hook.vsh b/cmd/tools/git_pre_commit_hook.vsh new file mode 100755 index 0000000000..ee80615057 --- /dev/null +++ b/cmd/tools/git_pre_commit_hook.vsh @@ -0,0 +1,49 @@ +#!/usr/bin/env -S v -raw-vsh-tmp-prefix tmp + +import os +import term + +// This script can be used to ensure that all commited V files are vfmt-ed automatically. +// By default, once setup, it will run `v fmt -w` on them, before commiting them. + +// To use the script in your V project, you need to be in the main folder +// of your project, then do the equivalent of: +// ```sh +// cp /PATH/TO_YOUR/V/cmd/tools/git_pre_commit_hook.vsh .git/hooks/pre-commit +// chmod 755 .git/hooks/pre-commit +// ``` +// +// Note: you can use this command: +// `git config --bool --add hooks.stopCommitOfNonVfmtedVFiles true` +// ... to make it just *prevent* the commiting of unformatted .v files, +// i.e. stop the commiting, if they are not, but *without modifying them* +// automatically (you will then need to run `v fmt -w` on them manually). +// +// Note 2: Git supports skipping the hooks, by passing the `--no-verify` option. +// That can be used to commit some .v files that are not formatted, without removing +// the hook. + +fn main() { + // This hook cares only about the changed V files, that will be commited, as reported by git itself: + changed := os.execute("git diff --cached --name-only --diff-filter=ACMR -- '*.v' '*.vsh' '*.vv'") + if changed.output == '' { + eprintln('>>> 0 changed V files found.') + exit(0) + } + vfiles := changed.output.trim_space().split('\n') + configured_stop_commiting := os.execute('git config --bool hooks.stopCommitOfNonVfmtedVFiles') + if configured_stop_commiting.output.trim_space().bool() { + verify_result := os.execute('v fmt -verify ${vfiles.join(' ')}') + if verify_result.exit_code != 0 { + eprintln(verify_result.output) + } + exit(verify_result.exit_code) + } else { + eprintln('The V pre commit hook will format $vfiles.len V file(s):') + for vfile in vfiles { + eprintln(' ${term.bold('$vfile')}') + } + os.system('v fmt -w ${vfiles.join(' ')}') + os.system('git add ${vfiles.join(' ')}') + } +}