git-lint 3.3.1 → 4.0.1

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 (37) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/LICENSE.adoc +134 -214
  4. data/git-lint.gemspec +7 -5
  5. data/lib/git/lint/analyzer.rb +6 -4
  6. data/lib/git/lint/analyzers/abstract.rb +6 -4
  7. data/lib/git/lint/analyzers/commit_author_capitalization.rb +2 -2
  8. data/lib/git/lint/analyzers/commit_author_email.rb +2 -2
  9. data/lib/git/lint/analyzers/commit_author_name.rb +2 -2
  10. data/lib/git/lint/analyzers/commit_subject_prefix.rb +1 -1
  11. data/lib/git/lint/analyzers/commit_trailer_collaborator_capitalization.rb +5 -2
  12. data/lib/git/lint/analyzers/commit_trailer_collaborator_duplication.rb +2 -2
  13. data/lib/git/lint/analyzers/commit_trailer_collaborator_email.rb +5 -3
  14. data/lib/git/lint/analyzers/commit_trailer_collaborator_key.rb +2 -2
  15. data/lib/git/lint/analyzers/commit_trailer_collaborator_name.rb +5 -3
  16. data/lib/git/lint/cli/actions/analyze/branch.rb +5 -9
  17. data/lib/git/lint/cli/actions/analyze/commit.rb +5 -7
  18. data/lib/git/lint/cli/actions/config.rb +5 -7
  19. data/lib/git/lint/cli/actions/container.rb +25 -0
  20. data/lib/git/lint/cli/actions/hook.rb +5 -9
  21. data/lib/git/lint/cli/actions/import.rb +13 -0
  22. data/lib/git/lint/cli/parser.rb +8 -5
  23. data/lib/git/lint/cli/parsers/core.rb +5 -5
  24. data/lib/git/lint/cli/shell.rb +17 -30
  25. data/lib/git/lint/commits/loader.rb +13 -22
  26. data/lib/git/lint/commits/systems/circle_ci.rb +1 -7
  27. data/lib/git/lint/commits/systems/container.rb +25 -0
  28. data/lib/git/lint/commits/systems/git_hub_action.rb +1 -7
  29. data/lib/git/lint/commits/systems/import.rb +13 -0
  30. data/lib/git/lint/commits/systems/local.rb +1 -7
  31. data/lib/git/lint/commits/systems/netlify_ci.rb +3 -13
  32. data/lib/git/lint/container.rb +4 -24
  33. data/lib/git/lint/import.rb +9 -0
  34. data.tar.gz.sig +0 -0
  35. metadata +53 -21
  36. metadata.gz.sig +0 -0
  37. data/lib/git/lint/commits/container.rb +0 -21
@@ -5,14 +5,16 @@ module Git
5
5
  module Analyzers
6
6
  # Analyzes commit trailer collaborator name construction.
7
7
  class CommitTrailerCollaboratorName < Abstract
8
+ # rubocop:disable Metrics/ParameterLists
8
9
  def initialize commit,
9
10
  parser: Parsers::Trailers::Collaborator,
10
- validator: Validators::Name
11
-
12
- super commit
11
+ validator: Validators::Name,
12
+ **dependencies
13
+ super commit, **dependencies
13
14
  @parser = parser
14
15
  @validator = validator
15
16
  end
17
+ # rubocop:enable Metrics/ParameterLists
16
18
 
17
19
  def valid? = affected_commit_trailers.empty?
18
20
 
@@ -7,9 +7,11 @@ module Git
7
7
  module Analyze
8
8
  # Handles analyze action for branch.
9
9
  class Branch
10
- def initialize analyzer: Analyzer.new, container: Container
10
+ include Git::Lint::Import[:repository, :kernel, :logger]
11
+
12
+ def initialize analyzer: Analyzer.new, **dependencies
13
+ super(**dependencies)
11
14
  @analyzer = analyzer
12
- @container = container
13
15
  end
14
16
 
15
17
  def call
@@ -21,7 +23,7 @@ module Git
21
23
 
22
24
  private
23
25
 
24
- attr_reader :analyzer, :container
26
+ attr_reader :analyzer
25
27
 
