git_toolbox 0.8.0 → 0.9.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/lib/get/commons/git.rb +11 -1
- data/lib/get/subcommand/complete/bash_completion.rb +5 -0
- data/lib/get/subcommand/complete/complete.rb +22 -6
- data/lib/get/subcommand/describe/change.rb +23 -4
- data/lib/get/subcommand/describe/describe.rb +3 -47
- data/lib/get/subcommand/describe/prerelease.rb +28 -9
- data/lib/get/subcommand/init/init.rb +1 -1
- data/lib/get/subcommand/tree/tree.rb +13 -6
- data/lib/get/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d18e02ebf90eb2595af4735f88043d1fdea653a03d8500dec75a7cf9a510bc51
|
4
|
+
data.tar.gz: c0344b2969623ab61aa94c6960fa88bdad522057541ece00052bfdf9f4cbf636
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9cbe2abd8b068d78436841419dddd776f72e97b57a5575f8447ae31e7744d8a7e54de9eaa55a242ff0c177b52a1f81b74309b044970c12ccaf98f4dc7d431d4
|
7
|
+
data.tar.gz: 9248e4bcce0371b73542e336591bc6844ac8a66f6d93334702fa0e7fbb2b13556c6d914682d9e8f62e964f5eb8aee6462bd4ebe739c4881effe69241c141ca1a
|
data/lib/get/commons/git.rb
CHANGED
@@ -23,6 +23,15 @@ require_relative './command_issuer'
|
|
23
23
|
module Git
|
24
24
|
# Groups: 1 = type, 2 = scope with (), 3 = scope, 4 = breaking change, 5 = summary
|
25
25
|
CONVENTIONAL_COMMIT_REGEX = %r{^(\w+)(\(([\w/-]+)\))?(!)?:(.*)}
|
26
|
+
DEFAULT_RELEASE_VERSION = '0.1.0'
|
27
|
+
# Groups:
|
28
|
+
# 1 = full stable version ; 2,3,4 = major,minor,patch
|
29
|
+
# 5 = prerelease ; 6 = metadata
|
30
|
+
FULL_SEMANTIC_VERSION_REGEX = /
|
31
|
+
^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)) # Stable version, major, minor, patch
|
32
|
+
(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))? # prerelease
|
33
|
+
(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ # metadata
|
34
|
+
/x
|
26
35
|
|
27
36
|
# Check if the command is called while in a git repository.
|
28
37
|
# If the command fails, it is assumed to not be in a git repository.
|
@@ -61,11 +70,12 @@ module Git
|
|
61
70
|
# Returns the last release and caches it for the next calls.
|
62
71
|
def self.last_release
|
63
72
|
@last_release ||=
|
64
|
-
CommandIssuer.run('git', '--no-pager', 'tag', '--list')
|
73
|
+
CommandIssuer.run('git', '--no-pager', 'tag', '--list', '--merged')
|
65
74
|
.then do |value|
|
66
75
|
unless value.output.empty?
|
67
76
|
value.output
|
68
77
|
.split("\n")
|
78
|
+
.select { |str| str.match(FULL_SEMANTIC_VERSION_REGEX)[5].nil? }
|
69
79
|
.map { |str| str.sub('+', '_') }
|
70
80
|
.sort
|
71
81
|
.map { |str| str.sub('_', '+') }
|
@@ -28,6 +28,10 @@ module BashCompletion
|
|
28
28
|
private
|
29
29
|
|
30
30
|
INITIAL_LEVEL = 1
|
31
|
+
NOT_NEGABLE_OPTIONS = [
|
32
|
+
'help',
|
33
|
+
'version',
|
34
|
+
].freeze
|
31
35
|
|
32
36
|
HEADER = <<~HEADER
|
33
37
|
#!/usr/bin/env bash
|
@@ -77,6 +81,7 @@ module BashCompletion
|
|
77
81
|
|
78
82
|
command_class.instance.option_parser.specs.each_value do |option|
|
79
83
|
long_options.push("--#{option.long}")
|
84
|
+
long_options.push("--no-#{option.long}") if option.flag? && !NOT_NEGABLE_OPTIONS.include?(option.long)
|
80
85
|
short_options.push("-#{option.short.nil? ? option.long[0] : option.short}") if option.short != :none
|
81
86
|
end
|
82
87
|
|
@@ -33,8 +33,18 @@ class Complete < Command
|
|
33
33
|
def initialize
|
34
34
|
super() do
|
35
35
|
@usage = 'complete -h|(<subcommand> [<subcommand-options])'
|
36
|
-
@description = 'Print the shell completion script.'
|
36
|
+
@description = 'Print the shell completion script. ' \
|
37
|
+
'Run \'get complete --info\' to learn how to install the completion.'
|
37
38
|
@subcommands = {}
|
39
|
+
@completions = {
|
40
|
+
bash: {
|
41
|
+
generator: proc { bash_completion(Get, 'get') },
|
42
|
+
info: <<~INFO
|
43
|
+
Add the following line to your .bashrc (or a sourced script):
|
44
|
+
eval "$(get complete)" && complete -F _get_completion get
|
45
|
+
INFO
|
46
|
+
}
|
47
|
+
}
|
38
48
|
end
|
39
49
|
end
|
40
50
|
|
@@ -51,6 +61,9 @@ class Complete < Command
|
|
51
61
|
opt :shell,
|
52
62
|
'Select the type of shell of which the completion will be generated.',
|
53
63
|
{ type: :string, default: 'bash' }
|
64
|
+
opt :info,
|
65
|
+
'Print the instructions to install the completion for the selected shell.',
|
66
|
+
{ short: :none }
|
54
67
|
educate_on_error
|
55
68
|
stop_on stop_condition
|
56
69
|
end
|
@@ -62,16 +75,19 @@ class Complete < Command
|
|
62
75
|
@option_parser.parse
|
63
76
|
end
|
64
77
|
|
65
|
-
@completions = {
|
66
|
-
bash: proc { bash_completion(Get, 'get') }
|
67
|
-
}
|
68
|
-
|
69
78
|
selected_shell = @options[:shell].to_sym
|
70
79
|
|
80
|
+
print_info_and_exit(selected_shell) if @options[:info]
|
81
|
+
|
71
82
|
Common.error "Completion for shell '#{selected_shell}' not available." unless @completions.key?(selected_shell)
|
72
83
|
|
73
|
-
puts @completions[selected_shell].call
|
84
|
+
puts @completions[selected_shell][:generator].call
|
74
85
|
end
|
75
86
|
end
|
87
|
+
|
88
|
+
def print_info_and_exit(selected_shell)
|
89
|
+
puts @completions[selected_shell][:info]
|
90
|
+
exit 0
|
91
|
+
end
|
76
92
|
end
|
77
93
|
# rubocop:enable Metrics/ClassLength
|
@@ -30,6 +30,27 @@ module ChangeHandler
|
|
30
30
|
Common.module_instance_attr(self, 'minor_trigger', :DEFAULT_MINOR_TRIGGER)
|
31
31
|
Common.module_instance_attr(self, 'patch_trigger', :DEFAULT_PATCH_TRIGGER)
|
32
32
|
|
33
|
+
def updated_stable_version(stable_version)
|
34
|
+
return Git::DEFAULT_RELEASE_VERSION if stable_version.nil?
|
35
|
+
|
36
|
+
greatest_change_from_stable_version = Git.with_commit_list_from(stable_version) do |commits_from_version|
|
37
|
+
greatest_change_in(commits_from_version)
|
38
|
+
end
|
39
|
+
split_version = stable_version.split('.')
|
40
|
+
case greatest_change_from_stable_version
|
41
|
+
when :MAJOR
|
42
|
+
"#{split_version[0].to_i + 1}.0.0"
|
43
|
+
when :MINOR
|
44
|
+
"#{split_version[0].to_i}.#{split_version[1].to_i + 1}.0"
|
45
|
+
when :PATCH
|
46
|
+
"#{split_version[0].to_i}.#{split_version[1].to_i}.#{split_version[2].to_i + 1}"
|
47
|
+
else
|
48
|
+
"#{split_version[0].to_i}.#{split_version[1].to_i}.#{split_version[2].to_i}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
33
54
|
def greatest_change_in(commit_list)
|
34
55
|
commit_list
|
35
56
|
.grep(Git::CONVENTIONAL_COMMIT_REGEX)
|
@@ -37,8 +58,6 @@ module ChangeHandler
|
|
37
58
|
.max { |a, b| CHANGE_TYPE.index(a) <=> CHANGE_TYPE.index(b) }
|
38
59
|
end
|
39
60
|
|
40
|
-
private
|
41
|
-
|
42
61
|
# In this block method arguments can be used by user.
|
43
62
|
# Also `eval` is needed to allow users to define their custom triggers.
|
44
63
|
# rubocop:disable Lint/UnusedMethodArgument
|
@@ -61,8 +80,8 @@ module ChangeHandler
|
|
61
80
|
def to_change(commit_message)
|
62
81
|
groups = Git::CONVENTIONAL_COMMIT_REGEX.match(commit_message)
|
63
82
|
return :MAJOR if triggers_major?(groups[1], groups[3], !groups[4].nil?)
|
64
|
-
return :MINOR if triggers_minor?(groups[1], groups[
|
65
|
-
return :PATCH if triggers_patch?(groups[1], groups[
|
83
|
+
return :MINOR if triggers_minor?(groups[1], groups[3])
|
84
|
+
return :PATCH if triggers_patch?(groups[1], groups[3])
|
66
85
|
|
67
86
|
:NONE
|
68
87
|
end
|
@@ -38,13 +38,6 @@ class Describe < Command
|
|
38
38
|
include PrereleaseHandler
|
39
39
|
include MetadataHandler
|
40
40
|
|
41
|
-
DEFAULT_RELEASE_VERSION = '0.1.0'
|
42
|
-
FULL_SEMANTIC_VERSION_REGEX = /
|
43
|
-
^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)) # Stable version, major, minor, patch
|
44
|
-
(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))? # prerelease
|
45
|
-
(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ # metadata
|
46
|
-
/x
|
47
|
-
|
48
41
|
def initialize
|
49
42
|
super() do
|
50
43
|
@usage = 'describe -h|(<subcommand> [<subcommand-options])'
|
@@ -84,50 +77,13 @@ class Describe < Command
|
|
84
77
|
|
85
78
|
def next_release
|
86
79
|
if @options[:prerelease]
|
87
|
-
|
80
|
+
updated_stable_version(Git.last_release)
|
81
|
+
.then { |stable| "#{stable}-#{updated_prerelease(Git.last_version, stable)}" }
|
88
82
|
else
|
89
|
-
|
83
|
+
updated_stable_version(Git.last_release).to_s
|
90
84
|
end + metadata
|
91
85
|
end
|
92
86
|
|
93
|
-
def prepare_release_tag(last_release)
|
94
|
-
updated_stable_version(last_release).to_s
|
95
|
-
end
|
96
|
-
|
97
|
-
def prepare_prerelease_tag(last_release, last_version)
|
98
|
-
new_stable_version = updated_stable_version(last_release)
|
99
|
-
base_version_match_data = FULL_SEMANTIC_VERSION_REGEX.match(last_version)
|
100
|
-
no_changes_from_last_release = base_version_match_data[1] == new_stable_version && base_version_match_data[5].nil?
|
101
|
-
Common.error 'No changes from last release' if no_changes_from_last_release
|
102
|
-
new_stable_version +
|
103
|
-
"-#{updated_prerelease(base_version_match_data[5], need_reset: base_version_match_data[1] != new_stable_version)}"
|
104
|
-
end
|
105
|
-
|
106
|
-
def updated_stable_version(stable_version)
|
107
|
-
return DEFAULT_RELEASE_VERSION if stable_version.nil?
|
108
|
-
|
109
|
-
greatest_change_from_stable_version = Git.with_commit_list_from(stable_version) do |commits_from_version|
|
110
|
-
greatest_change_in(commits_from_version)
|
111
|
-
end
|
112
|
-
split_version = stable_version.split('.')
|
113
|
-
case greatest_change_from_stable_version
|
114
|
-
when :MAJOR
|
115
|
-
"#{split_version[0].to_i + 1}.0.0"
|
116
|
-
when :MINOR
|
117
|
-
"#{split_version[0].to_i}.#{split_version[1].to_i + 1}.0"
|
118
|
-
when :PATCH
|
119
|
-
"#{split_version[0].to_i}.#{split_version[1].to_i}.#{split_version[2].to_i + 1}"
|
120
|
-
else
|
121
|
-
"#{split_version[0].to_i}.#{split_version[1].to_i}.#{split_version[2].to_i}"
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
# Return the updated prerelease number
|
126
|
-
def updated_prerelease(prerelease = nil, need_reset: false)
|
127
|
-
compute_prerelease(prerelease, need_reset: prerelease.nil? || need_reset)
|
128
|
-
end
|
129
|
-
|
130
|
-
# Compute the metadata string
|
131
87
|
def metadata
|
132
88
|
return '' if @options[:exclude_metadata] || @options[:metadata].empty?
|
133
89
|
|
@@ -27,20 +27,31 @@ module PrereleaseHandler
|
|
27
27
|
Common.module_instance_attr(self, 'prerelease_pattern', :DEFAULT_PRERELEASE_PATTERN)
|
28
28
|
Common.module_instance_attr(self, 'old_prerelease_pattern', 'proc { prerelease_pattern }')
|
29
29
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
30
|
+
def updated_prerelease(last_version, new_stable_version)
|
31
|
+
if last_version.nil?
|
32
|
+
compute_prerelease(nil, need_reset: true)
|
33
|
+
else
|
34
|
+
base_version_match_data = Git::FULL_SEMANTIC_VERSION_REGEX.match(last_version)
|
35
|
+
no_changes_from_last_release = base_version_match_data[1] == new_stable_version &&
|
36
|
+
base_version_match_data[5].nil?
|
37
|
+
Common.error 'No changes from last release' if no_changes_from_last_release
|
38
|
+
compute_prerelease(base_version_match_data[5], need_reset: base_version_match_data[1] != new_stable_version)
|
39
|
+
end
|
33
40
|
end
|
34
41
|
|
35
42
|
private
|
36
43
|
|
44
|
+
def compute_prerelease(current_prerelease, need_reset: false)
|
45
|
+
pattern_changed = PrereleaseHandler.prerelease_pattern != actual_old_prerelease_pattern
|
46
|
+
new_prerelease = if need_reset || pattern_changed
|
47
|
+
FIRST_PRERELEASE
|
48
|
+
else
|
49
|
+
extract_prerelease_number(current_prerelease) + 1
|
50
|
+
end.to_s
|
51
|
+
PrereleaseHandler.prerelease_pattern.sub(PRERELEASE_PLACEHOLDER, new_prerelease)
|
52
|
+
end
|
53
|
+
|
37
54
|
def extract_prerelease_number(current_prerelease)
|
38
|
-
actual_old_prerelease_pattern =
|
39
|
-
if PrereleaseHandler.old_prerelease_pattern.respond_to?('call')
|
40
|
-
PrereleaseHandler.old_prerelease_pattern.call
|
41
|
-
else
|
42
|
-
PrereleaseHandler.old_prerelease_pattern
|
43
|
-
end
|
44
55
|
Common.error "The given old pattern does not contains the placeholder '(p)'" unless
|
45
56
|
actual_old_prerelease_pattern.include?(PRERELEASE_PLACEHOLDER)
|
46
57
|
old_prerelease_regex = actual_old_prerelease_pattern.sub(PRERELEASE_PLACEHOLDER, '(\\d+)')
|
@@ -51,4 +62,12 @@ module PrereleaseHandler
|
|
51
62
|
"does not match the analyzed prerelease: '#{current_prerelease}'."
|
52
63
|
end
|
53
64
|
end
|
65
|
+
|
66
|
+
def actual_old_prerelease_pattern
|
67
|
+
if PrereleaseHandler.old_prerelease_pattern.respond_to?('call')
|
68
|
+
PrereleaseHandler.old_prerelease_pattern.call
|
69
|
+
else
|
70
|
+
PrereleaseHandler.old_prerelease_pattern
|
71
|
+
end
|
72
|
+
end
|
54
73
|
end
|
@@ -47,7 +47,7 @@ class Init < Command
|
|
47
47
|
|
48
48
|
def create_first_commit
|
49
49
|
command_result = CommandIssuer.run('git', 'commit', '--allow-empty', '-m', '"chore: initialize repository"')
|
50
|
-
Common.error
|
50
|
+
Common.error "Failed to create first commit: #{command_result.error}" if command_result.exit_status.positive?
|
51
51
|
end
|
52
52
|
|
53
53
|
protected
|
@@ -70,21 +70,18 @@ class Tree < Command
|
|
70
70
|
# calc color escape codes length
|
71
71
|
time_color_length = first_line_time.length - first_line_time.match(TIME_REGEX)[1].length
|
72
72
|
|
73
|
-
|
74
|
-
time_padding = 0
|
75
|
-
split_lines.each { |element| time_padding = [time_padding, element[1].length - time_color_length].max }
|
73
|
+
time_padding = global_fitting_time_padding(split_lines, time_color_length)
|
76
74
|
|
77
|
-
# format strings
|
78
75
|
split_lines
|
79
76
|
.map do |element|
|
80
77
|
# Only lines with the date reference have the color escape codes,
|
81
78
|
# the other lines do not need the additional padding
|
82
79
|
left_padding = TIME_MINIMUM_PADDING + time_padding +
|
83
|
-
|
80
|
+
(!element[1].nil? && element[1].match?(TIME_REGEX) ? time_color_length : 0)
|
84
81
|
format(
|
85
82
|
'%<date>s %<tree_mark>s %<pointers>s %<commit_text>s',
|
86
83
|
{
|
87
|
-
date: element[1].rjust(left_padding),
|
84
|
+
date: (element[1].nil? ? '' : element[1]).rjust(left_padding),
|
88
85
|
tree_mark: element[0],
|
89
86
|
pointers: element[2],
|
90
87
|
commit_text: element[3]
|
@@ -95,6 +92,16 @@ class Tree < Command
|
|
95
92
|
end
|
96
93
|
# rubocop:enable Metrics/MethodLength
|
97
94
|
|
95
|
+
def global_fitting_time_padding(lines, time_color_length)
|
96
|
+
time_padding = 0
|
97
|
+
lines
|
98
|
+
# If element[1].nil? then the line refers to a intersection between branch lines
|
99
|
+
# they do not have a time reference
|
100
|
+
.reject { |element| element[1].nil? }
|
101
|
+
.each { |element| time_padding = [time_padding, element[1].length - time_color_length].max }
|
102
|
+
time_padding
|
103
|
+
end
|
104
|
+
|
98
105
|
protected
|
99
106
|
|
100
107
|
def setup_option_parser
|
data/lib/get/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git_toolbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Speranza
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|
@@ -96,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
96
|
requirements:
|
97
97
|
- - ">="
|
98
98
|
- !ruby/object:Gem::Version
|
99
|
-
version: 3.
|
99
|
+
version: 3.0.0
|
100
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
102
|
- - ">="
|