fit-commit 2.1.2 → 2.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42a06e4e199108807d10a9df3d255f6c6feb8ea1
4
- data.tar.gz: f38ceba417a635db118576be6387778555d63851
3
+ metadata.gz: 6d0e5940862e5d3bb79d5e2fd77eab59035ecb41
4
+ data.tar.gz: 2fa241ffb6eae0aa6cfbfda5d12f8cba52bf4823
5
5
  SHA512:
6
- metadata.gz: fe2ab85e513e5c156ab4f05ad2d773d9893c09fec5efd36c2d1121284f7e9367d41a724cd0982589b11ec5985a04fc9d2e2be8f84e6d05df0db265bf0f7c6aa2
7
- data.tar.gz: 12fddefb3e3665f20ea822f93f0a94a1f322d95d00a63c69cd5b6190c1130ea5d748c3ba51db256674c4a8e185faa34701fe20f54af7973e76f3a312c2e7baf3
6
+ metadata.gz: 3024e9600be177394c86f8037f08d2ee8b0253008b22352da8b36378b9557511db17e9dd88c5f6efa03f37d68acc6a7b39b26bf1584fe63bfde58902bf8a590f
7
+ data.tar.gz: e6ce9e0c4df171f734ad6dd613662e8d35fe31d7de4dc361a2f9546666b90cabce6709497d0b844aa670546cffdbca0347efc5feffcf3ac9484f3c6303a2701a
data/.rubocop.yml CHANGED
@@ -40,3 +40,6 @@ Style/GuardClause:
40
40
 
41
41
  Style/FileName:
42
42
  Enabled: false
43
+
44
+ Style/DotPosition:
45
+ EnforcedStyle: trailing
data/CHANGELOG.md CHANGED
@@ -3,6 +3,9 @@
3
3
  ### master
4
4
  - N/A
5
5
 
6
+ ### v2.2.0 (2015-09-09)
7
+ - Configuration files to customize behavior.
8
+
6
9
  ### v2.1.1 (2015-08-31)
7
10
  - Compatibility for all POSIX shells.
8
11
 
data/README.md CHANGED
@@ -38,9 +38,46 @@ This creates a `.git/hooks/commit-msg` script which will automatically check you
38
38
  * **Line Length**: All lines must be <= 72 chars (URLs excluded). First line should be <= 50 chars. Second line must be blank.
39
39
  * **Tense**: Message must use imperative present tense: "Fix bug" and not "Fixed bug" or "Fixes bug."
40
40
  * **Summary Period**: Do not end your summary with a period.
41
- * **WIP**: Do not commit WIPs to master.
42
- * **Frat House**: No frat house commit messages in master.
41
+ * **WIP**: Do not commit WIPs to shared branches.
42
+ * **Frat House**: No frat house commit messages in shared branches.
43
+
44
+ ## Configuration
45
+
46
+ Settings are read from these files, in increasing precedence: `/etc/fit_commit.yml`, `$HOME/.fit_commit.yml`, `config/fit_commit.yml`, `./.fit_commit.yml`.
47
+
48
+ The default settings are:
49
+
50
+ ```yaml
51
+ ---
52
+ Validators/LineLength:
53
+ Enabled: true
54
+ MaxLineLength: 72
55
+ SummaryWarnLength: 50
56
+ AllowLongUrls: true
57
+ Validators/Tense:
58
+ Enabled: true
59
+ Validators/SummaryPeriod:
60
+ Enabled: true
61
+ Validators/Wip:
62
+ Enabled:
63
+ - master
64
+ Validators/Frathouse:
65
+ Enabled:
66
+ - master
67
+ ```
43
68
 
69
+ The `Enabled` property accepts multiple formats:
70
+
71
+ ```yaml
72
+ # true/false are branch agnostic
73
+ Validators/Foo:
74
+ Enabled: false
75
+ # Array of String/Regex matching each branch for which it's enabled
76
+ Validators/Bar:
77
+ Enabled:
78
+ - master
79
+ - !ruby/regexp /\Afoo.+bar/
80
+ ```
44
81
 
45
82
  ## FAQ
46
83
 
data/Rakefile CHANGED
@@ -7,4 +7,8 @@ Rake::TestTask.new do |test|
7
7
  test.verbose = false
8
8
  end
9
9
 
10
+ task :console do
11
+ exec "irb -r fit-commit -I ./lib"
12
+ end
13
+
10
14
  task default: :test