26
28
  def parse
27
29
  analyzer.call do |collector, reporter|
@@ -29,12 +31,6 @@ module Git
29
31
  kernel.abort if collector.errors?
30
32
  end
31
33
  end
32
-
33
- def repository = container[__method__]
34
-
35
- def kernel = container[__method__]
36
-
37
- def logger = container[__method__]
38
34
  end
39
35
  end
40
36
  end
@@ -7,12 +7,14 @@ module Git
7
7
  module Analyze
8
8
  # Handles analyze action for commit(s) by SHA.
9
9
  class Commit
10
+ include Git::Lint::Import[:kernel, :logger]
11
+
10
12
  def initialize analyzer: Analyzer.new,
11
13
  parser: GitPlus::Parsers::Commits::Saved::History.with_show,
12
- container: Container
14
+ **dependencies
15
+ super(**dependencies)
13
16
  @analyzer = analyzer
14
17
  @parser = parser
15
- @container = container
16
18
  end
17
19
 
18
20
  def call sha = nil
@@ -24,7 +26,7 @@ module Git
24
26
 
25
27
  private
26
28
 
27
- attr_reader :analyzer, :parser, :container
29
+ attr_reader :analyzer, :parser
28
30
 
29
31
  def process sha
30
32
  analyzer.call commits: parser.call(*sha) do |collector, reporter|
@@ -32,10 +34,6 @@ module Git
32
34
  kernel.abort if collector.errors?
33
35
  end
34
36
  end
35
-
36
- def kernel = container[__method__]
37
-
38
- def logger = container[__method__]
39
37
  end
40
38
  end
41
39
  end
@@ -6,9 +6,11 @@ module Git
6
6
  module Actions
7
7
  # Handles gem configuration action.
8
8
  class Config
9
- def initialize configuration: Configuration::Loader::CLIENT, container: Container
9
+ include Git::Lint::Import[:kernel, :logger]
10
+
11
+ def initialize configuration: Configuration::Loader::CLIENT, **dependencies
12
+ super(**dependencies)
10
13
  @configuration = configuration
11
- @container = container
12
14
  end
13
15
 
14
16
  def call action
@@ -21,15 +23,11 @@ module Git
21
23
 
22
24
  private
23
25
 
24
- attr_reader :configuration, :container
26
+ attr_reader :configuration
25
27
 
26
28
  def edit = kernel.system("$EDITOR #{configuration.current}")
27
29
 
28
30
  def view = kernel.system("cat #{configuration.current}")
29
-
30
- def kernel = container[__method__]
31
-
32
- def logger = container[__method__]
33
31
  end
34
32
  end
35
33
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/container"
4
+
5
+ module Git
6
+ module Lint
7
+ module CLI
8
+ module Actions
9
+ # Provides a single container with application and action specific dependencies.
10
+ module Container
11
+ extend Dry::Container::Mixin
12
+
13
+ config.registry = ->(container, key, value, _options) { container[key.to_s] = value }
14
+
15
+ merge Git::Lint::Container
16
+
17
+ register(:analyze_branch) { Analyze::Branch.new }
18
+ register(:analyze_commit) { Analyze::Commit.new }
19
+ register(:config) { Config.new }
20
+ register(:hook) { Hook.new }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -6,9 +6,11 @@ module Git
6
6
  module Actions
7
7
  # Handles unsaved Git commit action.
8
8
  class Hook
9
- def initialize analyzer: Analyzer.new, container: Container
9
+ include Git::Lint::Import[:repository, :kernel, :logger]
10
+
11
+ def initialize analyzer: Analyzer.new, **dependencies
12
+ super(**dependencies)
10
13
  @analyzer = analyzer
11
- @container = container
12
14
  end
13
15
 
14
16
  def call path
@@ -20,13 +22,7 @@ module Git
20
22
 
21
23
  private
22
24
 
23
- attr_reader :analyzer, :container
24
-
25
- def repository = container[__method__]
26
-
27
- def kernel = container[__method__]
28
-
29
- def logger = container[__method__]
25
+ attr_reader :analyzer
30
26
  end
31
27
  end
