git_toolbox 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -18,15 +18,14 @@
18
18
  # frozen_string_literal: true
19
19
 
20
20
  require 'highline'
21
- require 'get/commons/git'
21
+ require_relative '../../commons/git'
22
22
 
23
- # Module for asking to the user informations about a commit message.
23
+ # Module for asking to the user information about a commit message.
24
24
  module PromptHandler
25
- @@cli = HighLine.new
26
-
27
- @@custom_values_initialized = nil
28
- @@custom_types = []
29
- @@custom_scopes = []
25
+ Common.module_instance_value(self, 'cli', 'HighLine.new')
26
+ Common.module_instance_attr(self, 'custom_values_initialized', false)
27
+ Common.module_instance_value(self, 'custom_types', [])
28
+ Common.module_instance_value(self, 'custom_scopes', [])
30
29
 
31
30
  STRING_VALUE_VALIDATOR = /\s*\S+\s*/
32
31
  BODY_END_DELIMITER = "\n\n\n"
@@ -46,14 +45,15 @@ module PromptHandler
46
45
 
47
46
  def ask_for_type
48
47
  extract_types_and_scopes
49
- @@cli.choose do |menu|
48
+
49
+ MOD_REF.cli.choose do |menu|
50
50
  menu.flow = :columns_down
51
51
  menu.prompt = 'Choose the type of your commit: '
52
- DEFAULT_TYPES.union(@@custom_types).each do |type|
52
+ DEFAULT_TYPES.union(MOD_REF.custom_types).each do |type|
53
53
  menu.choice(type.to_sym)
54
54
  end
55
55
  menu.choice('Create a new type (rarely needed)') do |_|
56
- @@cli.ask('Write the new type to use', String) do |question|
56
+ MOD_REF.cli.ask('Write the new type to use', String) do |question|
57
57
  question.verify_match = true
58
58
  question.validate = STRING_VALUE_VALIDATOR
59
59
  end
@@ -63,14 +63,14 @@ module PromptHandler
63
63
 
64
64
  def ask_for_scope
65
65
  extract_types_and_scopes
66
- @@cli.choose do |menu|
66
+ MOD_REF.cli.choose do |menu|
67
67
  menu.flow = :columns_down
68
68
  menu.prompt = 'Choose the scope of your commit: '
69
- @@custom_scopes.each do |scope|
69
+ MOD_REF.custom_scopes.each do |scope|
70
70
  menu.choice(scope.to_sym)
71
71
  end
72
72
  menu.choice('Create a new scope') do |_|
73
- @@cli.ask('Write the new scope to use', String) do |question|
73
+ MOD_REF.cli.ask('Write the new scope to use', String) do |question|
74
74
  question.verify_match = true
75
75
  question.validate = STRING_VALUE_VALIDATOR
76
76
  end
@@ -80,13 +80,13 @@ module PromptHandler
80
80
  end
81
81
 
82
82
  def ask_for_breaking
83
- @@cli.agree('Does the commit contain a breaking change? (yes/no) ') do |question|
83
+ MOD_REF.cli.agree('Does the commit contain a breaking change? (yes/no) ') do |question|
84
84
  question.default = false
85
85
  end
86
86
  end
87
87
 
88
88
  def ask_for_summary
89
- @@cli.ask('The summary of the commit:') do |question|
89
+ MOD_REF.cli.ask('The summary of the commit:') do |question|
90
90
  question.verify_match = true
91
91
  question.validate = STRING_VALUE_VALIDATOR
92
92
  end
@@ -94,31 +94,33 @@ module PromptHandler
94
94
 
95
95
  def ask_for_message
96
96
  # This method needs a special implementation as the body message can span multiple lines.
97
- @@cli.puts('The body of the commit (ends after 3 new lines):')
98
- @@cli.input.gets(BODY_END_DELIMITER)
97
+ MOD_REF.cli.puts('The body of the commit (ends after 3 new lines):')
98
+ MOD_REF.cli.input.gets(BODY_END_DELIMITER)
99
99
  end
100
100
 
101
101
  private
102
102
 
103
103
  FIRST_COMMIT = nil
104
104
 
105
+ Common.add_module_self_reference(self)
106
+
105
107
  # This method tries to optimize input parsing by performing multiple operations in one go.
106
108
  # So its complexity is a bit higher as it needs to make multiple checks.
107
109
  # rubocop:disable Metrics/CyclomaticComplexity