@@ -0,0 +1,62 @@
1
+ require "yaml"
2
+
3
+ module FitCommit
4
+ class ConfigurationLoader
5
+ def global_configuration
6
+ all_filepaths.each_with_object({}) do |filepath, config|
7
+ config.merge!(read_config(filepath))
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def all_filepaths
14
+ # sorted by increasing precedence
15
+ [default_filepath, system_filepath, user_filepath, config_filepath, local_filepath]
16
+ end
17
+
18
+ def default_filepath
19
+ File.expand_path("../../../templates/config/fit_commit.default.yml", __FILE__)
20
+ end
21
+
22
+ def system_filepath
23
+ "/etc/fit_commit.yml"
24
+ end
25
+
26
+ def user_filepath
27
+ File.join(ENV["HOME"], ".fit_commit.yml")
28
+ end
29
+
30
+ def config_filepath
31
+ File.join(git_top_level, "config", "fit_commit.yml")
32
+ end
33
+
34
+ def local_filepath
35
+ ".fit_commit.yml"
36
+ end
37
+
38
+ def git_top_level
39
+ top_level = `git rev-parse --show-toplevel`.chomp.strip
40
+ fail "Git repo not found! Please submit a bug report." if top_level == ""
41
+ top_level
42
+ end
43
+
44
+ def read_config(path)
45
+ load_yaml(path).each_with_object({}) do |(key, value), config|
46
+ translated_key = translate_class_name(key)
47
+ config[translated_key] = value
48
+ end
49
+ end
50
+
51
+ def load_yaml(path)
52
+ content = YAML.load_file(path) if File.exist?(path)
53
+ content || {}
54
+ rescue => e
55
+ raise e, "Error parsing config file: #{e.message}"
56
+ end
57
+
58
+ def translate_class_name(config_class_name)
59
+ "FitCommit::" + config_class_name.gsub("/", "::")
60
+ end
61
+ end
62
+ end
@@ -1,5 +1,6 @@
1
1
  require "fit_commit/has_errors"
2
2
  require "fit_commit/message_parser"
3
+ require "fit_commit/validator_loader"
3
4
 
4
5
  module FitCommit
5
6
  class Runner
@@ -38,17 +39,15 @@ module FitCommit
38
39
  private
39
40
 
40
41
  def run_validators
41
- validator_classes.each do |validator_class|
42
- validator = validator_class.new(lines, branch_name)
43
- validator.validate
42
+ validators.each do |validator|
43
+ validator.validate(lines)
44
44
  merge_errors(validator.errors)
45
45
  merge_warnings(validator.warnings)
46
46
  end
47
47
  end
48
48
 
49
- def validator_classes
50
- Dir[File.dirname(__FILE__) + "/validators/*.rb"].each { |file| require file }
51
- FitCommit::Validators::Base.all
49
+ def validators
50
+ FitCommit::ValidatorLoader.new(branch_name).validators
52
51
  end
53
52
 
54
53
  def print_results
@@ -0,0 +1,32 @@
1
+ require "fit_commit/configuration_loader"
2
+
3
+ module FitCommit
4
+ class ValidatorLoader
5
+ attr_accessor :branch_name, :configuration
6
+ def initialize(branch_name, configuration = load_configuration)
7
+ self.branch_name = branch_name
8
+ self.configuration = configuration
9
+ end
10
+
11
+ def validators
12
+ all_validators.select(&:enabled?)
13
+ end
14
+
15
+ private
16
+
17
+ def load_configuration
18
+ FitCommit::ConfigurationLoader.new.global_configuration
19
+ end
20
+
21
+ def all_validators
22
+ Dir[File.dirname(__FILE__) + "/validators/*.rb"].each { |file| require file }
23
+ FitCommit::Validators::Base.all.map do |validator_class|
24
+ validator_class.new(branch_name, config_for(validator_class))
25
+ end
26
+ end
27
+
28
+ def config_for(validator_class)
29
+ configuration[validator_class.name] || {}
30
+ end
31
+ end
32
+ end
@@ -5,10 +5,10 @@ module FitCommit
5
5
  class Base
6
6
  include FitCommit::HasErrors
7
7
 
8
- attr_accessor :lines, :branch_name
9
- def initialize(lines, branch_name)
10
- self.lines = lines
8
+ attr_accessor :branch_name, :config
9
+ def initialize(branch_name, config)
11
10
  self.branch_name = branch_name
11
+ self.config = config
12
12
  end
13
13
 
14
14
  @all = []
@@ -19,15 +19,30 @@ module FitCommit
19
19
  end
20
20
  end
21
21
 
22
- def validate
23
- lines.each do |line|
24
- validate_line(line.lineno, line.text, branch_name)
25
- end
22
+ def validate(lines)
23
+ lines.each { |line| validate_line(line.lineno, line.text) }
26
24
  end
27
25
 
28
26
  def validate_line(*)
29
27
  fail NotImplementedError, "Implement in subclass"
30
28
  end