32
28
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "auto_injector"
4
+
5
+ module Git
6
+ module Lint
7
+ module CLI
8
+ module Actions
9
+ Import = AutoInjector[Container]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -7,26 +7,29 @@ module Git
7
7
  module CLI
8
8
  # Assembles and parses all Command Line Interface (CLI) options.
9
9
  class Parser
10
+ include Import[:configuration]
11
+
10
12
  CLIENT = OptionParser.new nil, 40, " "
11
13
  SECTIONS = [Parsers::Core, Parsers::Analyze].freeze # Order matters.
12
14
 
13
- def initialize sections: SECTIONS, client: CLIENT, container: Container
15
+ def initialize sections: SECTIONS, client: CLIENT, **dependencies
16
+ super(**dependencies)
14
17
  @sections = sections
15
18
  @client = client
16
- @configuration = container[:configuration].dup
19
+ @configuration_duplicate = configuration.dup
17
20
  end
18
21
 
19
22
  def call arguments = []
20
- sections.each { |section| section.call configuration, client: }
23
+ sections.each { |section| section.call configuration_duplicate, client: }
21
24
  client.parse arguments
22
- configuration.freeze
25
+ configuration_duplicate.freeze
23
26
  end
24
27
 
25
28
  def to_s = client.to_s
26
29
 
27
30
  private
28
31
 
29
- attr_reader :sections, :client, :configuration
32
+ attr_reader :sections, :client, :configuration_duplicate
30
33
  end
31
34
  end
32
35
  end
@@ -8,16 +8,18 @@ module Git
8
8
  module Parsers
9
9
  # Handles parsing of Command Line Interface (CLI) core options.
10
10
  class Core
11
+ include Import[:specification]
12
+
11
13
  using ::Refinements::Structs
12
14
 
13
15
  def self.call(...) = new(...).call
14
16
 
15
17
  def initialize configuration = Container[:configuration],
16
18
  client: Parser::CLIENT,
17
- container: Container
19
+ **dependencies
20
+ super(**dependencies)
18
21
  @configuration = configuration
19
22
  @client = client
20
- @container = container
21
23
  end
22
24
 
23
25
  def call arguments = []
@@ -30,7 +32,7 @@ module Git
30
32
 
31
33
  private
32
34
 
33
- attr_reader :configuration, :client, :container
35
+ attr_reader :configuration, :client
34
36
 
35
37
  def collate = private_methods.sort.grep(/add_/).each { |method| __send__ method }
36
38
 
@@ -68,8 +70,6 @@ module Git
68
70
  configuration.merge! action_help: true
69
71
  end
70
72
  end
71
-
72
- def specification = container[__method__]
73
73
  end
74
74
  end
75
75
  end
@@ -5,17 +5,18 @@ module Git
5
5
  module CLI
6
6
  # The main Command Line Interface (CLI) object.
7
7
  class Shell
8
- ACTIONS = {
9
- analyze_branch: Actions::Analyze::Branch.new,
10
- analyze_commit: Actions::Analyze::Commit.new,
11
- config: Actions::Config.new,
12
- hook: Actions::Hook.new
13
- }.freeze
14
-
15
- def initialize parser: Parser.new, actions: ACTIONS, container: Container
8
+ include Actions::Import[
9
+ :analyze_branch,
10
+ :analyze_commit,
11
+ :config,
12
+ :hook,
13
+ :specification,
14
+ :logger
15
+ ]
16
+
17
+ def initialize parser: Parser.new, **dependencies
18
+ super(**dependencies)
16
19
  @parser = parser
17
- @actions = actions
18
- @container = container
19
20
  end
20
21
 
21
22
  def call arguments = []
@@ -26,32 +27,18 @@ module Git
26
27
 
27
28
  private
28
29
 
29
- attr_reader :parser, :actions, :container
30
+ attr_reader :parser
30
31
 
31
32
  def perform configuration
32
33
  case configuration
