rails_git_hooks 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -6
- data/README.md +72 -115
- data/lib/rails_git_hooks/checks/base.rb +55 -0
- data/lib/rails_git_hooks/checks/commit_msg/jira_prefix.rb +31 -0
- data/lib/rails_git_hooks/checks/commit_msg.rb +10 -0
- data/lib/rails_git_hooks/checks/post_checkout/bundle_install.rb +16 -0
- data/lib/rails_git_hooks/checks/post_checkout/db_migrate.rb +16 -0
- data/lib/rails_git_hooks/checks/post_checkout.rb +11 -0
- data/lib/rails_git_hooks/checks/post_merge/bundle_install.rb +16 -0
- data/lib/rails_git_hooks/checks/post_merge/db_migrate.rb +16 -0
- data/lib/rails_git_hooks/checks/post_merge.rb +11 -0
- data/lib/rails_git_hooks/checks/pre_commit/debugger_check.rb +43 -0
- data/lib/rails_git_hooks/checks/pre_commit/default_branch.rb +20 -0
- data/lib/rails_git_hooks/checks/pre_commit/json_format_check.rb +30 -0
- data/lib/rails_git_hooks/checks/pre_commit/migrations_check.rb +37 -0
- data/lib/rails_git_hooks/checks/pre_commit/rubocop.rb +30 -0
- data/lib/rails_git_hooks/checks/pre_commit/whitespace_check.rb +31 -0
- data/lib/rails_git_hooks/checks/pre_commit/yaml_format_check.rb +31 -0
- data/lib/rails_git_hooks/checks/pre_commit.rb +16 -0
- data/lib/rails_git_hooks/checks/pre_push/run_tests.rb +24 -0
- data/lib/rails_git_hooks/checks/pre_push.rb +10 -0
- data/lib/rails_git_hooks/checks/shared/bundle_install_check.rb +28 -0
- data/lib/rails_git_hooks/checks/shared/db_migrate_check.rb +28 -0
- data/lib/rails_git_hooks/checks.rb +10 -0
- data/lib/rails_git_hooks/cli.rb +17 -90
- data/lib/rails_git_hooks/config/constants.rb +26 -0
- data/lib/rails_git_hooks/config/defaults.yml +190 -0
- data/lib/rails_git_hooks/config/defaults_loader.rb +42 -0
- data/lib/rails_git_hooks/core/check_definition.rb +63 -0
- data/lib/rails_git_hooks/core/check_result.rb +41 -0
- data/lib/rails_git_hooks/core/error.rb +5 -0
- data/lib/rails_git_hooks/install/installer.rb +79 -0
- data/lib/rails_git_hooks/runtime/check_registry.rb +33 -0
- data/lib/rails_git_hooks/runtime/dependency_checker.rb +51 -0
- data/lib/rails_git_hooks/runtime/file_matcher.rb +23 -0
- data/lib/rails_git_hooks/runtime/override_config.rb +131 -0
- data/lib/rails_git_hooks/runtime/policy_resolver.rb +36 -0
- data/lib/rails_git_hooks/runtime/repository.rb +69 -0
- data/lib/rails_git_hooks/runtime/runner.rb +80 -0
- data/lib/rails_git_hooks/runtime.rb +25 -0
- data/lib/rails_git_hooks/version.rb +1 -1
- data/lib/rails_git_hooks.rb +14 -6
- data/templates/hooks/commit-msg +7 -17
- data/templates/hooks/post-checkout +13 -0
- data/templates/hooks/post-merge +13 -0
- data/templates/hooks/pre-commit +7 -21
- data/templates/hooks/pre-push +7 -17
- metadata +41 -52
- data/lib/rails_git_hooks/constants.rb +0 -21
- data/lib/rails_git_hooks/installer.rb +0 -156
- data/templates/shared/commit_msg/jira_prefix.rb +0 -20
- data/templates/shared/pre_commit/debugger_check.rb +0 -48
- data/templates/shared/pre_commit/default_branch.rb +0 -9
- data/templates/shared/pre_commit/rubocop_check.rb +0 -24
- data/templates/shared/pre_commit/whitespace_check.rb +0 -25
- data/templates/shared/pre_push/run_tests.rb +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8f679908a499fe6aed2f61cf433d27bf93042bf0dcf1ecfe2e4854f05b0e7b9e
|
|
4
|
+
data.tar.gz: 481df290f21058504a14d0b6995854861ed7d15099b40a34ec9ccdf6f18fcf3c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63518e1bcbca51fc17881473b90a0eb510eb2a6e62b26e6471e8890f8fd4e702392b6401f92124d4cd9cc1d398ad0aa03b3c9306a4ce34dc40313d6ab028da52
|
|
7
|
+
data.tar.gz: c549c30ca8f646f65bdf10a7281e0f2412bb8a796e0665a80e68c05cdac6ed0a39aed58f48011e23b3eba4622db43b6764bae103e434170a601938f4e5f8291e
|
data/CHANGELOG.md
CHANGED
|
@@ -4,11 +4,42 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
6
|
|
|
7
|
-
## [0.7.
|
|
7
|
+
## [0.7.2]
|
|
8
8
|
|
|
9
9
|
### Added
|
|
10
10
|
|
|
11
|
-
- **
|
|
11
|
+
- **post-checkout hook** — Runs after branch checkout. Includes `bundle-install` (run `bundle install` when Gemfile/Gemfile.lock changed) and `db-migrate` (run `rails db:migrate` when migrations or schema changed). Both enabled by default.
|
|
12
|
+
- **post-merge hook** — Runs after merge. Same checks as post-checkout: `bundle-install` and `db-migrate`, enabled by default. Keeps the app bundled and migrated when pulling or merging (inspired by [hookup](https://rubygems.org/gems/hookup)).
|
|
13
|
+
- **Shared check modules** — `checks/shared/bundle_install_check.rb` and `checks/shared/db_migrate_check.rb` hold common logic and options for the post-checkout and post-merge bundle/migrate checks.
|
|
14
|
+
- **Specs for every check** — RSpec examples for all 13 checks (pre-commit, commit-msg, pre-push, post-checkout, post-merge) under `spec/rails_git_hooks/checks/`.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **Default install** — With no config file, `install` now installs **commit-msg**, **pre-commit**, **post-checkout**, and **post-merge** (post-checkout/post-merge bundle and db-migrate checks are on by default).
|
|
19
|
+
- **Runner** — `modified_files` now supports `post_checkout` (files changed between refs on branch checkout) and `post_merge` (files changed between ORIG_HEAD and HEAD). Repository adds `changed_files(ref1, ref2)`.
|
|
20
|
+
- **defaults.yml** — PostCheckout and PostMerge sections: `BundleInstall` and `DbMigrate` set to `enabled: true` by default.
|
|
21
|
+
|
|
22
|
+
## [0.7.1]
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **Code-first runtime architecture** — Hook behavior now lives in Ruby classes with a central runner, registry, policy resolver, dependency checker, and sparse override config loader.
|
|
27
|
+
- **Sparse override config** — Added optional `.rails_git_hooks.yml` with Overcommit-style per-check overrides for `enabled`, `quiet`, `on_fail`, `on_warn`, `on_missing_dependency`, `include`, `exclude`, and `command`.
|
|
28
|
+
- **Thin hook bootstraps** — `templates/hooks/*` now dispatch into the embedded `rails_git_hooks` runtime instead of loading copied script files per check.
|
|
29
|
+
- **Pre-commit YAML format check** — Warns (does not block) when any staged `.yml` or `.yaml` file fails to parse (invalid YAML). Reports file and line from the parser. On by default with pre-commit.
|
|
30
|
+
- **Pre-commit JSON format check** — Warns (does not block) when any staged `.json` file fails to parse (invalid JSON). Reports file and parser message. On by default with pre-commit.
|
|
31
|
+
- **Pre-commit migrations check** — Warns (does not block) when: (a) migration file(s) are staged but neither `db/schema.rb` nor `db/structure.sql` is staged; (b) data migration file(s) in `db/data/` or `db/data_migrate/` are staged but `db/data_schema.rb` is not. **On by default.** Disable with `rails_git_hooks disable migrations-check`.
|
|
32
|
+
- **Defaults YAML** — `lib/rails_git_hooks/config/defaults.yml` holds default settings for every check and hook. `DefaultsLoader` reads it; `OverrideConfig` uses it as the base when merging with `.rails_git_hooks.yml`. Edit the YAML to change built-in defaults.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- **CLI redesign** — Replaced per-check flag-file commands with generic config-driven commands: `install`, `list`, `init`, `enable`, `disable`, `set`, and `show-config`.
|
|
37
|
+
- **Manual install layout** — Manual install is via `bundle exec rails_git_hooks install` only; dropped `rake sync_hooks` and the repo `hooks/` tree.
|
|
38
|
+
- **Dependency handling** — Checks can now declare executables, Ruby libraries, files, and install hints, with centralized `on_missing_dependency` policy handling.
|
|
39
|
+
- **Runtime install** — Installer copies all runtime files (including `config/defaults.yml`), not only `*.rb`, into `.git/hooks/rails_git_hooks/`.
|
|
40
|
+
- **Removed `hooks/` directory** — `/hooks/` added to `.gitignore`. README manual-install section updated.
|
|
41
|
+
|
|
42
|
+
## [0.7.0]
|
|
12
43
|
|
|
13
44
|
### Changed
|
|
14
45
|
|
|
@@ -16,10 +47,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
16
47
|
- **Constants:** Extracted `lib/rails_git_hooks/constants.rb` (GEM_ROOT, HOOKS_DIR, DEFAULT_HOOKS, FEATURE_FLAG_FILES). Installer and CLI use it. Single source of truth; no config file.
|
|
17
48
|
- Gemspec includes `templates/**/*`. Version set to 0.7.0.
|
|
18
49
|
|
|
19
|
-
### Fixed
|
|
20
|
-
|
|
21
|
-
- **Hook scripts** — `RailsGitHooks::GIT_DIR` was set inside a `module` body, where the script’s local `git_dir` is out of scope (Ruby scope gate), causing `NameError` when hooks ran. All three hooks (commit-msg, pre-commit, pre-push) now set the constant via `RailsGitHooks.const_set(:GIT_DIR, git_dir.freeze)` from the script scope.
|
|
22
|
-
|
|
23
50
|
## [0.6.1]
|
|
24
51
|
|
|
25
52
|
### Changed
|
data/README.md
CHANGED
|
@@ -4,34 +4,38 @@
|
|
|
4
4
|
[](https://github.com/NikitaNazarov1/rails_git_hooks/actions/workflows/tests.yml?query=branch%3Amain)
|
|
5
5
|
[](https://github.com/NikitaNazarov1/rails_git_hooks/actions/workflows/rubocop.yml?query=branch%3Amain)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
7
|
+
Git hooks for Rails and Ruby projects: sensible defaults out of the box, optional YAML overrides, and per-check policies (enable/disable, fail vs warn, include/exclude).
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Code-first runtime** — Checks are Ruby classes; hook scripts are thin bootstraps that delegate to a shared runtime.
|
|
12
|
+
- **Sparse config** — Defaults live in the gem ([config/defaults.yml](https://github.com/NikitaNazarov1/rails_git_hooks/blob/main/lib/rails_git_hooks/config/defaults.yml)). But you can redefine them via your own yml config file in a root repository.
|
|
13
|
+
- **Flexible configuration options** — Per check: `enabled`, `quiet`, `on_fail`, `on_warn`, `on_missing_dependency`, `include`, `exclude`, `command`.
|
|
14
|
+
- **Dependency handling** — Checks declare executables/libraries; missing deps are handled by a single policy (`on_missing_dependency`).
|
|
15
|
+
|
|
16
|
+
## Included hooks and checks
|
|
17
|
+
|
|
18
|
+
| Hook | Check key | Enabled By Default | Description |
|
|
19
|
+
|-------------|----------------------|---------|-------------|
|
|
20
|
+
| **commit-msg** | `jira-prefix` | ✅ | Prefix commit messages with Jira-style ticket IDs from the branch name (e.g. `[TICKET-123]`). |
|
|
21
|
+
| **pre-commit** | `default-branch` | ✅ | Block commits on `master` / `main`; prompt to use a feature branch. |
|
|
22
|
+
| **pre-commit** | `debugger-check` | ✅ | Warn (or fail) on debugger statements in Ruby, JavaScript/TypeScript, and Python. |
|
|
23
|
+
| **pre-commit** | `yaml-format-check` | ✅ | Warn on invalid `.yml` / `.yaml` files. |
|
|
24
|
+
| **pre-commit** | `json-format-check` | ✅ | Warn on invalid `.json` files. |
|
|
25
|
+
| **pre-commit** | `migrations-check` | ✅ | Warn when migration files are staged but schema/data_schema files are not. |
|
|
26
|
+
| **pre-commit** | `whitespace-check` | Off | Fail on trailing whitespace and merge conflict markers. |
|
|
27
|
+
| **pre-commit** | `rubocop-check` | Off | Run RuboCop on staged Ruby files (requires `rubocop` in the project). |
|
|
28
|
+
| **pre-push** | `run-tests` | Off | Run test suite before push (default: `bundle exec rspec`). Enable in config to install pre-push. |
|
|
29
|
+
| **post-checkout** | `bundle-install` | ✅ | Run `bundle install` when Gemfile or Gemfile.lock changed after a branch checkout. |
|
|
30
|
+
| **post-checkout** | `db-migrate` | ✅ | Run `rails db:migrate` when migrations or schema changed after a branch checkout. |
|
|
31
|
+
| **post-merge** | `bundle-install` | ✅ | Run `bundle install` when Gemfile or Gemfile.lock changed after a merge. |
|
|
32
|
+
| **post-merge** | `db-migrate` | ✅ | Run `rails db:migrate` when migrations or schema changed after a merge. |
|
|
23
33
|
|
|
24
34
|
## Quick start
|
|
25
35
|
|
|
26
|
-
### 1.
|
|
36
|
+
### 1. Add the gem
|
|
27
37
|
|
|
28
|
-
**
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
gem install rails_git_hooks
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
**With Bundler** — add to your `Gemfile`:
|
|
38
|
+
**Gemfile:**
|
|
35
39
|
|
|
36
40
|
```ruby
|
|
37
41
|
gem "rails_git_hooks"
|
|
@@ -43,121 +47,74 @@ Then:
|
|
|
43
47
|
bundle install
|
|
44
48
|
```
|
|
45
49
|
|
|
50
|
+
Or install globally: `gem install rails_git_hooks`.
|
|
51
|
+
|
|
46
52
|
### 2. Install hooks
|
|
47
53
|
|
|
48
|
-
From your project root
|
|
54
|
+
From your project root:
|
|
49
55
|
|
|
50
56
|
```bash
|
|
51
57
|
bundle exec rails_git_hooks install
|
|
52
58
|
```
|
|
53
59
|
|
|
54
|
-
|
|
60
|
+
With default config this installs **commit-msg**, **pre-commit**, **post-checkout**, and **post-merge** into `.git/hooks/` and copies the runtime there (pre-push is off by default; enable `run-tests` in config to add it).
|
|
55
61
|
|
|
56
|
-
|
|
62
|
+
## Configuration
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
# Run tests before every push
|
|
60
|
-
rails_git_hooks install pre-push
|
|
61
|
-
|
|
62
|
-
# Run RuboCop on staged .rb files before commit
|
|
63
|
-
rails_git_hooks enable rubocop-check
|
|
64
|
-
|
|
65
|
-
# Reject trailing whitespace and conflict markers in staged files
|
|
66
|
-
rails_git_hooks enable whitespace-check
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
**Tip:** If a hook doesn’t run, make it executable: `chmod +x .git/hooks/<hook-name>`
|
|
64
|
+
### Priority (low → high)
|
|
70
65
|
|
|
71
|
-
|
|
66
|
+
1. **Built-in defaults** (in the gem’s `config/defaults.yml`)
|
|
67
|
+
2. **`.rails_git_hooks.yml`** in the repo root (sparse overrides; commit this)
|
|
68
|
+
3. **`.rails_git_hooks.local.yml`** in the repo root (optional; overrides the above, typically gitignored)
|
|
72
69
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
All commands are run from the project root.
|
|
76
|
-
|
|
77
|
-
| Command | Description |
|
|
78
|
-
|---------|-------------|
|
|
79
|
-
| `rails_git_hooks install [HOOK...]` | Install hooks. No arguments = install default (commit-msg + pre-commit). |
|
|
80
|
-
| `rails_git_hooks list` | List available hook names. |
|
|
81
|
-
| `rails_git_hooks disable HOOK [...]` | Disable hooks or options (use `*` for all). |
|
|
82
|
-
| `rails_git_hooks enable HOOK [...]` | Re-enable hooks or enable optional checks. |
|
|
83
|
-
| `rails_git_hooks disabled` | Show currently disabled hooks. |
|
|
84
|
-
|
|
85
|
-
**Common examples:**
|
|
70
|
+
**Create the main override file:**
|
|
86
71
|
|
|
87
72
|
```bash
|
|
88
|
-
|
|
89
|
-
rails_git_hooks install pre-push # add pre-push
|
|
90
|
-
rails_git_hooks disable pre-commit # turn off pre-commit temporarily
|
|
91
|
-
rails_git_hooks disable * # turn off all
|
|
92
|
-
rails_git_hooks enable pre-commit # turn pre-commit back on
|
|
93
|
-
rails_git_hooks enable rubocop-check # run RuboCop on staged .rb files
|
|
94
|
-
rails_git_hooks enable whitespace-check # reject trailing ws & conflict markers
|
|
73
|
+
bundle exec rails_git_hooks init
|
|
95
74
|
```
|
|
96
75
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
---
|
|
76
|
+
**Optional:** Create `.rails_git_hooks.local.yml` in the repo root for personal overrides (merged on top of `.rails_git_hooks.yml`). Add it to `.gitignore` if you don’t want to commit it.
|
|
100
77
|
|
|
101
|
-
|
|
78
|
+
### Example override file
|
|
102
79
|
|
|
103
|
-
|
|
80
|
+
```yaml
|
|
81
|
+
PreCommit:
|
|
82
|
+
DebuggerCheck:
|
|
83
|
+
on_fail: fail
|
|
104
84
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
### pre-commit — Branch protection and optional checks
|
|
116
|
-
|
|
117
|
-
**Always on (when installed):**
|
|
118
|
-
|
|
119
|
-
- Blocks commits to `master` or `main`. You must commit from a feature branch.
|
|
120
|
-
- **Debugger check** — Warns (does not block) when staged files contain debugger statements: Ruby (`binding.pry`, `debugger`, `byebug`, `binding.irb`), JavaScript/TypeScript (`.js`, `.jsx`, `.ts`, `.tsx` — `debugger`), Python (`breakpoint()`, `pdb.set_trace()`, `ipdb.set_trace()`).
|
|
121
|
-
|
|
122
|
-
**Optional (off by default):**
|
|
123
|
-
|
|
124
|
-
1. **RuboCop** — Run RuboCop on staged `.rb` files; commit fails if there are offenses.
|
|
125
|
-
`rails_git_hooks enable rubocop-check` / `disable rubocop-check`. Requires the `rubocop` gem.
|
|
126
|
-
|
|
127
|
-
2. **Whitespace & conflict markers** — Reject commits that add trailing spaces/tabs or `<<<<<<<` / `=======` / `>>>>>>>` in staged files.
|
|
128
|
-
`rails_git_hooks enable whitespace-check` / `disable whitespace-check`.
|
|
129
|
-
|
|
130
|
-
---
|
|
131
|
-
|
|
132
|
-
### pre-push — Run tests before push
|
|
133
|
-
|
|
134
|
-
Runs `bundle exec rspec` before every `git push`. If the suite fails, the push is aborted. Not installed by default; add with `rails_git_hooks install pre-push`. For Minitest, edit the hook to use `bundle exec rake test`.
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Manual installation (without the gem)
|
|
85
|
+
RuboCop:
|
|
86
|
+
enabled: true
|
|
87
|
+
quiet: true
|
|
88
|
+
include:
|
|
89
|
+
- "app/**/*.rb"
|
|
90
|
+
- "lib/**/*.rb"
|
|
91
|
+
exclude:
|
|
92
|
+
- "db/schema.rb"
|
|
93
|
+
```
|
|
139
94
|
|
|
140
|
-
|
|
95
|
+
### Per-check options
|
|
141
96
|
|
|
142
|
-
|
|
|
143
|
-
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
97
|
+
| Option | Description |
|
|
98
|
+
|--------|--------------|
|
|
99
|
+
| `enabled` | Turn the check on or off. |
|
|
100
|
+
| `quiet` | Suppress normal output unless the check warns or fails. |
|
|
101
|
+
| `on_fail` | `fail`, `warn`, or `pass` when the check fails. |
|
|
102
|
+
| `on_warn` | `warn`, `fail`, or `pass` when the check would warn. |
|
|
103
|
+
| `on_missing_dependency` | Behavior when a required executable/library is missing. |
|
|
104
|
+
| `include` | Glob patterns for files the check applies to. |
|
|
105
|
+
| `exclude` | Glob patterns to exclude from `include`. |
|
|
106
|
+
| `command` | Override the command for checks that run external commands. |
|
|
147
107
|
|
|
148
|
-
|
|
108
|
+
## CLI reference
|
|
149
109
|
|
|
150
|
-
|
|
110
|
+
| Command | Description |
|
|
111
|
+
|---------|--------------|
|
|
112
|
+
| `rails_git_hooks install` | Install hooks that have at least one enabled check in the merged config (defaults + .rails_git_hooks.yml + .rails_git_hooks.local.yml). |
|
|
113
|
+
| `rails_git_hooks init` | Create an empty `.rails_git_hooks.yml`. |
|
|
151
114
|
|
|
152
|
-
|
|
153
|
-
bundle install
|
|
154
|
-
bundle exec rake # run specs
|
|
155
|
-
bundle exec rake build # build the gem
|
|
156
|
-
bundle exec rake install # install locally
|
|
157
|
-
bundle exec rake sync_hooks # copy templates (hooks + shared subdirs) → hooks/
|
|
158
|
-
```
|
|
115
|
+
## Contributing
|
|
159
116
|
|
|
160
|
-
|
|
117
|
+
Contributions are welcome. Open an [issue](https://github.com/NikitaNazarov1/rails_git_hooks/issues) for bugs or ideas, or submit a pull request.
|
|
161
118
|
|
|
162
119
|
## License
|
|
163
120
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'open3'
|
|
5
|
+
require 'yaml'
|
|
6
|
+
|
|
7
|
+
module GitHooks
|
|
8
|
+
module Checks
|
|
9
|
+
class Base
|
|
10
|
+
class << self
|
|
11
|
+
attr_reader :definition
|
|
12
|
+
|
|
13
|
+
def check_definition(key:, hook:, description:, config_name: name.split('::').last, **options)
|
|
14
|
+
@definition = CheckDefinition.new(
|
|
15
|
+
key: key,
|
|
16
|
+
config_name: config_name,
|
|
17
|
+
hook: hook,
|
|
18
|
+
klass: self,
|
|
19
|
+
description: description,
|
|
20
|
+
**options
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
attr_reader :config, :context
|
|
26
|
+
|
|
27
|
+
def initialize(config:, context:)
|
|
28
|
+
@config = config
|
|
29
|
+
@context = context
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def repo
|
|
35
|
+
context.fetch(:repo)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def applicable_files
|
|
39
|
+
context.fetch(:applicable_files, [])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def argv
|
|
43
|
+
context.fetch(:argv, [])
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def stdin
|
|
47
|
+
context.fetch(:stdin, '')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def capture(*command)
|
|
51
|
+
Open3.capture2e(*command, chdir: repo.root)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GitHooks
|
|
4
|
+
module Checks
|
|
5
|
+
module CommitMsg
|
|
6
|
+
class JiraPrefix < Base
|
|
7
|
+
TICKET_PATTERN = /([A-Z]{2,5}-\d+)/.freeze
|
|
8
|
+
|
|
9
|
+
check_definition key: 'jira-prefix',
|
|
10
|
+
hook: :commit_msg,
|
|
11
|
+
description: 'Prefix commit messages with ticket id from branch'
|
|
12
|
+
|
|
13
|
+
def run
|
|
14
|
+
message_file = argv.first
|
|
15
|
+
return CheckResult.pass unless message_file && File.file?(message_file)
|
|
16
|
+
|
|
17
|
+
branch = repo.current_branch
|
|
18
|
+
ticket = branch[TICKET_PATTERN, 1]
|
|
19
|
+
return CheckResult.pass unless ticket
|
|
20
|
+
|
|
21
|
+
message = File.read(message_file)
|
|
22
|
+
prefix = "[#{ticket}]"
|
|
23
|
+
return CheckResult.pass if message.lstrip.start_with?(prefix)
|
|
24
|
+
|
|
25
|
+
File.write(message_file, "#{prefix} #{message}")
|
|
26
|
+
CheckResult.pass
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GitHooks
|
|
4
|
+
module Checks
|
|
5
|
+
module PostCheckout
|
|
6
|
+
class BundleInstall < Base
|
|
7
|
+
include BundleInstallCheck
|
|
8
|
+
|
|
9
|
+
check_definition key: 'bundle-install',
|
|
10
|
+
hook: :post_checkout,
|
|
11
|
+
description: 'Run bundle install when Gemfile or Gemfile.lock changed (branch checkout)',
|
|
12
|
+
**BundleInstallCheck::DEFINITION_OPTIONS
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GitHooks
|
|
4
|
+
module Checks
|
|
5
|
+
module PostCheckout
|
|
6
|
+
class DbMigrate < Base
|
|
7
|
+
include DbMigrateCheck
|
|
8
|
+
|
|
9
|
+
check_definition key: 'db-migrate',
|
|
10
|
+
hook: :post_checkout,
|
|
11
|
+
description: 'Run db:migrate when migrations or schema changed (branch checkout)',
|
|
12
|
+
**DbMigrateCheck::DEFINITION_OPTIONS
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GitHooks
|
|
4
|
+
module Checks
|
|
5
|
+
module PostMerge
|
|
6
|
+
class BundleInstall < Base
|
|
7
|
+
include BundleInstallCheck
|
|
8
|
+
|
|
9
|
+
check_definition key: 'bundle-install',
|
|
10
|
+
hook: :post_merge,
|
|
11
|
+
description: 'Run bundle install when Gemfile or Gemfile.lock changed (after merge)',
|
|
12
|
+
**BundleInstallCheck::DEFINITION_OPTIONS
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GitHooks
|
|
4
|
+
module Checks
|
|
5
|
+
module PostMerge
|
|
6
|
+
class DbMigrate < Base
|
|
7
|
+
include DbMigrateCheck
|
|
8
|
+
|
|
9
|
+
check_definition key: 'db-migrate',
|
|
10
|
+
hook: :post_merge,
|
|
11
|
+
description: 'Run db:migrate when migrations or schema changed (after merge)',
|
|
12
|
+
**DbMigrateCheck::DEFINITION_OPTIONS
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GitHooks
|
|
4
|
+
module Checks
|
|
5
|
+
module PreCommit
|
|
6
|
+
class DebuggerCheck < Base
|
|
7
|
+
DEBUGGER_PATTERNS = {
|
|
8
|
+
'.rb' => [/\bbinding\.pry\b/, /\bbinding\.irb\b/, /\bdebugger\b/, /\bbyebug\b/],
|
|
9
|
+
'.js' => [/\bdebugger\s*;?/],
|
|
10
|
+
'.jsx' => [/\bdebugger\s*;?/],
|
|
11
|
+
'.ts' => [/\bdebugger\s*;?/],
|
|
12
|
+
'.tsx' => [/\bdebugger\s*;?/],
|
|
13
|
+
'.mjs' => [/\bdebugger\s*;?/],
|
|
14
|
+
'.cjs' => [/\bdebugger\s*;?/],
|
|
15
|
+
'.py' => [/\bbreakpoint\s*\(\s*\)/, /\bpdb\.set_trace\s*\(\s*\)/, /\bipdb\.set_trace\s*\(\s*\)/]
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
check_definition key: 'debugger-check',
|
|
19
|
+
hook: :pre_commit,
|
|
20
|
+
description: 'Warn on debugger statements',
|
|
21
|
+
file_based: true,
|
|
22
|
+
on_fail: :warn
|
|
23
|
+
|
|
24
|
+
def run
|
|
25
|
+
warnings = []
|
|
26
|
+
|
|
27
|
+
applicable_files.each do |path|
|
|
28
|
+
next unless File.file?(path)
|
|
29
|
+
|
|
30
|
+
patterns = DEBUGGER_PATTERNS[File.extname(path)]
|
|
31
|
+
next unless patterns
|
|
32
|
+
|
|
33
|
+
File.read(path).lines.each_with_index do |line, index|
|
|
34
|
+
warnings << "#{path}:#{index + 1}: debugger statement" if patterns.any? { |pattern| line.match?(pattern) }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
warnings.empty? ? CheckResult.pass : CheckResult.fail(messages: warnings.uniq)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GitHooks
|
|
4
|
+
module Checks
|
|
5
|
+
module PreCommit
|
|
6
|
+
class DefaultBranch < Base
|
|
7
|
+
check_definition key: 'default-branch',
|
|
8
|
+
hook: :pre_commit,
|
|
9
|
+
description: 'Prevent commits on default branch'
|
|
10
|
+
|
|
11
|
+
def run
|
|
12
|
+
branch = repo.current_branch
|
|
13
|
+
return CheckResult.pass unless %w[master main].include?(branch)
|
|
14
|
+
|
|
15
|
+
CheckResult.fail(messages: ["Commits on '#{branch}' are not allowed. Create a feature branch."])
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GitHooks
|
|
4
|
+
module Checks
|
|
5
|
+
module PreCommit
|
|
6
|
+
class JSONFormatCheck < Base
|
|
7
|
+
check_definition key: 'json-format-check',
|
|
8
|
+
hook: :pre_commit,
|
|
9
|
+
description: 'Warn on invalid JSON',
|
|
10
|
+
file_based: true,
|
|
11
|
+
on_fail: :warn
|
|
12
|
+
|
|
13
|
+
def run
|
|
14
|
+
warnings = []
|
|
15
|
+
|
|
16
|
+
applicable_files.each do |path|
|
|
17
|
+
next unless File.file?(path)
|
|
18
|
+
next unless File.extname(path) == '.json'
|
|
19
|
+
|
|
20
|
+
JSON.parse(File.read(path))
|
|
21
|
+
rescue JSON::ParserError => e
|
|
22
|
+
warnings << "#{path}: #{e.message}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
warnings.empty? ? CheckResult.pass : CheckResult.fail(messages: warnings)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GitHooks
|
|
4
|
+
module Checks
|
|
5
|
+
module PreCommit
|
|
6
|
+
class MigrationsCheck < Base
|
|
7
|
+
check_definition key: 'migrations-check',
|
|
8
|
+
hook: :pre_commit,
|
|
9
|
+
description: 'Warn on missing schema files after migrations',
|
|
10
|
+
file_based: true,
|
|
11
|
+
on_fail: :warn
|
|
12
|
+
|
|
13
|
+
def run
|
|
14
|
+
messages = []
|
|
15
|
+
migration_files = applicable_files.grep(%r{\Adb/migrate/.*\.rb\z})
|
|
16
|
+
schema_staged = applicable_files.include?('db/schema.rb') || applicable_files.include?('db/structure.sql')
|
|
17
|
+
|
|
18
|
+
if migration_files.any? && !schema_staged
|
|
19
|
+
messages << 'Migration file(s) are staged but neither db/schema.rb nor db/structure.sql is staged.'
|
|
20
|
+
messages << 'Run `rails db:migrate` and add db/schema.rb (or db/structure.sql) to your commit.'
|
|
21
|
+
migration_files.each { |path| messages << "- #{path}" }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
data_migration_files = applicable_files.grep(%r{\Adb/(data/|data_migrate/).*\.rb\z})
|
|
25
|
+
data_schema_staged = applicable_files.include?('db/data_schema.rb')
|
|
26
|
+
if data_migration_files.any? && !data_schema_staged
|
|
27
|
+
messages << 'Data migration file(s) are staged but db/data_schema.rb is not staged.'
|
|
28
|
+
messages << 'Run your data migrate task and add db/data_schema.rb to your commit.'
|
|
29
|
+
data_migration_files.each { |path| messages << "- #{path}" }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
messages.empty? ? CheckResult.pass : CheckResult.fail(messages: messages)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|