29
+
30
+ def enabled?
31
+ enabled_val = config.fetch("Enabled")
32
+ if enabled_val.is_a?(Array)
33
+ enabled_val.any? { |pattern| matches_branch?(pattern) }
34
+ else
35
+ enabled_val
36
+ end
37
+ end
38
+
39
+ def matches_branch?(pattern)
40
+ if pattern.is_a?(Regexp)
41
+ pattern =~ branch_name
42
+ else
43
+ pattern == branch_name
44
+ end
45
+ end
31
46
  end
32
47
  end
33
48
  end
@@ -4,9 +4,9 @@ require "swearjar"
4
4
  module FitCommit
5
5
  module Validators
6
6
  class Frathouse < Base
7
- def validate_line(lineno, text, branch_name)
8
- if branch_name == "master" && Swearjar.default.profane?(text)
9
- add_error(lineno, "No frat house commit messages in master.")
7
+ def validate_line(lineno, text)
8
+ if Swearjar.default.profane?(text)
9
+ add_error(lineno, "No frat house commit messages in shared branches.")
10
10
  end
11
11
  end
12
12
  end
@@ -3,30 +3,39 @@ require "fit_commit/validators/base"
3
3
  module FitCommit
4
4
  module Validators
5
5
  class LineLength < Base
6
- FIRST_LINE_MAX_LENGTH = 50
7
- LINE_MAX_LENGTH = 72
8
-
9
- def validate_line(lineno, text, _branch_name)
6
+ def validate_line(lineno, text)
10
7
  if lineno == 1 && text.empty?
11
8
  add_error(lineno, "First line cannot be blank.")
12
9
  elsif lineno == 2 && !text.empty?
13
10
  add_error(lineno, "Second line must be blank.")
14
11
  elsif line_too_long?(text)
15
12
  add_error(lineno, format("Lines should be <= %i chars. (%i)",
16
- LINE_MAX_LENGTH, text.length))
17
- elsif lineno == 1 && text.length > FIRST_LINE_MAX_LENGTH
13
+ max_line_length, text.length))
14
+ elsif lineno == 1 && text.length > summary_warn_length
18
15
  add_warning(lineno, format("First line should be <= %i chars. (%i)",
19
- FIRST_LINE_MAX_LENGTH, text.length))
16
+ summary_warn_length, text.length))
20
17
  end
21
18
  end
22
19
 
23
20
  def line_too_long?(text)
24
- text.length > 72 && !contains_url?(text)
21
+ text.length > max_line_length && !(allow_long_urls? && contains_url?(text))
25
22
  end
26
23
 
27
24
  def contains_url?(text)
28
25
  text =~ %r{[a-z]+://}
29
26
  end
27
+
28
+ def max_line_length
29
+ config.fetch("MaxLineLength")
30
+ end
31
+
32
+ def summary_warn_length
33
+ config.fetch("SummaryWarnLength")
34
+ end
35
+
36
+ def allow_long_urls?
37
+ config.fetch("AllowLongUrls")
38
+ end
30
39
  end
31
40
  end
32
41
  end
@@ -3,7 +3,7 @@ require "fit_commit/validators/base"
3
3
  module FitCommit
4
4
  module Validators
5
5
  class SummaryPeriod < Base
6
- def validate_line(lineno, text, _branch_name)
6
+ def validate_line(lineno, text)
7
7
  if lineno == 1 && text.end_with?(".")
8
8
  add_error(lineno, "Do not end your summary with a period.")
9
9
  end
@@ -63,7 +63,7 @@ module FitCommit
63
63
  uses using used
64
64
  )
65
65
 
66
- def validate_line(lineno, text, _branch_name)
66
+ def validate_line(lineno, text)
67
67
  if lineno == 1 && starts_with_blacklisted_verb?(text)
68
68
  add_error(lineno, "Message must use imperative present tense.")
69
69
  end
@@ -3,10 +3,9 @@ require "fit_commit/validators/base"
3
3
  module FitCommit
4
4
  module Validators
5
5
  class Wip < Base
6
- def validate_line(lineno, text, branch_name)
7
- if lineno == 1 && branch_name == "master" &&
8
- text.split.any? { |word| word == "WIP" }
9
- add_error(lineno, "Do not commit WIPs to master.")
6
+ def validate_line(lineno, text)
7
+ if lineno == 1 && text.split.any? { |word| word == "WIP" }
8
+ add_error(lineno, "Do not commit WIPs to shared branches.")
10
9
  end
11
10
  end
12
11
  end
@@ -1,3 +1,3 @@
1
1
  module FitCommit
2
- VERSION = "2.1.2"
2
+ VERSION = "2.2.0"
3
3
  end