33
- in action_analyze: true, analyze_sha: nil then analyze_branch
34
- in action_analyze: true, analyze_sha: String => sha then analyze_commit sha
35
- in action_config: Symbol => action then config action
36
- in action_hook: Pathname => path then hook path
34
+ in action_analyze: true, analyze_sha: nil then analyze_branch.call
35
+ in action_analyze: true, analyze_sha: String => sha then analyze_commit.call sha
36
+ in action_config: Symbol => action then config.call action
37
+ in action_hook: Pathname => path then hook.call path
37
38
  in action_version: true then logger.info { specification.labeled_version }
38
- else usage
39
+ else logger.any { parser.to_s }
39
40
  end
40
41
  end
41
-
42
- def analyze_branch = actions.fetch(__method__).call
43
-
44
- def analyze_commit(sha) = actions.fetch(__method__).call(sha)
45
-
46
- def config(action) = actions.fetch(__method__).call(action)
47
-
48
- def hook(path) = actions.fetch(__method__).call(path)
49
-
50
- def usage = logger.unknown { parser.to_s }
51
-
52
- def specification = container[__method__]
53
-
54
- def logger = container[__method__]
55
42
  end
56
43
  end
57
44
  end
@@ -7,19 +7,16 @@ module Git
7
7
  module Commits
8
8
  # Automatically detects and loads system.
9
9
  class Loader
10
- using ::Refinements::Strings
11
-
12
- SYSTEMS = {
13
- circle_ci: Systems::CircleCI.new,
14
- git_hub_action: Systems::GitHubAction.new,
15
- netlify_ci: Systems::NetlifyCI.new,
16
- local: Systems::Local.new
17
- }.freeze
10
+ include Systems::Import[
11
+ :circle_ci,
12
+ :git_hub_action,
13
+ :netlify_ci,
14
+ :local,
15
+ :repository,
16
+ :environment
17
+ ]
18
18
 
19
- def initialize systems: SYSTEMS, container: Container
20
- @systems = systems
21
- @container = container
22
- end
19
+ using ::Refinements::Strings
23
20
 
24
21
  def call
25
22
  message = "Invalid repository. Are you within a Git repository?"
@@ -30,21 +27,15 @@ module Git
30
27
 
31
28
  private
32
29
 
33
- attr_reader :systems, :container
34
-
35
30
  def load_system
36
- if key? "CIRCLECI" then systems.fetch :circle_ci
37
- elsif key? "GITHUB_ACTIONS" then systems.fetch :git_hub_action
38
- elsif key? "NETLIFY" then systems.fetch :netlify_ci
39
- else systems.fetch :local
31
+ if key? "CIRCLECI" then circle_ci
32
+ elsif key? "GITHUB_ACTIONS" then git_hub_action
33
+ elsif key? "NETLIFY" then netlify_ci
34
+ else local
40
35
  end
41
36
  end
42
37
 
43
38
  def key?(key) = environment.fetch(key, "false").to_bool
44
-
45
- def repository = container[__method__]
46
-
47
- def environment = container[__method__]
48
39
  end
49
40
  end
50
41
  end
@@ -6,19 +6,13 @@ module Git
6
6
  module Systems
7
7
  # Provides Circle CI build environment feature branch information.
8
8
  class CircleCI
9
- def initialize container: Container
10
- @container = container
11
- end
9
+ include Git::Lint::Import[:repository]
12
10
 
13
11
  def call = repository.commits("origin/#{repository.branch_default}..#{name}")
14
12
 
15
13
  private
16
14
 
17
- attr_reader :container
18
-
19
15
  def name = "origin/#{repository.branch_name}"
20
-
21
- def repository = container[__method__]
22
16
  end
23
17
  end
24
18
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/container"
4
+
5
+ module Git
6
+ module Lint
7
+ module Commits
8
+ module Systems
9
+ # Provides a single container with application and system specific dependencies.
10
+ module Container
11
+ extend Dry::Container::Mixin
12
+
13
+ config.registry = ->(container, key, value, _options) { container[key.to_s] = value }
14
+
15
+ merge Git::Lint::Container
16
+
17
+ register(:circle_ci) { CircleCI.new }
18
+ register(:git_hub_action) { GitHubAction.new }
19
+ register(:netlify_ci) { NetlifyCI.new }
20
+ register(:local) { Local.new }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -6,19 +6,13 @@ module Git
6
6
  module Systems
