fit-commit 3.7.0 → 3.8.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a0b95d59622579ff58ddc0443293c4be66ae71b9
4
- data.tar.gz: 9a8d5cca328a035aa802c9e5514ed5c0c1e07c11
2
+ SHA256:
3
+ metadata.gz: df282f5ee34b3c0470ecfda368b8e4cdab62f0af1c11c9736bff1e5bfa579889
4
+ data.tar.gz: 93d726e9021c0b916ccea759a0af99aa23f692ae8463ca3d731216c65ba4406a
5
5
  SHA512:
6
- metadata.gz: 271657b39d8a59e5f9c8e537a8cd6c972f5e73e68cf289bfdebd9860585b4ef344e9a8b517c80615ac6791d0fe843f72cd32ed5a56491d09e6cd079e95f80b6a
7
- data.tar.gz: a38474d9139609b5672926e3c8e05069c1c655707fed2eaca6a2223cd01aa51067ceca1719247582498c2c37c6e8556fb50bb68623954e040c76db651106ac55
6
+ metadata.gz: 97c4c3ff3edbdbc56e9e6b5f5bb73ea8ddf99ffce4dc17744f0a25f01f277c02eea184e435bd8bad4636aec9efd65851d81cb4a63d2960bd079d022ac027bfe4
7
+ data.tar.gz: 352773141ef5ed5d0c16e9d466810bf30de4a999e3d7f748833fcbf8a4bd545f44740597a0a41ec31de3c5fe65d422c95136b68b2232ddcf86c48215c1cddabd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ### v3.8.0 (2018-08-06)
4
+ - Add CapitalizeSubject config option to warn on WIPlikes
5
+
6
+ ### v3.7.0 (2017-01-07)
7
+ - Run via Bundler if available
8
+
9
+ ### v3.6.0 (2016-11-18)
10
+ - Disable WIP check by default
11
+
3
12
  ### v3.5.0 (2016-04-05)
4
13
  - All validations are enabled on all branches by default
5
14
 
data/README.md CHANGED
@@ -61,6 +61,7 @@ Validators/SubjectPeriod:
61
61
  Enabled: true
62
62
  Validators/CapitalizeSubject:
63
63
  Enabled: true
64
+ WarnOnWiplikes: true
64
65
  Validators/Frathouse:
65
66
  Enabled: true
66
67
  Validators/Wip:
@@ -73,10 +74,10 @@ The `Enabled` property accepts multiple formats:
73
74
  # true/false to enable/disable the validation (branch agnostic)
74
75
  Validators/Foo:
75
76
  Enabled: false
76
- # Array of String/Regex matching each branch for which it's enabled
77
+ # Array of String or Regex matching each branch it's enabled on
77
78
  Validators/Bar:
78
79
  Enabled:
79
- - master
80
+ - main
80
81
  - !ruby/regexp /\Afoo.+bar/
81
82
  ```
82
83
 
@@ -161,10 +162,15 @@ $ git init
161
162
  Fit Commit can be run outside of a Git hook context with a simple shell script:
162
163
 
163
164
  ```sh