@@ -0,0 +1,16 @@
1
+ ---
2
+ Validators/LineLength:
3
+ Enabled: true
4
+ MaxLineLength: 72
5
+ SummaryWarnLength: 50
6
+ AllowLongUrls: true
7
+ Validators/Tense:
8
+ Enabled: true
9
+ Validators/SummaryPeriod:
10
+ Enabled: true
11
+ Validators/Wip:
12
+ Enabled:
13
+ - master
14
+ Validators/Frathouse:
15
+ Enabled:
16
+ - master
@@ -0,0 +1,77 @@
1
+ require "minitest/autorun"
2
+ require "fit_commit/configuration_loader"
3
+
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, "nofile" do
13
+ subject.stub :system_filepath, (system_file ? system_file.path : "nofile") do
14
+ subject.stub :user_filepath, (user_file ? user_file.path : "nofile") do
15
+ subject.stub :config_filepath, "nofile" do
16
+ subject.stub :local_filepath, "nofile" 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
+ def tempfile(filename, content)
28
+ Tempfile.new(filename).tap do |f|
29
+ f.write(content)
30
+ f.close
31
+ end
32
+ end
33
+
34
+ describe "no configuration files present" do
35
+ let(:system_file) { nil }
36
+ let(:user_file) { nil }
37
+ it "is empty" do
38
+ assert_equal({}, global_configuration)
39
+ end
40
+ end
41
+
42
+ describe "just one configuration file present" do
43
+ let(:system_file) { nil }
44
+ let(:user_file) { tempfile("user_file", user_file_content) }
45
+ let(:user_file_content) do
46
+ "Foo/Bar:\n Baz: false\nQux/Norf/Blah:\n - !ruby/regexp /\\Afoo/"
47
+ end
48
+
49
+ it "is a configuration equal to that file" do
50
+ expected = {
51
+ "FitCommit::Foo::Bar" => { "Baz" => false },
52
+ "FitCommit::Qux::Norf::Blah" => [/\Afoo/]
53
+ }
54
+ assert_equal expected, global_configuration
55
+ end
56
+ end
57
+
58
+ describe "multiple configuration files present" do
59
+ let(:system_file) { tempfile("system_file", system_file_content) }
60
+ let(:user_file) { tempfile("user_file", user_file_content) }
61
+ let(:system_file_content) do
62
+ "Foo/Bar:\n Baz: false\nQux/Norf/Blah:\n - !ruby/regexp /\\Afoo/"
63
+ end
64
+ let(:user_file_content) do
65
+ "Qux/Norf/Blah:\n Foobar: true\nBuz:\n - hi"
66
+ end
67
+
68
+ it "is a merged configuration that takes precedence into account" do
69
+ expected = {
70
+ "FitCommit::Foo::Bar" => { "Baz" => false },
71
+ "FitCommit::Qux::Norf::Blah" => { "Foobar" => true },
72
+ "FitCommit::Buz" => ["hi"]
73
+ }
74
+ assert_equal expected, global_configuration
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,48 @@
1
+ require "minitest/autorun"
2
+ require "fit_commit/validator_loader"
3
+ Dir[File.dirname(__FILE__) + "/validators/*.rb"].each { |file| require file }
4
+
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
10
+ {
11
+ "FitCommit::Validators::LineLength" => { "Enabled" => false },
12
+ "FitCommit::Validators::Tense" => { "Enabled" => false },
13
+ "FitCommit::Validators::SummaryPeriod" => { "Enabled" => true },
14
+ "FitCommit::Validators::Wip" => { "Enabled" => true },
15
+ "FitCommit::Validators::Frathouse" => { "Enabled" => ["bar", /\Abaz+/] }
16
+ }
17
+ end
18
+
19
+ it "loads enabled validators" do
20
+ assert validators.any? { |v| v.is_a? FitCommit::Validators::SummaryPeriod }
21
+ assert validators.any? { |v| v.is_a? FitCommit::Validators::Wip }
22
+ end
23
+
24
+ it "doesn't load disabled validators" do
25
+ assert validators.none? { |v| v.is_a? FitCommit::Validators::LineLength }
26
+ assert validators.none? { |v| v.is_a? FitCommit::Validators::Tense }
27
+ end
28
+
29
+ describe "non-boolean options for Enabled" do
30
+ it "doesn't load validators with a non-matching string/regex Enabled values" do
31
+ assert validators.none? { |v| v.is_a? FitCommit::Validators::Frathouse }
32
+ end
33
+
34
+ describe "validator has a matching string Enabled value" do
35
+ let(:branch_name) { "bar" }
36
+ it "loads validator" do
37
+ assert validators.any? { |v| v.is_a? FitCommit::Validators::Frathouse }
38
+ end
39
+ end
40
+
41
+ describe "validator has a matching regex Enabled value" do
42
+ let(:branch_name) { "bazzz" }
43
+ it "loads validator" do
44
+ assert validators.any? { |v| v.is_a? FitCommit::Validators::Frathouse }
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,47 +1,37 @@
1
- require "minitest/autorun"
1
+ require File.expand_path "../validator_helper.rb", __FILE__
2
2
  require "fit_commit/validators/frathouse"
