cl 0.1.1 → 0.1.2

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: da6cdad4d896abab8412852de0be59f703cd8ac6f0e45a48f79f918d5d62af07
4
- data.tar.gz: e0b943d332a2879a408f242c4704f53b43a27f18f7b59aaf4fade5e85aade13f
3
+ metadata.gz: 8887728de74e5c76602f7aacb96b7681f89186b8f9688c9a2fe5dc239a921dbe
4
+ data.tar.gz: a7105d685d6965d82179c9f7b329d185016dd808b4468a0aa17d7f6f61fbfb25
5
5
  SHA512:
6
- metadata.gz: e61008ae542e1ac9c3ec28c558ad85c64ea37bbb102c6c45a2cc91ce1acba24b5bc59a4f4b081b3c130724cf877df6b7cb9f635470d5f598f69fb9d6d7c28f8b
7
- data.tar.gz: 82a49b01e5ac7f7969c701f12c78a6e345ed333e72ad006aea843cb6fe0f7d540bb143f8e4abbc9ee4c97e338cd6175a2fac1f88e0a07ada7b6f4b459a0a9cd1
6
+ metadata.gz: 774ddb21196dd996ed6a627e24eb67a01f0f9a4b44dbf1c04326ff1840c5c999dd4b738bdfd3e1d9d6a874cdb7f6edad8df21c2d0431755b724e47ef74e38ff8
7
+ data.tar.gz: baa6e4fc6ca95b7d34763422a1d25efbffad810173f8c79cc981c375a45c75c0542e9db1104cb5caa1d966aa2d7c3b3dba63f6073ed2dd8daec86466275e2a88
data/CHANGELOG.md CHANGED
@@ -6,16 +6,19 @@
6
6
 
7
7
  * Add config, reading from env vars and yml files (inspired by gem-release)
8
8
  * Add `abstract` in order to signal a cmd is a base class that is not meant to be executed
9
- * Add `opt '--path', type: :array` for options that can be given multiple times
9
+ * Add `required :one, [:two, :three]` (DNF, i.e: either :one or both :two and :three must be given)
10
+ * Add `opt '--one STR', type: :array` for options that can be given multiple times
10
11
  * Add `opt '--one STR', default: 'one'`
11
12
  * Add `opt '--one STR', requires :two` or `[:two, :three]` for options that depend on other options
12
13
  * Add `opt '--one', alias: :other`
13
14
  * Add `opt '--one', deprecated: 'message'`, and `cmd.deprected_opts`, so clients can look up which deprecated options were used
14
15
  * Add `opt '--one', alias: :other, deprecated: :other`, so that `cmd.deprecated_opts` returns the alias name if it was used