108
110
  def extract_types_and_scopes
109
- return unless @@custom_values_initialized.nil?
111
+ return if MOD_REF.custom_values_initialized
110
112
 
111
113
  Git.with_commit_list_from(FIRST_COMMIT) do |commit_list|
112
- commit_list.map do |element|
114
+ commit_list.reverse.map do |element|
113
115
  match = Git::CONVENTIONAL_COMMIT_REGEX.match(element)
114
116
  next if match.nil?
115
117
 
116
- type_already_added = DEFAULT_TYPES.include?(match[1].to_sym) || @@custom_types.include?(match[1])
117
- @@custom_types.append(match[1]) unless type_already_added
118
- @@custom_scopes.append(match[3]) unless match[3].nil? || @@custom_scopes.include?(match[3])
118
+ type_already_added = DEFAULT_TYPES.include?(match[1].to_sym) || MOD_REF.custom_types.include?(match[1])
119
+ MOD_REF.custom_types.append(match[1]) unless type_already_added
120
+ MOD_REF.custom_scopes.append(match[3]) unless match[3].nil? || MOD_REF.custom_scopes.include?(match[3])
119
121
  end
120
122
  end
121
- @@custom_values_initialized = true
123
+ MOD_REF.custom_values_initialized = true
122
124
  end
123
125
  # rubocop:enable Metrics/CyclomaticComplexity
124
126
  end
@@ -22,7 +22,7 @@ module BashCompletion
22
22
  def bash_completion(main_module, command_name)
23
23
  generate_functions(main_module, command_name, INITIAL_LEVEL)
24
24
 
25
- "#{HEADER}\n#{@@function_stack.reverse.join("\n")}"
25
+ "#{HEADER}\n#{MOD_REF.function_stack.reverse.join("\n")}"
26
26
  end
27
27
 
28
28
  private
@@ -37,7 +37,8 @@ module BashCompletion
37
37
  #
38
38
  HEADER
39
39
 
40
- @@function_stack = []
40
+ Common.add_module_self_reference(self)
41
+ Common.module_instance_value(self, 'function_stack', [])
41
42
 
42
43
  def full_subcommand_name(base, name)
43
44
  "#{base}_#{name}"
@@ -74,18 +75,18 @@ module BashCompletion
74
75
  short_options = []
75
76
  subcommands = []
76
77
 
77
- command_class.class_variable_get(:@@option_parser).specs.each_value do |option|
78
+ command_class.instance.option_parser.specs.each_value do |option|
78
79
  long_options.push("--#{option.long}")
79
80
  short_options.push("-#{option.short.nil? ? option.long[0] : option.short}") if option.short != :none
80
81
  end
81
82
 
82
- command_class.class_variable_get(:@@subcommands).each_key do |subcommand|
83
+ command_class.instance.subcommands.each_key do |subcommand|
83
84
  subcommands.push(subcommand.to_s)
84
85
  end
85
86
 
86
- @@function_stack.push(completion_function_definition(name, level, long_options, short_options, subcommands))
87
+ MOD_REF.function_stack.push(completion_function_definition(name, level, long_options, short_options, subcommands))
87
88
 
88
- command_class.class_variable_get(:@@subcommands).each do |element|
89
+ command_class.instance.subcommands.each do |element|
89
90
  generate_functions(element[1].class, full_subcommand_name(name, element[0].to_s), level + 1)
90
91
  end
91
92
  end
@@ -17,54 +17,49 @@
17
17
 
18
18
  # frozen_string_literal: true
19
19
 
20
- require 'English'
21
- require 'get/commons/common'
22
- require 'get/subcommand/command'
23
- require 'get/subcommand/complete/bash_completion'
24
- require 'get'
20
+ require_relative '../../commons/common'
21
+ require_relative '../command'
22
+ require_relative './bash_completion'
23
+ require_relative '../../../get'
25
24
 
26
25
  # Class length is disabled as most of its length is given by formatting.
27
26
  # rubocop:disable Metrics/ClassLength
28
27
  # Subcommand, prints the bash completion script.
29
28
  class Complete < Command
30
- def self.command
31
- @@command ||= new
32
- @@command
33
- end
34
-
35
- private_class_method :new
36
-
37
29
  private
38
30
 
39
31
  include BashCompletion
40
32
 
