Class: SemVerComponents::LocalGit

Inherits:
Object
  • Object
show all
Defined in:
lib/sem_ver_components/local_git.rb

Overview

Analyzer of a local git repository

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(git_repo, git_from, git_to) ⇒ LocalGit

Constructor

Parameters:

  • git_repo (String) —

    The git repository to analyze

  • git_from (String, nil) —

    The git from ref

  • git_to (String) —

    The git to ref



13
14
15
16
17
18
# File 'lib/sem_ver_components/local_git.rb', line 13

def initialize(git_repo, git_from, git_to)
  @git_repo = git_repo
  @git_from = git_from
  @git_to = git_to
  @git = Git.open(@git_repo)
end

Instance Attribute Details

#git ⇒ Object (readonly)

Returns the value of attribute git.



6
7
8
# File 'lib/sem_ver_components/local_git.rb', line 6

def git
  @git
end

#git_from ⇒ Object (readonly)

Returns the value of attribute git_from.



6
7
8
# File 'lib/sem_ver_components/local_git.rb', line 6

def git_from
  @git_from
end

#git_to ⇒ Object (readonly)

Returns the value of attribute git_to.



6
7
8
# File 'lib/sem_ver_components/local_git.rb', line 6

def git_to
  @git_to
end

Instance Method Details

#analyze_commits ⇒ Array<Hash{Symbol => Object}>

Semantically analyze commits.

Returns:

  • (Array<Hash{Symbol => Object}>) —

    The commits information:

    • :components_bump_levels [Hash{String or nil => Integer}] Set of bump levels (0: patch, 1: minor, 2: major) per component name (nil for global)
    • :commit (Git::Object::Commit): Corresponding git commit


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/sem_ver_components/local_git.rb', line 34

def analyze_commits
  @git.log(nil).between(git_from.nil? ? git_log.last.sha : git_from, git_to).execute.map do |git_commit|
    # Analyze the message
    # Always consider a minimum of global patch bump per commit.
    components_bump_levels = { nil => [0] }
    # Extract tags enclosed in square brackets, like in '[feat] Some change' or '[feat(customers)] Some change'
    commit_labels = git_commit.message.scan(/\[([^\]]+)\]/).flatten(1).map do |commit_label|
      commit_label =~ /^(.+)\((.+)\)$/ ? [::Regexp.last_match(1), ::Regexp.last_match(2)] : [commit_label, nil]
    end
    # Extract also tags of the form 'type: Some change' or 'type(component): Some change' at the beginning of the message,
    # like in 'feat: Some change' or 'feat(customers): Some change'
    conventional_commit_tag = git_commit.message.match(/\A(feat|feature|break|breaking|major|minor|fix|patch|chore)(?:\(([^)]+)\))?:\s+/i)
    commit_labels << [conventional_commit_tag[1], conventional_commit_tag[2]] unless conventional_commit_tag.nil?
    commit_labels.each do |commit_type, component|
      components_bump_levels[component] = [] unless components_bump_levels.key?(component)
      components_bump_levels[component] <<
        case commit_type.downcase
        when 'break', 'breaking', 'major'
          2
        when 'feat', 'feature', 'minor'
          1
        else
          0
        end
    end
    {
      commit: git_commit,
      components_bump_levels: components_bump_levels.to_h { |component, component_bump_levels| [component, component_bump_levels.max] }
    }
  end
end

#git_log ⇒ Git::Log::Result

Get full the git log. Keep a cache of it.

Returns:

  • (Git::Log::Result) —

    Full git log (Enumerable of Git::Object::Commit)



24
25
26
27
# File 'lib/sem_ver_components/local_git.rb', line 24

def git_log
  @git_log = @git.log(nil).execute unless defined?(@git_log)
  @git_log
end

#on_release_branch? ⇒ Boolean

Is the git to ref part of a release branch?

Returns:

  • (Boolean) —

    Is the git to ref part of a release branch?



69
70
71
# File 'lib/sem_ver_components/local_git.rb', line 69

def on_release_branch?
  %w[master main].include?(@git_to)
end