3
+ require "fit_commit/line"
3
4
 
4
5
  describe FitCommit::Validators::Frathouse do
5
- let(:validator) { FitCommit::Validators::Frathouse.new(commit_lines, branch_name) }
6
+ let(:validator) { FitCommit::Validators::Frathouse.new(branch_name, config) }
6
7
  let(:commit_lines) { FitCommit::Line.from_text_array(commit_msg.split("\n")) }
8
+ let(:default_config) { default_config_for("Validators/Frathouse") }
9
+ let(:config) { default_config }
10
+ let(:branch_name) { "any" }
7
11
 
8
- describe "master branch" do
9
- let(:branch_name) { "master" }
10
- describe "contains swear word" do
11
- let(:commit_msg) { "fucking foobar" }
12
- it "has error" do
13
- validator.validate
14
- assert_equal 1, validator.errors[1].size
15
- assert_empty validator.warnings
16
- end
12
+ describe "contains swear word" do
13
+ let(:commit_msg) { "fucking foobar" }
14
+ it "has error" do
15
+ validator.validate(commit_lines)
16
+ assert_equal 1, validator.errors[1].size
17
+ assert_empty validator.warnings
17
18
  end
18
- describe "contains swear words on multiple lines" do
19
- let(:commit_msg) { "damn\n\nIE7 is fucking bullshit!" }
20
- it "has 1 error per line" do
21
- validator.validate
22
- assert_equal 1, validator.errors[1].size
23
- assert_equal 1, validator.errors[3].size
24
- assert_empty validator.warnings
25
- end
26
- end
27
- describe "does not contain swear words" do
28
- let(:commit_msg) { "foo" }
29
- it "does not have errors/warnings" do
30
- validator.validate
31
- assert_empty validator.errors
32
- assert_empty validator.warnings
33
- end
19
+ end
20
+ describe "contains swear words on multiple lines" do
21
+ let(:commit_msg) { "damn\n\nIE7 is fucking bullshit!" }
22
+ it "has 1 error per line" do
23
+ validator.validate(commit_lines)
24
+ assert_equal 1, validator.errors[1].size
25
+ assert_equal 1, validator.errors[3].size
26
+ assert_empty validator.warnings
34
27
  end
35
28
  end
36
- describe "not master branch" do
37
- let(:branch_name) { "notmaster" }
38
- describe "contains swear word" do
39
- let(:commit_msg) { "fucking foo" }
40
- it "does not have errors/warnings" do
41
- validator.validate
42
- assert_empty validator.errors
43
- assert_empty validator.warnings
44
- end
29
+ describe "does not contain swear words" do
30
+ let(:commit_msg) { "foo" }
31
+ it "does not have errors/warnings" do
32
+ validator.validate(commit_lines)
33
+ assert_empty validator.errors
34
+ assert_empty validator.warnings
45
35
  end
46
36
  end
47
37
  end
@@ -1,17 +1,19 @@
1
- require "minitest/autorun"
1
+ require File.expand_path "../validator_helper.rb", __FILE__
2
2
  require "fit_commit/validators/line_length"
3
+ require "fit_commit/line"
3
4
 
4
5
  describe FitCommit::Validators::LineLength do
5
- let(:validator) { FitCommit::Validators::LineLength.new(commit_lines, branch_name) }
6
+ let(:validator) { FitCommit::Validators::LineLength.new(branch_name, config) }
6
7
  let(:commit_lines) { FitCommit::Line.from_text_array(commit_msg.split("\n")) }
7
-
8
+ let(:default_config) { default_config_for("Validators/LineLength") }
9
+ let(:config) { default_config }
8
10
  let(:branch_name) { "any" }
9
11
 
10
12
  describe "first line" do
11
13
  describe "first line is empty" do
12
14
  let(:commit_msg) { "\n\nbar" }
13
15
  it "has error" do
14
- validator.validate
16
+ validator.validate(commit_lines)
15
17
  assert_equal 1, validator.errors[1].size
16
18
  assert_empty validator.warnings
17
19
  end
@@ -19,47 +21,52 @@ describe FitCommit::Validators::LineLength do
19
21
  describe "first line is not empty" do
20
22
  let(:commit_msg) { "foo\n\nbar" }
21
23
  it "does not have error" do
22
- validator.validate
24
+ validator.validate(commit_lines)
23
25
  assert_empty validator.errors
24
26
  assert_empty validator.warnings
25
27
  end
26
28
  end
27
29
  describe "first line is over warning limit" do
28
- let(:commit_msg) do
29
- "x" * (FitCommit::Validators::LineLength::FIRST_LINE_MAX_LENGTH + 1)
30
- end
30
+ let(:commit_msg) { "x" * 51 }
31
31
  it "has a warning" do