15
- * Add `opt '--int', max: 10, type: :integer`
16
- * Add `opt '--one', format: /.+/`
17
- * Add `opt '--one', enum: ['one', 'two']`
18
- * Add `required :one, [:two, :three]` (DNF, i.e: either :one or both :two and :three must be given)
16
+ * Add `opt '--int INT', max: 10, type: :integer`
17
+ * Add `opt '--one STR', format: /.+/`
18
+ * Add `opt '--one STR', enum: ['one', /\w+/]`
19
+ * Add `opt '--one STR', downcase: true`
20
+ * Add `opt '--one STR', example: 'foo'`
21
+ * Add `opt '--one STR', see: 'https://provider.com/docs'
19
22
 
20
23
  ### Changed
21
24
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cl (0.0.4)
4
+ cl (0.1.1)
5
5
  regstry (~> 1.0.3)
6
6
 
7
7
  GEM
@@ -33,4 +33,4 @@ DEPENDENCIES
33
33
  rspec
34
34
 
35
35
  BUNDLED WITH
36
- 1.17.2
36
+ 2.0.1
data/NOTES.md CHANGED
@@ -1,3 +1,5 @@
1
1
  - properly catch errors, see examples/cast etc
2
2
  - add conditional required: ->(opts) { opts[:key].nil? }
3
3
 
4
+
5
+ - wrap long lines in help output
data/lib/cl/help/cmd.rb CHANGED
@@ -102,7 +102,10 @@ class Cl
102
102
  opts << "default: #{format_default(opt)}" if opt.default?
103
103
  opts << "known values: #{opt.enum.join(', ')}" if opt.enum?
104
104
  opts << "format: #{opt.format}" if opt.format?
105
+ opts << "downcase: true" if opt.downcase?
105
106
  opts << "max: #{opt.max}" if opt.max?
107
+ opts << "e.g.: #{opt.example}" if opt.example?
108
+ opts << "see: #{opt.see}" if opt.see?
106
109
  opts << format_deprecated(opt) if opt.deprecated?
107
110
  opts.compact
108
111
  end
@@ -118,7 +121,7 @@ class Cl
118
121
 
119
122
  def format_type(obj)
120
123
  return obj.type unless obj.is_a?(Opt) && obj.type == :array
121
- "array (can be given multiple times)"
124
+ "array (string, can be given multiple times)"
122
125
  end
123
126
 
124
127
  def format_default(opt)
data/lib/cl/helper.rb CHANGED
@@ -8,4 +8,13 @@ class Cl
8
8
  objs.inject({}) { |lft, rgt| lft.merge(rgt, &MERGE) }
9
9
  end
10
10
  end
11
+
12
+ module Regex
13
+ def format_regex(str)
14
+ return str unless str.is_a?(Regexp)
15
+ "/#{str.to_s.sub('(?-mix:', '').sub(/\)$/, '')}/"
16
+ end
17
+ end
18
+
19
+ extend Merge, Regex
11
20
  end
data/lib/cl/opt.rb CHANGED
@@ -2,7 +2,7 @@ require 'cl/cast'
2
2
 
3
3
  class Cl
4
4
  class Opt < Struct.new(:strs, :opts, :block)
5
- include Cast
5
+ include Cast, Regex
6
6
 
7
7
  OPT = /^--(?:\[.*\])?(.*)$/
8
8
 
@@ -45,10 +45,6 @@ class Cl
45
45
  type == :int || type == :integer
46
46
  end
47
47
 
48
- def description
49
- opts[:description]
50
- end
51
-
52
48
  def aliases?
53
49
  !!opts[:alias]
54
50
  end
@@ -57,6 +53,10 @@ class Cl
57
53
  Array(opts[:alias])
58
54
  end
59
55
 
56
+ def description
57
+ opts[:description]
58
+ end
59
+
60
60
  def deprecated?
61
61
  !!opts[:deprecated]
62
62
  end
@@ -66,6 +66,10 @@ class Cl
66
66
  [opts[:deprecated], name] if opts[:deprecated]
67
67
  end
68
68
 
69
+ def downcase?
70
+ !!opts[:downcase]
71
+ end
72
+
69
73
  def default?
70
74
  !!default
71
75
  end
@@ -84,6 +88,19 @@ class Cl
84
88
 
85
89
  def known?(value)
86
90
  enum.include?(value)
91
+ enum.any? { |obj| matches?(obj, value) }
92
+ end
93
+
94
+ def matches?(obj, value)
95
+ obj.is_a?(Regexp) ? obj =~ value.to_s : obj == value
96
+ end
97
+
98
+ def example?
99
+ !!opts[:example]
100
+ end
101
+
102
+ def example
103
+ opts[:example]
87
104
  end
88
105
 
89
106
  def format?
@@ -91,7 +108,7 @@ class Cl
91
108
  end
92
109
 
93
110
  def format
94
- opts[:format].to_s.sub('(?-mix:', '').sub(/\)$/, '')
111
+ format_regex(opts[:format])
95
112
  end
96
113
 
97
114
  def formatted?(value)
@@ -118,6 +135,14 @@ class Cl
118
135
  Array(opts[:requires])
119
136
  end
120
137
 
138
+ def see?
139
+ !!opts[:see]
140
+ end
141
+
142
+ def see
143
+ opts[:see]
144
+ end
145
+
121
146
  def block
122
147
  # raise if no block was given, and the option's name cannot be inferred
123
148
  super || method(:assign)
data/lib/cl/opts.rb CHANGED
@@ -2,7 +2,7 @@ require 'cl/opt'
2
2
 
3
3
  class Cl
4
4
  class Opts
5
- include Enumerable
5
+ include Enumerable, Regex
6
6
 
7
7
  def define(const, *args, &block)
8
8
  opts = args.last.is_a?(Hash) ? args.pop : {}
@@ -16,6 +16,7 @@ class Cl
16
16
 
17
17
  def apply(cmd, opts)
18
18
  opts = with_defaults(cmd, opts)
19
+ opts = downcase(opts)
19
20
  opts = cast(opts)
20
21
  validate(cmd, opts) unless opts[:help]
21
22
  opts
@@ -106,6 +107,7 @@ class Cl
106
107
 
107
108
  def missing_requires(opts)
108
109
  select(&:requires?).map do |opt|
110
+ next unless opts.key?(opt.name)
109
111
  missing = opt.requires.select { |key| !opts.key?(key) }
110
112
  [opt.name, missing] if missing.any?
111
113
  end.compact
@@ -113,19 +115,24 @@ class Cl
113
115
 
114
116
  def exceeding_max(opts)
115
117
  select(&:max?).map do |opt|
116
- [opt.name, opt.max] if opts[opt.name] > opt.max
118
+ value = opts[opt.name]
119
+ [opt.name, opt.max] if value && value > opt.max
117
120
  end.compact
118
121
  end
119
122
 
120
123
  def invalid_format(opts)
121
124
  select(&:format?).map do |opt|
122
- [opt.name, opt.format] unless opt.formatted?(opts[opt.name])
125
+ value = opts[opt.name]
126
+ [opt.name, opt.format] if value && !opt.formatted?(value)
123
127
  end.compact
124
128
  end
125
129
 
126
130
  def unknown_values(opts)
127
131
  select(&:enum?).map do |opt|
128
- [opt.name, opts[opt.name], opt.enum] unless opt.known?(opts[opt.name])
132
+ value = opts[opt.name]
133
+ next unless value && !opt.known?(value)
134
+ known = opt.enum.map { |str| format_regex(str) }
135
+ [opt.name, value, known]
129
136
  end.compact
130
137
  end
131
138
 
@@ -142,6 +149,13 @@ class Cl
142
149
  opts[key] || cmd.respond_to?(key) && cmd.send(key)
143
150
  end
144
151
 
152
+ def downcase(opts)
153
+ select(&:downcase?).inject(opts) do |opts, opt|
154
+ next opts unless value = opts[opt.name]
155
+ opts.merge(opt.name => value.to_s.downcase)
156
+ end
157
+ end
158
+
145
159
  def cast(opts)
146
160
  opts.map do |key, value|
147
161
  [key, self[key] ? self[key].cast(value) : value]
data/lib/cl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Cl
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.2'
3
3
  end
data/lib/cl.rb CHANGED
@@ -29,8 +29,8 @@ class Cl
29
29
 
30
30
  class RequiredsOpts < OptionError
31
31
  def initialize(opts)
32
- opts = opts.map { |alts| alts.map { |alt| Array(alt).join(' and ') }.join(' or ' ) }
33
- super(:requires_opts, opts.join(', '))
32
+ opts = opts.map { |alts| alts.map { |alt| Array(alt).join(' and ') }.join(', or ' ) }
33
+ super(:requires_opts, opts.join('; '))
34
34
  end
35
35
  end
36
36
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs