git-lint 2.4.0 → 3.0.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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/LICENSE.adoc +207 -155
  4. data/README.adoc +201 -203
  5. data/{bin → exe}/git-lint +1 -3
  6. data/lib/git/lint/analyzer.rb +76 -0
  7. data/lib/git/lint/analyzers/abstract.rb +8 -18
  8. data/lib/git/lint/analyzers/commit_author_capitalization.rb +3 -9
  9. data/lib/git/lint/analyzers/commit_author_email.rb +3 -9
  10. data/lib/git/lint/analyzers/commit_author_name.rb +5 -14
  11. data/lib/git/lint/analyzers/commit_body_bullet.rb +2 -9
  12. data/lib/git/lint/analyzers/commit_body_bullet_capitalization.rb +2 -9
  13. data/lib/git/lint/analyzers/commit_body_bullet_delimiter.rb +2 -9
  14. data/lib/git/lint/analyzers/commit_body_leading_line.rb +1 -7
  15. data/lib/git/lint/analyzers/commit_body_line_length.rb +4 -11
  16. data/lib/git/lint/analyzers/commit_body_paragraph_capitalization.rb +1 -7
  17. data/lib/git/lint/analyzers/commit_body_phrase.rb +2 -38
  18. data/lib/git/lint/analyzers/commit_body_presence.rb +4 -11
  19. data/lib/git/lint/analyzers/commit_body_single_bullet.rb +2 -9
  20. data/lib/git/lint/analyzers/commit_body_tracker_shorthand.rb +27 -0
  21. data/lib/git/lint/analyzers/commit_subject_length.rb +4 -11
  22. data/lib/git/lint/analyzers/commit_subject_prefix.rb +2 -9
  23. data/lib/git/lint/analyzers/commit_subject_suffix.rb +2 -13
  24. data/lib/git/lint/analyzers/commit_trailer_collaborator_capitalization.rb +3 -12
  25. data/lib/git/lint/analyzers/commit_trailer_collaborator_duplication.rb +3 -11
  26. data/lib/git/lint/analyzers/commit_trailer_collaborator_email.rb +3 -12
  27. data/lib/git/lint/analyzers/commit_trailer_collaborator_key.rb +4 -13
  28. data/lib/git/lint/analyzers/commit_trailer_collaborator_name.rb +5 -15
  29. data/lib/git/lint/cli/actions/analyze/branch.rb +43 -0
  30. data/lib/git/lint/cli/actions/analyze/commit.rb +44 -0
  31. data/lib/git/lint/cli/actions/config.rb +37 -0
  32. data/lib/git/lint/cli/actions/hook.rb +34 -0
  33. data/lib/git/lint/cli/parser.rb +33 -0
  34. data/lib/git/lint/cli/parsers/analyze.rb +40 -0
  35. data/lib/git/lint/cli/parsers/core.rb +72 -0
  36. data/lib/git/lint/cli/shell.rb +56 -0
  37. data/lib/git/lint/collector.rb +3 -4
  38. data/lib/git/lint/commits/container.rb +19 -0
  39. data/lib/git/lint/commits/loader.rb +51 -0
  40. data/lib/git/lint/commits/systems/circle_ci.rb +26 -0
  41. data/lib/git/lint/{branches/environments → commits/systems}/git_hub_action.rb +10 -8
  42. data/lib/git/lint/commits/systems/local.rb +26 -0
  43. data/lib/git/lint/{branches/environments → commits/systems}/netlify_ci.rb +14 -10
  44. data/lib/git/lint/configuration/content.rb +26 -0
  45. data/lib/git/lint/configuration/defaults.yml +118 -0
  46. data/lib/git/lint/configuration/loader.rb +50 -0
  47. data/lib/git/lint/configuration/setting.rb +24 -0
  48. data/lib/git/lint/container.rb +41 -0
  49. data/lib/git/lint/errors/severity.rb +1 -0
  50. data/lib/git/lint/errors/sha.rb +1 -0
  51. data/lib/git/lint/identity.rb +2 -1
  52. data/lib/git/lint/kit/filter_list.rb +1 -1
  53. data/lib/git/lint/parsers/trailers/collaborator.rb +1 -0
  54. data/lib/git/lint/rake/tasks.rb +5 -4
  55. data/lib/git/lint/reporters/branch.rb +12 -6
  56. data/lib/git/lint/reporters/commit.rb +3 -1
  57. data/lib/git/lint/reporters/line.rb +3 -5
  58. data/lib/git/lint/reporters/lines/paragraph.rb +3 -0
  59. data/lib/git/lint/reporters/lines/sentence.rb +3 -0
  60. data/lib/git/lint/reporters/style.rb +3 -1
  61. data/lib/git/lint/validators/capitalization.rb +1 -0
  62. data/lib/git/lint/validators/email.rb +1 -0
  63. data/lib/git/lint/validators/name.rb +1 -0
  64. data/lib/git/lint.rb +18 -47
  65. data.tar.gz.sig +0 -0
  66. metadata +54 -28
  67. metadata.gz.sig +0 -0
  68. data/lib/git/lint/analyzers/commit_body_issue_tracker_link.rb +0 -39
  69. data/lib/git/lint/branches/environments/circle_ci.rb +0 -24
  70. data/lib/git/lint/branches/environments/local.rb +0 -24
  71. data/lib/git/lint/branches/environments/travis_ci.rb +0 -49
  72. data/lib/git/lint/branches/feature.rb +0 -42
  73. data/lib/git/lint/cli.rb +0 -117
  74. data/lib/git/lint/refinements/strings.rb +0 -21
  75. data/lib/git/lint/runner.rb +0 -35
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Git
4
- module Lint
5
- module Analyzers
6
- class CommitBodyIssueTrackerLink < Abstract
7
- def self.defaults
8
- {
9
- enabled: true,
10
- severity: :error,
11
- excludes: [
12
- "(f|F)ix(es|ed)?\\s\\#\\d+",
13
- "(c|C)lose(s|d)?\\s\\#\\d+",
14
- "(r|R)esolve(s|d)?\\s\\#\\d+",
15
- "github\\.com\\/.+\\/issues\\/\\d+"
16
- ]
17
- }
18
- end
19
-
20
- def valid? = commit.body_lines.none? { |line| invalid_line? line }
21
-
22
- def issue
23
- return {} if valid?
24
-
25
- {
26
- hint: "Explain issue instead of using link. Avoid: #{filter_list.to_hint}.",
27
- lines: affected_commit_body_lines
28
- }
29
- end
30
-
31
- protected
32
-
33
- def load_filter_list = Kit::FilterList.new(settings.fetch(:excludes))
34
-
35
- def invalid_line?(line) = line.match?(/.*#{Regexp.union filter_list.to_regexp}.*/)
36
- end
37
- end
38
- end
39
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Git
4
- module Lint
5
- module Branches
6
- module Environments
7
- # Provides Circle CI build environment feature branch information.
8
- class CircleCI
9
- def initialize repository: GitPlus::Repository.new
10
- @repository = repository
11
- end
12
-
13
- def name = "origin/#{repository.branch_name}"
14
-
15
- def commits = repository.commits("origin/#{repository.branch_default}..#{name}")
16
-
17
- private
18
-
19
- attr_reader :repository
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Git
4
- module Lint
5
- module Branches
6
- module Environments
7
- # Provides local build environment feature branch information.
8
- class Local
9
- def initialize repository: GitPlus::Repository.new
10
- @repository = repository
11
- end
12
-
13
- def name = repository.branch_name
14
-
15
- def commits = repository.commits("#{repository.branch_default}..#{name}")
16
-
17
- private
18
-
19
- attr_reader :repository
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "open3"
4
-
5
- module Git
6
- module Lint
7
- module Branches
8
- module Environments
9
- # Provides Travis CI build environment feature branch information.
10
- class TravisCI
11
- def initialize repository: GitPlus::Repository.new, shell: Open3, environment: ENV
12
- @repository = repository
13
- @shell = shell
14
- @environment = environment
15
- end
16
-
17
- def name = pull_request_branch.empty? ? ci_branch : pull_request_branch
18
-
19
- def commits
20
- prepare_project
21
- repository.commits "origin/#{repository.branch_default}..#{name}"
22
- end
23
-
24
- private
25
-
26
- attr_reader :environment, :repository, :shell
27
-
28
- def prepare_project
29
- slug = pull_request_slug
30
-
31
- unless slug.empty?
32
- shell.capture3 "git remote add -f original_branch https://github.com/#{slug}.git"
33
- shell.capture3 "git fetch original_branch #{name}:#{name}"
34
- end
35
-
36
- shell.capture3 "git remote set-branches --add origin #{repository.branch_default}"
37
- shell.capture3 "git fetch"
38
- end
39
-
40
- def ci_branch = environment["TRAVIS_BRANCH"]
41
-
42
- def pull_request_branch = environment["TRAVIS_PULL_REQUEST_BRANCH"]
43
-
44
- def pull_request_slug = environment["TRAVIS_PULL_REQUEST_SLUG"]
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "forwardable"
4
- require "refinements/strings"
5
-
6
- module Git
7
- module Lint
8
- module Branches
9
- # Represents a feature branch.
10
- class Feature
11
- extend Forwardable
12
-
13
- using ::Refinements::Strings
14
-
15
- def_delegators :selected_environment, :name, :commits
16
-
17
- def initialize environment: ENV, git_repo: GitPlus::Repository.new
18
- message = "Invalid repository. Are you within a Git-enabled project?"
19
- fail Errors::Base, message unless git_repo.exist?
20
-
21
- @current_environment = environment
22
- @selected_environment = load_environment
23
- end
24
-
25
- private
26
-
27
- attr_reader :current_environment, :selected_environment
28
-
29
- def load_environment
30
- if key? "CIRCLECI" then Environments::CircleCI.new
31
- elsif key? "GITHUB_ACTIONS" then Environments::GitHubAction.new
32
- elsif key? "NETLIFY" then Environments::NetlifyCI.new environment: current_environment
33
- elsif key? "TRAVIS" then Environments::TravisCI.new environment: current_environment
34
- else Environments::Local.new
35
- end
36
- end
37
-
38
- def key?(key) = current_environment.fetch(key, "false").to_bool
39
- end
40
- end
41
- end
42
- end
data/lib/git/lint/cli.rb DELETED
@@ -1,117 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "thor"
4
- require "thor/actions"
5
- require "runcom"
6
- require "pathname"
7
- require "pastel"
8
-
9
- module Git
10
- module Lint
11
- # The Command Line Interface (CLI) for the gem.
12
- class CLI < Thor
13
- include Thor::Actions
14
-
15
- package_name Identity::VERSION_LABEL
16
-
17
- def self.configuration
18
- defaults = Analyzers::Abstract.descendants.reduce({}) do |settings, analyzer|
19
- settings.merge analyzer.id => analyzer.defaults
20
- end
21
-
22
- Runcom::Config.new "#{Identity::NAME}/configuration.yml", defaults: defaults
23
- end
24
-
25
- def initialize args = [], options = {}, config = {}
26
- super args, options, config
27
- @configuration = self.class.configuration
28
- @runner = Runner.new configuration: @configuration.to_h
29
- @colorizer = Pastel.new
30
- rescue Runcom::Errors::Base => error
31
- abort error.message
32
- end
33
-
34
- desc "-c, [--config]", "Manage gem configuration."
35
- map %w[-c --config] => :config
36
- method_option :edit,
37
- aliases: "-e",
38
- desc: "Edit gem configuration.",
39
- type: :boolean,
40
- default: false
41
- method_option :info,
42
- aliases: "-i",
43
- desc: "Print gem configuration.",
44
- type: :boolean,
45
- default: false
46
- def config
47
- path = configuration.current
48
-
49
- if options.edit? then `#{ENV["EDITOR"]} #{path}`
50
- elsif options.info?
51
- path ? say(path) : say("Configuration doesn't exist.")
52
- else help :config
53
- end
54
- end
55
-
56
- desc "-a, [--analyze]", "Analyze feature branch for issues."
57
- map %w[-a --analyze] => :analyze
58
- method_option :commits,
59
- aliases: "-c",
60
- desc: "Analyze specific commit SHA(s).",
61
- type: :array,
62
- default: []
63
- def analyze
64
- # FIX: Need to accept SHAs.
65
- # collector = analyze_commits options.commits
66
- collector = analyze_commits
67
- abort if collector.errors?
68
- rescue Errors::Base => error
69
- abort colorizer.red("#{Identity::LABEL}: #{error.message}")
70
- end
71
-
72
- desc "--hook", "Add Git Hook support."
73
- map "--hook" => :hook
74
- method_option :commit_message, desc: "Analyze commit message.", banner: "PATH", type: :string
75
- def hook
76
- if options.commit_message?
77
- check_commit_message options.commit_message
78
- else
79
- help "--hook"
80
- end
81
- rescue Errors::Base, GitPlus::Error => error
82
- abort colorizer.red("#{Identity::LABEL}: #{error.message}")
83
- end
84
-
85
- desc "-v, [--version]", "Show gem version."
86
- map %w[-v --version] => :version
87
- def version
88
- say Identity::VERSION_LABEL
89
- end
90
-
91
- desc "-h, [--help=COMMAND]", "Show this message or get help for a command."
92
- map %w[-h --help] => :help
93
- def help task = nil
94
- say and super
95
- end
96
-
97
- private
98
-
99
- attr_reader :configuration, :runner, :colorizer
100
-
101
- def analyze_commits
102
- runner.call.tap do |collector|
103
- reporter = Reporters::Branch.new collector: collector
104
- say reporter.to_s
105
- end
106
- end
107
-
108
- def check_commit_message path
109
- commit = GitPlus::Repository.new.unsaved Pathname(path)
110
- collector = runner.call commits: [commit]
111
- reporter = Reporters::Branch.new collector: collector
112
- say reporter.to_s
113
- abort if collector.errors?
114
- end
115
- end
116
- end
117
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Git
4
- module Lint
5
- module Refinements
6
- module Strings
7
- refine String do
8
- def pluralize count:, suffix: "s"
9
- return "#{count} #{self}" if count == 1
10
-
11
- "#{count} #{self}#{suffix}"
12
- end
13
-
14
- def fixup? = match?(/\Afixup!\s/)
15
-
16
- def squash? = match?(/\Asquash!\s/)
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Git
4
- module Lint
5
- class Runner
6
- def initialize configuration:, branch: Branches::Feature.new, collector: Collector.new
7
- @configuration = configuration
8
- @branch = branch
9
- @collector = collector
10
- end
11
-
12
- def call commits: branch.commits
13
- commits.map { |commit| check commit }
14
- collector
15
- end
16
-
17
- private
18
-
19
- attr_reader :configuration, :branch, :collector
20
-
21
- def check commit
22
- configuration.map { |id, settings| load_analyzer id, commit, settings }
23
- .select(&:enabled?)
24
- .map { |analyzer| collector.add analyzer }
25
- end
26
-
27
- def load_analyzer id, commit, settings
28
- klass = Analyzers::Abstract.descendants.find { |descendant| descendant.id == id }
29
- fail Errors::Base, "Invalid analyzer: #{id}. See docs for supported analyzer." unless klass
30
-
31
- klass.new commit: commit, settings: settings
32
- end
33
- end
34
- end
35
- end