32
- validator.validate
32
+ validator.validate(commit_lines)
33
33
  assert_empty validator.errors
34
34
  assert_equal 1, validator.warnings[1].size
35
35
  end
36
36
  end
37
37
  describe "first line is over error limit" do
38
- let(:commit_msg) do
39
- "x" * (FitCommit::Validators::LineLength::LINE_MAX_LENGTH + 1)
40
- end
38
+ let(:commit_msg) { "x" * 73 }
41
39
  it "has an error and no warning" do
42
- validator.validate
40
+ validator.validate(commit_lines)
43
41
  assert_equal 1, validator.errors[1].size
44
42
  assert_empty validator.warnings
45
43
  end
46
44
  end
45
+ describe "SummaryWarnLength modified in config" do
46
+ let(:config) { default_config.merge("SummaryWarnLength" => 5) }
47
+ describe "first line is over modified warning limit" do
48
+ let(:commit_msg) { "x" * 6 }
49
+ it "has a warning" do
50
+ validator.validate(commit_lines)
51
+ assert_empty validator.errors
52
+ assert_equal 1, validator.warnings[1].size
53
+ end
54
+ end
55
+ end
47
56
  end
48
57
  describe "second line" do
49
58
  describe "second line is not empty" do
50
59
  let(:commit_msg) { "foo\nbar" }
51
60
  it "has error" do
52
- validator.validate
61
+ validator.validate(commit_lines)
53
62
  assert_equal 1, validator.errors[2].size
54
63
  assert_empty validator.warnings
55
64
  end
56
65
  end
57
66
  describe "second line is not empty and too long" do
58
- let(:commit_msg) do
59
- "foo\n" + ("x" * (FitCommit::Validators::LineLength::LINE_MAX_LENGTH + 1))
60
- end
67
+ let(:commit_msg) { "foo\n" + ("x" * 73) }
61
68
  it "only mentions blank error" do
62
- validator.validate
69
+ validator.validate(commit_lines)
63
70
  assert_equal 1, validator.errors[2].size
64
71
  assert_match(/must be blank/, validator.errors[2][0])
65
72
  assert_empty validator.warnings
@@ -68,7 +75,7 @@ describe FitCommit::Validators::LineLength do
68
75
  describe "second line is empty" do
69
76
  let(:commit_msg) { "foo\n\nbar" }
70
77
  it "does not have error" do
71
- validator.validate
78
+ validator.validate(commit_lines)
72
79
  assert_empty validator.errors
73
80
  assert_empty validator.warnings
74
81
  end
@@ -76,7 +83,7 @@ describe FitCommit::Validators::LineLength do
76
83
  describe "does not have a second line" do
77
84
  let(:commit_msg) { "foo" }
78
85
  it "does not have error" do
79
- validator.validate
86
+ validator.validate(commit_lines)
80
87
  assert_empty validator.errors
81
88
  assert_empty validator.warnings
82
89
  end
@@ -84,24 +91,47 @@ describe FitCommit::Validators::LineLength do
84
91
  end
85
92
  describe "body text" do
86
93
  describe "line is over length limit" do
87
- let(:commit_msg) do
88
- "foo\n\n" + ("x" * (FitCommit::Validators::LineLength::LINE_MAX_LENGTH + 1))
89
- end
94
+ let(:commit_msg) { "foo\n\n" + ("x" * 73) }
90
95
  it "has error" do
91
- validator.validate
96
+ validator.validate(commit_lines)
92
97
  assert_equal 1, validator.errors[3].size
93
98
  assert_empty validator.warnings
94
99
  end
95
100
  end
96
- describe "line is equal to length limit" do
97
- let(:commit_msg) do
98
- "foo\n\n" + ("x" * FitCommit::Validators::LineLength::LINE_MAX_LENGTH)
101
+ describe "line is over length limit and has an URL" do
102
+ let(:commit_msg) { "foo\n\nhttps://" + ("x" * 100) }
103
+ it "does not have error" do
104
+ validator.validate(commit_lines)
105
+ assert_empty validator.errors
106
+ assert_empty validator.warnings
107
+ end
108
+ describe "AllowLongUrls modified in config" do
109
+ let(:config) { default_config.merge("AllowLongUrls" => false) }
110
+ it "has error" do
111
+ validator.validate(commit_lines)
112
+ assert_equal 1, validator.errors[3].size
113
+ assert_empty validator.warnings
114
+ end
99
115
  end
116
+ end
117
+ describe "line is equal to length limit" do
118
+ let(:commit_msg) { "foo\n\n" + ("x" * 72) }
100
119
  it "does not have error" do
101
- validator.validate
120
+ validator.validate(commit_lines)
102
121
  assert_empty validator.errors
103
122
  assert_empty validator.warnings
104
123
  end
