Skip to content

Commit

Permalink
Merge pull request #17 from gabyx/feature/rework-prompt-settings
Browse files Browse the repository at this point in the history
Rework prompt settings
  • Loading branch information
gabyx authored Mar 17, 2021
2 parents 1ef12c6 + f3439e8 commit 55076eb
Show file tree
Hide file tree
Showing 154 changed files with 1,451 additions and 741 deletions.
Empty file modified .githooks/pre-commit/list-staged-files
100644 → 100755
Empty file.
Empty file modified .githooks/pre-commit/no-setx
100644 → 100755
Empty file.
Empty file modified .githooks/pre-commit/no-tabs
100644 → 100755
Empty file.
Empty file modified .githooks/pre-commit/no-todo-or-fixme
100644 → 100755
Empty file.
Empty file modified .githooks/pre-commit/shellcheck
100644 → 100755
Empty file.
Empty file modified .githooks/pre-commit/shellcheck-ignore-format
100644 → 100755
Empty file.
Empty file modified .githooks/pre-commit/shfmt
100644 → 100755
Empty file.
Empty file modified .githooks/pre-commit/validate
100644 → 100755
Empty file.
92 changes: 43 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Also it searches for hooks in configured shared hook repositories.
- [Global Hooks Location core.hooksPath](#global-hooks-location-corehookspath)
- [Updates](#updates)
- [Update Mechanics](#update-mechanics)
- [Custom User Prompt](#custom-user-prompt)
- [User Prompts](#user-prompts)
- [Uninstalling](#uninstalling)
- [YAML Specifications](#yaml-specifications)
- [Migration](#migration)
Expand Down Expand Up @@ -342,8 +342,8 @@ on any local repositories. Any other local path will be used **directly and will
Additionally, the update can also be triggered on other hook names by setting a comma-separated list of additional
hook names in the Git configuration parameter `githooks.sharedHooksUpdateTriggers` on any configuration level.

An additional global configuration parameter `githooks.failOnNonExistingSharedHooks` makes hooks fail with an error if any shared hook configured in `.shared.yaml` is missing, meaning `git hooks update` has not yet been called.
See [`git hooks config fail-on-non-existing-shared-hooks --help`](docs/cli/git_hooks_config_fail-on-non-existing-shared-hooks.md)
An additional global configuration parameter `githooks.skipNonExistingSharedHooks` makes Githooks skip any configured non-existing shared hooks. Otherwise, Githooks will fail and you need to update them by running `git hooks update`.
See [`git hooks config skip-non-existing-shared-hooks --help`](docs/cli/skip-non-existing-shared-hooks.md)

You can also manage and update shared hook repositories using the [`git hooks shared --help`](docs/cli/git_hooks_shared.md) tool.

Expand Down Expand Up @@ -405,25 +405,27 @@ Hooks in individual shared repositories can be disabled as well, with [`git hook
## Trusting Hooks

To try and make things a little bit more secure, Githooks checks if any new hooks were added we haven't run before,
or if any of the existing ones have changed. When they have, it will prompt for confirmation whether you accept
or if any of the existing ones have changed. When they have, it will prompt for confirmation (trust prompt) whether you accept
those changes or not, and you can also disable specific hooks to skip running them until you decide otherwise.
The trust prompt is always **fatal** meaning that failing to answer the prompt, or any other prompt error,
will result in a failing Git hook. To make the `runner` non-interactive, see [user prompts](#user-prompts).
If a hook is still *active and untrusted* after the prompt, Githooks will fail by default.
This is useful to be sure that all hooks get executed.
However, you can disabled this behavior by skipping active, untrusted hooks with [`git hooks config skip-untrusted-hooks --enable`](docs/cli/git_hooks_config_skip-untrusted-hooks.md).

The accepted checksums are maintained in the `.git/.githooks.checksum` directory, per local repository.
You can however use a global checksum directory setup by specifing `githooks.checksumCacheDir`
in any suitable Git config (can be different for each repository).

If the repository contains a `.githooks/trust-all` file, it is marked as a trusted repository. On the first interaction with hooks, Githooks will ask for confirmation that the user trusts all existing and future hooks in the repository,
If the repository contains a `.githooks/trust-all` file, it is marked as a trusted repository.
Consult [`git hooks trust --help`](docs/cli/git_hooks_trust.md). On the first interaction with hooks,
Githooks will ask for confirmation that the user trusts all existing and future hooks in the repository,
and if she does, no more confirmation prompts will be shown.
This can be reverted by running either the
`git config --unset githooks.trustAll`, or the [`git hooks config trusted --help`](docs/cli/git_hooks_config_trusted.md) command.
This is a per-repository setting.
Consult [`git hooks trust --help`](docs/cli/git_hooks_trust.md) and [`git hooks config trusted --help`](docs/cli/git_hooks_config_trusted.md)
for more information.

There is a caveat worth mentioning: if a terminal *(tty)* can't be allocated, then the default action is to accept the changes or new hooks.
A terminal cannot be allocated for exmaple if you execute Git over a GUI such as VS Code or any other Git GUI.
Let me know in an issue if you strongly disagree, and you think this is a big enough risk worth having slightly worse UX instead.
This can be reverted by running [`git hooks config trust-all --reset`](docs/cli/git_hooks_config_trust-all.md) command
(modifying the local Git config setting `githooks.trustAll`). This is a per-repository setting.
Consult [`git hooks config trust-all --help`](docs/cli/git_hooks_config_trust-all.md) for more information.

You can also accept (trust) hooks by using [`git hooks trust hooks ---help`](docs/cli/git_hooks_trust_hooks.md).
You can also trust individual hooks by using [`git hooks trust hooks --help`](docs/cli/git_hooks_trust_hooks.md).

## Disabling Githooks

Expand Down Expand Up @@ -582,28 +584,25 @@ See also the [setup for bare repositories](#setup-for-bare-repositories).

#### Setup for Bare Repositories

Because bare repositories mostly live on a server, you should setup the following if
you use a shared hooks repository (can live on the same server, see [shared URLs](#supported-urls))
If you want to use Githooks with bare repositories on a server, you should setup the following to ensure smooth operations (see [user prompts](#user-prompts)):

```shell
cd bareRepo
# Install Githooks into this bare repository
# which will only install server hooks:
git hooks install

# Creates `.githooks/trust-all` marker for this bare repo
# This is necessary to circumvent trust prompts for shared hooks.
git hooks trust

# Automatically accept changes to all existing and new
# hooks in the current repository.
git hooks config trusted --accept
# This makes the fatal trust prompt pass.
git hooks config trust-all-hooks --accept

# Don't do global automatic updates, since the Githooks update
# script should not be run in parallel on a server.
# Don't do global automatic updates, since the Githooks updater
# might get invoked in parallel on a server.
git hooks config update --disable
```

Enabling auto-updates on the server, is a todo and needs file locks.

### Templates or Global Hooks

This installer command can work in one of 2 ways:
Expand Down Expand Up @@ -681,39 +680,34 @@ You can also check for updates at any time by executing
[`git hooks update`](docs/cli/git_hooks_update.md) or using
[`git hooks config update [--enable|--disable]`](docs/cli/git_hooks_config_update.md) command to enable or disable the automatic update checks.

### Custom User Prompt
### User Prompts

Githooks comes already with a [**platform-independend dialog tool**](#dialog-tool) which it uses also internally and you probably don't need this:
Githooks shows user prompts during installation, updating (automatic or manual), uninstallation and when executing hooks (the `runner` executable).

If you want to use a GUI dialog when Githooks asks for user input, you can use an executable or script file to display it.
The `runner` might get executed over a Git GUI or any other environment where no terminal is available. In this case all user prompts are shown as
GUI dialogs with the included [platform-independent dialog tool](#dialog-tool). The GUI dialog fallback is currently only enabled for the `runner`.

The example in the `examples/tools/dialog` folder contains a Python script `run` which uses the Python (> version 3.9) provided `tkinter` to show a dialog.
Githooks distinguishes between *fatal* and *non-fatal* prompts.

```shell
# install the example dialog tool from this repository
$ git hooks tools register dialog "./examples/tools/dialog"
```

This will copy the tool to the Githooks install folder to execute when displaying user prompts.
The tool's interface is as follows.
- A *fatal* prompt will result in a complete abort if
- The prompt could not be shown (terminal or GUI dialog).
- The answer returned by the user is incorrect (terminal only) or the
user canceled the GUI dialog.

```shell
$ run <title> <text> <options> <long-options> # if `run` is executable
$ sh run <title> <text> <options> <long-options> # otherwise, assuming `run` is a shell script
```
- A *non-fatal* prompt always has a default answer which is taken in the above failing cases and the execution continues. Warning messages might be shown however.

The arguments for the dialog tool are:
The `runner` will show prompts, either in the terminal or as GUI dialog, in the following cases:

- `<title>` the title for the GUI dialog
- `<text>` the text for the GUI dialog
- `<short-options>` the button return values, separated by slashes, e.g. `Y/n/d`. The default button is the first capital character found.
- `<long-options>` the button texts in the GUI, e.g. `Yes/no/disable`
1. **Trust prompt**: The user is required to trust/untrust a new/changed hook: **fatal**.
2. **Update prompts**: The user is requested to accept a new update if automatic updates are enabled (`git hooks update --enable`): **non-fatal**.
- Various other prompts when the updater is launched: **non-fatal**.

The script needs to return one of the short-options on the standard output.
If the exit code is not `0`, the normal prompt on the standard input is shown as a fallback mechanism.
User prompts during `runner` execution are sometimes not desirable (server infastructure, docker container, etc...) and need to be disabled. Setting `git hooks config runner-non-interactive --enable --global` will:

**Note:** Githooks will probably in the future provide a default cross-platform Dialog implementation, which will render this feature obsolete.
(PRs welcome, see [https://github.com/gen2brain/dlgs](https://github.com/gen2brain/dlgs))
- Take default answers for all **non-fatal** prompts. No warnings are shown.
- Take default answer for a **fatal prompt** if it is configured:
The only fatal prompt is the **trust prompt** which can be configured to pass by executing
`git hooks config trust-all --accept`.

## Uninstalling

Expand Down
6 changes: 4 additions & 2 deletions docs/cli/git_hooks_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ git hooks config
* [git hooks config clone-url](git_hooks_config_clone-url.md) - Changes the Githooks clone url used for any update.
* [git hooks config delete-detected-lfs-hooks](git_hooks_config_delete-detected-lfs-hooks.md) - Change the behavior for detected LFS hooks during install.
* [git hooks config disable](git_hooks_config_disable.md) - Disables Githooks in the current repository or globally.
* [git hooks config fail-on-non-existing-shared-hooks](git_hooks_config_fail-on-non-existing-shared-hooks.md) - Updates the list of local or global shared hook repositories.
* [git hooks config list](git_hooks_config_list.md) - Lists settings of the Githooks configuration.
* [git hooks config non-interactive-runner](git_hooks_config_non-interactive-runner.md) - Enables/disables non-interactive execution of the runner.
* [git hooks config search-dir](git_hooks_config_search-dir.md) - Changes the search directory used during installation.
* [git hooks config shared](git_hooks_config_shared.md) - Updates the list of local or global shared hook repositories.
* [git hooks config trusted](git_hooks_config_trusted.md) - Change trust settings in the current repository.
* [git hooks config skip-non-existing-shared-hooks](git_hooks_config_skip-non-existing-shared-hooks.md) - Enable or disable skipping non-existing shared hooks.
* [git hooks config skip-untrusted-hooks](git_hooks_config_skip-untrusted-hooks.md) - Enable/disable skipping active, untrusted hooks.
* [git hooks config trust-all](git_hooks_config_trust-all.md) - Change trust settings in the current repository.
* [git hooks config update](git_hooks_config_update.md) - Change Githooks update settings.
* [git hooks config update-time](git_hooks_config_update-time.md) - Changes the Githooks update time.

Expand Down
32 changes: 0 additions & 32 deletions docs/cli/git_hooks_config_fail-on-non-existing-shared-hooks.md

This file was deleted.

34 changes: 34 additions & 0 deletions docs/cli/git_hooks_config_non-interactive-runner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## git hooks config non-interactive-runner

Enables/disables non-interactive execution of the runner.

### Synopsis

Enable or disables non-interactive execution of
the Githooks runner executable.

Enabling non-interactivity will only default answer all non-fatal prompts.
Fatal prompts (e.g. the trust prompts) still need to be configured to pass.
See `git hooks config trust-all --help`.

```
git hooks config non-interactive-runner [flags]
```

### Options

```
--print Print the setting.
--enable Enables non-interactive mode of the runner executable.
--disable Disables non-interactive mode of the runner executable.
--Reset non-interactive mode of the runner executable. Reset the setting.
--local Use the local Git configuration (default, except for `--print`).
--global Use the global Git configuration.
-h, --help help for non-interactive-runner
```

### SEE ALSO

* [git hooks config](git_hooks_config.md) - Manages various Githooks configuration.

###### Auto generated by spf13/cobra
31 changes: 31 additions & 0 deletions docs/cli/git_hooks_config_skip-non-existing-shared-hooks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## git hooks config skip-non-existing-shared-hooks

Enable or disable skipping non-existing shared hooks.

### Synopsis

Enable or disable failing hooks with an error when any
shared hooks are missing. This usually means `git hooks shared update`
has not been called yet.

```
git hooks config skip-non-existing-shared-hooks [flags]
```

### Options

```
--print Print the setting.
--enable Enable skipping non-existing shared hooks.
--disable Disable skipping non-existing shared hooks.
--Reset skipping non-existing shared hooks. Reset the setting.
--local Use the local Git configuration (default, except for `--print`).
--global Use the global Git configuration.
-h, --help help for skip-non-existing-shared-hooks
```

### SEE ALSO

* [git hooks config](git_hooks_config.md) - Manages various Githooks configuration.

###### Auto generated by spf13/cobra
31 changes: 31 additions & 0 deletions docs/cli/git_hooks_config_skip-untrusted-hooks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## git hooks config skip-untrusted-hooks

Enable/disable skipping active, untrusted hooks.

### Synopsis

Enable or disable failing hooks with an error when any
active, untrusted hooks are present.
Mostly wanted if all hooks must be executed.

```
git hooks config skip-untrusted-hooks [flags]
```

### Options

```
--print Print the setting.
--enable Enable skipping active, untrusted hooks.
--disable Disable skipping active, untrusted hooks.
--Reset skipping active, untrusted hooks. Reset the setting.
--local Use the local Git configuration (default, except for `--print`).
--global Use the global Git configuration.
-h, --help help for skip-untrusted-hooks
```

### SEE ALSO

* [git hooks config](git_hooks_config.md) - Manages various Githooks configuration.

###### Auto generated by spf13/cobra
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## git hooks config trusted
## git hooks config trust-all

Change trust settings in the current repository.

Expand All @@ -9,7 +9,7 @@ Change the trust setting in the current repository.
This command needs to be run at the root of a repository.

```
git hooks config trusted [flags]
git hooks config trust-all [flags]
```

### Options
Expand All @@ -22,7 +22,7 @@ git hooks config trusted [flags]
--deny Marks the repository as it has refused to
trust the changes, even if the trust marker is present.
--reset Clears the trust setting.
-h, --help help for trusted
-h, --help help for trust-all
```

### SEE ALSO
Expand Down
2 changes: 1 addition & 1 deletion docs/cli/git_hooks_trust.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Sets up, or reverts the trusted setting for the local repository.
When called without arguments, it marks the local repository as trusted.

The `revoke` argument resets the already accepted trust setting,
and the `delete` argument also deletes the trusted marker.
and the `delete` argument also deletes the trust marker.

The `forget` option unsets the trust setting, asking for accepting
it again next time, if the repository is marked as trusted.
Expand Down
Loading

0 comments on commit 55076eb

Please sign in to comment.