git_toolbox 0.7.2 → 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/bin/get +1 -1
- data/lib/get/commons/command_issuer.rb +60 -0
- data/lib/get/commons/common.rb +70 -0
- data/lib/get/commons/git.rb +41 -21
- data/lib/get/commons/http_client.rb +79 -0
- data/lib/get/subcommand/changelog/changelog.rb +55 -60
- data/lib/get/subcommand/command.rb +58 -6
- data/lib/get/subcommand/commit/commit.rb +58 -61
- data/lib/get/subcommand/commit/prompt.rb +25 -23
- data/lib/get/subcommand/complete/bash_completion.rb +12 -6
- data/lib/get/subcommand/complete/complete.rb +53 -42
- data/lib/get/subcommand/describe/change.rb +44 -27
- data/lib/get/subcommand/describe/describe.rb +103 -155
- data/lib/get/subcommand/describe/docker/docker.rb +55 -58
- data/lib/get/subcommand/describe/metadata.rb +16 -19
- data/lib/get/subcommand/describe/prerelease.rb +32 -14
- data/lib/get/subcommand/init/init.rb +43 -44
- data/lib/get/subcommand/license/license.rb +78 -56
- data/lib/get/subcommand/license/license_retriever.rb +38 -23
- data/lib/get/subcommand/tree/tree.rb +57 -48
- data/lib/get/version.rb +1 -3
- data/lib/get.rb +47 -34
- metadata +17 -15
@@ -17,24 +17,20 @@
|
|
17
17
|
|
18
18
|
# frozen_string_literal: true
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
require_relative '../../commons/common'
|
21
|
+
require_relative '../../commons/git'
|
22
|
+
require_relative '../command'
|
23
|
+
require_relative './change'
|
24
|
+
require_relative './prerelease'
|
25
|
+
require_relative './metadata'
|
26
|
+
require_relative './docker/docker'
|
27
27
|
|
28
28
|
# Class length is disabled as most of its length is given by formatting.
|
29
29
|
# rubocop:disable Metrics/ClassLength
|
30
30
|
# Subcommand, it manages the description of the current git repository using semantic version.
|
31
|
+
# All its subcommands should have a method named "describe_current_commit" as it will be called.
|
31
32
|
class Describe < Command
|
32
|
-
|
33
|
-
@@command ||= new
|
34
|
-
@@command
|
35
|
-
end
|
36
|
-
|
37
|
-
private_class_method :new
|
33
|
+
include Singleton
|
38
34
|
|
39
35
|
private
|
40
36
|
|
@@ -42,105 +38,24 @@ class Describe < Command
|
|
42
38
|
include PrereleaseHandler
|
43
39
|
include MetadataHandler
|
44
40
|
|
45
|
-
@@command = nil
|
46
|
-
|
47
|
-
DEFAULT_RELEASE_VERSION = '0.1.0'
|
48
|
-
FULL_SEMANTIC_VERSION_REGEX = /
|
49
|
-
^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)) # Stable version, major, minor, patch
|
50
|
-
(?:-((?: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
|
51
|
-
(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ # metadata
|
52
|
-
/x
|
53
|
-
|
54
|
-
@@usage = 'describe -h|(<subcommand> [<subcommand-options])'
|
55
|
-
@@description = 'Describe the current git repository with semantic version.'
|
56
|
-
@@subcommands = {
|
57
|
-
docker: DescribeDocker.command,
|
58
|
-
}
|
59
|
-
# This block is Optimist configuration. It is as long as the number of options of the command.
|
60
|
-
# rubocop:disable Metrics/BlockLength
|
61
|
-
@@option_parser = Optimist::Parser.new do
|
62
|
-
subcommand_max_length = @@subcommands.keys.map { |k| k.to_s.length }.max
|
63
|
-
subcommand_section = <<~SUBCOMMANDS unless @@subcommands.empty?
|
64
|
-
Subcommands:
|
65
|
-
#{@@subcommands.keys.map { |k| " #{k.to_s.ljust(subcommand_max_length)} => #{@@subcommands[k].description}" }.join("\n")}
|
66
|
-
SUBCOMMANDS
|
67
|
-
usage @@usage
|
68
|
-
synopsis @@description + (subcommand_section.nil? ? '' : "\n") + subcommand_section.to_s
|
69
|
-
opt :prerelease,
|
70
|
-
'Describe a prerelease rather than a release',
|
71
|
-
short: :none
|
72
|
-
opt :exclude_metadata,
|
73
|
-
'Do not include metadata in version.'
|
74
|
-
opt :metadata,
|
75
|
-
'Set which metadata to include in the string. ' \
|
76
|
-
'Multiple value can be specified by separating the with a comma \',\'.',
|
77
|
-
{ type: :string, default: 'sha' }
|
78
|
-
opt :major_trigger,
|
79
|
-
'Set the trigger for a major release. ' \
|
80
|
-
'This must be a valid Ruby expression. ' \
|
81
|
-
'In this expression the string values "type" and "scope" ' \
|
82
|
-
'and the boolean value "is_breaking" can be used.',
|
83
|
-
{ short: :none, type: :string, default: 'is_breaking' }
|
84
|
-
opt :minor_trigger,
|
85
|
-
'Set the trigger for a minor release. ' \
|
86
|
-
'This must be a valid Ruby expression. ' \
|
87
|
-
'In this expression the string values "type" and "scope" can be used.',
|
88
|
-
{ short: :none, type: :string, default: "type == 'feat'" }
|
89
|
-
opt :patch_trigger,
|
90
|
-
'Set the trigger for a patch release. ' \
|
91
|
-
'This must be a valid Ruby expression. ' \
|
92
|
-
'In this expression the string values "type" and "scope" can be used.',
|
93
|
-
{ short: :none, type: :string, default: "type == 'fix'" }
|
94
|
-
opt :prerelease_pattern,
|
95
|
-
'Set the pattern of the prerelease. This must contain the placeholder "(p)".',
|
96
|
-
{ short: :none, type: :string, default: 'dev(p)' }
|
97
|
-
opt :old_prerelease_pattern,
|
98
|
-
'Set the pattern of the old prerelease. It is useful for changing prerelease pattern.',
|
99
|
-
{ short: :none, type: :string, default: 'prerelease-pattern value' }
|
100
|
-
opt :diff,
|
101
|
-
'Print also the last version.'
|
102
|
-
opt :create_tag,
|
103
|
-
'Create a signed tag with the computed version.',
|
104
|
-
{ short: :none }
|
105
|
-
opt :tag_message,
|
106
|
-
'Add the given message to the tag. Requires "--create-tag".',
|
107
|
-
{ short: :none, type: :string }
|
108
|
-
educate_on_error
|
109
|
-
stop_on @@subcommands.keys.map(&:to_s)
|
110
|
-
end
|
111
|
-
# rubocop:enable Metrics/BlockLength
|
112
|
-
|
113
41
|
def initialize
|
114
|
-
super(
|
115
|
-
@
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
if ARGV.length.positive?
|
122
|
-
subcommand = ARGV.shift.to_sym
|
123
|
-
if @@subcommands.include?(subcommand)
|
124
|
-
@@subcommands[subcommand].action.call(describe_current_commit)
|
125
|
-
else
|
126
|
-
# This error should not be disabled by -W0
|
127
|
-
# rubocop:disable Style/StderrPuts
|
128
|
-
$stderr.puts "Error: subcommand '#{subcommand}' unknown."
|
129
|
-
# rubocop:enable Style/StderrPuts
|
130
|
-
exit 1
|
131
|
-
end
|
132
|
-
else
|
133
|
-
puts describe_current_commit
|
134
|
-
end
|
42
|
+
super() do
|
43
|
+
@usage = 'describe -h|(<subcommand> [<subcommand-options])'
|
44
|
+
@description = 'Describe the current git repository with semantic version.'
|
45
|
+
@subcommands = {
|
46
|
+
docker: DescribeDocker.instance,
|
47
|
+
}
|
135
48
|
end
|
136
49
|
end
|
137
50
|
|
138
51
|
def set_options
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
52
|
+
ChangeHandler.major_trigger = @options[:major_trigger] if @options[:major_trigger_given]
|
53
|
+
ChangeHandler.minor_trigger = @options[:minor_trigger] if @options[:minor_trigger_given]
|
54
|
+
ChangeHandler.patch_trigger = @options[:patch_trigger] if @options[:patch_trigger_given]
|
55
|
+
if @options[:old_prerelease_pattern_given]
|
56
|
+
PrereleaseHandler.old_prerelease_pattern = @options[:old_prerelease_pattern]
|
57
|
+
end
|
58
|
+
PrereleaseHandler.prerelease_pattern = @options[:prerelease_pattern] if @options[:prerelease_pattern_given]
|
144
59
|
end
|
145
60
|
|
146
61
|
def describe_current_commit
|
@@ -162,68 +77,101 @@ class Describe < Command
|
|
162
77
|
|
163
78
|
def next_release
|
164
79
|
if @options[:prerelease]
|
165
|
-
|
80
|
+
updated_stable_version(Git.last_release)
|
81
|
+
.then { |stable| "#{stable}-#{updated_prerelease(Git.last_version, stable)}" }
|
166
82
|
else
|
167
|
-
|
83
|
+
updated_stable_version(Git.last_release).to_s
|
168
84
|
end + metadata
|
169
85
|
end
|
170
86
|
|
171
|
-
def
|
172
|
-
|
173
|
-
end
|
87
|
+
def metadata
|
88
|
+
return '' if @options[:exclude_metadata] || @options[:metadata].empty?
|
174
89
|
|
175
|
-
|
176
|
-
new_stable_version = updated_stable_version(last_release)
|
177
|
-
base_version_match_data = FULL_SEMANTIC_VERSION_REGEX.match(last_version)
|
178
|
-
no_changes_from_last_release = base_version_match_data[1] == new_stable_version && base_version_match_data[5].nil?
|
179
|
-
Common.error 'No changes from last release' if no_changes_from_last_release
|
180
|
-
new_stable_version +
|
181
|
-
"-#{updated_prerelease(base_version_match_data[5], need_reset: base_version_match_data[1] != new_stable_version)}"
|
90
|
+
"+#{compute_metadata(@options[:metadata])}"
|
182
91
|
end
|
183
92
|
|
184
|
-
def
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
case greatest_change_from_stable_version
|
192
|
-
when :MAJOR
|
193
|
-
"#{split_version[0].to_i + 1}.0.0"
|
194
|
-
when :MINOR
|
195
|
-
"#{split_version[0].to_i}.#{split_version[1].to_i + 1}.0"
|
196
|
-
when :PATCH
|
197
|
-
"#{split_version[0].to_i}.#{split_version[1].to_i}.#{split_version[2].to_i + 1}"
|
198
|
-
else
|
199
|
-
"#{split_version[0].to_i}.#{split_version[1].to_i}.#{split_version[2].to_i}"
|
200
|
-
end
|
93
|
+
def create_signed_tag(computed_version)
|
94
|
+
tag_message_cli = if @options[:tag_message_given]
|
95
|
+
"\"#{@options[:tag_message].gsub('"', '\"')}\""
|
96
|
+
else
|
97
|
+
'""'
|
98
|
+
end
|
99
|
+
CommandIssuer.run('git', 'tag', '-s', '-m', tag_message_cli, "'#{computed_version}'")
|
201
100
|
end
|
202
101
|
|
203
|
-
|
204
|
-
|
205
|
-
|
102
|
+
protected
|
103
|
+
|
104
|
+
def setup_option_parser
|
105
|
+
@option_parser = Optimist::Parser.new(
|
106
|
+
@usage,
|
107
|
+
full_description,
|
108
|
+
stop_condition
|
109
|
+
) do |usage_header, description, stop_condition|
|
110
|
+
usage usage_header
|
111
|
+
synopsis description
|
112
|
+
opt :prerelease,
|
113
|
+
'Describe a prerelease rather than a release',
|
114
|
+
short: :none
|
115
|
+
opt :exclude_metadata,
|
116
|
+
'Do not include metadata in version.'
|
117
|
+
opt :metadata,
|
118
|
+
'Set which metadata to include in the string. ' \
|
119
|
+
'Multiple value can be specified by separating the with a comma \',\'.',
|
120
|
+
{ type: :string, default: 'sha' }
|
121
|
+
opt :major_trigger,
|
122
|
+
'Set the trigger for a major release. ' \
|
123
|
+
'This must be a valid Ruby expression. ' \
|
124
|
+
'In this expression the string values "type" and "scope" ' \
|
125
|
+
'and the boolean value "is_breaking" can be used.',
|
126
|
+
{ short: :none, type: :string, default: 'is_breaking' }
|
127
|
+
opt :minor_trigger,
|
128
|
+
'Set the trigger for a minor release. ' \
|
129
|
+
'This must be a valid Ruby expression. ' \
|
130
|
+
'In this expression the string values "type" and "scope" can be used.',
|
131
|
+
{ short: :none, type: :string, default: "type == 'feat'" }
|
132
|
+
opt :patch_trigger,
|
133
|
+
'Set the trigger for a patch release. ' \
|
134
|
+
'This must be a valid Ruby expression. ' \
|
135
|
+
'In this expression the string values "type" and "scope" can be used.',
|
136
|
+
{ short: :none, type: :string, default: "type == 'fix'" }
|
137
|
+
opt :prerelease_pattern,
|
138
|
+
'Set the pattern of the prerelease. This must contain the placeholder "(p)".',
|
139
|
+
{ short: :none, type: :string, default: 'dev(p)' }
|
140
|
+
opt :old_prerelease_pattern,
|
141
|
+
'Set the pattern of the old prerelease. It is useful for changing prerelease pattern.',
|
142
|
+
{ short: :none, type: :string, default: 'prerelease-pattern value' }
|
143
|
+
opt :diff,
|
144
|
+
'Print also the last version.'
|
145
|
+
opt :create_tag,
|
146
|
+
'Create a signed tag with the computed version.',
|
147
|
+
{ short: :none }
|
148
|
+
opt :tag_message,
|
149
|
+
'Add the given message to the tag. Requires "--create-tag".',
|
150
|
+
{ short: :none, type: :string }
|
151
|
+
educate_on_error
|
152
|
+
stop_on stop_condition
|
153
|
+
end
|
206
154
|
end
|
207
155
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
156
|
+
def setup_action
|
157
|
+
@action = lambda do
|
158
|
+
@options = Common.with_subcommand_exception_handling @option_parser do
|
159
|
+
@option_parser.parse
|
160
|
+
end
|
161
|
+
Common.error 'describe need to be run inside a git repository' unless Git.in_repo?
|
162
|
+
set_options
|
214
163
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
if @options[:tag_message_given]
|
220
|
-
"-m #{@options[:tag_message]}"
|
164
|
+
if ARGV.length.positive?
|
165
|
+
subcommand = ARGV.shift.to_sym
|
166
|
+
if @subcommands.include?(subcommand)
|
167
|
+
@subcommands[subcommand].action.call(describe_current_commit)
|
221
168
|
else
|
222
|
-
''
|
169
|
+
Common.error "subcommand '#{subcommand}' unknown."
|
223
170
|
end
|
224
|
-
|
225
|
-
|
226
|
-
|
171
|
+
else
|
172
|
+
puts describe_current_commit
|
173
|
+
end
|
174
|
+
end
|
227
175
|
end
|
228
176
|
end
|
229
177
|
# rubocop:enable Metrics/ClassLength
|
@@ -17,82 +17,43 @@
|
|
17
17
|
|
18
18
|
# frozen_string_literal: true
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
require_relative '../../../commons/common'
|
21
|
+
require_relative '../../../commons/git'
|
22
|
+
require_relative '../../command'
|
23
23
|
|
24
24
|
# Class length is disabled as most of its length is given by formatting.
|
25
25
|
# rubocop:disable Metrics/ClassLength
|
26
26
|
# Subcommand, it manages the description of the current git repository using semantic version.
|
27
27
|
class DescribeDocker < Command
|
28
|
-
def self.command
|
29
|
-
@@command ||= new
|
30
|
-
@@command
|
31
|
-
end
|
32
|
-
|
33
|
-
private_class_method :new
|
34
|
-
|
35
28
|
private
|
36
29
|
|
37
30
|
INCREMENTAL_VERSION_PATTERN = /(((\d+)\.\d+)\.\d+)/
|
38
31
|
|
39
|
-
@@command = nil
|
40
|
-
|
41
|
-
@@usage = 'describe docker -h|(<subcommand> [<subcommand-options])'
|
42
|
-
@@description = 'Describe the current git repository with a list of version for docker'
|
43
|
-
@@subcommands = {}
|
44
|
-
# This block is Optimist configuration. It is as long as the number of options of the command.
|
45
|
-
# rubocop:disable Metrics/BlockLength
|
46
|
-
@@option_parser = Optimist::Parser.new do
|
47
|
-
subcommand_max_length = @@subcommands.keys.map { |k| k.to_s.length }.max
|
48
|
-
usage @@usage
|
49
|
-
synopsis <<~SUBCOMMANDS unless @@subcommands.empty?
|
50
|
-
Subcommands:
|
51
|
-
#{@@subcommands.keys.map { |k| " #{k.to_s.ljust(subcommand_max_length)} => #{@@subcommands[k].description}" }.join("\n")}
|
52
|
-
SUBCOMMANDS
|
53
|
-
opt :separator,
|
54
|
-
'Use the given value as separator for versions',
|
55
|
-
{ type: :string, default: '\n' }
|
56
|
-
opt :not_latest,
|
57
|
-
'Do not include "latest" in the version list.',
|
58
|
-
short: :none
|
59
|
-
opt :substitute_plus,
|
60
|
-
'Set which character will be used in place of "+".',
|
61
|
-
{ type: :string, short: :none }
|
62
|
-
educate_on_error
|
63
|
-
stop_on @@subcommands.keys.map(&:to_s)
|
64
|
-
end
|
65
|
-
# rubocop:enable Metrics/BlockLength
|
66
|
-
|
67
32
|
def initialize
|
68
|
-
super(
|
69
|
-
|
70
|
-
@
|
71
|
-
|
72
|
-
end
|
73
|
-
set_options
|
74
|
-
|
75
|
-
puts version_list_from(version).join(@@separator)
|
33
|
+
super() do
|
34
|
+
@usage = 'describe docker -h|(<subcommand> [<subcommand-options])'
|
35
|
+
@description = 'Describe the current git repository with a list of version for docker'
|
36
|
+
@subcommands = {}
|
76
37
|
end
|
77
38
|
end
|
78
39
|
|
79
40
|
def set_options
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
41
|
+
@separator = if @options[:separator_given]
|
42
|
+
@options[:separator]
|
43
|
+
else
|
44
|
+
"\n"
|
45
|
+
end
|
46
|
+
@not_latest = @options[:not_latest]
|
47
|
+
@plus_substitution = if @options[:substitute_plus_given]
|
48
|
+
@options[:substitute_plus]
|
49
|
+
else
|
50
|
+
'+'
|
51
|
+
end
|
91
52
|
end
|
92
53
|
|
93
54
|
def version_list_from(full_version)
|
94
55
|
[
|
95
|
-
full_version.sub('+',
|
56
|
+
full_version.sub('+', @plus_substitution),
|
96
57
|
reduced_versions(full_version),
|
97
58
|
latest
|
98
59
|
]
|
@@ -114,5 +75,41 @@ class DescribeDocker < Command
|
|
114
75
|
['latest']
|
115
76
|
end
|
116
77
|
end
|
78
|
+
|
79
|
+
protected
|
80
|
+
|
81
|
+
def setup_option_parser
|
82
|
+
@option_parser = Optimist::Parser.new(
|
83
|
+
@usage,
|
84
|
+
full_description,
|
85
|
+
stop_condition
|
86
|
+
) do |usage_header, description, stop_condition|
|
87
|
+
usage usage_header
|
88
|
+
synopsis description
|
89
|
+
opt :separator,
|
90
|
+
'Use the given value as separator for versions',
|
91
|
+
{ type: :string, default: '\n' }
|
92
|
+
opt :not_latest,
|
93
|
+
'Do not include "latest" in the version list.',
|
94
|
+
short: :none
|
95
|
+
opt :substitute_plus,
|
96
|
+
'Set which character will be used in place of "+".',
|
97
|
+
{ type: :string, short: :none }
|
98
|
+
educate_on_error
|
99
|
+
stop_on stop_condition
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def setup_action
|
104
|
+
@action = lambda do |version|
|
105
|
+
Common.error 'describe need to be run inside a git repository' unless Git.in_repo?
|
106
|
+
@options = Common.with_subcommand_exception_handling @option_parser do
|
107
|
+
@option_parser.parse
|
108
|
+
end
|
109
|
+
set_options
|
110
|
+
|
111
|
+
puts version_list_from(version).join(@separator)
|
112
|
+
end
|
113
|
+
end
|
117
114
|
end
|
118
115
|
# rubocop:enable Metrics/ClassLength
|
@@ -17,37 +17,34 @@
|
|
17
17
|
|
18
18
|
# frozen_string_literal: true
|
19
19
|
|
20
|
+
require_relative '../../commons/command_issuer'
|
21
|
+
|
20
22
|
# Module with methods to handle tag metadata.
|
21
23
|
#
|
22
24
|
# To add a new metadata type, create a new method and link it to a symbol.
|
23
25
|
module MetadataHandler
|
24
|
-
|
26
|
+
def compute_metadata(metadata_specs)
|
27
|
+
requested_metadata = metadata_specs.split(',')
|
28
|
+
unless requested_metadata.all? { |element| metadata_computers.include?(element.to_sym) }
|
29
|
+
Common.error('Some of the metadata requested are not supported')
|
30
|
+
end
|
31
|
+
requested_metadata.map { |element| metadata_computers[element.to_sym].call }.join('-')
|
32
|
+
end
|
25
33
|
|
26
|
-
|
34
|
+
private
|
27
35
|
|
28
36
|
def last_commit_sha
|
29
|
-
|
37
|
+
CommandIssuer.run('git', '--no-pager', 'log', '-n', '1', '--pretty=%h').output.strip
|
30
38
|
end
|
31
39
|
|
32
40
|
def current_date
|
33
41
|
Time.now.strftime('%0Y%0m%0d')
|
34
42
|
end
|
35
43
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
public
|
42
|
-
|
43
|
-
def compute_metadata(metadata_specs)
|
44
|
-
metadata_specs
|
45
|
-
.split(',')
|
46
|
-
.map { |element| @@metadata_computers[element.to_sym].call }
|
47
|
-
.join('-')
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.included(_mod)
|
51
|
-
init_computers
|
44
|
+
def metadata_computers
|
45
|
+
@metadata_computers ||= {
|
46
|
+
sha: proc { last_commit_sha },
|
47
|
+
date: proc { current_date },
|
48
|
+
}
|
52
49
|
end
|
53
50
|
end
|
@@ -22,19 +22,36 @@ module PrereleaseHandler
|
|
22
22
|
FIRST_PRERELEASE = 1
|
23
23
|
DEFAULT_PRERELEASE_STRING = 'dev'
|
24
24
|
PRERELEASE_PLACEHOLDER = '(p)'
|
25
|
+
DEFAULT_PRERELEASE_PATTERN = "#{DEFAULT_PRERELEASE_STRING}#{PRERELEASE_PLACEHOLDER}".freeze
|
25
26
|
|
26
|
-
|
27
|
-
|
27
|
+
Common.module_instance_attr(self, 'prerelease_pattern', :DEFAULT_PRERELEASE_PATTERN)
|
28
|
+
Common.module_instance_attr(self, 'old_prerelease_pattern', 'proc { prerelease_pattern }')
|
28
29
|
|
29
|
-
|
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
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
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
|
30
53
|
|
31
54
|
def extract_prerelease_number(current_prerelease)
|
32
|
-
actual_old_prerelease_pattern =
|
33
|
-
if @@old_prerelease_pattern.respond_to?('call')
|
34
|
-
@@old_prerelease_pattern.call
|
35
|
-
else
|
36
|
-
@@old_prerelease_pattern
|
37
|
-
end
|
38
55
|
Common.error "The given old pattern does not contains the placeholder '(p)'" unless
|
39
56
|
actual_old_prerelease_pattern.include?(PRERELEASE_PLACEHOLDER)
|
40
57
|
old_prerelease_regex = actual_old_prerelease_pattern.sub(PRERELEASE_PLACEHOLDER, '(\\d+)')
|
@@ -46,10 +63,11 @@ module PrereleaseHandler
|
|
46
63
|
end
|
47
64
|
end
|
48
65
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
54
72
|
end
|
55
73
|
end
|
@@ -17,60 +17,28 @@
|
|
17
17
|
|
18
18
|
# frozen_string_literal: true
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
require 'get/subcommand/command'
|
20
|
+
require_relative '../../commons/common'
|
21
|
+
require_relative '../../commons/git'
|
22
|
+
require_relative '../command'
|
24
23
|
|
25
24
|
# Class length is disabled as most of its length is given by formatting.
|
26
25
|
# rubocop:disable Metrics/ClassLength
|
27
26
|
# Subcommand, it allow to create a new repository and add an initial, empty commit to it.
|
28
27
|
class Init < Command
|
29
|
-
def self.command
|
30
|
-
@@command ||= new
|
31
|
-
@@command
|
32
|
-
end
|
33
|
-
|
34
|
-
private_class_method :new
|
35
|
-
|
36
28
|
private
|
37
29
|
|
38
|
-
@@command = nil
|
39
|
-
|
40
|
-
@@usage = 'init -h|(<subcommand> [<subcommand-options])'
|
41
|
-
@@description = 'Initialize a new git repository with an initial empty commit.'
|
42
|
-
@@subcommands = {}
|
43
|
-
# This block is Optimist configuration. It is as long as the number of options of the command.
|
44
|
-
# rubocop:disable Metrics/BlockLength
|
45
|
-
@@option_parser = Optimist::Parser.new do
|
46
|
-
subcommand_max_length = @@subcommands.keys.map { |k| k.to_s.length }.max
|
47
|
-
subcommand_section = <<~SUBCOMMANDS unless @@subcommands.empty?
|
48
|
-
Subcommands:
|
49
|
-
#{@@subcommands.keys.map { |k| " #{k.to_s.ljust(subcommand_max_length)} => #{@@subcommands[k].description}" }.join("\n")}
|
50
|
-
SUBCOMMANDS
|
51
|
-
usage @@usage
|
52
|
-
synopsis @@description + (subcommand_section.nil? ? '' : "\n") + subcommand_section.to_s
|
53
|
-
opt :empty,
|
54
|
-
'Do not create the first, empty commit.'
|
55
|
-
educate_on_error
|
56
|
-
stop_on @@subcommands.keys.map(&:to_s)
|
57
|
-
end
|
58
|
-
# rubocop:enable Metrics/BlockLength
|
59
|
-
|
60
30
|
def initialize
|
61
|
-
super(
|
62
|
-
@
|
63
|
-
|
64
|
-
|
65
|
-
Common.error 'The current directory is already a git repository' if Git.in_repo?
|
66
|
-
|
67
|
-
init_repository
|
31
|
+
super() do
|
32
|
+
@usage = 'init -h|(<subcommand> [<subcommand-options])'
|
33
|
+
@description = 'Initialize a new git repository with an initial empty commit.'
|
34
|
+
@subcommands = {}
|
68
35
|
end
|
69
36
|
end
|
70
37
|
|
71
38
|
def init_repository
|
72
|
-
|
73
|
-
|
39
|
+
command_result = CommandIssuer.run('git', 'init')
|
40
|
+
|
41
|
+
Common.error 'Failed to init the repository' if command_result.exit_status.positive?
|
74
42
|
|
75
43
|
create_first_commit unless @options[:empty]
|
76
44
|
|
@@ -78,8 +46,39 @@ class Init < Command
|
|
78
46
|
end
|
79
47
|
|
80
48
|
def create_first_commit
|
81
|
-
|
82
|
-
Common.error
|
49
|
+
command_result = CommandIssuer.run('git', 'commit', '--allow-empty', '-m', '"chore: initialize repository"')
|
50
|
+
Common.error "Failed to create first commit: #{command_result.error}" if command_result.exit_status.positive?
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def setup_option_parser
|
56
|
+
# This block is Optimist configuration. It is as long as the number of options of the command.
|
57
|
+
# rubocop:disable Metrics/BlockLength
|
58
|
+
@option_parser = Optimist::Parser.new(
|
59
|
+
@usage,
|
60
|
+
full_description,
|
61
|
+
stop_condition
|
62
|
+
) do |usage_header, description, stop_condition|
|
63
|
+
usage usage_header
|
64
|
+
synopsis description
|
65
|
+
opt :empty,
|
66
|
+
'Do not create the first, empty commit.'
|
67
|
+
educate_on_error
|
68
|
+
stop_on stop_condition
|
69
|
+
end
|
70
|
+
# rubocop:enable Metrics/BlockLength
|
71
|
+
end
|
72
|
+
|
73
|
+
def setup_action
|
74
|
+
@action = lambda do
|
75
|
+
@options = Common.with_subcommand_exception_handling @option_parser do
|
76
|
+
@option_parser.parse
|
77
|
+
end
|
78
|
+
Common.error 'The current directory is already a git repository' if Git.in_repo?
|
79
|
+
|
80
|
+
init_repository
|
81
|
+
end
|
83
82
|
end
|
84
83
|
end
|
85
84
|
# rubocop:enable Metrics/ClassLength
|