105
124
  end
125
+ describe "MaxLineLength modified in config" do
126
+ let(:config) { default_config.merge("MaxLineLength" => 5) }
127
+ describe "line is over modified limit" do
128
+ let(:commit_msg) { "foo\n\n" + ("x" * 6) }
129
+ it "has error" do
130
+ validator.validate(commit_lines)
131
+ assert_equal 1, validator.errors[3].size
132
+ assert_empty validator.warnings
133
+ end
134
+ end
135
+ end
106
136
  end
107
137
  end
@@ -1,15 +1,18 @@
1
- require "minitest/autorun"
1
+ require File.expand_path "../validator_helper.rb", __FILE__
2
2
  require "fit_commit/validators/summary_period"
3
+ require "fit_commit/line"
3
4
 
4
5
  describe FitCommit::Validators::SummaryPeriod do
5
- let(:validator) { FitCommit::Validators::SummaryPeriod.new(commit_lines, branch_name) }
6
+ let(:validator) { FitCommit::Validators::SummaryPeriod.new(branch_name, config) }
6
7
  let(:commit_lines) { FitCommit::Line.from_text_array(commit_msg.split("\n")) }
8
+ let(:default_config) { default_config_for("Validators/SummaryPeriod") }
9
+ let(:config) { default_config }
7
10
  let(:branch_name) { "any" }
8
11
 
9
12
  describe "summary ends with period" do
10
13
  let(:commit_msg) { "foo bar." }
11
14
  it "has error" do
12
- validator.validate
15
+ validator.validate(commit_lines)
13
16
  assert_equal 1, validator.errors[1].size
14
17
  assert_empty validator.warnings
15
18
  end
@@ -17,7 +20,7 @@ describe FitCommit::Validators::SummaryPeriod do
17
20
  describe "summary does not end with period" do
18
21
  let(:commit_msg) { "foo bar\n\nhi." }
19
22
  it "does not have errors/warnings" do
20
- validator.validate
23
+ validator.validate(commit_lines)
21
24
  assert_empty validator.errors
22
25
  assert_empty validator.warnings
23
26
  end
@@ -1,16 +1,18 @@
1
- require "minitest/autorun"
1
+ require File.expand_path "../validator_helper.rb", __FILE__
2
2
  require "fit_commit/validators/tense"
3
+ require "fit_commit/line"
3
4
 
4
5
  describe FitCommit::Validators::Tense do
5
- let(:validator) { FitCommit::Validators::Tense.new(commit_lines, branch_name) }
6
+ let(:validator) { FitCommit::Validators::Tense.new(branch_name, config) }
6
7
  let(:commit_lines) { FitCommit::Line.from_text_array(commit_msg.split("\n")) }
7
-
8
- let(:branch_name) { "anybranch" }
8
+ let(:default_config) { default_config_for("Validators/Tense") }
9
+ let(:config) { default_config }
10
+ let(:branch_name) { "any" }
9
11
 
10
12
  describe "uses incorrect tense on first line" do
11
13
  let(:commit_msg) { "Changed something" }
12
14
  it "has error" do
13
- validator.validate
15
+ validator.validate(commit_lines)
14
16
  assert_equal 1, validator.errors[1].size
15
17
  assert_empty validator.warnings
16
18
  end
@@ -19,7 +21,7 @@ describe FitCommit::Validators::Tense do
19
21
  describe "uses incorrect tense on first line" do
20
22
  let(:commit_msg) { "[#ticketno] Changed something" }
21
23
  it "has error" do
22
- validator.validate
24
+ validator.validate(commit_lines)
23
25
  assert_equal 1, validator.errors[1].size
24
26
  assert_empty validator.warnings
25
27
  end
@@ -28,7 +30,7 @@ describe FitCommit::Validators::Tense do
28
30
  describe "has incorrect tense after the first word" do
29
31
  let(:commit_msg) { "Document fixes to bug" }
30
32
  it "does not have errors/warnings" do
31
- validator.validate
33
+ validator.validate(commit_lines)
32
34
  assert_empty validator.errors
33
35
  assert_empty validator.warnings
34
36
  end
@@ -37,7 +39,7 @@ describe FitCommit::Validators::Tense do
37
39
  describe "uses incorrect tense on a line other than first line" do
38
40
  let(:commit_msg) { "Fix bug\n\nChanged something" }
39
41
  it "does not have errors/warnings" do
40
- validator.validate
42
+ validator.validate(commit_lines)
41
43
  assert_empty validator.errors
42
44
  assert_empty validator.warnings
43
45
  end
