git-commit 0.1.0.pre → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -1
- data/exe/git.commit +6 -0
- data/git-commit.gemspec +2 -0
- data/lib/git/commit.rb +7 -6
- data/lib/git/commit/cli.rb +14 -0
- data/lib/git/commit/cli/command.rb +19 -0
- data/lib/git/commit/cli/command/validate.rb +21 -0
- data/lib/git/commit/format.rb +5 -0
- data/lib/git/commit/format/angular_js.rb +23 -0
- data/lib/git/commit/format/angular_js/builder.rb +11 -0
- data/lib/git/commit/format/angular_js/validator.rb +112 -0
- data/lib/git/commit/format/error.rb +2 -0
- data/lib/git/commit/version.rb +2 -5
- data/spike/gistfile1.txt +56 -0
- data/spike/git_hook.txt +1 -0
- metadata +31 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e849002bae64f9743ce916140e26d398a0070969
|
4
|
+
data.tar.gz: 9f27d45a96c913ad1ed92f979c7634caff5d8740
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a3f8c75c3d99b452cb81baa5613b19ed59ea47bf1a262f1becf3e2ddc3ca535766e64f6d7a89c2adaf4dc9a2a99f2bcd48fb52eaf89aab3b3c923522e5d3302
|
7
|
+
data.tar.gz: b40a8fd6328c02b3fcd40499a0bd1cd42e566333eed76fcb0dceda55bf6e4299c8d75f8a94b1ab8beb037eef9e4368ce09467111e908f3f61e5ee0909aa577dc
|
data/README.md
CHANGED
@@ -20,7 +20,15 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
|
23
|
+
```
|
24
|
+
git.commit help
|
25
|
+
Commands:
|
26
|
+
git.commit help [COMMAND] # Describe available commands or one specific command
|
27
|
+
git.commit validate [COMMAND] # Validate Commit message or commit file content
|
28
|
+
git.commit validate angularjs <git commit message or file path> # validate commit message or file content by angularjs commit conventions
|
29
|
+
```
|
30
|
+
|
31
|
+
I use this for enfoce angularJS git commit convention in commit-msg hook
|
24
32
|
|
25
33
|
## Development
|
26
34
|
|
data/exe/git.commit
ADDED
data/git-commit.gemspec
CHANGED
data/lib/git/commit.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
|
1
|
+
Git = Module.new unless defined?(Git)
|
2
|
+
module Git::Commit
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
require 'git/commit/version'
|
5
|
+
require 'git/commit/format'
|
6
|
+
require 'git/commit/cli'
|
7
|
+
|
8
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'thor'
|
2
|
+
class Git::Commit::CLI < Thor
|
3
|
+
|
4
|
+
require 'git/commit/cli/command'
|
5
|
+
|
6
|
+
ObjectSpace.each_object(Class).select { |klass| klass < Git::Commit::CLI::Command }.each do |command|
|
7
|
+
|
8
|
+
subcommand_name = command.to_s.split('::').last.downcase
|
9
|
+
desc("#{subcommand_name} [COMMAND]",command.get_class_description)
|
10
|
+
subcommand(subcommand_name, command)
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Git::Commit::CLI::Command < Thor
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def get_class_description
|
6
|
+
@class_description
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
def class_description(description)
|
12
|
+
@class_description = description
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'git/commit/cli/command/validate'
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Git::Commit::CLI::Command::Validate < Git::Commit::CLI::Command
|
2
|
+
|
3
|
+
class_description 'Validate Commit message or commit file content'
|
4
|
+
|
5
|
+
desc 'angularjs <git commit message or file path>',
|
6
|
+
'validate commit message or file content by angularjs commit conventions'
|
7
|
+
|
8
|
+
def angularjs_format(commit_message)
|
9
|
+
|
10
|
+
commit_message = File.read(commit_message) if File.exists?(commit_message)
|
11
|
+
|
12
|
+
begin
|
13
|
+
Git::Commit::Format::AngularJS::Validator.new(commit_message).validate
|
14
|
+
rescue Git::Commit::Format::Error => ex
|
15
|
+
$stderr.puts(ex.message,"\n",commit_message)
|
16
|
+
exit(1)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Git::Commit::Format::AngularJS
|
2
|
+
|
3
|
+
TYPES = {
|
4
|
+
feat: 'A new feature',
|
5
|
+
fix: 'A bug fix',
|
6
|
+
docs: 'Documentation only changes',
|
7
|
+
style: 'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
|
8
|
+
refactor: 'A code change that neither fixes a bug nor adds a feature',
|
9
|
+
perf: 'A code change that improves performance',
|
10
|
+
test: 'Adding missing tests',
|
11
|
+
chore: 'Changes to the build process or auxiliary tools and libraries such as documentation generation'
|
12
|
+
}
|
13
|
+
|
14
|
+
SCOPE = 'The scope could be anything specifying place of the commit change.'
|
15
|
+
|
16
|
+
require 'git/commit/format/angular_js/builder'
|
17
|
+
require 'git/commit/format/angular_js/validator'
|
18
|
+
|
19
|
+
def self.type_help_text
|
20
|
+
TYPES.map{|k,v| "\t#{k}:\t#{v}" }.join("\n")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# Accepted AngularJS commit format
|
2
|
+
#
|
3
|
+
# <type>(<scope>): <subject>
|
4
|
+
# <BLANK LINE>
|
5
|
+
# <body>
|
6
|
+
# <BLANK LINE>
|
7
|
+
# <footer>
|
8
|
+
class Git::Commit::Format::AngularJS::Validator
|
9
|
+
|
10
|
+
def validate
|
11
|
+
validate_mandatory_type
|
12
|
+
validate_mandatory_subject
|
13
|
+
validate_optional_scope
|
14
|
+
validate_optional_body
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate_mandatory_type
|
18
|
+
|
19
|
+
types = fetch_by(/^(\w+)/)[0]
|
20
|
+
|
21
|
+
if types.empty?
|
22
|
+
raise_format_error('missing type from the commit!')
|
23
|
+
end
|
24
|
+
|
25
|
+
type_sym = types.first.to_sym
|
26
|
+
unless Git::Commit::Format::AngularJS::TYPES.keys.include?(type_sym)
|
27
|
+
raise_format_error(
|
28
|
+
"invalid type given in the commit: #{type_sym}",
|
29
|
+
"use the following types: \n#{Git::Commit::Format::AngularJS.type_help_text}"
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def validate_mandatory_subject
|
36
|
+
|
37
|
+
subjects = @commit_message.to_s.split("\n")[0].scan(/^[^:]+:\s+(.*?)$/)[0]
|
38
|
+
|
39
|
+
if subjects.nil? or [*subjects].select{|str| not str.to_s.empty? }.empty?
|
40
|
+
raise_format_error('missing subject from the commit!')
|
41
|
+
end
|
42
|
+
|
43
|
+
subject = subjects[0]
|
44
|
+
if subject =~ /\b(changed|changes)\b/i
|
45
|
+
raise_format_error('use the imperative, present tense: "change" not "changed" nor "changes"')
|
46
|
+
end
|
47
|
+
|
48
|
+
if subject =~ /^[A-Z]\w*/
|
49
|
+
raise_format_error("Don't capitalize first letter")
|
50
|
+
end
|
51
|
+
|
52
|
+
if subject =~ /\.\s*$/
|
53
|
+
raise_format_error('No dot (.) at the end')
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
def validate_optional_scope
|
59
|
+
|
60
|
+
scope_begins = fetch_by(/^\w+(\()/)
|
61
|
+
|
62
|
+
if not scope_begins.empty? and not scope_begins[0].empty? and scope_content.nil?
|
63
|
+
raise_format_error('scope is malformed!')
|
64
|
+
end
|
65
|
+
|
66
|
+
first_line_scope_strs = scope_content
|
67
|
+
|
68
|
+
return if first_line_scope_strs.nil?
|
69
|
+
|
70
|
+
scope_str = first_line_scope_strs[0]
|
71
|
+
if not scope_str.nil? and scope_str.to_s.length == 0
|
72
|
+
raise_format_error('scope is too short!')
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def validate_optional_body
|
79
|
+
|
80
|
+
body_content_lines = fetch_by(/^.*$/)[1..-1].select { |str| !(str =~ /^\s*$/) }
|
81
|
+
given_a_blank_line = @commit_message.split("\n")[1].to_s.empty?
|
82
|
+
|
83
|
+
if not given_a_blank_line and not body_content_lines.empty?
|
84
|
+
raise_format_error('body must be placed after a blank line!')
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
def validate_optional_footer
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
|
94
|
+
def initialize(commit_message)
|
95
|
+
@commit_message = commit_message.to_s.dup.strip
|
96
|
+
end
|
97
|
+
|
98
|
+
def fetch_by(regular_expression)
|
99
|
+
@commit_message.scan(regular_expression)
|
100
|
+
end
|
101
|
+
|
102
|
+
def raise_format_error(*messages)
|
103
|
+
raise(Git::Commit::Format::Error, messages.join("\n"))
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def scope_content
|
109
|
+
fetch_by(/^\w+\(([^\)]*)\)/)[0]
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
data/lib/git/commit/version.rb
CHANGED
data/spike/gistfile1.txt
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
## Using ruby's standard OptionParser to get subcommand's in command line arguments
|
3
|
+
## Note you cannot do: opt.rb help command
|
4
|
+
## other options are commander, main, GLI, trollop...
|
5
|
+
|
6
|
+
# run it as
|
7
|
+
# ruby opt.rb --help
|
8
|
+
# ruby opt.rb foo --help
|
9
|
+
# ruby opt.rb foo -q
|
10
|
+
# etc
|
11
|
+
|
12
|
+
require 'optparse'
|
13
|
+
|
14
|
+
options = {}
|
15
|
+
|
16
|
+
subtext = <<HELP
|
17
|
+
Commonly used command are:
|
18
|
+
foo : does something awesome
|
19
|
+
baz : does something fantastic
|
20
|
+
|
21
|
+
See 'opt.rb COMMAND --help' for more information on a specific command.
|
22
|
+
HELP
|
23
|
+
|
24
|
+
global = OptionParser.new do |opts|
|
25
|
+
opts.banner = "Usage: opt.rb [options] [subcommand [options]]"
|
26
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
27
|
+
options[:verbose] = v
|
28
|
+
end
|
29
|
+
opts.separator ""
|
30
|
+
opts.separator subtext
|
31
|
+
end
|
32
|
+
#end.parse!
|
33
|
+
|
34
|
+
subcommands = {
|
35
|
+
'foo' => OptionParser.new do |opts|
|
36
|
+
opts.banner = "Usage: foo [options]"
|
37
|
+
opts.on("-f", "--[no-]force", "force verbosely") do |v|
|
38
|
+
options[:force] = v
|
39
|
+
end
|
40
|
+
end,
|
41
|
+
'baz' => OptionParser.new do |opts|
|
42
|
+
opts.banner = "Usage: baz [options]"
|
43
|
+
opts.on("-q", "--[no-]quiet", "quietly run ") do |v|
|
44
|
+
options[:quiet] = v
|
45
|
+
end
|
46
|
+
end
|
47
|
+
}
|
48
|
+
|
49
|
+
global.order!
|
50
|
+
command = ARGV.shift
|
51
|
+
subcommands[command].order!
|
52
|
+
|
53
|
+
puts "Command: #{command} "
|
54
|
+
p options
|
55
|
+
puts "ARGV:"
|
56
|
+
p ARGV
|
data/spike/git_hook.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.git/hooks/commit-msg
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-commit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Luzsi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,10 +52,25 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: thor
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: Git Commit helper.
|
56
70
|
email:
|
57
71
|
- adamluzsi@gmail.com
|
58
|
-
executables:
|
72
|
+
executables:
|
73
|
+
- git.commit
|
59
74
|
extensions: []
|
60
75
|
extra_rdoc_files: []
|
61
76
|
files:
|
@@ -69,9 +84,20 @@ files:
|
|
69
84
|
- Rakefile
|
70
85
|
- bin/console
|
71
86
|
- bin/setup
|
87
|
+
- exe/git.commit
|
72
88
|
- git-commit.gemspec
|
73
89
|
- lib/git/commit.rb
|
90
|
+
- lib/git/commit/cli.rb
|
91
|
+
- lib/git/commit/cli/command.rb
|
92
|
+
- lib/git/commit/cli/command/validate.rb
|
93
|
+
- lib/git/commit/format.rb
|
94
|
+
- lib/git/commit/format/angular_js.rb
|
95
|
+
- lib/git/commit/format/angular_js/builder.rb
|
96
|
+
- lib/git/commit/format/angular_js/validator.rb
|
97
|
+
- lib/git/commit/format/error.rb
|
74
98
|
- lib/git/commit/version.rb
|
99
|
+
- spike/gistfile1.txt
|
100
|
+
- spike/git_hook.txt
|
75
101
|
homepage: https://github.com/adamluzsi/git-commit
|
76
102
|
licenses: []
|
77
103
|
metadata: {}
|
@@ -86,9 +112,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
86
112
|
version: '0'
|
87
113
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
114
|
requirements:
|
89
|
-
- - "
|
115
|
+
- - ">="
|
90
116
|
- !ruby/object:Gem::Version
|
91
|
-
version:
|
117
|
+
version: '0'
|
92
118
|
requirements: []
|
93
119
|
rubyforge_project:
|
94
120
|
rubygems_version: 2.2.2
|