sem_ver_components 0.4.1 → 1.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.
- checksums.yaml +4 -4
- data/bin/sem_ver_git +14 -9
- data/lib/sem_ver_components/git_hosting.rb +2 -3
- data/lib/sem_ver_components/git_hostings/bitbucket.rb +17 -23
- data/lib/sem_ver_components/git_hostings/github.rb +10 -15
- data/lib/sem_ver_components/local_git.rb +23 -23
- data/lib/sem_ver_components/output.rb +2 -7
- data/lib/sem_ver_components/outputs/info.rb +8 -15
- data/lib/sem_ver_components/outputs/semantic_release_analyze.rb +4 -10
- data/lib/sem_ver_components/outputs/semantic_release_generate_notes.rb +18 -22
- data/lib/sem_ver_components/plugins.rb +10 -17
- data/lib/sem_ver_components/semver.rb +25 -38
- data/lib/sem_ver_components/version.rb +2 -3
- data/lib/sem_ver_components.rb +3 -0
- metadata +22 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 478f0c6d8c4367e4892b9fb22a2ac76fd3673abd9dfa8d9f9931a091943646ea
|
|
4
|
+
data.tar.gz: 5a671cb67c267a9e72b5fe618fe32253ba2ee0ac2878e23e49d307395df2b06c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 50942553eb735fa7d94647a223e13b441db129dd5ddfa565a00a065519d3a6533d5247927328f7171c9ffea3b1cac474b277995a95e43416db1a04b7f23ad149
|
|
7
|
+
data.tar.gz: e5147c73184abbbe1c6435005a4cdc39198540420952bd39e96f31d1a2bd1f3149845ed502f001b6882b44174194bdf54007a5c0b5e80b871a171f7716fd1ac1
|
data/bin/sem_ver_git
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
require 'optparse'
|
|
3
|
-
require 'sem_ver_components
|
|
4
|
-
require 'sem_ver_components/local_git'
|
|
5
|
-
require 'sem_ver_components/version'
|
|
6
|
-
require 'sem_ver_components/output'
|
|
7
|
-
require 'sem_ver_components/git_hosting'
|
|
3
|
+
require 'sem_ver_components'
|
|
8
4
|
|
|
9
5
|
# Default values
|
|
10
6
|
git_repo = '.'
|
|
@@ -15,18 +11,27 @@ output = :info
|
|
|
15
11
|
output_plugins = SemVerComponents::Plugins.new(:outputs)
|
|
16
12
|
git_hosting_plugins = SemVerComponents::Plugins.new(:git_hostings)
|
|
17
13
|
OptionParser.new do |opts|
|
|
18
|
-
opts.banner = "Usage: #{File.basename($
|
|
14
|
+
opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} [options]"
|
|
19
15
|
opts.on('-f', '--from GIT_REF', 'Git reference from which commits are to be analyzed (defaults to first commit)') do |git_ref|
|
|
20
16
|
git_from = git_ref.empty? ? nil : git_ref
|
|
21
17
|
end
|
|
22
|
-
opts.on(
|
|
18
|
+
opts.on(
|
|
19
|
+
'-g',
|
|
20
|
+
'--git_hosting GIT_HOSTING',
|
|
21
|
+
'Specify which kind of git hosting is used. Used to format URLs to commits and comparisons. ' \
|
|
22
|
+
"Possible values are #{git_hosting_plugins.list.sort.join(', ')}. (defaults to #{git_hosting})"
|
|
23
|
+
) do |git_hosting_str|
|
|
23
24
|
git_hosting = git_hosting_str.to_sym
|
|
24
25
|
end
|
|
25
26
|
opts.on('-h', '--help', 'Display this help') do
|
|
26
27
|
puts opts
|
|
27
28
|
exit 0
|
|
28
29
|
end
|
|
29
|
-
opts.on(
|
|
30
|
+
opts.on(
|
|
31
|
+
'-o',
|
|
32
|
+
'--output OUTPUT',
|
|
33
|
+
"Specify the output format of the analysis. Possible values are #{output_plugins.list.sort.join(', ')} (defauts to #{output})"
|
|
34
|
+
) do |output_str|
|
|
30
35
|
output = output_str.to_sym
|
|
31
36
|
end
|
|
32
37
|
opts.on('-r', '--repo GIT_URL', "Specify the Git URL of the repository to analyze (defaults to #{git_repo})") do |git_url|
|
|
@@ -36,7 +41,7 @@ OptionParser.new do |opts|
|
|
|
36
41
|
git_to = git_ref
|
|
37
42
|
end
|
|
38
43
|
opts.on('-v', '--version', 'Display version') do
|
|
39
|
-
puts "#{File.basename($
|
|
44
|
+
puts "#{File.basename($PROGRAM_NAME)} v#{SemVerComponents::VERSION}"
|
|
40
45
|
exit 0
|
|
41
46
|
end
|
|
42
47
|
end.parse!
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
# Tools helping in maintaining semantic versioning at a components level instead of a global package-only level
|
|
1
2
|
module SemVerComponents
|
|
2
|
-
|
|
3
3
|
# Base class for all git hosting plugins
|
|
4
4
|
class GitHosting
|
|
5
|
-
|
|
5
|
+
# Marker class for all plugins of type GitHosting
|
|
6
6
|
end
|
|
7
|
-
|
|
8
7
|
end
|
|
@@ -1,49 +1,43 @@
|
|
|
1
1
|
module SemVerComponents
|
|
2
|
-
|
|
2
|
+
# Namespace for all git hosting plugins
|
|
3
3
|
module GitHostings
|
|
4
|
-
|
|
4
|
+
# Plugin providing URLs to a Bitbucket hosting
|
|
5
5
|
class Bitbucket < GitHosting
|
|
6
|
-
|
|
7
6
|
# Get the URL to a given commit sha
|
|
8
7
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
8
|
+
# @param git_url [String] The git URL
|
|
9
|
+
# @param commit_sha [String] The commit sha
|
|
10
|
+
# @return [String] The URL to the commit
|
|
12
11
|
def commit_url(git_url, commit_sha)
|
|
13
12
|
"#{public_url(git_url)}/commits/#{commit_sha}"
|
|
14
13
|
end
|
|
15
14
|
|
|
16
15
|
# Get the URL to compare 2 tags
|
|
17
16
|
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
def compare_url(git_url,
|
|
23
|
-
"#{public_url(git_url)}/compare/commits?targetBranch=refs%2Ftags%2F#{
|
|
17
|
+
# @param git_url [String] The git URL
|
|
18
|
+
# @param tag1 [String] The first tag
|
|
19
|
+
# @param tag2 [String] The second tag
|
|
20
|
+
# @return [String] The URL to compare the 2 tags
|
|
21
|
+
def compare_url(git_url, tag1, tag2)
|
|
22
|
+
"#{public_url(git_url)}/compare/commits?targetBranch=refs%2Ftags%2F#{tag1}&sourceBranch=refs%2Ftags%2F#{tag2}"
|
|
24
23
|
end
|
|
25
24
|
|
|
26
25
|
private
|
|
27
26
|
|
|
28
27
|
# Convert the git remote URL to the public URL
|
|
29
28
|
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
# Result::
|
|
33
|
-
# * String: The corresponding public URL
|
|
29
|
+
# @param git_url [String] Git remote URL
|
|
30
|
+
# @return [String] The corresponding public URL
|
|
34
31
|
def public_url(git_url)
|
|
35
|
-
if git_url =~
|
|
36
|
-
base_url =
|
|
37
|
-
project =
|
|
38
|
-
repo =
|
|
32
|
+
if git_url =~ %r{^(.+)/scm/([^/]+)/(.+)$}
|
|
33
|
+
base_url = ::Regexp.last_match(1)
|
|
34
|
+
project = ::Regexp.last_match(2)
|
|
35
|
+
repo = ::Regexp.last_match(3)
|
|
39
36
|
"#{base_url}/projects/#{project}/repos/#{repo}"
|
|
40
37
|
else
|
|
41
38
|
git_url
|
|
42
39
|
end
|
|
43
40
|
end
|
|
44
|
-
|
|
45
41
|
end
|
|
46
|
-
|
|
47
42
|
end
|
|
48
|
-
|
|
49
43
|
end
|
|
@@ -1,30 +1,25 @@
|
|
|
1
1
|
module SemVerComponents
|
|
2
|
-
|
|
3
2
|
module GitHostings
|
|
4
|
-
|
|
3
|
+
# Plugin providing URLs to a GitHub hosting
|
|
5
4
|
class Github < GitHosting
|
|
6
|
-
|
|
7
5
|
# Get the URL to a given commit sha
|
|
8
6
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
7
|
+
# @param git_url [String] The git URL
|
|
8
|
+
# @param commit_sha [String] The commit sha
|
|
9
|
+
# @return [String] The URL to the commit
|
|
12
10
|
def commit_url(git_url, commit_sha)
|
|
13
11
|
"#{git_url}/commit/#{commit_sha}"
|
|
14
12
|
end
|
|
15
13
|
|
|
16
14
|
# Get the URL to compare 2 tags
|
|
17
15
|
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
def compare_url(git_url,
|
|
23
|
-
"#{git_url}/compare/#{
|
|
16
|
+
# @param git_url [String] The git URL
|
|
17
|
+
# @param tag1 [String] The first tag
|
|
18
|
+
# @param tag2 [String] The second tag
|
|
19
|
+
# @return [String] The URL to compare the 2 tags
|
|
20
|
+
def compare_url(git_url, tag1, tag2)
|
|
21
|
+
"#{git_url}/compare/#{tag1}...#{tag2}"
|
|
24
22
|
end
|
|
25
|
-
|
|
26
23
|
end
|
|
27
|
-
|
|
28
24
|
end
|
|
29
|
-
|
|
30
25
|
end
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
require 'git'
|
|
2
2
|
|
|
3
3
|
module SemVerComponents
|
|
4
|
-
|
|
4
|
+
# Analyzer of a local git repository
|
|
5
5
|
class LocalGit
|
|
6
|
-
|
|
7
|
-
attr_reader *%i[git_from git_to git]
|
|
6
|
+
attr_reader :git_from, :git_to, :git
|
|
8
7
|
|
|
9
8
|
# Constructor
|
|
10
9
|
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# * *git_to* (String): The git to ref
|
|
10
|
+
# @param git_repo [String] The git repository to analyze
|
|
11
|
+
# @param git_from [String, nil] The git from ref
|
|
12
|
+
# @param git_to [String] The git to ref
|
|
15
13
|
def initialize(git_repo, git_from, git_to)
|
|
16
14
|
@git_repo = git_repo
|
|
17
15
|
@git_from = git_from
|
|
@@ -22,26 +20,31 @@ module SemVerComponents
|
|
|
22
20
|
# Get full the git log.
|
|
23
21
|
# Keep a cache of it.
|
|
24
22
|
#
|
|
25
|
-
# Result::
|
|
26
|
-
# * Array< Git::Object::Commit >: Full git log
|
|
23
|
+
# @return [Git::Log::Result] Full git log (Enumerable of Git::Object::Commit)
|
|
27
24
|
def git_log
|
|
28
|
-
@git_log = @git.log(nil) unless defined?(@git_log)
|
|
25
|
+
@git_log = @git.log(nil).execute unless defined?(@git_log)
|
|
29
26
|
@git_log
|
|
30
27
|
end
|
|
31
28
|
|
|
32
29
|
# Semantically analyze commits.
|
|
33
30
|
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
# * *commit* (Git::Object::Commit): Corresponding git commit
|
|
31
|
+
# @return [Array<Hash{Symbol => Object}>] The commits information:
|
|
32
|
+
# - +:components_bump_levels+ [Hash\\{String or nil => Integer}] Set of bump levels (0: patch, 1: minor, 2: major) per component name (nil for global)
|
|
33
|
+
# - +:commit+ (Git::Object::Commit): Corresponding git commit
|
|
38
34
|
def analyze_commits
|
|
39
|
-
|
|
35
|
+
@git.log(nil).between(git_from.nil? ? git_log.last.sha : git_from, git_to).execute.map do |git_commit|
|
|
40
36
|
# Analyze the message
|
|
41
37
|
# Always consider a minimum of global patch bump per commit.
|
|
42
38
|
components_bump_levels = { nil => [0] }
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
# Extract tags enclosed in square brackets, like in '[feat] Some change' or '[feat(customers)] Some change'
|
|
40
|
+
commit_labels = git_commit.message.scan(/\[([^\]]+)\]/).flatten(1).map do |commit_label|
|
|
41
|
+
commit_label =~ /^(.+)\((.+)\)$/ ? [::Regexp.last_match(1), ::Regexp.last_match(2)] : [commit_label, nil]
|
|
42
|
+
end
|
|
43
|
+
# Extract also tags of the form 'type: Some change' or 'type(component): Some change' at the beginning of the message,
|
|
44
|
+
# like in 'feat: Some change' or 'feat(customers): Some change'
|
|
45
|
+
conventional_commit_tag = git_commit.message.match(/\A(feat|feature|break|breaking|major|minor|fix|patch|chore)(?:\(([^)]+)\))?:\s+/i)
|
|
46
|
+
commit_labels << [conventional_commit_tag[1], conventional_commit_tag[2]] unless conventional_commit_tag.nil?
|
|
47
|
+
commit_labels.each do |commit_type, component|
|
|
45
48
|
components_bump_levels[component] = [] unless components_bump_levels.key?(component)
|
|
46
49
|
components_bump_levels[component] <<
|
|
47
50
|
case commit_type.downcase
|
|
@@ -55,19 +58,16 @@ module SemVerComponents
|
|
|
55
58
|
end
|
|
56
59
|
{
|
|
57
60
|
commit: git_commit,
|
|
58
|
-
components_bump_levels:
|
|
61
|
+
components_bump_levels: components_bump_levels.to_h { |component, component_bump_levels| [component, component_bump_levels.max] }
|
|
59
62
|
}
|
|
60
63
|
end
|
|
61
64
|
end
|
|
62
65
|
|
|
63
66
|
# Is the git to ref part of a release branch?
|
|
64
67
|
#
|
|
65
|
-
#
|
|
66
|
-
# * Boolean: Is the git to ref part of a release branch?
|
|
68
|
+
# @return [Boolean] Is the git to ref part of a release branch?
|
|
67
69
|
def on_release_branch?
|
|
68
|
-
@git_to
|
|
70
|
+
%w[master main].include?(@git_to)
|
|
69
71
|
end
|
|
70
|
-
|
|
71
72
|
end
|
|
72
|
-
|
|
73
73
|
end
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
module SemVerComponents
|
|
2
|
-
|
|
3
2
|
# Base class for all output plugins
|
|
4
3
|
class Output
|
|
5
|
-
|
|
6
4
|
# Constructor
|
|
7
5
|
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# * *git_hosting* (GitHosting): The git hosting to be used for URLs
|
|
6
|
+
# @param local_git [LocalGit] The git repository
|
|
7
|
+
# @param git_hosting [GitHosting] The git hosting to be used for URLs
|
|
11
8
|
def initialize(local_git, git_hosting)
|
|
12
9
|
@local_git = local_git
|
|
13
10
|
@git_hosting = git_hosting
|
|
14
11
|
end
|
|
15
|
-
|
|
16
12
|
end
|
|
17
|
-
|
|
18
13
|
end
|
|
@@ -1,22 +1,18 @@
|
|
|
1
|
-
require 'sem_ver_components/semver'
|
|
2
|
-
|
|
3
1
|
module SemVerComponents
|
|
4
|
-
|
|
2
|
+
# Namespace for all output plugins
|
|
5
3
|
module Outputs
|
|
6
|
-
|
|
4
|
+
# Output plugin displaying components' bump levels and next version info
|
|
7
5
|
class Info < Output
|
|
8
|
-
|
|
9
6
|
# Process commits info
|
|
10
7
|
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# * *commit* (Git::Object::Commit): Corresponding git commit
|
|
8
|
+
# @param commits_info [Array<Hash{Symbol => Object}>] List of commits info:
|
|
9
|
+
# - +:components_bump_levels+ [Hash\\{String or nil => Integer}] Set of bump levels (0: patch, 1: minor, 2: major) per component name (nil for global)
|
|
10
|
+
# - +:commit+ [Git::Object::Commit] Corresponding git commit
|
|
15
11
|
def process(commits_info)
|
|
16
12
|
# Display bump levels per component
|
|
17
13
|
bumps_per_component = commits_info.inject({}) do |components_bump_levels, commit_info|
|
|
18
|
-
components_bump_levels.merge(commit_info[:components_bump_levels]) do |_component,
|
|
19
|
-
[
|
|
14
|
+
components_bump_levels.merge(commit_info[:components_bump_levels]) do |_component, bump_level1, bump_level2|
|
|
15
|
+
[bump_level1, bump_level2].max
|
|
20
16
|
end
|
|
21
17
|
end
|
|
22
18
|
bumps_per_component.each do |component, bump_level|
|
|
@@ -38,14 +34,11 @@ module SemVerComponents
|
|
|
38
34
|
if global_bump_level.nil?
|
|
39
35
|
puts 'No next version'
|
|
40
36
|
else
|
|
41
|
-
puts "Next global version#{
|
|
37
|
+
puts "Next global version#{' (not on release branch)' unless @local_git.on_release_branch?}: #{
|
|
42
38
|
Semver.next_version_from(Semver.version_from_git_ref(@local_git.git_from), global_bump_level, pre_release: !@local_git.on_release_branch?)
|
|
43
39
|
}"
|
|
44
40
|
end
|
|
45
41
|
end
|
|
46
|
-
|
|
47
42
|
end
|
|
48
|
-
|
|
49
43
|
end
|
|
50
|
-
|
|
51
44
|
end
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
module SemVerComponents
|
|
2
|
-
|
|
3
2
|
module Outputs
|
|
4
|
-
|
|
3
|
+
# Output plugin reporting the next version bump level in the semantic-release format
|
|
5
4
|
class SemanticReleaseAnalyze < Output
|
|
6
|
-
|
|
7
5
|
# Process commits info
|
|
8
6
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# * *commit* (Git::Object::Commit): Corresponding git commit
|
|
7
|
+
# @param commits_info [Array<Hash{Symbol => Object}>] List of commits info:
|
|
8
|
+
# - +:components_bump_levels+ [Hash\\{String or nil => Integer}] Set of bump levels (0: patch, 1: minor, 2: major) per component name (nil for global)
|
|
9
|
+
# - +:commit+ [Git::Object::Commit] Corresponding git commit
|
|
13
10
|
def process(commits_info)
|
|
14
11
|
bump_level = commits_info.map { |commit_info| commit_info[:components_bump_levels].values }.flatten(1).max
|
|
15
12
|
puts(
|
|
@@ -28,9 +25,6 @@ module SemVerComponents
|
|
|
28
25
|
end
|
|
29
26
|
)
|
|
30
27
|
end
|
|
31
|
-
|
|
32
28
|
end
|
|
33
|
-
|
|
34
29
|
end
|
|
35
|
-
|
|
36
30
|
end
|
|
@@ -1,27 +1,24 @@
|
|
|
1
1
|
require 'time'
|
|
2
|
-
require 'sem_ver_components/semver'
|
|
3
2
|
|
|
4
3
|
module SemVerComponents
|
|
5
|
-
|
|
6
4
|
module Outputs
|
|
7
|
-
|
|
5
|
+
# Output plugin generating release notes in the semantic-release changelog format
|
|
8
6
|
class SemanticReleaseGenerateNotes < Output
|
|
9
|
-
|
|
10
7
|
# Process commits info
|
|
11
8
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
# * *commit* (Git::Object::Commit): Corresponding git commit
|
|
9
|
+
# @param commits_info [Array<Hash{Symbol => Object}>] List of commits info:
|
|
10
|
+
# - +:components_bump_levels+ [Hash\\{String or nil => Integer}] Set of bump levels (0: patch, 1: minor, 2: major) per component name (nil for global)
|
|
11
|
+
# - +:commit+ [Git::Object::Commit] Corresponding git commit
|
|
16
12
|
def process(commits_info)
|
|
17
13
|
# Compute new version
|
|
18
14
|
new_version = Semver.next_version_from(
|
|
19
15
|
Semver.version_from_git_ref(@local_git.git_from),
|
|
20
16
|
commits_info.map { |commit_info| commit_info[:components_bump_levels].values }.flatten(1).max
|
|
21
17
|
)
|
|
22
|
-
git_url = @local_git.git.remote
|
|
18
|
+
git_url = @local_git.git.remote_list.find { |remote| remote.name == 'origin' }.url.first
|
|
23
19
|
git_url = git_url[0..-5] if git_url.end_with?('.git')
|
|
24
|
-
# Reference merge commits: merged commits will not be part of the changelog,
|
|
20
|
+
# Reference merge commits: merged commits will not be part of the changelog,
|
|
21
|
+
# but their bump level will be taken into account when reporting the merge commit.
|
|
25
22
|
# List of merged commits' shas, per merge commit sha.
|
|
26
23
|
# Hash< String, Array< String > >
|
|
27
24
|
merge_commits = {}
|
|
@@ -29,10 +26,11 @@ module SemVerComponents
|
|
|
29
26
|
git_commit = commit_info[:commit]
|
|
30
27
|
git_commit_parents = git_commit.parents
|
|
31
28
|
# In the case of a merge commit, reference all commits that are part of this merge commit, directly from the graph
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
next unless git_commit_parents.size > 1
|
|
30
|
+
|
|
31
|
+
git_commit_sha = git_commit.sha
|
|
32
|
+
merge_commits[git_commit_sha] =
|
|
33
|
+
@local_git.git.log(nil).between(@local_git.git.merge_base(*git_commit_parents.map(&:sha)).first, git_commit_sha).execute[1..].map(&:sha)
|
|
36
34
|
end
|
|
37
35
|
commits_to_ignore = merge_commits.values.flatten(1).sort.uniq
|
|
38
36
|
# Group commits per bump level, per component
|
|
@@ -43,6 +41,7 @@ module SemVerComponents
|
|
|
43
41
|
git_commit_sha = git_commit.sha
|
|
44
42
|
# Don't put merged commits as we consider the changelog should contain the merge commit comment.
|
|
45
43
|
next if commits_to_ignore.include?(git_commit_sha)
|
|
44
|
+
|
|
46
45
|
components_bump_levels = commit_info[:components_bump_levels]
|
|
47
46
|
# If we are dealing with a merge commit, consider the components' bump levels of the merged commits
|
|
48
47
|
if merge_commits.key?(git_commit_sha)
|
|
@@ -51,10 +50,10 @@ module SemVerComponents
|
|
|
51
50
|
# If the merged commit is not part of the list of commits, it means that the merge commit was not rebased on the previous release tag.
|
|
52
51
|
# In this case we can have some merged commits that are already part of the previous release.
|
|
53
52
|
# So we can ignore them.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
next if merged_commit_info.nil?
|
|
54
|
+
|
|
55
|
+
components_bump_levels = components_bump_levels.merge(merged_commit_info[:components_bump_levels]) do |_component, bump_level1, bump_level2|
|
|
56
|
+
[bump_level1, bump_level2].max
|
|
58
57
|
end
|
|
59
58
|
end
|
|
60
59
|
end
|
|
@@ -90,7 +89,7 @@ module SemVerComponents
|
|
|
90
89
|
commit_line = message_lines.first
|
|
91
90
|
if commit_line =~ /^Merge pull request .+$/
|
|
92
91
|
# Consider the next line as commit line
|
|
93
|
-
next_line = message_lines[1
|
|
92
|
+
next_line = message_lines[1..].join("\n").strip.split("\n").first
|
|
94
93
|
commit_line = next_line unless next_line.nil?
|
|
95
94
|
end
|
|
96
95
|
commit_lines[commit_line] = commit.sha
|
|
@@ -102,9 +101,6 @@ module SemVerComponents
|
|
|
102
101
|
end
|
|
103
102
|
end
|
|
104
103
|
end
|
|
105
|
-
|
|
106
104
|
end
|
|
107
|
-
|
|
108
105
|
end
|
|
109
|
-
|
|
110
106
|
end
|
|
@@ -1,43 +1,36 @@
|
|
|
1
1
|
module SemVerComponents
|
|
2
|
-
|
|
2
|
+
# Loader of plugin classes available in the plugin directories
|
|
3
3
|
class Plugins
|
|
4
|
-
|
|
5
4
|
# Constructor
|
|
6
5
|
#
|
|
7
|
-
#
|
|
8
|
-
# * *plugins_type* (Symbol): Plugins type we are parsing
|
|
6
|
+
# @param plugins_type [Symbol] Plugins type we are parsing
|
|
9
7
|
def initialize(plugins_type)
|
|
10
8
|
@plugins_type = plugins_type
|
|
11
|
-
@plugins =
|
|
9
|
+
@plugins = Dir.glob("#{__dir__}/#{plugins_type}/*.rb").to_h do |plugin_file|
|
|
12
10
|
plugin_name = File.basename(plugin_file, '.rb').to_sym
|
|
13
11
|
require "#{__dir__}/#{plugins_type}/#{plugin_name}.rb"
|
|
14
12
|
[
|
|
15
13
|
plugin_name,
|
|
16
|
-
SemVerComponents
|
|
17
|
-
const_get(plugins_type.to_s.split('_').collect(&:capitalize).join.to_sym)
|
|
18
|
-
const_get(plugin_name.to_s.split('_').collect(&:capitalize).join.to_sym)
|
|
14
|
+
SemVerComponents
|
|
15
|
+
.const_get(plugins_type.to_s.split('_').collect(&:capitalize).join.to_sym)
|
|
16
|
+
.const_get(plugin_name.to_s.split('_').collect(&:capitalize).join.to_sym)
|
|
19
17
|
]
|
|
20
|
-
end
|
|
18
|
+
end
|
|
21
19
|
end
|
|
22
20
|
|
|
23
21
|
# List available plugin names
|
|
24
22
|
#
|
|
25
|
-
#
|
|
26
|
-
# * Array<Symbol>: Available plugin names
|
|
23
|
+
# @return [Array<Symbol>] Available plugin names
|
|
27
24
|
def list
|
|
28
25
|
@plugins.keys
|
|
29
26
|
end
|
|
30
27
|
|
|
31
28
|
# Get a plugin class
|
|
32
29
|
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
# Result::
|
|
36
|
-
# * Class: The corresponding plugin class
|
|
30
|
+
# @param plugin_name [Symbol] The plugin name
|
|
31
|
+
# @return [Class] The corresponding plugin class
|
|
37
32
|
def [](plugin_name)
|
|
38
33
|
@plugins[plugin_name]
|
|
39
34
|
end
|
|
40
|
-
|
|
41
35
|
end
|
|
42
|
-
|
|
43
36
|
end
|
|
@@ -1,66 +1,53 @@
|
|
|
1
1
|
module SemVerComponents
|
|
2
|
-
|
|
3
2
|
# Helpers giving ways to adapt to semantic versioning conventions
|
|
4
3
|
module Semver
|
|
5
|
-
|
|
6
4
|
# Compute next version from an existing one and a bump level
|
|
7
5
|
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# Result::
|
|
13
|
-
# * String: The next version
|
|
6
|
+
# @param version [String] Existing version
|
|
7
|
+
# @param bump_level [Integer] The bump level (0: patch, 1: minor, 2: major)
|
|
8
|
+
# @param pre_release [Boolean] Should we get a pre-release version (adding a unique metadata)?
|
|
9
|
+
# @return [String] The next version
|
|
14
10
|
def self.next_version_from(version, bump_level, pre_release: false)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
raise "Invalid bump level: #{bump_level}"
|
|
31
|
-
end
|
|
32
|
-
"#{major}.#{minor}.#{patch}#{pre_release ? "-#{pre_release_metadata}" : ''}"
|
|
11
|
+
raise "Invalid version: #{version}" unless version =~ /^(\d+)\.(\d+)\.(\d+)$/
|
|
12
|
+
|
|
13
|
+
major = Integer(::Regexp.last_match(1))
|
|
14
|
+
minor = Integer(::Regexp.last_match(2))
|
|
15
|
+
patch = Integer(::Regexp.last_match(3))
|
|
16
|
+
case bump_level
|
|
17
|
+
when 0
|
|
18
|
+
patch += 1
|
|
19
|
+
when 1
|
|
20
|
+
minor += 1
|
|
21
|
+
patch = 0
|
|
22
|
+
when 2
|
|
23
|
+
major += 1
|
|
24
|
+
minor = 0
|
|
25
|
+
patch = 0
|
|
33
26
|
else
|
|
34
|
-
raise "Invalid
|
|
27
|
+
raise "Invalid bump level: #{bump_level}"
|
|
35
28
|
end
|
|
29
|
+
"#{major}.#{minor}.#{patch}#{"-#{pre_release_metadata}" if pre_release}"
|
|
36
30
|
end
|
|
37
31
|
|
|
38
32
|
# Get a version from a git ref
|
|
39
33
|
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
# Result::
|
|
43
|
-
# * String: Corresponding version
|
|
34
|
+
# @param git_ref [String, nil] The git ref
|
|
35
|
+
# @return [String] Corresponding version
|
|
44
36
|
def self.version_from_git_ref(git_ref)
|
|
45
37
|
if git_ref.nil?
|
|
46
38
|
'0.0.0'
|
|
47
39
|
elsif git_ref =~ /^v(\d+\.\d+\.\d+)$/
|
|
48
|
-
|
|
40
|
+
::Regexp.last_match(1)
|
|
49
41
|
else
|
|
50
42
|
raise "Can't assume version from git ref: #{git_ref}"
|
|
51
43
|
end
|
|
52
44
|
end
|
|
53
45
|
|
|
54
|
-
private
|
|
55
|
-
|
|
56
46
|
# Get a pre-release metadata to be appended to a version
|
|
57
47
|
#
|
|
58
|
-
#
|
|
59
|
-
# * String: The pre-release metadata
|
|
48
|
+
# @return [String] The pre-release metadata
|
|
60
49
|
def self.pre_release_metadata
|
|
61
50
|
"#{`whoami`.strip}-#{Time.now.utc.strftime('%Y%m%d%H%M%S')}-SNAPSHOT"
|
|
62
51
|
end
|
|
63
|
-
|
|
64
52
|
end
|
|
65
|
-
|
|
66
53
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sem_ver_components
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Muriel Salvan
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: git
|
|
@@ -15,14 +15,28 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '4
|
|
18
|
+
version: '5.4'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '4
|
|
25
|
+
version: '5.4'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: zeitwerk
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.8'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2.8'
|
|
26
40
|
description: Tools helping in maintaining semantic versioning at a components level
|
|
27
41
|
instead of a global package-only level.
|
|
28
42
|
email:
|
|
@@ -33,6 +47,7 @@ extensions: []
|
|
|
33
47
|
extra_rdoc_files: []
|
|
34
48
|
files:
|
|
35
49
|
- bin/sem_ver_git
|
|
50
|
+
- lib/sem_ver_components.rb
|
|
36
51
|
- lib/sem_ver_components/git_hosting.rb
|
|
37
52
|
- lib/sem_ver_components/git_hostings/bitbucket.rb
|
|
38
53
|
- lib/sem_ver_components/git_hostings/github.rb
|
|
@@ -47,7 +62,8 @@ files:
|
|
|
47
62
|
homepage: https://github.com/Muriel-Salvan/sem_ver_components
|
|
48
63
|
licenses:
|
|
49
64
|
- BSD-3-Clause
|
|
50
|
-
metadata:
|
|
65
|
+
metadata:
|
|
66
|
+
rubygems_mfa_required: 'true'
|
|
51
67
|
rdoc_options: []
|
|
52
68
|
require_paths:
|
|
53
69
|
- lib
|
|
@@ -55,7 +71,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
55
71
|
requirements:
|
|
56
72
|
- - ">="
|
|
57
73
|
- !ruby/object:Gem::Version
|
|
58
|
-
version: '
|
|
74
|
+
version: '3.1'
|
|
59
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
76
|
requirements:
|
|
61
77
|
- - ">="
|