@@ -0,0 +1,8 @@
1
+ require "minitest/autorun"
2
+ require "yaml"
3
+
4
+ def default_config_for(key)
5
+ YAML.load_file(
6
+ File.expand_path("../../../templates/config/fit_commit.default.yml", __FILE__)).
7
+ fetch(key)
8
+ end
@@ -1,38 +1,28 @@
1
- require "minitest/autorun"
1
+ require File.expand_path "../validator_helper.rb", __FILE__
2
2
  require "fit_commit/validators/wip"
3
+ require "fit_commit/line"
3
4
 
4
5
  describe FitCommit::Validators::Wip do
5
- let(:validator) { FitCommit::Validators::Wip.new(commit_lines, branch_name) }
6
+ let(:validator) { FitCommit::Validators::Wip.new(branch_name, config) }
6
7
  let(:commit_lines) { FitCommit::Line.from_text_array(commit_msg.split("\n")) }
8
+ let(:default_config) { default_config_for("Validators/Wip") }
9
+ let(:config) { default_config }
10
+ let(:branch_name) { "any" }
7
11
 
8
- describe "master branch" do
9
- let(:branch_name) { "master" }
10
- describe "contains WIP" do
11
- let(:commit_msg) { "WIP foo" }
12
- it "has error" do
13
- validator.validate
14
- assert_equal 1, validator.errors[1].size
15
- assert_empty validator.warnings
16
- end
17
- end
18
- describe "does not contain WIP" do
19
- let(:commit_msg) { "foo" }
20
- it "does not have errors/warnings" do
21
- validator.validate
22
- assert_empty validator.errors
23
- assert_empty validator.warnings
24
- end
12
+ describe "contains WIP" do
13
+ let(:commit_msg) { "WIP foo" }
14
+ it "has error" do
15
+ validator.validate(commit_lines)
16
+ assert_equal 1, validator.errors[1].size
17
+ assert_empty validator.warnings
25
18
  end
26
19
  end
27
- describe "not master branch" do
28
- let(:branch_name) { "notmaster" }
29
- describe "contains WIP" do
30
- let(:commit_msg) { "WIP foo" }
31
- it "does not have errors/warnings" do
32
- validator.validate
33
- assert_empty validator.errors
34
- assert_empty validator.warnings
35
- end
20
+ describe "does not contain WIP" do
21
+ let(:commit_msg) { "foo" }
22
+ it "does not have errors/warnings" do
23
+ validator.validate(commit_lines)
24
+ assert_empty validator.errors
25
+ assert_empty validator.warnings
36
26
  end
37
27
  end
38
28
  end
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: 2.1.2
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Foley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-31 00:00:00.000000000 Z
11
+ date: 2015-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: swearjar
@@ -73,11 +73,13 @@ files:
73
73
  - fit-commit.gemspec
74
74
  - lib/fit_commit.rb
75
75
  - lib/fit_commit/cli.rb
76
+ - lib/fit_commit/configuration_loader.rb
76
77
  - lib/fit_commit/has_errors.rb
77
78
  - lib/fit_commit/installer.rb
78
79
  - lib/fit_commit/line.rb
79
80
  - lib/fit_commit/message_parser.rb
80
81
  - lib/fit_commit/runner.rb
82
+ - lib/fit_commit/validator_loader.rb
81
83
  - lib/fit_commit/validators/base.rb
82
84
  - lib/fit_commit/validators/frathouse.rb
83
85
  - lib/fit_commit/validators/line_length.rb
@@ -85,13 +87,17 @@ files:
85
87
  - lib/fit_commit/validators/tense.rb
86
88
  - lib/fit_commit/validators/wip.rb
87
89
  - lib/fit_commit/version.rb
90
+ - templates/config/fit_commit.default.yml
88
91
  - templates/hooks/commit-msg
92
+ - test/configuration_loader_test.rb
89
93
  - test/message_parser_test.rb
90
94
  - test/runner_test.rb
95
+ - test/validator_loader_test.rb
91
96
  - test/validators/frathouse_test.rb
92
97
  - test/validators/line_length_test.rb
93
98
  - test/validators/summary_period_test.rb
94
99
  - test/validators/tense_test.rb
100
+ - test/validators/validator_helper.rb
95
101
  - test/validators/wip_test.rb
96
102
  homepage: https://github.com/m1foley/fit-commit
97
103
  licenses:
@@ -126,11 +132,14 @@ signing_key:
126
132
  specification_version: 4
127
133
  summary: A Git hook to validate your commit messages
128
134
  test_files:
135
+ - test/configuration_loader_test.rb
129
136
  - test/message_parser_test.rb
130
137
  - test/runner_test.rb
138
+ - test/validator_loader_test.rb
131
139
  - test/validators/frathouse_test.rb
132
140
  - test/validators/line_length_test.rb
133
141
  - test/validators/summary_period_test.rb
134
142
  - test/validators/tense_test.rb
143
+ - test/validators/validator_helper.rb
135
144
  - test/validators/wip_test.rb
136
145
  has_rdoc: