create_github_release 1.0.0 → 1.2.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/.solargraph.yml +23 -0
  4. data/.vscode/launch.json +19 -0
  5. data/.yardopts +1 -0
  6. data/CHANGELOG.md +26 -0
  7. data/README.md +165 -47
  8. data/Rakefile +7 -4
  9. data/create_github_release.gemspec +7 -4
  10. data/exe/create-github-release +5 -1
  11. data/lib/create_github_release/assertion_base.rb +0 -2
  12. data/lib/create_github_release/assertions/bundle_is_up_to_date.rb +1 -1
  13. data/lib/create_github_release/assertions/gh_authenticated.rb +1 -1
  14. data/lib/create_github_release/assertions/gh_command_exists.rb +1 -1
  15. data/lib/create_github_release/assertions/git_command_exists.rb +1 -1
  16. data/lib/create_github_release/assertions/in_git_repo.rb +1 -1
  17. data/lib/create_github_release/assertions/in_repo_root_directory.rb +1 -1
  18. data/lib/create_github_release/assertions/local_and_remote_on_same_commit.rb +1 -1
  19. data/lib/create_github_release/assertions/local_release_branch_does_not_exist.rb +1 -1
  20. data/lib/create_github_release/assertions/no_staged_changes.rb +1 -1
  21. data/lib/create_github_release/assertions/no_uncommitted_changes.rb +1 -1
  22. data/lib/create_github_release/assertions/on_default_branch.rb +1 -1
  23. data/lib/create_github_release/assertions/remote_release_branch_does_not_exist.rb +1 -1
  24. data/lib/create_github_release/assertions/remote_release_tag_does_not_exist.rb +1 -1
  25. data/lib/create_github_release/command_line/options.rb +151 -0
  26. data/lib/create_github_release/command_line/parser.rb +253 -0
  27. data/lib/create_github_release/command_line/validations.rb +293 -0
  28. data/lib/create_github_release/command_line/validator.rb +93 -0
  29. data/lib/create_github_release/command_line.rb +43 -0
  30. data/lib/create_github_release/project.rb +136 -76
  31. data/lib/create_github_release/release_assertions.rb +2 -1
  32. data/lib/create_github_release/release_tasks.rb +2 -1
  33. data/lib/create_github_release/tasks/commit_release.rb +1 -1
  34. data/lib/create_github_release/tasks/create_github_release.rb +1 -1
  35. data/lib/create_github_release/tasks/create_release_branch.rb +1 -1
  36. data/lib/create_github_release/tasks/create_release_pull_request.rb +1 -1
  37. data/lib/create_github_release/tasks/create_release_tag.rb +1 -1
  38. data/lib/create_github_release/tasks/push_release.rb +1 -1
  39. data/lib/create_github_release/tasks/update_changelog.rb +1 -1
  40. data/lib/create_github_release/tasks/update_version.rb +13 -14
  41. data/lib/create_github_release/version.rb +1 -1
  42. data/lib/create_github_release.rb +1 -2
  43. metadata +31 -25
  44. data/lib/create_github_release/command_line_options.rb +0 -367
  45. data/lib/create_github_release/command_line_parser.rb +0 -225
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require 'forwardable'
5
+
6
+ module CreateGithubRelease
7
+ module CommandLine
8
+ # Stores and validates the command line options
9
+ #
10
+ # @example
11
+ # options = CreateGithubRelease::CommandLine::Options.new
12
+ # options.release_type = 'major'
13
+ # options.valid? #=> true
14
+ # options.errors #=> []
15
+ #
16
+ # @api public
17
+ #
18
+ class Options
19
+ CreateGithubRelease::CommandLine::ALLOWED_OPTIONS.each { |option| attr_accessor option }
20
+
21
+ # @attribute release_type [rw] the type of release to create
22
+ #
23
+ # Must be one of the VALID_RELEASE_TYPES
24
+ #
25
+ # @example
26
+ # options = CreateGithubRelease::CommandLine::Options.new(release_type: 'major')
27
+ # options.release_type #=> 'major'
28
+ # @return [String]
29
+ # @api public
30
+
31
+ # @attribute default_branch [rw] the default branch of the repository
32
+ # @example
33
+ # options = CreateGithubRelease::CommandLine::Options.new(default_branch: 'main')
34
+ # options.default_branch #=> 'main'
35
+ # @return [String]
36
+ # @api public
37
+
38
+ # @attribute release_branch [rw] the branch use to create the release
39
+ # @example
40
+ # options = CreateGithubRelease::CommandLine::Options.new(release_branch: 'release-v1.0.0')
41
+ # options.release_branch #=> 'release-v1.0.0'
42
+ # @return [String]
43
+ # @api public
44
+
45
+ # @attribute remote [rw] the name of the remote to use to access Github
46
+ # @example
47
+ # options = CreateGithubRelease::CommandLine::Options.new(remote: 'origin')
48
+ # options.remote #=> 'origin'
49
+ # @return [String]
50
+ # @api public
51
+
52
+ # @attribute last_release_version [rw] the version of the last release
53
+ # @example
54
+ # options = CreateGithubRelease::CommandLine::Options.new(last_release_version: '0.1.1')
55
+ # options.last_release_version #=> '0.1.1'
56
+ # @return [String]
57
+ # @api public
58
+
59
+ # @attribute next_release_version [rw] the version of the next release
60
+ # @example
61
+ # options = CreateGithubRelease::CommandLine::Options.new(next_release_version: '1.0.0')
62
+ # options.next_release_version #=> '1.0.0'
63
+ # @return [String]
64
+ # @api public
65
+
66
+ # @attribute changelog_path [rw] the path to the changelog file
67
+ # @example
68
+ # options = CreateGithubRelease::CommandLine::Options.new(changelog_path: 'CHANGELOG.md')
69
+ # options.changelog_path #=> 'CHANGELOG.md'
70
+ # @return [String]
71
+ # @api public
72
+
73
+ # @attribute quiet [rw] if `true`, suppresses all output
74
+ # @example
75
+ # options = CreateGithubRelease::CommandLine::Options.new(quiet: true)
76
+ # options.quiet #=> true
77
+ # @return [Boolean]
78
+ # @api public
79
+
80
+ # @attribute verbose [rw] if `true`, enables verbose output
81
+ # @example
82
+ # options = CreateGithubRelease::CommandLine::Options.new(verbose: true)
83
+ # options.verbose #=> true
84
+ # @return [Boolean]
85
+ # @api public
86
+
87
+ # Create a new instance of this class
88
+ #
89
+ # @example No arguments or block given
90
+ # options = CreateGithubRelease::CommandLine::Options.new
91
+ # options.release_type #=> nil
92
+ # options.valid? #=> false
93
+ # options.errors #=> ["--release-type must be given and be one of 'major', 'minor', 'patch'"]
94
+ #
95
+ # @example With keyword arguments
96
+ # config = { release_type: 'major', default_branch: 'main', quiet: true }
97
+ # options = CreateGithubRelease::CommandLine::Options.new(**config)
98
+ # options.release_type #=> 'major'
99
+ # options.default_branch #=> 'main'
100
+ # options.quiet #=> true
101
+ # options.valid? #=> true
102
+ #
103
+ # @example with a configuration block
104
+ # options = CreateGithubRelease::CommandLine::Options.new do |o|
105
+ # o.release_type = 'major'
106
+ # o.default_branch = 'main'
107
+ # o.quiet = true
108
+ # end
109
+ # options.release_type #=> 'major'
110
+ # options.default_branch #=> 'main'
111
+ # options.quiet #=> true
112
+ # options.valid? #=> true
113
+ #
114
+ # @yield [self] an initialization block
115
+ # @yieldparam self [CreateGithubRelease::CommandLine::Options] the instance being initialized
116
+ # @yieldreturn [void] the return value is ignored
117
+ #
118
+ def initialize(**options)
119
+ assert_no_unknown_options(options)
120
+ options.each { |k, v| instance_variable_set("@#{k}", v) }
121
+
122
+ self.quiet ||= false
123
+ self.verbose ||= false
124
+ self.pre ||= false
125
+ @errors = []
126
+
127
+ yield(self) if block_given?
128
+
129
+ @validator = CommandLine::Validator.new(self)
130
+
131
+ valid?
132
+ end
133
+
134
+ extend Forwardable
135
+ def_delegators :@validator, :valid?, :errors
136
+
137
+ private
138
+
139
+ # Raise ArgumentError if options has a key not in ALLOWED_OPTIONS
140
+ # @return [void]
141
+ # @api private
142
+ def assert_no_unknown_options(options)
143
+ unknown_options = options.keys - ALLOWED_OPTIONS
144
+ return if unknown_options.empty?
145
+
146
+ message = "Unknown keywords: #{unknown_options.join(', ')}"
147
+ raise ArgumentError, message
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,253 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+ require 'optparse'
5
+ require 'create_github_release/command_line/options'
6
+
7
+ module CreateGithubRelease
8
+ module CommandLine
9
+ # rubocop:disable Metrics/ClassLength
10
+
11
+ # Parses the options for this script
12
+ #
13
+ # @example Specify the release type
14
+ # options = CommandLineParser.new.parse('major')
15
+ # options.valid? # => true
16
+ # options.release_type # => "major"
17
+ # options.quiet # => false
18
+ #
19
+ # @example Specify the release type and the quiet option
20
+ # parser = CommandLineParser.new
21
+ # args = %w[minor --quiet]
22
+ # options = parser.parse(*args)
23
+ # options.release_type # => "minor"
24
+ # options.quiet # => true
25
+ #
26
+ # @example Show the command line help
27
+ # CommandLineParser.new.parse('--help')
28
+ # parser.parse('--help')
29
+ #
30
+ # @api public
31
+ #
32
+ class Parser
33
+ # Create a new command line parser
34
+ #
35
+ # @example
36
+ # parser = CommandLineParser.new
37
+ #
38
+ def initialize
39
+ @option_parser = OptionParser.new
40
+ define_options
41
+ @options = CreateGithubRelease::CommandLine::Options.new
42
+ end
43
+
44
+ # Parse the command line arguements returning the options
45
+ #
46
+ # @example
47
+ # parser = CommandLineParser.new
48
+ # options = parser.parse(['major'])
49
+ #
50
+ # @param args [Array<String>] the command line arguments
51
+ #
52
+ # @return [CreateGithubRelease::CommandLine::Options] the options
53
+ #
54
+ def parse(*args)
55
+ begin
56
+ option_parser.parse!(remaining_args = args.dup)
57
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
58
+ report_errors(e.message)
59
+ end
60
+ parse_remaining_args(remaining_args)
61
+ # puts options unless options.quiet
62
+ report_errors(*options.errors) unless options.valid?
63
+ options
64
+ end
65
+
66
+ private
67
+
68
+ # @!attribute [rw] options
69
+ #
70
+ # The options to used for the create-github-release script
71
+ #
72
+ # @example
73
+ # parser = CommandLineParser.new
74
+ # parser.parse(['major'])
75
+ # options = parser.options
76
+ # options.release_type # => 'major'
77
+ #
78
+ # @return [CreateGithubRelease::CommandLine::Options] the options
79
+ #
80
+ # @api private
81
+ #
82
+ attr_reader :options
83
+
84
+ # @!attribute [rw] option_parser
85
+ #
86
+ # The option parser
87
+ #
88
+ # @return [OptionParser] the option parser
89
+ #
90
+ # @api private
91
+ #
92
+ attr_reader :option_parser
93
+
94
+ # Parse non-option arguments (the release type)
95
+ # @return [void]
96
+ # @api private
97
+ def parse_remaining_args(remaining_args)
98
+ options.release_type = remaining_args.shift || nil
99
+ report_errors('Too many args') unless remaining_args.empty?
100
+ end
101
+
102
+ # An error message constructed from the given errors array
103
+ # @return [String]
104
+ # @api private
105
+ def error_message(errors)
106
+ <<~MESSAGE
107
+ #{errors.map { |e| "ERROR: #{e}" }.join("\n")}
108
+
109
+ Use --help for usage
110
+ MESSAGE
111
+ end
112
+
113
+ # Output an error message and useage to stderr and exit
114
+ # @return [void]
115
+ # @api private
116
+ def report_errors(*errors)
117
+ warn error_message(errors)
118
+ exit 1
119
+ end
120
+
121
+ # The command line template as a string
122
+ # @return [String]
123
+ # @api private
124
+ def command_template
125
+ <<~COMMAND
126
+ #{File.basename($PROGRAM_NAME)} --help | RELEASE_TYPE [options]
127
+ COMMAND
128
+ end
129
+
130
+ # Define the options for OptionParser
131
+ # @return [void]
132
+ # @api private
133
+ def define_options
134
+ # @sg-ignore
135
+ option_parser.banner = "Usage:\n#{command_template}"
136
+ option_parser.separator ''
137
+ option_parser.separator "RELEASE_TYPE must be 'major', 'minor', 'patch', 'pre', 'release', or 'first'"
138
+ option_parser.separator ''
139
+ option_parser.separator 'Options:'
140
+ %i[
141
+ define_help_option define_default_branch_option define_release_branch_option define_pre_option
142
+ define_pre_type_option define_remote_option define_last_release_version_option
143
+ define_next_release_version_option define_changelog_path_option define_quiet_option define_verbose_option
144
+ ].each { |m| send(m) }
145
+ end
146
+
147
+ # Define the pre option
148
+ # @return [void]
149
+ # @api private
150
+ def define_pre_option
151
+ option_parser.on('-p', '--pre', 'Create a pre-release') do |pre|
152
+ options.pre = pre
153
+ end
154
+ end
155
+
156
+ # Define the pre-type option
157
+ # @return [void]
158
+ # @api private
159
+ def define_pre_type_option
160
+ description = 'Type of pre-release to create (e.g. alpha, beta, etc.)'
161
+ option_parser.on('-t', '--pre-type=TYPE', description) do |pre_type|
162
+ options.pre_type = pre_type
163
+ end
164
+ end
165
+
166
+ # Define the quiet option
167
+ # @return [void]
168
+ # @api private
169
+ def define_quiet_option
170
+ option_parser.on('-q', '--[no-]quiet', 'Do not show output') do |quiet|
171
+ options.quiet = quiet
172
+ end
173
+ end
174
+
175
+ # Define the verbose option
176
+ # @return [void]
177
+ # @api private
178
+ def define_verbose_option
179
+ option_parser.on('-v', '--[no-]verbose', 'Show extra output') do |verbose|
180
+ options.verbose = verbose
181
+ end
182
+ end
183
+
184
+ # Define the help option
185
+ # @return [void]
186
+ # @api private
187
+ def define_help_option
188
+ option_parser.on_tail('-h', '--help', 'Show this message') do
189
+ puts option_parser
190
+ exit 0
191
+ end
192
+ end
193
+
194
+ # Define the default_branch option which requires a value
195
+ # @return [void]
196
+ # @api private
197
+ def define_default_branch_option
198
+ option_parser.on('--default-branch=BRANCH_NAME', 'Override the default branch') do |name|
199
+ options.default_branch = name
200
+ end
201
+ end
202
+
203
+ # Define the release_branch option which requires a value
204
+ # @return [void]
205
+ # @api private
206
+ def define_release_branch_option
207
+ option_parser.on('--release-branch=BRANCH_NAME', 'Override the release branch to create') do |name|
208
+ options.release_branch = name
209
+ end
210
+ end
211
+
212
+ # Define the remote option which requires a value
213
+ # @return [void]
214
+ # @api private
215
+ def define_remote_option
216
+ option_parser.on('--remote=REMOTE_NAME', "Use this remote name instead of 'origin'") do |name|
217
+ options.remote = name
218
+ end
219
+ end
220
+
221
+ # Define the last_release_version option which requires a value
222
+ # @return [void]
223
+ # @api private
224
+ def define_last_release_version_option
225
+ option_parser.on('--last-release-version=VERSION', 'Use this version instead `semverify current`') do |version|
226
+ options.last_release_version = version
227
+ end
228
+ end
229
+
230
+ # Define the next_release_version option which requires a value
231
+ # @return [void]
232
+ # @api private
233
+ def define_next_release_version_option
234
+ option_parser.on(
235
+ '--next-release-version=VERSION',
236
+ 'Use this version instead `semverify next-RELEASE_TYPE`'
237
+ ) do |version|
238
+ options.next_release_version = version
239
+ end
240
+ end
241
+
242
+ # Define the changelog_path option which requires a value
243
+ # @return [void]
244
+ # @api private
245
+ def define_changelog_path_option
246
+ option_parser.on('--changelog-path=PATH', 'Use this file instead of CHANGELOG.md') do |name|
247
+ options.changelog_path = name
248
+ end
249
+ end
250
+ end
251
+ # rubocop:enable Metrics/ClassLength
252
+ end
253
+ end
@@ -0,0 +1,293 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CreateGithubRelease
4
+ module CommandLine
5
+ # Module containing all option validations
6
+ #
7
+ # All validation classes must inherit from `CreateGithubRelease::Validations::Base`
8
+ # and implement the `#valid?` and `#error` methods.
9
+ #
10
+ # All validation classes must be named `Validate*` and must be defined in the
11
+ # `CreateGithubRelease::Validations` namespace. Classes that follow this convention
12
+ # are automatically run by `CreateGithubRelease::CommandLine::OptionsValidator`.
13
+ #
14
+ # @api private
15
+ #
16
+ module Validations
17
+ # All validation classes inherit this classes initializer and options reader
18
+ # @api public
19
+ class Base
20
+ # Create a new validation object with the given options
21
+ #
22
+ # @example
23
+ # class ValidatePreFlag < Base
24
+ # def validate
25
+ # options.pre == false || %w[major minor patch].include?(options.release_type)
26
+ # end
27
+ # end
28
+ #
29
+ # @param options [CreateGithubRelease::CommandLine::Options] the options to validate
30
+ #
31
+ def initialize(options)
32
+ @options = options
33
+ end
34
+
35
+ private
36
+
37
+ # The options to validate
38
+ # @return [CreateGithubRelease::CommandLine::Options]
39
+ # @api private
40
+ attr_reader :options
41
+
42
+ # Returns `true` if the given version is a valid gem version
43
+ # @return [Boolean]
44
+ # @api private
45
+ def valid_gem_version?(version)
46
+ Gem::Version.new(version)
47
+ true
48
+ rescue ArgumentError
49
+ false
50
+ end
51
+
52
+ # `true` if the given name is a valid git reference
53
+ # @return [Boolean]
54
+ # @api private
55
+ def valid_reference?(name)
56
+ VALID_REF_PATTERN.match?(name)
57
+ end
58
+
59
+ # Returns `true` if the given path is a valid path
60
+ # @param path [String] the path to validate
61
+ # @return [Boolean]
62
+ # @api private
63
+ def valid_path?(path)
64
+ File.expand_path(path)
65
+ true
66
+ rescue ArgumentError
67
+ false
68
+ end
69
+ end
70
+
71
+ # Validate that `pre` is unset or is set with the appropriate release types
72
+ # @api private
73
+ #
74
+ class ValidatePreFlag < Base
75
+ # Returns `true` if valid
76
+ # @return [Boolean]
77
+ # @api private
78
+ def valid?
79
+ options.pre == false || %w[major minor patch].include?(options.release_type)
80
+ end
81
+
82
+ # Called when valid? is `false` to return the error messages
83
+ # @return [String, Array<String>]
84
+ # @api private
85
+ def error
86
+ '--pre can only be given with a release type of major, minor, or patch'
87
+ end
88
+ end
89
+
90
+ # Validate if pre_type is nil or releast_type is 'pre' or the pre flag is set
91
+ # @api private
92
+ #
93
+ class ValidatePreType < Base
94
+ # Returns `true` if valid
95
+ # @return [Boolean]
96
+ # @api private
97
+ def valid?
98
+ options.pre_type.nil? ||
99
+ options.release_type == 'pre' ||
100
+ (%w[major minor patch].include?(options.release_type) && options.pre == true)
101
+ end
102
+
103
+ # Called when valid? is `false` to return the error messages
104
+ # @return [String, Array<String>]
105
+ # @api private
106
+ def error
107
+ if %w[major minor patch pre].include?(options.release_type)
108
+ '--pre must be given when --pre-type is given'
109
+ else
110
+ '--pre-type can only be given with a release type of major, minor, patch, or pre'
111
+ end
112
+ end
113
+ end
114
+
115
+ # Validate that the quiet flag is true or false
116
+ # @api private
117
+ class ValidateQuiet < Base
118
+ # Returns `true` if valid
119
+ # @return [Boolean]
120
+ # @api private
121
+ def valid?
122
+ options.quiet == true || options.quiet == false
123
+ end
124
+
125
+ # Called when valid? is `false` to return the error messages
126
+ # @return [String, Array<String>]
127
+ # @api private
128
+ def error
129
+ 'quiet must be either true or false'
130
+ end
131
+ end
132
+
133
+ # Validate that the verbose flag is true or false
134
+ # @api private
135
+ class ValidateVerbose < Base
136
+ # Returns `true` if the `#verbose` is `true` or `false` and `false` otherwise
137
+ # @return [Boolean]
138
+ # @api private
139
+ def valid?
140
+ options.verbose == true || options.verbose == false
141
+ end
142
+
143
+ # Called when valid? is `false` to return the error messages
144
+ # @return [String, Array<String>]
145
+ # @api private
146
+ def error
147
+ 'verbose must be either true or false'
148
+ end
149
+ end
150
+
151
+ # Validate that either quiet or verbose is given, but not both
152
+ # @api private
153
+ class ValidateOnlyQuietOrVerbose < Base
154
+ # Returns `true` if at most only one of `#quiet` or `#verbose` is `true`
155
+ # @return [Boolean]
156
+ # @api private
157
+ def valid? = !options.quiet || !options.verbose
158
+
159
+ # Called when valid? is `false` to return the error messages
160
+ # @return [String, Array<String>]
161
+ # @api private
162
+ def error = '--quiet and --verbose cannot be used together'
163
+ end
164
+
165
+ # Validates that a release type is given
166
+ # @api private
167
+ class ValidateReleaseTypeGiven < Base
168
+ # Returns `true` if the `#release_type` is not nil
169
+ # @return [Boolean]
170
+ # @api private
171
+ def valid? = !options.release_type.nil?
172
+
173
+ # Called when valid? is `false` to return the error messages
174
+ # @return [String, Array<String>]
175
+ # @api private
176
+ def error
177
+ valid_release_types = "'#{VALID_RELEASE_TYPES.join("', '")}'"
178
+ "RELEASE_TYPE must be given. Must be one of #{valid_release_types}"
179
+ end
180
+ end
181
+
182
+ # Validates that the given release type is valid
183
+ # @api private
184
+ class ValidateReleaseType < Base
185
+ # Returns `true` if the `#release_type` is nil or a valid release type
186
+ # @return [Boolean]
187
+ # @api private
188
+ def valid? = options.release_type.nil? || VALID_RELEASE_TYPES.include?(options.release_type)
189
+
190
+ # Called when valid? is `false` to return the error messages
191
+ # @return [String, Array<String>]
192
+ # @api private
193
+ def error
194
+ valid_release_types = "'#{VALID_RELEASE_TYPES.join("', '")}'"
195
+ "RELEASE_TYPE '#{options.release_type}' is not valid. Must be one of #{valid_release_types}"
196
+ end
197
+ end
198
+
199
+ # Validates the default branch (if given) a valid Git reference
200
+ # @api private
201
+ class ValidateDefaultBranch < Base
202
+ # Returns `true` if the `#default_branch` is nil or is a valid git reference
203
+ # @return [Boolean]
204
+ # @api private
205
+ def valid? = options.default_branch.nil? || valid_reference?(options.default_branch)
206
+
207
+ # Called when valid? is `false` to return the error messages
208
+ # @return [String, Array<String>]
209
+ # @api private
210
+ def error = "--default-branch='#{options.default_branch}' is not valid"
211
+ end
212
+
213
+ # Validates the release branch (if given) a valid Git reference
214
+ # @api private
215
+ class ValidateReleaseBranch < Base
216
+ # Returns `true` if the `#release_branch` is nil or is a valid git reference
217
+ # @return [Boolean]
218
+ # @api private
219
+ def valid? = options.release_branch.nil? || valid_reference?(options.release_branch)
220
+
221
+ # Called when valid? is `false` to return the error messages
222
+ # @return [String, Array<String>]
223
+ # @api private
224
+ def error = "--release-branch='#{options.release_branch}' is not valid"
225
+ end
226
+
227
+ # Validate that the remote (if given) is a valid Git reference
228
+ # @api private
229
+ class ValidateRemote < Base
230
+ # Returns `true` if the `#remote` is nil or is a valid git reference
231
+ # @return [Boolean]
232
+ # @api private
233
+ def valid? = options.remote.nil? || valid_reference?(options.remote)
234
+
235
+ # Called when valid? is `false` to return the error messages
236
+ # @return [String, Array<String>]
237
+ # @api private
238
+ def error = "--remote='#{options.remote}' is not valid"
239
+ end
240
+
241
+ # Validate that the last release version (if given) is a valid gem version
242
+ # @api private
243
+ class ValidateLastReleaseVersion < Base
244
+ # Returns `true` if the `#last_release_version` is nil or is a valid gem version
245
+ # @return [Boolean]
246
+ # @api private
247
+ def valid? = options.last_release_version.nil? || valid_gem_version?(options.last_release_version)
248
+
249
+ # Called when valid? is `false` to return the error messages
250
+ # @return [String, Array<String>]
251
+ # @api private
252
+ def error = "--last-release-version='#{options.last_release_version}' is not valid"
253
+ end
254
+
255
+ # Validate that the next release version (if given) is a valid gem version
256
+ # @api private
257
+ class ValidateNextReleaseVersion < Base
258
+ # Returns `true` if the `#next_release_version` is nil or is a valid gem version
259
+ # @return [Boolean]
260
+ # @api private
261
+ def valid? = options.next_release_version.nil? || valid_gem_version?(options.next_release_version)
262
+
263
+ # Called when valid? is `false` to return the error messages
264
+ # @return [String, Array<String>]
265
+ # @api private
266
+ def error = "--next-release-version='#{options.next_release_version}' is not valid"
267
+ end
268
+
269
+ # Validate that the change log path (if given) is a valid path
270
+ # @api private
271
+ class ValidateChangelogPath < Base
272
+ # Returns `true` if `#changelog_path` is nil or is a valid regular file path
273
+ # @return [Boolean]
274
+ # @api private
275
+ def valid?
276
+ options.changelog_path.nil? ||
277
+ (valid_path?(options.changelog_path) && File.file?(File.expand_path(options.changelog_path)))
278
+ end
279
+
280
+ # Called when valid? is `false` to return the error messages
281
+ # @return [String, Array<String>]
282
+ # @api private
283
+ def error
284
+ if valid_path?(options.changelog_path)
285
+ "The change log path '#{options.changelog_path}' is not a regular file"
286
+ else
287
+ "The change log path '#{options.changelog_path}' is not a valid path"
288
+ end
289
+ end
290
+ end
291
+ end
292
+ end
293
+ end