philiprehberger-cli_kit 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15240e9c9eb6ad374dafd6457c91e3d1514b34031ccb57f00b4283b266bf3575
4
- data.tar.gz: 77fd549d9211ab095433cebe4938db8fd1188e1cffb124c19c91a77e5ce428a8
3
+ metadata.gz: c4606c83ce0c95c7b047c9db662457bce97852169987a96a44566d4811e78313
4
+ data.tar.gz: 907327c09e57175ca6e1c07d03369fdfe5f157534836e64acf348b79dc439a5e
5
5
  SHA512:
6
- metadata.gz: b18bf81377d13116b703b5938d8e0b6c84e18272570d1f0eb2b598f125d80d0f603298735445873445882e073d504c25694313c7604157b907817c908b71417f
7
- data.tar.gz: 636957466367093c8cdd87305abcffb8523633182e513223f50898d876e3c93e2d3dab4c0a1290350c344d8f6d04d53f66cce5b097b609990e4907f10a54d931
6
+ metadata.gz: '08bb60e7b9c05a9e6d5572a8a393f61b987c07a136f7cb1eaf6e6ac58168fea50230f5855d073c47bd0516b178d19e138d223ccc7ff4e529248b9aef16f08699'
7
+ data.tar.gz: 20864d8ed45d20aabe85d072ba1adcb44590c76f346329e51314b4163bce07951b2759327ef852112bccaec05f82705e28b5534502d5b5dde6e2b0efaddb4733
data/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.0] - 2026-04-18
11
+
12
+ ### Added
13
+ - `option :name, required: true` — DSL flag that raises `CliKit::Error` at parse time when the option is omitted; help output appends `(required)` to the option's description
14
+
15
+ ## [0.3.1] - 2026-04-15
16
+
17
+ ### Changed
18
+ - Compliance audit against Ruby package, gemspec, and README guides — no blocking issues found; reaffirmed gemspec metadata (5 URIs, `rubygems_mfa_required`, `required_ruby_version >= 3.1.0`, `Dir['lib/**/*.rb', 'LICENSE', 'README.md', 'CHANGELOG.md']`), README structure (10 sections with 3 badges and emoji Support list), Keep a Changelog format, full `.github/` scaffolding (issue templates, dependabot, PR template, CI matrix with publish job), and config files (`.rubocop.yml`, `.gitignore`, `Gemfile`, `Rakefile`)
19
+
10
20
  ## [0.3.0] - 2026-04-15
11
21
 
12
22
  ### Added
@@ -58,7 +68,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
58
68
  - Animated spinner for long-running operations
59
69
  - Positional argument collection
60
70
 
61
- [Unreleased]: https://github.com/philiprehberger/rb-cli-kit/compare/v0.3.0...HEAD
71
+ [Unreleased]: https://github.com/philiprehberger/rb-cli-kit/compare/v0.4.0...HEAD
72
+ [0.4.0]: https://github.com/philiprehberger/rb-cli-kit/compare/v0.3.1...v0.4.0
73
+ [0.3.1]: https://github.com/philiprehberger/rb-cli-kit/compare/v0.3.0...v0.3.1
62
74
  [0.3.0]: https://github.com/philiprehberger/rb-cli-kit/compare/v0.2.1...v0.3.0
63
75
  [0.2.1]: https://github.com/philiprehberger/rb-cli-kit/compare/v0.2.0...v0.2.1
64
76
  [0.2.0]: https://github.com/philiprehberger/rb-cli-kit/compare/v0.1.2...v0.2.0
data/README.md CHANGED
@@ -105,6 +105,20 @@ port = Philiprehberger::CliKit.ask('Port:', error: 'Must be a number') do |answe
105
105
  end
106
106
  ```
107
107
 
108
+ ### Required options
109
+
110
+ ```ruby
111
+ result = Philiprehberger::CliKit.parse(ARGV) do
112
+ option :env, short: :e, required: true, desc: 'Target environment'
113
+ end
114
+
115
+ # Invoked without --env raises Philiprehberger::CliKit::Error:
116
+ # Missing required option(s): --env
117
+ #
118
+ # Help text appends "(required)" to the option's description:
119
+ # -e, --env VALUE Target environment (required)
120
+ ```
121
+
108
122
  ### Repeatable Options
109
123
 
110
124
  ```ruby
