shellopts 2.0.22 → 2.1.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: d3f9f19d62ccf36d5de39421163eb70e7aa8ae621cee13381d48ce68e7ab593d
4
- data.tar.gz: 13351ee8dceceea7c5da573de7c5bd257aa2efd1c4690be760f6ebe1445ca8c9
3
+ metadata.gz: f1d0ed936b5b28c84361778049101596d995b5b38f9f23be0dc5643f86dc3592
4
+ data.tar.gz: d856b85fc55bf2f58b7d5245318e122f3c3508301775d281d579f0acdc0441be
5
5
  SHA512:
6
- metadata.gz: 4afd636e92e1ff74b45c77399d4dbaba6afaccd441ee528800a727ed5e4db802d481d8dcaaddcd46bdbcd7c28f3b121b35e42b63e44f02d006c557eafda29692
7
- data.tar.gz: 7c12cd6d9f0dede5c7931cf82b8e1ff32d4de738c2d3dd42fb5c2f65740ed0804078eb65ca0b951ce28a1095fd9b43289df01501275a5f9c178a965e569aa054
6
+ metadata.gz: 3ebba6fac6a845cc7a71d468db989a34379ead52aeb5ce634df83ea8eafad4a9cfc3bea553fa5d477a2cff50a9e3056865e50490b721a7e3df38094fbdfae102
7
+ data.tar.gz: 52403c31f4f35b19b52cb7e41f5cdfb15733b28eeb4e374dbb2f9b0f6f1ebff8085d047342cb3860173e5bfc1fe039c022b40f17e4e2a06c8b88213c393d6617
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.7.1
1
+ ruby-3.1.2
data/TODO CHANGED
@@ -1,4 +1,5 @@
1
1
 
2
+ o Assigner methods for options
2
3
  o Make opts[] point at the main object
3
4
  opts[].subcommand is the direct subcommand of main
4
5
  o Make opts be the aggrated set of options in a subcommand
@@ -18,7 +18,8 @@ module ShellOpts
18
18
  # if type is an IntegerArgument
19
19
  def value?(value) true end
20
20
 
21
- # Convert value to Ruby type
21
+ # Convert value to Ruby type. This method can also be used to translate
22
+ # special keywords
22
23
  def convert(value) value end
23
24
 
24
25
  # String representation. Equal to #name
@@ -60,69 +61,120 @@ module ShellOpts
60
61
  attr_reader :kind
61
62
 
62
63
  def initialize(kind)
63
- constrain kind, :file, :dir, :path, :efile, :edir, :epath, :nfile, :ndir, :npath
64
+ constrain kind, :file, :dir, :path, :efile, :edir, :epath, :nfile, :ndir, :npath, :ifile, :ofile
64
65
  @kind = kind
65
66
  end
66
67
 
67
68
  def match?(name, literal)
68
- case kind
69
- when :file; match_path(name, literal, kind, :file?, :default)
70
- when :dir; match_path(name, literal, kind, :directory?, :default)
71
- when :path; match_path(name, literal, kind, :exist?, :default)
72
-
73
- when :efile; match_path(name, literal, kind, :file?, :exist)
74
- when :edir; match_path(name, literal, kind, :directory?, :exist)
75
- when :epath; match_path(name, literal, kind, :exist?, :exist)
76
-
77
- when :nfile; match_path(name, literal, kind, :file?, :new)
78
- when :ndir; match_path(name, literal, kind, :directory?, :new)
79
- when :npath; match_path(name, literal, kind, :exist?, :new)
69
+ # Special-case '-' keyword
70
+ if literal == '-' && [:ifile, :ofile].include?(kind)
71
+ true
72
+
73
+ # Special-case standard I/O files
74
+ elsif %w(/dev/stdin /dev/stdout /dev/stderr /dev/null).include?(literal)
75
+ case kind
76
+ when :file, :path, :efile, :epath, :nfile, :npath
77
+ true
78
+ when :ifile
79
+ %w(/dev/stdin /dev/null).include? literal or
80
+ set_message "Can't read #{literal}"
81
+ when :ofile
82
+ %w(/dev/stdout /dev/stderr /dev/null).include?(literal) or
83
+ set_message "Can't write to #{literal}"
84
+ when :dir, :edir, :ndir
85
+ set_message "Expected file, got directory #{literal}"
86
+ else
87
+ raise ArgumentError, "Unhandled kind: #{kind.inspect}"
88
+ end
89
+
90
+ # All other files or directories
80
91
  else