7
7
  # Provides GitHub Action build environment feature branch information.
8
8
  class GitHubAction
9
- def initialize container: Container
10
- @container = container
11
- end
9
+ include Git::Lint::Import[:repository]
12
10
 
13
11
  def call = repository.commits("origin/#{repository.branch_default}..#{name}")
14
12
 
15
13
  private
16
14
 
17
- attr_reader :container
18
-
19
15
  def name = "origin/#{repository.branch_name}"
20
-
21
- def repository = container[__method__]
22
16
  end
23
17
  end
24
18
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "auto_injector"
4
+
5
+ module Git
6
+ module Lint
7
+ module Commits
8
+ module Systems
9
+ Import = AutoInjector[Container]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -6,19 +6,13 @@ module Git
6
6
  module Systems
7
7
  # Provides local build environment feature branch information.
8
8
  class Local
9
- def initialize container: Container
10
- @container = container
11
- end
9
+ include Git::Lint::Import[:repository]
12
10
 
13
11
  def call = repository.commits("#{repository.branch_default}..#{name}")
14
12
 
15
13
  private
16
14
 
17
- attr_reader :container
18
-
19
15
  def name = repository.branch_name
20
-
21
- def repository = container[__method__]
22
16
  end
23
17
  end
24
18
  end
@@ -8,27 +8,17 @@ module Git
8
8
  module Systems
9
9
  # Provides Netlify CI build environment feature branch information.
10
10
  class NetlifyCI
11
- def initialize container: Container
12
- @container = container
13
- end
11
+ include Git::Lint::Import[:repository, :executor, :environment]
14
12
 
15
13
  def call
16
- shell.capture3 "git remote add -f origin #{environment["REPOSITORY_URL"]}"
17
- shell.capture3 "git fetch origin #{name}:#{name}"
14
+ executor.capture3 "git remote add -f origin #{environment["REPOSITORY_URL"]}"
15
+ executor.capture3 "git fetch origin #{name}:#{name}"
18
16
  repository.commits "origin/#{repository.branch_default}..origin/#{name}"
19
17
  end
20
18
 
21
19
  private
22
20
 
23
- attr_reader :container
24
-
25
21
  def name = environment["HEAD"]
26
-
27
- def repository = container[__method__]
28
-
29
- def shell = container[__method__]
30
-
31
- def environment = container[__method__]
32
22
  end
33
23
  end
34
24
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "cogger"
3
4
  require "dry-container"
4
5
  require "git_plus"
5
- require "logger"
6
- require "pastel"
6
+ require "open3"
7
7
  require "spek"
8
8
 
9
9
  module Git
@@ -16,29 +16,9 @@ module Git
16
16
  register(:environment) { ENV }
17
17
  register(:repository) { GitPlus::Repository.new }
18
18
  register(:specification) { Spek::Loader.call "#{__dir__}/../../../git-lint.gemspec" }
19
- register(:colorizer) { Pastel.new enabled: $stdout.tty? }
20
19
  register(:kernel) { Kernel }
21
-
22
- register :log_colors do
23
- {
24
- "DEBUG" => self[:colorizer].white.detach,
25
- "INFO" => self[:colorizer].green.detach,
26
- "WARN" => self[:colorizer].yellow.detach,
27
- "ERROR" => self[:colorizer].red.detach,
28
- "FATAL" => self[:colorizer].white.bold.on_red.detach,
29
- "ANY" => self[:colorizer].white.bold.detach
30
- }
31
- end
32
-
33
- register :logger do
34
- Logger.new $stdout,
35
- level: Logger.const_get(ENV.fetch("LOG_LEVEL", "INFO")),
36
- formatter: (
37
- lambda do |severity, _at, _name, message|
38
- self[:log_colors][severity].call "#{message}\n"
39
- end
40
- )
41
- end
20
+ register(:executor) { Open3 }
21
+ register(:logger) { Cogger::Client.new }
42
22
  end
43
23
  end
44
24
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "auto_injector"
4
+
5
+ module Git
6
+ module Lint
7
+ Import = AutoInjector[Container]
8
+ end
9
+ end
data.tar.gz.sig CHANGED
Binary file