41
- @@command = nil
33
+ def initialize
34
+ super() do
35
+ @usage = 'complete -h|(<subcommand> [<subcommand-options])'
36
+ @description = 'Print the shell completion script.'
37
+ @subcommands = {}
38
+ end
39
+ end
42
40
 
43
- @@usage = 'complete -h|(<subcommand> [<subcommand-options])'
44
- @@description = 'Print the shell completion script.'
45
- @@subcommands = {}
46
- # This block is Optimist configuration. It is as long as the number of options of the command.
47
- # rubocop:disable Metrics/BlockLength
48
- @@option_parser = Optimist::Parser.new do
49
- subcommand_max_length = @@subcommands.keys.map { |k| k.to_s.length }.max
50
- subcommand_section = <<~SUBCOMMANDS unless @@subcommands.empty?
51
- Subcommands:
52
- #{@@subcommands.keys.map { |k| " #{k.to_s.ljust(subcommand_max_length)} => #{@@subcommands[k].description}" }.join("\n")}
53
- SUBCOMMANDS
54
- usage @@usage
55
- synopsis @@description + (subcommand_section.nil? ? '' : "\n") + subcommand_section.to_s
56
- opt :shell,
57
- 'Select the type of shell of which the completion will be generated.',
58
- { type: :string, default: 'bash' }
59
- educate_on_error
60
- stop_on @@subcommands.keys.map(&:to_s)
41
+ protected
42
+
43
+ def setup_option_parser
44
+ @option_parser = Optimist::Parser.new(
45
+ @usage,
46
+ full_description,
47
+ stop_condition
48
+ ) do |usage_header, description, stop_condition|
49
+ usage usage_header
50
+ synopsis description
51
+ opt :shell,
52
+ 'Select the type of shell of which the completion will be generated.',
53
+ { type: :string, default: 'bash' }
54
+ educate_on_error
55
+ stop_on stop_condition
56
+ end
61
57
  end
62
- # rubocop:enable Metrics/BlockLength
63
58
 
64
- def initialize
65
- super(@@usage, @@description) do
66
- @options = Common.with_subcommand_exception_handling @@option_parser do
67
- @@option_parser.parse
59
+ def setup_action
60
+ @action = lambda do
61
+ @options = Common.with_subcommand_exception_handling @option_parser do
62
+ @option_parser.parse
68
63
  end
69
64
 