81
- raise InternalError, "Illegal kind: #{kind.inspect}"
92
+ case kind # TODO: node, enode, npath - special files: character, block, socket, etc.
93
+ when :file; match_path(name, literal, kind, :file?, :default)
94
+ when :dir; match_path(name, literal, kind, :directory?, :default)
95
+ when :path; match_path(name, literal, kind, :exist?, :default)
96
+
97
+ when :efile; match_path(name, literal, kind, :file?, :exist)
98
+ when :edir; match_path(name, literal, kind, :directory?, :exist)
99
+ when :epath; match_path(name, literal, kind, :exist?, :exist)
100
+
101
+ when :nfile; match_path(name, literal, kind, :file?, :new)
102
+ when :ndir; match_path(name, literal, kind, :directory?, :new)
103
+ when :npath; match_path(name, literal, kind, :exist?, :new)
104
+
105
+ when :ifile; match_path(name, literal, kind, :readable?, :default)
106
+ when :ofile; match_path(name, literal, kind, :writable?, :default)
107
+ else
108
+ raise InternalError, "Illegal kind: #{kind.inspect}"
109
+ end
82
110
  end
83
111
  end
84
112
 
85
113
  # Note: No checks done, not sure if it is a feature or a bug
86
114
  def value?(value) value.is_a?(String) end
87
115
 
116
+ def convert(value)
117
+ if value == "-"
118
+ case kind
119
+ when :ifile; "/dev/stdin"
120
+ when :ofile; "/dev/stdout"
121
+ else
122
+ value
123
+ end
124
+ else
125
+ value
126
+ end
127
+ end
128
+
88
129
  protected
89
130
  def match_path(name, literal, kind, method, mode)
90
131
  subject =
91
132
  case kind
92
- when :file, :efile, :nfile; "regular file"
133
+ when :file, :efile, :nfile, :ifile, :ofile; "file"
93
134
  when :dir, :edir, :ndir; "directory"
94
135
  when :path, :epath, :npath; "path"
95
136
  else
96
137
  raise ArgumentError
97
138
  end
98
139
 
99
- if File.send(method, literal) # exists?
140
+ # file exists and is the rigth type?
141
+ if File.send(method, literal)
100
142
  if mode == :new
101
143
  set_message "#{subject.capitalize} already exists in #{name}: #{literal}"
102
144
  elsif kind == :path || kind == :epath
103
145
  if File.file?(literal) || File.directory?(literal)
104
146
  true
105
147
  else
106
- set_message "Expected regular file or directory as #{name} argument: #{literal}"
148
+ set_message "Expected file or directory as #{name} argument: #{literal}"
107
149
  end
150
+ elsif (kind == :ifile || kind == :ofile) && File.directory?(literal)
151
+ set_message "File expected, got directory: #{literal}"
108
152
  else
109
153
  true
110
154
  end
111
- elsif File.exist?(literal) # exists but not the right type
112
- if mode == :new
113
- set_message "#{subject.capitalize} already exists"
155
+
156
+ # file exists but not the right type?
157
+ elsif File.exist?(literal)
158
+ if kind == :ifile
159
+ set_message "Can't read #{literal}"
160
+ elsif kind == :ofile
161
+ set_message "Can't write to #{literal}"
162
+ elsif mode == :new
163
+ set_message "#{subject.capitalize} already exists - #{literal}"
114
164
  else
115
165
  set_message "Expected #{subject} as #{name} argument: #{literal}"
116
166
  end
117
- else # does not exist
167
+
168
+ # file does not exist
169
+ else
118
170
  if [:default, :new].include? mode
119
- if File.exist?(File.dirname(literal))
171
+ if File.exist?(File.dirname(literal)) || kind == :ofile
120
172
  true
121
173
  else
122
174
  set_message "Illegal path in #{name}: #{literal}"
123
175
  end
124
176
  else
125
- set_message "Error in #{name} argument: Can't find #{literal}"
177
+ set_message "Can't find #{literal}"
126
178
  end
127
179
  end
128
180
  end
@@ -83,8 +83,8 @@ module ShellOpts
83
83
  when "$"
84
84
  @argument_name ||= "NUM"
85
85
  @argument_type = FloatArgument.new
86
- when "FILE", "DIR", "PATH", "EFILE", "EDIR", "EPATH", "NFILE", "NDIR", "NPATH"
87
- @argument_name ||= arg.sub(/^(?:E|N)/, "")
86
+ when "FILE", "DIR", "PATH", "EFILE", "EDIR", "EPATH", "NFILE", "NDIR", "NPATH", "IFILE", "OFILE"
87
+ @argument_name ||= arg.sub(/^(?:E|N|I|O)/, "")
88
88
  @argument_type = FileArgument.new(arg.downcase.to_sym)
89
89
  when /,/
90
90
  @argument_name ||= arg
@@ -1,3 +1,3 @@
1
1
  module ShellOpts
2
- VERSION = "2.0.22"
2
+ VERSION = "2.1.0"
3
3
  end
data/lib/shellopts.rb CHANGED
@@ -27,6 +27,17 @@ require 'shellopts/renderer.rb'
27
27
  require 'shellopts/formatter.rb'
28
28
  require 'shellopts/dump.rb'
29
29
 
30
+ # TODO: Describe exception handling
31
+ #
32
+ # Notes
33
+ # * Two kinds of exceptions: Expected & unexpected. Expected exceptions are
34
+ # RuntimeError or IOError. Unexpected exceptions are the rest. Both results
35
+ # in shellopts.failure messages if shellopts error handling is enabled
36
+ # * Describe the difference between StandardError, RuntimeError, and IOError
37
+ # * Add an #internal error handling for the production environment that
38
+ # prints an intelligble error message and prettyfies stack dump. This
39
+ # should catch non-RuntimeError/UIError exceptions
40
+ # * Find a reliable way of testing environment
30
41
 
31
42
  module ShellOpts
32
43
  # Base error class
@@ -140,7 +151,7 @@ module ShellOpts
140
151
  float: true,
141
152
 
142
153
  # Let exceptions through
143
- exceptions: false
154
+ exception: false
144
155
  )
145
156
 
146
157
  @name = name || File.basename($PROGRAM_NAME)
data/shellopts.gemspec CHANGED
@@ -25,11 +25,10 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  spec.add_dependency "forward_to"
27
27
  spec.add_dependency "constrain", "~> 0.5.1"
28
- spec.add_dependency "ruby-terminfo"
28
+ spec.add_dependency "ruby-terminfo-r3"
29
29
  spec.add_dependency "indented_io"
30
30
 
31
- spec.add_development_dependency "bundler", "~> 2.2.10"
32
- spec.add_development_dependency "rake", ">= 12.3.3"
33
- spec.add_development_dependency "rspec", "~> 3.0"
31
+ spec.add_development_dependency "rake"
32
+ spec.add_development_dependency "rspec"
34
33
  spec.add_development_dependency "simplecov"
35
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shellopts
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.22
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-23 00:00:00.000000000 Z
11
+ date: 2022-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: forward_to
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.5.1
41
41
  - !ruby/object:Gem::Dependency
42
- name: ruby-terminfo
42
+ name: ruby-terminfo-r3
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -66,48 +66,34 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: bundler
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 2.2.10
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 2.2.10
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: rake
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - ">="
88
74
  - !ruby/object:Gem::Version
89
- version: 12.3.3
75
+ version: '0'
90
76
  type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
80
  - - ">="
95
81
  - !ruby/object:Gem::Version
96
- version: 12.3.3
82
+ version: '0'
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: rspec
99
85
  requirement: !ruby/object:Gem::Requirement
100
86
  requirements:
101
- - - "~>"
87
+ - - ">="
102
88
  - !ruby/object:Gem::Version
103
- version: '3.0'
89
+ version: '0'
104
90
  type: :development
105
91
  prerelease: false
106
92
  version_requirements: !ruby/object:Gem::Requirement
107
93
  requirements:
108
- - - "~>"
94
+ - - ">="
109
95
  - !ruby/object:Gem::Version
110
- version: '3.0'
96
+ version: '0'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: simplecov
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -172,7 +158,7 @@ files:
172
158
  homepage: http://github.com/clrgit/shellopts
173
159
  licenses: []
174
160
  metadata: {}
175
- post_install_message:
161
+ post_install_message:
176
162
  rdoc_options: []
177
163
  require_paths:
178
164
  - lib
@@ -187,8 +173,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
173
  - !ruby/object:Gem::Version
188
174
  version: '0'
189
175
  requirements: []
190
- rubygems_version: 3.1.4
191
- signing_key:
176
+ rubygems_version: 3.3.18
177
+ signing_key:
192
178
  specification_version: 4
193
179
  summary: Parse command line options and arguments
194
180
  test_files: []