@@ -176,6 +190,7 @@ end
176
190
  | `.multi_select(message, choices, defaults:)` | Present numbered menu and return multiple selections |
177
191
  | `.spinner(message) { ... }` | Show spinner during block execution |
178
192
  | `Parser#option(name, multi: true)` | Collect repeated option values into an array |
193
+ | `Parser#option(name, required: true)` | Raise `CliKit::Error` at parse time when the option is omitted |
179
194
  | `Parser#flags` | Hash of boolean flag values |
180
195
  | `Parser#options` | Hash of option values (arrays when `multi: true`) |
181
196
  | `Parser#arguments` | Array of positional arguments |
@@ -13,6 +13,7 @@ module Philiprehberger
13
13
  @flags = {}
14
14
  @options = {}
15
15
  @arguments = []
16
+ @supplied_options = []
16
17
  @command_name = nil
17
18
  @program_name = nil
18
19
  end
@@ -35,9 +36,12 @@ module Philiprehberger
35
36
  # @param default [Object, nil] default value
36
37
  # @param desc [String, nil] description for help text
37
38
  # @param multi [Boolean] when true, collect repeated values into an array
39
+ # @param required [Boolean] when true, raise if the option is not supplied at parse time
38
40
  # @return [void]
39
- def option(name, short: nil, default: nil, desc: nil, multi: false)
40
- @option_definitions[name] = { short: short, default: default, desc: desc, multi: multi }
41
+ def option(name, short: nil, default: nil, desc: nil, multi: false, required: false)
42
+ @option_definitions[name] = {
43
+ short: short, default: default, desc: desc, multi: multi, required: required
44
+ }
41
45
  @options[name] = multi ? [] : default
42
46
  end
43
47
 
@@ -131,6 +135,7 @@ module Philiprehberger
131
135
  @arguments << arg
132
136
  end
133
137
  end
138
+ validate_required_options!
134
139
  self
135
140
  end
136
141
 
@@ -172,6 +177,7 @@ module Philiprehberger
172
177
 
173
178
  def assign_option(name, value)
174
179
  defn = @option_definitions[name]
180
+ @supplied_options << name
175
181
  if defn && defn[:multi]
176
182
  @options[name] = [] unless @options[name].is_a?(Array)
177
183
  @options[name] << value unless value.nil?
@@ -180,6 +186,16 @@ module Philiprehberger
180
186
  end
181
187
  end
182
188
 
189
+ def validate_required_options!
190
+ missing = @option_definitions.each_with_object([]) do |(name, defn), acc|
191
+ acc << name if defn[:required] && !@supplied_options.include?(name)
192
+ end
193
+ return if missing.empty?
194
+
195
+ names = missing.map { |n| "--#{n.to_s.tr('_', '-')}" }.join(', ')
196
+ raise Error, "Missing required option(s): #{names}"
197
+ end
198
+
183
199
  def format_flag_help(name, defn)
184
200
  long = "--#{name.to_s.tr('_', '-')}"
185
201
  if defn[:short]
@@ -204,8 +220,10 @@ module Philiprehberger
204
220
  else
205
221
  label = " #{long}"
206
222
  end
207
- if defn[:desc]
208
- "#{label.ljust(24)}#{defn[:desc]}"
223
+ desc = defn[:desc]
224
+ desc = desc ? "#{desc} (required)" : '(required)' if defn[:required]
225
+ if desc
226
+ "#{label.ljust(24)}#{desc}"
209
227
  else
210
228
  label
211
229
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module CliKit
5
- VERSION = '0.3.0'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-cli_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Rehberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-15 00:00:00.000000000 Z
11
+ date: 2026-04-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Lightweight CLI toolkit combining argument parsing with flags and options,
14
14
  interactive prompts with confirmation, and animated spinners for long-running operations.