70
65
  @completions = {
@@ -22,50 +22,48 @@ module ChangeHandler
22
22
  # Array with change types in ascending order of importance.
23
23
  CHANGE_TYPE = %i[NONE PATCH MINOR MAJOR].freeze
24
24
 
25
- @@major_trigger = 'is_breaking'
26
- @@minor_trigger = "type == 'feat'"
27
- @@patch_trigger = "type == 'fix'"
25
+ DEFAULT_MAJOR_TRIGGER = 'is_breaking'
26
+ DEFAULT_MINOR_TRIGGER = "type == 'feat'"
27
+ DEFAULT_PATCH_TRIGGER = "type == 'fix'"
28
28
 
29
- module_function
29
+ Common.module_instance_attr(self, 'major_trigger', :DEFAULT_MAJOR_TRIGGER)
30
+ Common.module_instance_attr(self, 'minor_trigger', :DEFAULT_MINOR_TRIGGER)
31
+ Common.module_instance_attr(self, 'patch_trigger', :DEFAULT_PATCH_TRIGGER)
32
+
33
+ def greatest_change_in(commit_list)
34
+ commit_list
35
+ .grep(Git::CONVENTIONAL_COMMIT_REGEX)
36
+ .map { |commit| to_change(commit) }
37
+ .max { |a, b| CHANGE_TYPE.index(a) <=> CHANGE_TYPE.index(b) }
38
+ end
39
+
40
+ private
30
41
 
31
42
  # In this block method arguments can be used by user.
32
43
  # Also `eval` is needed to allow users to define their custom triggers.
33
44
  # rubocop:disable Lint/UnusedMethodArgument
34
45
  # rubocop:disable Security/Eval
35
46
  def triggers_major?(type, scope, is_breaking)
36
- eval(@@major_trigger)
47
+ eval(ChangeHandler.major_trigger)
37
48
  end
38
49
 
39
50
  def triggers_minor?(type, scope)
40
- eval(@@minor_trigger)
51
+ eval(ChangeHandler.minor_trigger)
41
52
  end
42
53
 
43
54
  def triggers_patch?(type, scope)
44
- eval(@@patch_trigger)
55
+ eval(ChangeHandler.patch_trigger)
45
56
  end
46
57
  # rubocop:enable Lint/UnusedMethodArgument
47
58
  # rubocop:enable Security/Eval
48
59
 
49
- # Open String class to inject method to convert a (commit) string into
50
- # a change.
51
- class ::String
52
- # Convert the string (as a conventional commit string) into a change type.
53
- def to_change
54
- groups = Git::CONVENTIONAL_COMMIT_REGEX.match(self)
55
- return :MAJOR if ChangeHandler.triggers_major?(groups[1], groups[3], !groups[4].nil?)
56
- return :MINOR if ChangeHandler.triggers_minor?(groups[1], groups[2])
57
- return :PATCH if ChangeHandler.triggers_patch?(groups[1], groups[2])
60
+ # Convert the string (as a conventional commit string) into a change type.
61
+ def to_change(commit_message)
62
+ groups = Git::CONVENTIONAL_COMMIT_REGEX.match(commit_message)
63
+ return :MAJOR if triggers_major?(groups[1], groups[3], !groups[4].nil?)
64
+ return :MINOR if triggers_minor?(groups[1], groups[2])
65
+ return :PATCH if triggers_patch?(groups[1], groups[2])
58
66
 
59
- :NONE
60
- end
61
- end
62
-
63
- public
64
-
65
- def greatest_change_in(commit_list)
66
- commit_list
67
- .grep(Git::CONVENTIONAL_COMMIT_REGEX)
68
- .map(&:to_change)
69
- .max { |a, b| CHANGE_TYPE.index(a) <=> CHANGE_TYPE.index(b) }
67
+ :NONE
70
68
  end
71
69
  end
@@ -17,24 +17,20 @@
17
17
 
18
18
  # frozen_string_literal: true
19
19
 
20
- require 'get/commons/common'
21
- require 'get/commons/git'
22
- require 'get/subcommand/command'
23
- require 'get/subcommand/describe/change'
24
- require 'get/subcommand/describe/prerelease'
25
- require 'get/subcommand/describe/metadata'
26
- require 'get/subcommand/describe/docker/docker'
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
- def self.command
33
- @@command ||= new
34
- @@command
35
- end
36
-
37
- private_class_method :new
33
+ include Singleton
38
34
 
39
35
  private
40
36
 
@@ -42,8 +38,6 @@ class Describe < Command
42
38
  include PrereleaseHandler
43
39
  include MetadataHandler
44
40
 
45
- @@command = nil
46
-
47
41
  DEFAULT_RELEASE_VERSION = '0.1.0'
48
42
  FULL_SEMANTIC_VERSION_REGEX = /
49
43
  ^((0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)) # Stable version, major, minor, patch
@@ -51,96 +45,24 @@ class Describe < Command
51
45
  (?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ # metadata
52
46
  /x
53
47
 
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
48
  def initialize
114
- super(@@usage, @@description) do
115
- @options = Common.with_subcommand_exception_handling @@option_parser do
116
- @@option_parser.parse
117
- end
118
- Common.error 'describe need to be run inside a git repository' unless Git.in_repo?
119
- set_options
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
49
+ super() do
50
+ @usage = 'describe -h|(<subcommand> [<subcommand-options])'
51
+ @description = 'Describe the current git repository with semantic version.'
52
+ @subcommands = {
53
+ docker: DescribeDocker.instance,
54
+ }
135
55
  end
136
56
  end
137
57
 
138
58
  def set_options
139
- @@major_trigger = @options[:major_trigger] if @options[:major_trigger_given]
140
- @@minor_trigger = @options[:minor_trigger] if @options[:minor_trigger_given]
141
- @@patch_trigger = @options[:patch_trigger] if @options[:patch_trigger_given]
142
- @@old_prerelease_pattern = @options[:old_prerelease_pattern] if @options[:old_prerelease_pattern_given]
143
- @@prerelease_pattern = @options[:prerelease_pattern] if @options[:prerelease_pattern_given]
59
+ ChangeHandler.major_trigger = @options[:major_trigger] if @options[:major_trigger_given]
60
+ ChangeHandler.minor_trigger = @options[:minor_trigger] if @options[:minor_trigger_given]
61
+ ChangeHandler.patch_trigger = @options[:patch_trigger] if @options[:patch_trigger_given]
62
+ if @options[:old_prerelease_pattern_given]
63
+ PrereleaseHandler.old_prerelease_pattern = @options[:old_prerelease_pattern]
64
+ end
65
+ PrereleaseHandler.prerelease_pattern = @options[:prerelease_pattern] if @options[:prerelease_pattern_given]
144
66
  end
145
67
 
146
68
  def describe_current_commit
@@ -213,17 +135,87 @@ class Describe < Command
213
135
  end
214
136
 
215
137
  def create_signed_tag(computed_version)
216
- system(
217
- 'git tag -s ' \
218
- "#{
219
- if @options[:tag_message_given]
220
- "-m #{@options[:tag_message]}"
138
+ tag_message_cli = if @options[:tag_message_given]
139
+ "\"#{@options[:tag_message].gsub('"', '\"')}\""
140
+ else
141
+ '""'
142
+ end
143
+ CommandIssuer.run('git', 'tag', '-s', '-m', tag_message_cli, "'#{computed_version}'")
144
+ end
145
+
146
+ protected
147
+
148
+ def setup_option_parser
149
+ @option_parser = Optimist::Parser.new(
150
+ @usage,
151
+ full_description,
152
+ stop_condition
153
+ ) do |usage_header, description, stop_condition|
154
+ usage usage_header
155
+ synopsis description
156
+ opt :prerelease,
157
+ 'Describe a prerelease rather than a release',
158
+ short: :none
159
+ opt :exclude_metadata,
160
+ 'Do not include metadata in version.'
161
+ opt :metadata,
162
+ 'Set which metadata to include in the string. ' \
163
+ 'Multiple value can be specified by separating the with a comma \',\'.',
164
+ { type: :string, default: 'sha' }
165
+ opt :major_trigger,
166
+ 'Set the trigger for a major release. ' \
167
+ 'This must be a valid Ruby expression. ' \
168
+ 'In this expression the string values "type" and "scope" ' \
169
+ 'and the boolean value "is_breaking" can be used.',
170
+ { short: :none, type: :string, default: 'is_breaking' }
171
+ opt :minor_trigger,
172
+ 'Set the trigger for a minor release. ' \
173
+ 'This must be a valid Ruby expression. ' \
174
+ 'In this expression the string values "type" and "scope" can be used.',
175
+ { short: :none, type: :string, default: "type == 'feat'" }
176
+ opt :patch_trigger,
177
+ 'Set the trigger for a patch release. ' \
178
+ 'This must be a valid Ruby expression. ' \
179
+ 'In this expression the string values "type" and "scope" can be used.',
180
+ { short: :none, type: :string, default: "type == 'fix'" }
181
+ opt :prerelease_pattern,
182
+ 'Set the pattern of the prerelease. This must contain the placeholder "(p)".',
183
+ { short: :none, type: :string, default: 'dev(p)' }
184
+ opt :old_prerelease_pattern,
185
+ 'Set the pattern of the old prerelease. It is useful for changing prerelease pattern.',
186
+ { short: :none, type: :string, default: 'prerelease-pattern value' }
187
+ opt :diff,
188
+ 'Print also the last version.'
189
+ opt :create_tag,
190
+ 'Create a signed tag with the computed version.',
191
+ { short: :none }
192
+ opt :tag_message,
193
+ 'Add the given message to the tag. Requires "--create-tag".',
194
+ { short: :none, type: :string }
195
+ educate_on_error
196
+ stop_on stop_condition
197
+ end
198
+ end
199
+
200
+ def setup_action
201
+ @action = lambda do
202
+ @options = Common.with_subcommand_exception_handling @option_parser do
203
+ @option_parser.parse
204
+ end
205
+ Common.error 'describe need to be run inside a git repository' unless Git.in_repo?
206
+ set_options
207
+
208
+ if ARGV.length.positive?
209
+ subcommand = ARGV.shift.to_sym
210
+ if @subcommands.include?(subcommand)
211
+ @subcommands[subcommand].action.call(describe_current_commit)
221
212
  else
222
- ''
213
+ Common.error "subcommand '#{subcommand}' unknown."
223
214
  end
224
- } " \
225
- "'#{computed_version}'"
226
- )
215
+ else
216
+ puts describe_current_commit
217
+ end
218
+ end
227
219
  end
228
220
  end
229
221
  # rubocop:enable Metrics/ClassLength