rails_git_hooks 0.4.0
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 +7 -0
- data/CHANGELOG.md +56 -0
- data/LICENSE +21 -0
- data/README.md +143 -0
- data/bin/rails_git_hooks +8 -0
- data/lib/rails_git_hooks/cli.rb +126 -0
- data/lib/rails_git_hooks/installer.rb +99 -0
- data/lib/rails_git_hooks/templates/commit-msg +32 -0
- data/lib/rails_git_hooks/templates/pre-commit +37 -0
- data/lib/rails_git_hooks/version.rb +5 -0
- data/lib/rails_git_hooks.rb +8 -0
- metadata +97 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 109ffcd87e2ce426eba039b823d0ff33826a3dbed17551aa064bd2102af0e0eb
|
|
4
|
+
data.tar.gz: 8669d08859c06afc5aa43b6e3476b6fec3f1fb2edcdf93a1eb0e437ee30ca8d0
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: bbe3c679e9cb4d71be001cb02ce82a80d16a36764aff795a1d3d1cffeca86a14a6036b9f55a86679afebf70acb16f797f6952f87e4900d29bf22c615cb3ac840
|
|
7
|
+
data.tar.gz: 482cda03ee82f8aee5caad95611eec7deaf190136d97be665b74de5a89d842bcdae5a7086ceeb65fb5d74d8e7cc1ef41ecab3d7b05a708dd60e34d6d890aeedf
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.4.0] - (latest)
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Gem and project renamed to **rails_git_hooks** (from `git_hooks`)
|
|
14
|
+
- Library: `lib/git_hooks/` → `lib/rails_git_hooks/`; entry point `lib/rails_git_hooks.rb`
|
|
15
|
+
- CLI executable: `rails_git_hooks` (replaces `git_hooks`)
|
|
16
|
+
- Disabled state file: `.git/rails_git_hooks_disabled` (was `.git/git_hooks_disabled`)
|
|
17
|
+
- README, docs, and in-repo paths updated for `rails_git_hooks`
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- RuboCop `Lint/ScriptPermission` exclusion for `lib/rails_git_hooks/templates/*` (templates are made executable at install time)
|
|
22
|
+
|
|
23
|
+
## [0.3.0]
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- fixed versioning
|
|
28
|
+
|
|
29
|
+
## [0.2.0]
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- RSpec test suite for CLI and Installer
|
|
34
|
+
- `rake sync_hooks` task to copy templates from `lib/git_hooks/templates` to `hooks/` for manual install
|
|
35
|
+
- Gemspec metadata: `source_code_uri`, `changelog_uri`; author email
|
|
36
|
+
- CHANGELOG.md (Keep a Changelog format)
|
|
37
|
+
- Default Rake task runs specs (`rake` = `rake spec`)
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- **Single source of truth:** `lib/git_hooks/templates/` is canonical; `hooks/` kept in sync via `rake sync_hooks`
|
|
42
|
+
- CLI install: `--jira` parsed with OptionParser instead of manual loop
|
|
43
|
+
- Installer `#disable`: simplified to `(disabled_hooks + hook_names).uniq`
|
|
44
|
+
- Hooks: commit-msg and pre-commit now include disable check (`.git/rails_git_hooks_disabled`); commit-msg uses `JIRA_PROJECT_KEY` placeholder for manual install
|
|
45
|
+
- pre-commit: use `warn` instead of `$stderr.puts` for default-branch message
|
|
46
|
+
- README: manual install points to `hooks/` and `JIRA_PROJECT_KEY`; development section documents `rake`, `rake sync_hooks`
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- (none)
|
|
51
|
+
|
|
52
|
+
## [0.1.0] - (initial release)
|
|
53
|
+
|
|
54
|
+
- commit-msg hook: Jira ticket prefix in commit messages
|
|
55
|
+
- pre-commit hook: RuboCop on staged Ruby files, block commits on default branch (master/main)
|
|
56
|
+
- `rails_git_hooks install`, `disable`, `enable`, `disabled`, `list` CLI commands
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Nikita Nazarov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Git Hooks
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/rb/rails_git_hooks)
|
|
4
|
+
[](https://github.com/NikitaNazarov1/rails_git_hooks/actions/workflows/tests.yml?query=branch%3Amain)
|
|
5
|
+
[](https://github.com/NikitaNazarov1/rails_git_hooks/actions/workflows/rubocop.yml?query=branch%3Amain)
|
|
6
|
+
|
|
7
|
+
> Automate Jira ticket prefixes and RuboCop checks with git hooks. Built for Rails and Ruby projects.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What you get
|
|
12
|
+
|
|
13
|
+
| Hook | What it does |
|
|
14
|
+
|------|--------------|
|
|
15
|
+
| **commit-msg** | Prepends `[TICKET-123]` to commit messages when your branch name contains a Jira ticket. |
|
|
16
|
+
| **pre-commit** | Blocks commits to `master`/`main` and runs RuboCop on staged `.rb` files. |
|
|
17
|
+
|
|
18
|
+
Hooks can be disabled temporarily (e.g. for quick WIP commits or CI) without uninstalling.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
**1. Install the gem**
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
gem install rails_git_hooks
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or with Bundler — add to your `Gemfile`:
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
gem "rails_git_hooks"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Then:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
bundle install
|
|
40
|
+
bundle exec rails_git_hooks install
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**2. (Optional) Set your Jira project key**
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
rails_git_hooks install --jira MYPROJ
|
|
47
|
+
# or
|
|
48
|
+
export GIT_HOOKS_JIRA_PROJECT=MYPROJ
|
|
49
|
+
rails_git_hooks install
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Default is `APD` if not set.
|
|
53
|
+
|
|
54
|
+
> **Tip:** If the pre-commit hook doesn’t run, make it executable: `chmod +x .git/hooks/pre-commit`
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Commands
|
|
59
|
+
|
|
60
|
+
Run from your project root (inside a git repo).
|
|
61
|
+
|
|
62
|
+
| Command | Description |
|
|
63
|
+
|---------|-------------|
|
|
64
|
+
| `rails_git_hooks install [HOOK...] [--jira PROJECT]` | Install hooks. No args = install all. |
|
|
65
|
+
| `rails_git_hooks list` | List available hook names. |
|
|
66
|
+
| `rails_git_hooks disable HOOK [HOOK...]` | Disable hooks (use `*` for all). |
|
|
67
|
+
| `rails_git_hooks enable HOOK [HOOK...]` | Re-enable disabled hooks. |
|
|
68
|
+
| `rails_git_hooks disabled` | Show which hooks are currently disabled. |
|
|
69
|
+
|
|
70
|
+
**Examples**
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Install everything with custom Jira key
|
|
74
|
+
rails_git_hooks install --jira MYPROJ
|
|
75
|
+
|
|
76
|
+
# Install only specific hooks
|
|
77
|
+
rails_git_hooks install pre-commit commit-msg --jira APD
|
|
78
|
+
|
|
79
|
+
# Temporarily disable pre-commit (e.g. for a quick fix)
|
|
80
|
+
rails_git_hooks disable pre-commit
|
|
81
|
+
|
|
82
|
+
# Disable all hooks
|
|
83
|
+
rails_git_hooks disable *
|
|
84
|
+
|
|
85
|
+
# Turn them back on
|
|
86
|
+
rails_git_hooks enable pre-commit
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Disabled state is stored in `.git/rails_git_hooks_disabled` and persists until you run `enable`.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Hooks in detail
|
|
94
|
+
|
|
95
|
+
### commit-msg — Jira ticket prefix
|
|
96
|
+
|
|
97
|
+
If your branch name contains a Jira ticket (e.g. `task/APD-1234/fix-bug`), the hook prepends `[APD-1234] ` to the commit message unless it’s already there.
|
|
98
|
+
|
|
99
|
+
**Example**
|
|
100
|
+
|
|
101
|
+
- Branch: `task/APD-1234/fix-bug`
|
|
102
|
+
- You run: `git commit -m 'fix bug'`
|
|
103
|
+
- Result: **`[APD-1234] fix bug`**
|
|
104
|
+
|
|
105
|
+
Set the Jira project key at install time with `--jira PROJECT` or `GIT_HOOKS_JIRA_PROJECT`.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
### pre-commit — Default branch protection + RuboCop
|
|
110
|
+
|
|
111
|
+
1. **Blocks commits on `master` / `main`** — You must commit from a feature branch; direct commits to the default branch are rejected.
|
|
112
|
+
2. **Runs RuboCop** on staged `.rb` files. If there are offenses, the commit is aborted.
|
|
113
|
+
|
|
114
|
+
Requires the `rubocop` gem in your project. If the hook doesn’t run, ensure it’s executable: `chmod +x .git/hooks/pre-commit`.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Manual installation (without the gem)
|
|
119
|
+
|
|
120
|
+
If you don’t want to use the gem, copy the scripts from `hooks/` into `.git/hooks`. The `hooks/` directory is synced from the gem templates via `rake sync_hooks` in development.
|
|
121
|
+
|
|
122
|
+
| File | Notes |
|
|
123
|
+
|------|--------|
|
|
124
|
+
| [commit-msg](hooks/commit-msg) | Replace `JIRA_PROJECT_KEY` in the script with your Jira project key (e.g. `APD`). |
|
|
125
|
+
| [pre-commit](hooks/pre-commit) | Requires the `rubocop` gem in the repo where you use it. |
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Development
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
bundle install
|
|
133
|
+
bundle exec rake # run specs (default task)
|
|
134
|
+
bundle exec rake build # build the gem
|
|
135
|
+
bundle exec rake install # install the gem locally
|
|
136
|
+
bundle exec rake sync_hooks # copy templates to hooks/
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT. See [LICENSE](LICENSE).
|
data/bin/rails_git_hooks
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_git_hooks'
|
|
4
|
+
require 'optparse'
|
|
5
|
+
|
|
6
|
+
module GitHooks
|
|
7
|
+
class CLI
|
|
8
|
+
def self.run(argv = ARGV)
|
|
9
|
+
new.run(argv)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def run(argv)
|
|
13
|
+
case argv[0]
|
|
14
|
+
when 'install'
|
|
15
|
+
run_install(argv[1..])
|
|
16
|
+
when 'list'
|
|
17
|
+
run_list
|
|
18
|
+
when 'disable'
|
|
19
|
+
run_disable(argv[1..])
|
|
20
|
+
when 'enable'
|
|
21
|
+
run_enable(argv[1..])
|
|
22
|
+
when 'disabled'
|
|
23
|
+
run_disabled
|
|
24
|
+
when nil, '-h', '--help'
|
|
25
|
+
print_help
|
|
26
|
+
else
|
|
27
|
+
warn "Unknown command: #{argv[0]}"
|
|
28
|
+
print_help
|
|
29
|
+
exit 1
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def run_install(args)
|
|
36
|
+
jira = nil
|
|
37
|
+
OptionParser.new do |opts|
|
|
38
|
+
opts.on('--jira PROJECT', 'Jira project key (e.g. APD)') { |v| jira = v }
|
|
39
|
+
end.parse!(args)
|
|
40
|
+
hooks = args
|
|
41
|
+
|
|
42
|
+
installer = Installer.new(jira_project: jira)
|
|
43
|
+
installed = installer.install(*hooks)
|
|
44
|
+
puts "Installed hooks: #{installed.join(', ')}"
|
|
45
|
+
rescue GitHooks::Error => e
|
|
46
|
+
warn "Error: #{e.message}"
|
|
47
|
+
exit 1
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def run_list
|
|
51
|
+
dir = GitHooks::Installer::HOOKS_DIR
|
|
52
|
+
hooks = Dir.children(dir).select { |f| File.file?(File.join(dir, f)) }
|
|
53
|
+
puts "Available hooks: #{hooks.join(', ')}"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def run_disable(args)
|
|
57
|
+
hooks = args.reject { |a| a.start_with?('-') }
|
|
58
|
+
if hooks.empty?
|
|
59
|
+
warn 'Usage: rails_git_hooks disable HOOK [HOOK...]'
|
|
60
|
+
warn "Use '*' to disable all hooks."
|
|
61
|
+
exit 1
|
|
62
|
+
end
|
|
63
|
+
installer = Installer.new
|
|
64
|
+
installer.disable(*hooks)
|
|
65
|
+
puts "Disabled: #{hooks.join(', ')}"
|
|
66
|
+
rescue GitHooks::Error => e
|
|
67
|
+
warn "Error: #{e.message}"
|
|
68
|
+
exit 1
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def run_enable(args)
|
|
72
|
+
hooks = args.reject { |a| a.start_with?('-') }
|
|
73
|
+
if hooks.empty?
|
|
74
|
+
warn 'Usage: rails_git_hooks enable HOOK [HOOK...]'
|
|
75
|
+
exit 1
|
|
76
|
+
end
|
|
77
|
+
installer = Installer.new
|
|
78
|
+
installer.enable(*hooks)
|
|
79
|
+
puts "Enabled: #{hooks.join(', ')}"
|
|
80
|
+
rescue GitHooks::Error => e
|
|
81
|
+
warn "Error: #{e.message}"
|
|
82
|
+
exit 1
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def run_disabled
|
|
86
|
+
installer = Installer.new
|
|
87
|
+
list = installer.disabled_hooks
|
|
88
|
+
if list.empty?
|
|
89
|
+
puts 'No hooks disabled.'
|
|
90
|
+
else
|
|
91
|
+
puts "Disabled hooks: #{list.join(', ')}"
|
|
92
|
+
end
|
|
93
|
+
rescue GitHooks::Error => e
|
|
94
|
+
warn "Error: #{e.message}"
|
|
95
|
+
exit 1
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def print_help
|
|
99
|
+
puts <<~HELP
|
|
100
|
+
rails_git_hooks - Install git hooks for Jira commit prefix and RuboCop
|
|
101
|
+
|
|
102
|
+
Usage:
|
|
103
|
+
rails_git_hooks install [HOOK...] [--jira PROJECT_KEY]
|
|
104
|
+
rails_git_hooks disable HOOK [HOOK...] (use * for all)
|
|
105
|
+
rails_git_hooks enable HOOK [HOOK...]
|
|
106
|
+
rails_git_hooks disabled
|
|
107
|
+
rails_git_hooks list
|
|
108
|
+
rails_git_hooks --help
|
|
109
|
+
|
|
110
|
+
Commands:
|
|
111
|
+
install Install hooks into current repo's .git/hooks.
|
|
112
|
+
disable Disable hooks (they no-op until enabled).
|
|
113
|
+
enable Re-enable disabled hooks.
|
|
114
|
+
disabled List currently disabled hooks.
|
|
115
|
+
list List available hook names.
|
|
116
|
+
|
|
117
|
+
Examples:
|
|
118
|
+
rails_git_hooks install
|
|
119
|
+
rails_git_hooks disable pre-commit
|
|
120
|
+
rails_git_hooks disable * # disable all
|
|
121
|
+
rails_git_hooks enable pre-commit
|
|
122
|
+
rails_git_hooks install commit-msg pre-commit --jira MYPROJ
|
|
123
|
+
HELP
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GitHooks
|
|
4
|
+
class Installer
|
|
5
|
+
HOOKS_DIR = File.expand_path('templates', __dir__).freeze
|
|
6
|
+
|
|
7
|
+
def initialize(git_dir: nil, jira_project: nil)
|
|
8
|
+
@git_dir = git_dir || find_git_dir
|
|
9
|
+
@jira_project = jira_project || ENV['GIT_HOOKS_JIRA_PROJECT'] || 'APD'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def install(*hook_names)
|
|
13
|
+
target_dir = File.join(@git_dir, 'hooks')
|
|
14
|
+
raise GitHooks::Error, "Not a git repository or .git/hooks not found: #{@git_dir}" unless Dir.exist?(target_dir)
|
|
15
|
+
|
|
16
|
+
hooks = hook_names.empty? ? available_hooks : hook_names
|
|
17
|
+
installed = []
|
|
18
|
+
|
|
19
|
+
hooks.each do |name|
|
|
20
|
+
src = File.join(HOOKS_DIR, name)
|
|
21
|
+
next unless File.file?(src)
|
|
22
|
+
|
|
23
|
+
dest = File.join(target_dir, name)
|
|
24
|
+
content = read_template(name)
|
|
25
|
+
content = content.gsub('JIRA_PROJECT_KEY', @jira_project) if name == 'commit-msg'
|
|
26
|
+
write_hook(dest, content)
|
|
27
|
+
make_executable(dest)
|
|
28
|
+
installed << name
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
installed
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def available_hooks
|
|
35
|
+
Dir.children(HOOKS_DIR).select { |f| File.file?(File.join(HOOKS_DIR, f)) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
DISABLED_FILE = 'rails_git_hooks_disabled'
|
|
39
|
+
|
|
40
|
+
def disabled_file_path
|
|
41
|
+
File.join(@git_dir, DISABLED_FILE)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def disabled_hooks
|
|
45
|
+
path = disabled_file_path
|
|
46
|
+
return [] unless File.exist?(path)
|
|
47
|
+
|
|
48
|
+
File.read(path).split("\n").map(&:strip).reject(&:empty?)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def disable(*hook_names)
|
|
52
|
+
path = disabled_file_path
|
|
53
|
+
current = (disabled_hooks + hook_names).uniq
|
|
54
|
+
File.write(path, "#{current.join("\n")}\n")
|
|
55
|
+
hook_names
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def enable(*hook_names)
|
|
59
|
+
path = disabled_file_path
|
|
60
|
+
return [] unless File.exist?(path)
|
|
61
|
+
|
|
62
|
+
current = disabled_hooks - hook_names
|
|
63
|
+
if current.empty?
|
|
64
|
+
File.delete(path)
|
|
65
|
+
else
|
|
66
|
+
File.write(path, "#{current.join("\n")}\n")
|
|
67
|
+
end
|
|
68
|
+
hook_names
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
def find_git_dir
|
|
74
|
+
dir = Dir.pwd
|
|
75
|
+
loop do
|
|
76
|
+
git = File.join(dir, '.git')
|
|
77
|
+
return git if File.directory?(git)
|
|
78
|
+
|
|
79
|
+
parent = File.dirname(dir)
|
|
80
|
+
raise GitHooks::Error, 'Not inside a git repository' if parent == dir
|
|
81
|
+
|
|
82
|
+
dir = parent
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def read_template(name)
|
|
87
|
+
path = File.join(HOOKS_DIR, name)
|
|
88
|
+
File.read(path)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def write_hook(path, content)
|
|
92
|
+
File.write(path, content)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def make_executable(path)
|
|
96
|
+
File.chmod(0o755, path)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# Git commit-msg hook: if branch name contains a Jira ticket (e.g. APD-1234),
|
|
6
|
+
# prepends "[APD-1234] " to commit messages unless already present.
|
|
7
|
+
# JIRA_PROJECT_KEY is replaced at install time by git_hooks; for manual install, replace it with your project key.
|
|
8
|
+
|
|
9
|
+
# Git runs hooks with CWD = repo root; find .git from here
|
|
10
|
+
repo_root = Dir.pwd
|
|
11
|
+
git_dir = File.join(repo_root, '.git')
|
|
12
|
+
git_dir = File.expand_path(File.read(git_dir).strip.sub(/\Agitdir: \s*/, ''), repo_root) if File.file?(git_dir)
|
|
13
|
+
disabled_file = File.join(git_dir, 'rails_git_hooks_disabled')
|
|
14
|
+
if File.exist?(disabled_file)
|
|
15
|
+
disabled = File.read(disabled_file).split("\n").map(&:strip)
|
|
16
|
+
exit 0 if disabled.include?('*') || disabled.include?('commit-msg')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
commit_message_file = ARGV[0]
|
|
20
|
+
branch_name = `git branch --no-color 2> /dev/null`[/^\* (.+)/, 1].to_s
|
|
21
|
+
original_commit_message = File.read(commit_message_file).strip
|
|
22
|
+
|
|
23
|
+
pattern = /(JIRA_PROJECT_KEY-\d+)/i
|
|
24
|
+
|
|
25
|
+
if (m = branch_name.match(pattern))
|
|
26
|
+
jira_number = m.captures.first
|
|
27
|
+
|
|
28
|
+
exit 0 if original_commit_message.include?(jira_number)
|
|
29
|
+
|
|
30
|
+
message = "[#{jira_number}] #{original_commit_message}"
|
|
31
|
+
File.open(commit_message_file, 'w') { |f| f.write message }
|
|
32
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# Runs RuboCop on staged .rb files. Commit is aborted if RuboCop reports offenses.
|
|
6
|
+
|
|
7
|
+
# Git runs hooks with CWD = repo root; find .git from here
|
|
8
|
+
repo_root = Dir.pwd
|
|
9
|
+
git_dir = File.join(repo_root, '.git')
|
|
10
|
+
git_dir = File.expand_path(File.read(git_dir).strip.sub(/\Agitdir: \s*/, ''), repo_root) if File.file?(git_dir)
|
|
11
|
+
disabled_file = File.join(git_dir, 'rails_git_hooks_disabled')
|
|
12
|
+
if File.exist?(disabled_file)
|
|
13
|
+
disabled = File.read(disabled_file).split("\n").map(&:strip)
|
|
14
|
+
exit 0 if disabled.include?('*') || disabled.include?('pre-commit')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Prevent commits on default branch (master/main)
|
|
18
|
+
branch = `git rev-parse --abbrev-ref HEAD`.strip
|
|
19
|
+
if %w[master main].include?(branch)
|
|
20
|
+
warn "Commits on '#{branch}' are not allowed. Create a feature branch."
|
|
21
|
+
exit 1
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
require 'english'
|
|
25
|
+
require 'rubocop'
|
|
26
|
+
|
|
27
|
+
ADDED_OR_MODIFIED = /A|AM|^M/.freeze
|
|
28
|
+
|
|
29
|
+
changed_files = `git status --porcelain`.split(/\n/)
|
|
30
|
+
.select { |file_name_with_status| file_name_with_status =~ ADDED_OR_MODIFIED }
|
|
31
|
+
.map { |file_name_with_status| file_name_with_status.split(' ')[1] }
|
|
32
|
+
.select { |file_name| File.extname(file_name) == '.rb' }
|
|
33
|
+
.join(' ')
|
|
34
|
+
|
|
35
|
+
system("rubocop #{changed_files}") unless changed_files.empty?
|
|
36
|
+
|
|
37
|
+
exit $CHILD_STATUS.to_s[-1].to_i
|
metadata
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rails_git_hooks
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.4.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Nikita Nazarov
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rake
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '13.0'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '13.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rspec
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '3.0'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '3.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rubocop
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.0'
|
|
54
|
+
description: Installs commit-msg (Jira ticket prefix) and pre-commit (RuboCop) hooks
|
|
55
|
+
into your git repository.
|
|
56
|
+
email:
|
|
57
|
+
- nikenor11@gmail.com
|
|
58
|
+
executables:
|
|
59
|
+
- rails_git_hooks
|
|
60
|
+
extensions: []
|
|
61
|
+
extra_rdoc_files: []
|
|
62
|
+
files:
|
|
63
|
+
- CHANGELOG.md
|
|
64
|
+
- LICENSE
|
|
65
|
+
- README.md
|
|
66
|
+
- bin/rails_git_hooks
|
|
67
|
+
- lib/rails_git_hooks.rb
|
|
68
|
+
- lib/rails_git_hooks/cli.rb
|
|
69
|
+
- lib/rails_git_hooks/installer.rb
|
|
70
|
+
- lib/rails_git_hooks/templates/commit-msg
|
|
71
|
+
- lib/rails_git_hooks/templates/pre-commit
|
|
72
|
+
- lib/rails_git_hooks/version.rb
|
|
73
|
+
homepage: https://github.com/NikitaNazarov1/rails_git_hooks
|
|
74
|
+
licenses:
|
|
75
|
+
- MIT
|
|
76
|
+
metadata:
|
|
77
|
+
homepage_uri: https://github.com/NikitaNazarov1/rails_git_hooks
|
|
78
|
+
source_code_uri: https://github.com/NikitaNazarov1/rails_git_hooks
|
|
79
|
+
changelog_uri: https://github.com/NikitaNazarov1/rails_git_hooks/blob/main/CHANGELOG.md
|
|
80
|
+
rdoc_options: []
|
|
81
|
+
require_paths:
|
|
82
|
+
- lib
|
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - ">="
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: 2.6.0
|
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
|
+
requirements:
|
|
90
|
+
- - ">="
|
|
91
|
+
- !ruby/object:Gem::Version
|
|
92
|
+
version: '0'
|
|
93
|
+
requirements: []
|
|
94
|
+
rubygems_version: 3.6.9
|
|
95
|
+
specification_version: 4
|
|
96
|
+
summary: Git hooks for Jira commit prefix and RuboCop on staged files
|
|
97
|
+
test_files: []
|