164
- $ GIT_BRANCH_NAME=branch_name COMMIT_MESSAGE_PATH=path/to/message rbenv exec ruby -rrubygems -e 'require "fit_commit"; FitCommit.run'
165
+ $ export GIT_BRANCH_NAME=branch_name
166
+ $ export COMMIT_MESSAGE_PATH=path/to/message
167
+ # Using Bundler
168
+ $ bundle exec ruby -e 'require "fit_commit"; FitCommit.run'
169
+ # Not using Bundler
170
+ $ rbenv exec ruby -rrubygems -e 'require "fit_commit"; FitCommit.run'
165
171
  ```
166
172
 
167
- It exits with an error code if any errors are present, which will fail a build if it's part of a CI run. The configuration should be modified for CI to be more lenient, otherwise false positives will break the build too often.
173
+ It exits with an error code if any errors are present, which will fail a build if it's part of a CI run.
168
174
 
169
175
  ### Who decided these rules?
170
176
  Fit Commit aims to enforce *community standards*. The two influential guides are:
data/TODO.md ADDED
@@ -0,0 +1,3 @@
1
+ # TODO
2
+
3
+ - Ideas from: https://github.com/bkuhlmann/git-cop
data/fit-commit.gemspec CHANGED
@@ -12,22 +12,20 @@ Gem::Specification.new do |gem|
12
12
  gem.description = "A Git hook to validate your commit messages based on community standards."
13
13
  gem.files = `git ls-files`.split("\n")
14
14
  gem.executables = ["fit-commit"]
15
- gem.default_executable = "fit-commit"
16
15
  gem.test_files = `git ls-files -- test/*`.split("\n")
17
16
  gem.require_paths = ["lib"]
18
17
  gem.extra_rdoc_files = ["README.md"]
19
18
  gem.rdoc_options = ["--main", "README.md"]
20
19
 
21
20
  gem.post_install_message = <<-EOF
22
- Thank you for installing Fit Commit!
23
- Install the hook in each git repo you want to scan using:
21
+ Install Fit Commit hooks in each git repo you want to scan using:
24
22
 
25
23
  > fit-commit install
26
24
 
27
25
  Read more: https://github.com/m1foley/fit-commit#readme
28
26
  EOF
29
27
 
30
- gem.add_dependency("swearjar", "~> 1.0")
31
- gem.add_development_dependency("minitest", "~> 5.8")
32
- gem.add_development_dependency("rake", "~> 10.4")
28
+ gem.add_dependency("swearjar", "~> 1.4")
29
+ gem.add_development_dependency("minitest", "~> 5.14")
30
+ gem.add_development_dependency("rake", "~> 13.0")
33
31
  end
@@ -23,7 +23,7 @@ module FitCommit
23
23
  $stderr.puts "fit-commit v#{FitCommit::VERSION}"
24
24
  $stderr.puts "Usage: fit-commit install"
25
25
  $stderr.puts "Usage: fit-commit uninstall"
26
- EXIT_CODE_FAILURE
26
+ EXIT_CODE_SUCCESS
27
27
  end
28
28
 
29
29
  def install
@@ -2,47 +2,58 @@ require "yaml"
2
2
 
3
3
  module FitCommit
4
4
  class ConfigurationLoader
5
- def global_configuration
6
- all_filepaths.each_with_object({}) do |filepath, config|
5
+ SYSTEM_FILEPATH = "/etc/fit_commit.yml"
6
+ LOCAL_FILEPATH = ".fit_commit.yml"
7
+
8
+ def initialize(filepaths)
9
+ self.filepaths = filepaths
10
+ end
11
+
12
+ def self.default_configuration
13
+ new(default_filepaths).configuration
14
+ end
15
+
16
+ def configuration
17
+ filepaths.each_with_object({}) do |filepath, config|
7
18
  config.merge!(read_config(filepath)) do |_key, oldval, newval|
8
19
  oldval.merge(newval)
9
20
  end
10
21
  end
11
22
  end
12
23
 
13
- private
14
-
15
- def all_filepaths
16
- # sorted by increasing precedence
17
- [default_filepath, system_filepath, user_filepath, config_filepath, local_filepath]
24
+ def self.default_filepaths
25
+ [
26
+ gem_default_filepath,
27
+ SYSTEM_FILEPATH,
28
+ user_filepath,
29
+ config_filepath,
30
+ LOCAL_FILEPATH
31
+ ]
18
32
  end
19
33
 
20
- def default_filepath
34
+ def self.gem_default_filepath
21
35
  File.expand_path("../../../templates/config/fit_commit.default.yml", __FILE__)
22
36
  end
23
37
 
24
- def system_filepath
25
- "/etc/fit_commit.yml"
26
- end
27
-
28
- def user_filepath
38
+ def self.user_filepath
29
39
  File.join(ENV["HOME"], ".fit_commit.yml")
30
40
  end
31
41
 
32
- def config_filepath
42
+ def self.config_filepath
33
43
  File.join(git_top_level, "config", "fit_commit.yml")
34
44
  end
35
45
 
36
- def local_filepath
37
- ".fit_commit.yml"
38
- end
39
-
40
- def git_top_level
46
+ def self.git_top_level
41
47
  top_level = `git rev-parse --show-toplevel`.chomp.strip
42
48
  fail "Git repo not found! Please submit a bug report." if top_level == ""
43
49
  top_level
44
50
  end
45
51
 
52
+ private
53
+
54
+ # sorted by increasing precedence
55
+ attr_accessor :filepaths
56
+
46
57
  def read_config(path)
47
58
  load_yaml(path).each_with_object({}) do |(key, value), config|
48
59
  translated_key = translate_config_key(key)
@@ -2,6 +2,9 @@ require "fit_commit/line"
2
2
 
3
3
  module FitCommit
4
4
  class MessageParser
5
+ GIT_VERBOSE_MARKER = "# ------------------------ >8 ------------------------"
6
+ COMMENT_REGEX = /\A#/
7
+
5
8
  attr_accessor :message_path
6
9
  def initialize(message_path)
7
10
  self.message_path = message_path
@@ -13,9 +16,6 @@ module FitCommit
13
16
 
14
17
  private
15
18
 
16
- GIT_VERBOSE_MARKER = "# ------------------------ >8 ------------------------"
17
- COMMENT_REGEX = /\A#/
18
-
19
19
  def relevant_lines
20
20
  message_text.lines.each_with_object([]) do |line, relevant_lines|
21
21
  line.chomp!
@@ -8,6 +8,7 @@ module FitCommit
8
8
 
9
9
  EXIT_CODE_ALLOW_COMMIT = 0
10
10
  EXIT_CODE_REJECT_COMMIT = 1
11
+ DEFAULT_EDITOR = "vim"
11
12
 
12
13
  attr_accessor :message_path, :branch_name, :stderr, :stdin
13
14
  def initialize(message_path, branch_name, stderr = $stderr, stdin = $stdin)
@@ -105,8 +106,6 @@ module FitCommit
105
106
  system(editor, message_path)
106
107
  end
107
108
 
108
- DEFAULT_EDITOR = "vim"
109
-
110
109
  def editor
111
110
  editor = ENV["EDITOR"]
112
111
  editor = DEFAULT_EDITOR unless editor && editor != "none"
@@ -2,7 +2,6 @@ require "fit_commit/configuration_loader"
2
2
 
3
3
  module FitCommit
4
4
  class ValidatorLoader
5
- attr_accessor :branch_name, :configuration
6
5
  def initialize(branch_name, configuration = load_configuration)
7
6
  self.branch_name = branch_name
8
7
  self.configuration = configuration
@@ -14,8 +13,10 @@ module FitCommit
14
13
 
15
14
  private
16
15
 
16
+ attr_accessor :branch_name, :configuration
17
+
17
18
  def load_configuration
18
- FitCommit::ConfigurationLoader.new.global_configuration
19
+ FitCommit::ConfigurationLoader.default_configuration
19
20
  end
20
21
 
21
22
  def all_validators
@@ -3,13 +3,29 @@ require "fit_commit/validators/base"
3
3
  module FitCommit
4
4
  module Validators
5
5
  class CapitalizeSubject < Base
6
+ MESSAGE = "Begin all subject lines with a capital letter."
7
+ SINGLE_WORD = /\A\w+\z/
6
8
  AUTOSQUASH = /\A(fixup|squash)! /
7
9
 
8
- def validate_line(lineno, text)
9
- if lineno == 1 && text[0] =~ /[[:lower:]]/ && text !~ AUTOSQUASH
10
- add_error(lineno, "Begin all subject lines with a capital letter.")
10
+ def validate(lines)
11
+ if lines[0].text =~ /\A[[:lower:]]/ && lines[0].text !~ AUTOSQUASH
12
+ if ignore_on_wiplikes? && wiplike?(lines)
13
+ add_warning(1, MESSAGE)
14
+ else
15
+ add_error(1, MESSAGE)
16
+ end
11
17
  end
12
18
  end
19
+
20
+ private
21
+
22
+ def wiplike?(lines)
23
+ lines[0].text =~ SINGLE_WORD && lines[1..-1].all?(&:empty?)
24
+ end
25
+
26
+ def ignore_on_wiplikes?
27
+ config.fetch("WarnOnWiplikes")
28
+ end
13
29
  end
14
30
  end
15
31
  end
@@ -3,28 +3,32 @@ require "fit_commit/validators/base"
3
3
  module FitCommit
4
4
  module Validators
5
5
  class LineLength < Base
6
+ MERGE_COMMIT = /\AMerge branch '[^']+' into ./
7
+ URL = %r{[a-z]+://}
8
+
6
9
  def validate_line(lineno, text)
7
- if lineno == 1 && text.empty?
8
- add_error(lineno, "Subject line cannot be blank.")
9
- elsif lineno == 2 && !text.empty?
10
- add_error(lineno, "Second line must be blank.")
11
- elsif line_too_long?(text)
10
+ if lineno == 1
11
+ if text.empty?
12
+ add_error(lineno, "Subject line cannot be blank.")
13
+ elsif text !~ MERGE_COMMIT
14
+ if text.length > max_line_length
15
+ add_error(lineno, format("Lines should be <= %i chars. (%i)",
16
+ max_line_length, text.length))
17
+ elsif text.length > subject_warn_length
18
+ add_warning(lineno, format("Subject line should be <= %i chars. (%i)",
19
+ subject_warn_length, text.length))
20
+ end
21
+ end
22
+ elsif lineno == 2
23
+ unless text.empty?
24
+ add_error(lineno, "Second line must be blank.")
25
+ end
26
+ elsif text.length > max_line_length && !(allow_long_urls? && text =~ URL)
12
27
  add_error(lineno, format("Lines should be <= %i chars. (%i)",
13
28
  max_line_length, text.length))
14
- elsif lineno == 1 && text.length > subject_warn_length
15
- add_warning(lineno, format("Subject line should be <= %i chars. (%i)",
16
- subject_warn_length, text.length))
17
29
  end
18
30
  end
19
31
 
20
- def line_too_long?(text)
21
- text.length > max_line_length && !(allow_long_urls? && contains_url?(text))
22
- end
23
-
24
- def contains_url?(text)
25
- text =~ %r{[a-z]+://}
26
- end
27
-
28
32
  def max_line_length
29
33
  config.fetch("MaxLineLength")
30
34
  end
@@ -45,6 +45,7 @@ module FitCommit
45
45
  removes removing removed
46
46
  renames renaming renamed
47
47
  reorders reordering reordered
48
+ replaces replacing replaced
48
49
  requires requiring required
49
50
  restores restoring restored
50
51
  sends sending sent
@@ -1,3 +1,3 @@
1
1
  module FitCommit
2
- VERSION = "3.7.0"
2
+ VERSION = "3.8.3"
3
3
  end
@@ -10,6 +10,7 @@ Validators/SubjectPeriod:
10
10
  Enabled: true
11
11
  Validators/CapitalizeSubject:
12
12
  Enabled: true
13
+ WarnOnWiplikes: true
13
14
  Validators/Frathouse:
14
15
  Enabled: true
15
16
  Validators/Wip:
@@ -33,7 +33,7 @@ describe "Install and run in a fresh Git repo" do
33
33
  assert_match(/^#{commit_message}/, results)
34
34
  assert_match(/^1: Error: /, results)
35
35
  refute_match(/Warning:/, results)
36
- refute_match(/^\[master .+\]/, results)
36
+ refute_match(/^\[main .+\]/, results)
37
37
  end
38
38
  end
39
39
 
@@ -44,7 +44,7 @@ describe "Install and run in a fresh Git repo" do
44
44
  refute_match(/^#{commit_message}/, results)
45
45
  refute_match(/Error:/, results)
46
46
  refute_match(/Warning:/, results)
47
- assert_match(/^\[master .+\] #{commit_message}/, results)
47
+ assert_match(/^\[main .+\] #{commit_message}/, results)
48
48
  end
49
49
  end
50
50
 
@@ -55,7 +55,7 @@ describe "Install and run in a fresh Git repo" do
55
55
  refute_match(/^#{commit_message}/, results)
56
56
  refute_match(/Error/, results)
57
57
  assert_match(/^1: Warning: /, results)
58
- assert_match(/^\[master .+\] #{commit_message}/, results)
58
+ assert_match(/^\[main .+\] #{commit_message}/, results)
59
59
  end
60
60
  end
61
61
  end
data/test/test_helper.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require "minitest/autorun"
2
2
 
3
- def create_tempfile(filename, content)
3
+ def create_tempfile(content, filename="")
4
4
  Tempfile.new(filename).tap do |f|
5
5
  f.write(content)
6
6
  f.close
@@ -2,81 +2,109 @@ require "test_helper"
2
2
  require "fit_commit/configuration_loader"
3
3
 
4
4
  describe FitCommit::ConfigurationLoader do
5
- subject { FitCommit::ConfigurationLoader.new }
6
-
7
- after do
8
- [system_file, user_file].compact.each(&:unlink)
9
- end
10
-
11
- let(:global_configuration) do
12
- subject.stub :default_filepath, "/dev/null" do
13
- subject.stub :system_filepath, (system_file ? system_file.path : "/dev/null") do
14
- subject.stub :user_filepath, (user_file ? user_file.path : "/dev/null") do
15
- subject.stub :config_filepath, "/dev/null" do
16
- subject.stub :local_filepath, "/dev/null" do
17
- subject.stub :git_top_level, "." do
18
- subject.global_configuration
19
- end
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
26
-
27
5
  describe "no configuration files present" do
28
- let(:system_file) { nil }
29
- let(:user_file) { nil }
30
6
  it "is empty" do
31
- assert_equal({}, global_configuration)
7
+ config = FitCommit::ConfigurationLoader.new(["/dev/null"]).configuration
8
+ assert_equal({}, config)
32
9
  end
33
10
  end
34
11
 
35
12
  describe "just one configuration file present" do
36
- let(:system_file) { nil }
37
- let(:user_file) { create_tempfile("user_file", user_file_content) }
38
- let(:user_file_content) do
39
- "Foo/Bar:\n Baz: false\nQux/Norf/Blah:\n - !ruby/regexp /\\Afoo/"
40
- end
41
-
42
13
  it "is a configuration equal to that file" do
43
- expected = {
14
+ config_content = <<~EOF
15
+ Foo/Bar:
16
+ Baz: false
17
+ Qux/Norf/Blah:
18
+ - !ruby/regexp /\\Afoo/
19
+ EOF
20
+ config_file_path = create_tempfile(config_content).path
21
+
22
+ expected_config = {
44
23
  "FitCommit::Foo::Bar" => { "Baz" => false },
45
24
  "FitCommit::Qux::Norf::Blah" => [/\Afoo/]
46
25
  }
47
- assert_equal expected, global_configuration
26
+
27
+ config = FitCommit::ConfigurationLoader.new([config_file_path]).configuration
28
+ assert_equal expected_config, config
48
29
  end
49
30
 
50
- describe "has a non-validation key" do
51
- let(:user_file_content) do
52
- "FitCommit:\n Require:\n - foo/bar"
53
- end
31
+ describe "has a key without a slash" do
54
32
  it "doesn't try to namespace the key" do
55
- expected = {
33
+ config_content = <<~EOF
34
+ FitCommit:
35
+ Require:
36
+ - foo/bar
37
+ EOF
38
+ config_file_path = create_tempfile(config_content).path
39
+
40
+ expected_config = {
56
41
  "FitCommit" => { "Require" => ["foo/bar"] }
57
42
  }
58
- assert_equal expected, global_configuration
43
+
44
+ config = FitCommit::ConfigurationLoader.new([config_file_path]).configuration
45
+ assert_equal expected_config, config
59
46
  end
60
47
  end
61
48
  end
62
49
 
63
50
  describe "multiple configuration files present" do
64
- let(:system_file) { create_tempfile("system_file", system_file_content) }
65
- let(:user_file) { create_tempfile("user_file", user_file_content) }
66
- let(:system_file_content) do
67
- "Foo/Bar:\n Baz: false\nQux/Norf/Blah:\n Foobar:\n - !ruby/regexp /\\Afoo/\n Booyah: false"
68
- end
69
- let(:user_file_content) do
70
- "Qux/Norf/Blah:\n Foobar: true\nAbc/Buz:\n - hi"
71
- end
72
-
73
51
  it "is a merged configuration that takes precedence into account" do
74
- expected = {
52
+ config1_content = <<~EOF
53
+ Foo/Bar:
54
+ Baz: false
55
+ Qux/Norf/Blah:
56
+ Foobar:
57
+ - !ruby/regexp /\\Afoo/
58
+ Booyah: false
59
+ EOF
60
+
61
+ config2_content = <<~EOF
62
+ Qux/Norf/Blah:
63
+ Foobar: true
64
+ Abc/Buz:
65
+ - hi
66
+ EOF
67
+
68
+ config_file_paths = [
69
+ create_tempfile(config1_content).path,
70
+ create_tempfile(config2_content).path
71
+ ]
72
+
73
+ expected_config = {
75
74
  "FitCommit::Foo::Bar" => { "Baz" => false },
76
75
  "FitCommit::Qux::Norf::Blah" => { "Foobar" => true, "Booyah" => false },
77
76
  "FitCommit::Abc::Buz" => ["hi"]
78
77
  }
79
- assert_equal expected, global_configuration
78
+
79
+ config = FitCommit::ConfigurationLoader.new(config_file_paths).configuration
80
+ assert_equal expected_config, config
81
+ end
82
+ end
83
+
84
+ describe "default_configuration" do
85
+ it "loads configuration from default filepaths" do
86
+ config_content = <<~EOF
87
+ FitCommit:
88
+ Require:
89
+ - foo/bar
90
+ EOF
91
+ config_file_path = create_tempfile(config_content).path
92
+
93
+ expected_config = {
94
+ "FitCommit" => { "Require" => ["foo/bar"] }
95
+ }
96
+
97
+ config = FitCommit::ConfigurationLoader.stub(:default_filepaths, [config_file_path]) do
98
+ FitCommit::ConfigurationLoader.default_configuration
99
+ end
100
+ assert_equal expected_config, config
101
+ end
102
+ end
103
+
104
+ describe "gem_default_filepath" do
105
+ it "returns a valid filepath" do
106
+ gem_default_filepath = FitCommit::ConfigurationLoader.gem_default_filepath
107
+ assert File.exist?(gem_default_filepath)
80
108
  end
81
109
  end
82
110
  end
@@ -2,12 +2,8 @@ require "test_helper"
2
2
  require "fit_commit/message_parser"
3
3
 
4
4
  describe FitCommit::MessageParser do
5
- after do
6
- commit_msg_file.unlink
7
- end
8
-
9
- let(:commit_msg_file) { create_tempfile("test-commit-msg", commit_msg) }
10
- let(:lines) { FitCommit::MessageParser.new(commit_msg_file.path).lines }
5
+ let(:commit_msg_file_path) { create_tempfile(commit_msg).path }
6
+ let(:lines) { FitCommit::MessageParser.new(commit_msg_file_path).lines }
11
7
 
12
8
  describe "empty commit msg" do
13
9
  let(:commit_msg) { "" }
@@ -2,15 +2,12 @@ require "test_helper"
2
2
  require "fit_commit/runner"
3
3
 
4
4
  describe FitCommit::Runner do
5
- after do
6
- commit_msg_file.unlink
7
- end
8
- let(:commit_msg_file) { create_tempfile("test-commit-msg", commit_msg) }
5
+ let(:commit_msg_file_path) { create_tempfile(commit_msg).path }
9
6
  let(:stderr) { StringIO.new }
10
7
  let(:stdin) { StringIO.new }
11
8
  let(:branch_name) { "any" }
12
9
  let(:runner) do
13
- FitCommit::Runner.new(commit_msg_file.path, branch_name, stderr, stdin)
10
+ FitCommit::Runner.new(commit_msg_file_path, branch_name, stderr, stdin)
14
11
  end
15
12
 
16
13
  def call_runner
@@ -3,81 +3,71 @@ require "fit_commit/validator_loader"
3
3
  Dir[File.dirname(__FILE__) + "/validators/*.rb"].each { |file| require file }
4
4
 
5
5
  describe FitCommit::ValidatorLoader do
6
- let(:validators) { loader.validators }
7
- let(:loader) { FitCommit::ValidatorLoader.new(branch_name, configuration) }
8
- let(:branch_name) { "foo" }
9
- let(:configuration) do
6
+ def simple_validators(branch_name: "mybranch")
10
7
  # Starting with all disabled because every validator needs at least a
11
8
  # default entry.
12
9
  # The ones specified here are the ones we care about testing.
13
- all_disabled_configuration.merge(
10
+ configuration = all_disabled_configuration.merge(
14
11
  FitCommit::Validators::LineLength.name => { "Enabled" => false },
15
12
  FitCommit::Validators::Wip.name => { "Enabled" => true },
16
13
  FitCommit::Validators::Frathouse.name => { "Enabled" => ["bar", /\Abaz+/] }
17
14
  )
15
+ FitCommit::ValidatorLoader.new(branch_name, configuration).validators
18
16
  end
19
- let(:all_disabled_configuration) do
17
+
18
+ def all_disabled_configuration
20
19
  FitCommit::Validators::Base.all.each_with_object({}) do |v, config|
21
20
  config[v.name] = { "Enabled" => false }
22
21
  end
23
22
  end
24
23
 
25
24
  it "loads enabled validators" do
26
- assert validators.one? { |v| v.is_a? FitCommit::Validators::Wip }
25
+ assert simple_validators.grep(FitCommit::Validators::Wip).one?
27
26
  end
28
27
 
29
28
  it "doesn't load disabled validators" do
30
- assert validators.none? { |v| v.is_a? FitCommit::Validators::LineLength }
29
+ assert simple_validators.grep(FitCommit::Validators::LineLength).none?
31
30
  end
32
31
 
33
32
  describe "non-boolean options for Enabled" do
34
33
  describe "branch_name does not match validator" do
35
34
  it "doesn't load validator" do
36
- assert validators.none? { |v| v.is_a? FitCommit::Validators::Frathouse }
35
+ assert simple_validators.grep(FitCommit::Validators::Frathouse).none?
37
36
  end
38
37
  end
39
38
 
40
39
  describe "branch_name matches validator via String" do
41
- let(:branch_name) { "bar" }
42
40
  it "loads validator" do
43
- assert validators.one? { |v| v.is_a? FitCommit::Validators::Frathouse }
41
+ assert simple_validators(branch_name: "bar").
42
+ grep(FitCommit::Validators::Frathouse).one?
44
43
  end
45
44
  end
46
45
 
47
46
  describe "branch_name matches validator via regex" do
48
- let(:branch_name) { "bazzz" }
49
47
  it "loads validator" do
50
- assert validators.one? { |v| v.is_a? FitCommit::Validators::Frathouse }
48
+ assert simple_validators(branch_name: "bazzz").
49
+ grep(FitCommit::Validators::Frathouse).one?
51
50
  end
52
51
  end
53
52
  end
54
53
 
55
54
  describe "branch_name is blank" do
56
- let(:branch_name) { "" }
57
55
  it "loads enabled validators" do
58
- assert validators.one? { |v| v.is_a? FitCommit::Validators::Wip }
56
+ assert simple_validators(branch_name: "").grep(FitCommit::Validators::Wip).one?
59
57
  end
60
58
  it "doesn't load disabled validators" do
61
- assert validators.none? { |v| v.is_a? FitCommit::Validators::LineLength }
59
+ assert simple_validators(branch_name: "").grep(FitCommit::Validators::LineLength).none?
62
60
  end
63
61
  it "doesn't load validators that have non-boolean options for Enabled" do
64
- assert validators.none? { |v| v.is_a? FitCommit::Validators::Frathouse }
62
+ assert simple_validators(branch_name: "").grep(FitCommit::Validators::Frathouse).none?
65
63
  end
66
64
  end
67
65
 
68
66
  describe "custom validators required" do
69
- after do
70
- custom_validator_file.unlink
71
- end
72
-
73
- let(:custom_validator_file) do
74
- create_tempfile(["my_custom_validator", ".rb"], custom_validator_code)
75
- end
76
-
77
- # Not actually subclassing FitCommit::Validators::Base because
78
- # that affects the loaded validators for other tests.
79
- let(:custom_validator_code) do
80
- <<-EOF
67
+ it "loads enabled custom validator" do
68
+ # Not actually subclassing FitCommit::Validators::Base because
69
+ # that affects the loaded validators for other tests.
70
+ custom_validator_code = <<~EOF
81
71
  class MyCustomValidator
82
72
  attr_accessor :config
83
73
  def initialize(_branch_name, config)
@@ -88,23 +78,24 @@ describe FitCommit::ValidatorLoader do
88
78
  end
89
79
  end
90
80
  EOF
91
- end
92
81
 
93
- let(:configuration) do
94
- all_disabled_configuration.merge(
82
+ # rb extension is necessary to `require` it
83
+ custom_validator_file = create_tempfile(
84
+ custom_validator_code, ["custom_validator", ".rb"])
85
+
86
+ configuration = all_disabled_configuration.merge(
95
87
  "FitCommit" => { "Require" => [custom_validator_file.path] },
96
88
  "MyCustomValidator" => { "Enabled" => true }
97
89
  )
98
- end
99
90
 
100
- it "loads enabled custom validator" do
101
91
  # stub which will be overridden when the custom validator file is loaded
102
92
  MyCustomValidator = Class.new
103
93
 
104
- FitCommit::Validators::Base.stub(:all, [MyCustomValidator]) do
105
- assert_equal 1, validators.size
106
- assert validators.first.is_a?(MyCustomValidator)
94
+ validators = FitCommit::Validators::Base.stub(:all, [MyCustomValidator]) do
95
+ FitCommit::ValidatorLoader.new("mybranch", configuration).validators
107
96
  end
97
+ assert_equal 1, validators.size
98
+ assert validators.first.is_a?(MyCustomValidator)
108
99
  end
109
100
  end
110
101
  end
@@ -9,7 +9,7 @@ describe FitCommit::Validators::CapitalizeSubject do
9
9
  let(:config) { default_config }
10
10
  let(:branch_name) { "any" }
11
11
 
12
- describe "subject is not capitalized" do
12
+ describe "subject is uncapitalized" do
13
13
  let(:commit_msg) { "foo bar" }
14
14
  it "has error" do
15
15
  validator.validate(commit_lines)
@@ -17,6 +17,34 @@ describe FitCommit::Validators::CapitalizeSubject do
17
17
  assert_empty validator.warnings
18
18
  end
19
19
  end
20
+ describe "subject is WIPlike (single uncapitalized word with no body)" do
21
+ let(:commit_msg) { "foo" }
22
+
23
+ describe "WarnOnWiplikes is true" do
24
+ it "has a warning" do
25
+ validator.validate(commit_lines)
26
+ assert_empty validator.errors
27
+ assert_equal 1, validator.warnings[1].size
28
+ end
29
+ end
30
+
31
+ describe "WarnOnWiplikes is false" do
32
+ let(:config) { default_config.merge("WarnOnWiplikes" => false) }
33
+ it "has an error" do
34
+ validator.validate(commit_lines)
35
+ assert_equal 1, validator.errors[1].size
36
+ assert_empty validator.warnings
37
+ end
38
+ end
39
+ end
40
+ describe "subject is a single uncapitalized word with a body" do
41
+ let(:commit_msg) { "foo\n\nbaz" }
42
+ it "has error" do
43
+ validator.validate(commit_lines)
44
+ assert_equal 1, validator.errors[1].size
45
+ assert_empty validator.warnings
46
+ end
47
+ end
20
48
  describe "subject is fixup commit" do
21
49
  let(:commit_msg) { "fixup! foo bar" }
22
50
  it "does not have errors/warnings" do
@@ -42,6 +42,22 @@ describe FitCommit::Validators::LineLength do
42
42
  assert_empty validator.warnings
43
43
  end
44
44
  end
45
+ describe "first line is over error limit and has an URL" do
46
+ let(:commit_msg) { "foo https://" + ("x" * 70) }
47
+ it "has an error and no warning" do
48
+ validator.validate(commit_lines)
49
+ assert_equal 1, validator.errors[1].size
50
+ assert_empty validator.warnings
51
+ end
52
+ end
53
+ describe "merge commit is over error limit" do
54
+ let(:commit_msg) { "Merge branch '#{"x" * 30}' into #{"y" * 30}" }
55
+ it "does not have error" do
56
+ validator.validate(commit_lines)
57
+ assert_empty validator.errors
58
+ assert_empty validator.warnings
59
+ end
60
+ end
45
61
  describe "SubjectWarnLength modified in config" do
46
62
  let(:config) { default_config.merge("SubjectWarnLength" => 5) }
47
63
  describe "first line is over modified warning limit" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fit-commit
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.0
4
+ version: 3.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Foley
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-08 00:00:00.000000000 Z
11
+ date: 2021-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: swearjar
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '1.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '1.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '5.8'
33
+ version: '5.14'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '5.8'
40
+ version: '5.14'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '10.4'
47
+ version: '13.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '10.4'
54
+ version: '13.0'
55
55
  description: A Git hook to validate your commit messages based on community standards.
56
56
  email:
57
57
  - foley3@gmail.com
@@ -69,6 +69,7 @@ files:
69
69
  - LICENSE
70
70
  - README.md
71
71
  - Rakefile
72
+ - TODO.md
72
73
  - bin/fit-commit
73
74
  - fit-commit.gemspec
74
75
  - lib/fit_commit.rb
@@ -108,8 +109,7 @@ licenses:
108
109
  - MIT
109
110
  metadata: {}
110
111
  post_install_message: |2
111
- Thank you for installing Fit Commit!
112
- Install the hook in each git repo you want to scan using:
112
+ Install Fit Commit hooks in each git repo you want to scan using:
113
113
 
114
114
  > fit-commit install
115
115
 
@@ -130,9 +130,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  requirements: []
133
- rubyforge_project:
134
- rubygems_version: 2.2.3
135
- signing_key:
133
+ rubygems_version: 3.1.4
134
+ signing_key:
136
135
  specification_version: 4
137
136
  summary: A Git hook to validate your commit messages
138
137
  test_files: