@@ -100,25 +100,28 @@ class Option
100100 # @return [:text, :textarea, :radio, :checkbox, :select, :url, :url2, :none]
101101 attr_reader :control
102102
103- # Is this a required option?
104- # @return [Boolean ]
105- attr_reader :required
103+ # Use of this option
104+ # @return [:optional, :disabled, :removed, :required ]
105+ attr_accessor :use
106106
107107 ##
108108 # Create a new option with optional callback.
109109 #
110110 # @param [Symbol] symbol
111111 # @param [Array<String>] on
112+ # @param [String] datatype
113+ # @param [String] control
112114 # @param [String] description
115+ # @param [[:optional, :disabled, :removed, :required]] use
113116 # @yield value which may be used within `OptionParser#on`
114117 # @yieldparam [Object] value The option value as parsed using `on` argument
115118 # @yieldparam [OptionParser] options (nil) optional OptionParser
116119 # @yieldreturn [Object] a possibly modified input value
117120 def initialize ( symbol : nil , on : nil , datatype : nil , control : nil ,
118- description : nil , required : false , **options , &block )
121+ description : nil , use : :optional , **options , &block )
119122 raise ArgumentError , "symbol is a required argument" unless symbol
120123 raise ArgumentError , "on is a required argument" unless on
121- @symbol , @on , @datatype , @control , @description , @required , @callback = symbol . to_sym , Array ( on ) , datatype , control , description , required , block
124+ @symbol , @on , @datatype , @control , @description , @use , @callback = symbol . to_sym , Array ( on ) , datatype , control , description , use , block
122125 end
123126
124127 def call ( arg , options )
@@ -139,7 +142,7 @@ def to_hash
139142 datatype : ( datatype . is_a? ( Class ) ? datatype . name : datatype ) ,
140143 control : control ,
141144 description : description ,
142- required : required
145+ use : use
143146 }
144147 end
145148 end
@@ -151,12 +154,14 @@ def to_hash
151154 # * `lambda` code run to execute command.
152155 # * `filter` Option values that must match for command to be used
153156 # * `control` Used to indicate how (if) command is displayed
154- # * `options` an optional array of `RDF::CLI::Option` describing command-specific options, which may also be used to remove general options.
157+ # * `options` an optional array of `RDF::CLI::Option` describing command-specific options.
158+ # * `option_use`: A hash of option symbol to option usage, used for overriding the default status of an option for this command.
155159 # @return [Hash{Symbol => Hash{Symbol => Object}}]
156160 COMMANDS = {
157161 count : {
158162 description : "Count statements in parsed input" ,
159163 parse : false ,
164+ control : :none ,
160165 help : "count [options] [args...]\n returns number of parsed statements" ,
161166 lambda : -> ( argv , opts ) do
162167 unless repository . count > 0
@@ -171,9 +176,7 @@ def to_hash
171176 opts [ :output ] . puts "Parsed #{ count } statements with #{ @readers . join ( ', ' ) } in #{ secs } seconds @ #{ count /secs } statements/second."
172177 end
173178 end ,
174- options : [
175- RDF ::CLI ::Option . new ( symbol : :output_format , on : [ ] )
176- ]
179+ option_use : { output_format : :disabled }
177180 } ,
178181 help : {
179182 description : "This message" ,
@@ -184,44 +187,41 @@ def to_hash
184187 lengths : {
185188 description : "Lengths of each parsed statement" ,
186189 parse : true ,
190+ control : :none ,
187191 help : "lengths [options] [args...]\n returns lengths of each parsed statement" ,
188192 lambda : -> ( argv , opts ) do
189193 opts [ :output ] . puts "Lengths"
190194 repository . each_statement do |statement |
191195 opts [ :output ] . puts statement . to_s . size
192196 end
193197 end ,
194- options : [
195- RDF ::CLI ::Option . new ( symbol : :output_format , on : [ ] )
196- ]
198+ option_use : { output_format : :disabled }
197199 } ,
198200 objects : {
199201 description : "Serialize each parsed object to N-Triples" ,
200202 parse : true ,
203+ control : :none ,
201204 help : "objects [options] [args...]\n returns unique objects serialized in N-Triples format" ,
202205 lambda : -> ( argv , opts ) do
203206 opts [ :output ] . puts "Objects"
204207 repository . each_object do |object |
205208 opts [ :output ] . puts object . to_ntriples
206209 end
207210 end ,
208- options : [
209- RDF ::CLI ::Option . new ( symbol : :output_format , on : [ ] )
210- ]
211+ option_use : { output_format : :disabled }
211212 } ,
212213 predicates : {
213214 parse : true ,
214215 description : "Serialize each parsed predicate to N-Triples" ,
216+ control : :none ,
215217 help : "predicates [options] [args...]\n returns unique predicates serialized in N-Triples format" ,
216218 lambda : -> ( argv , opts ) do
217219 opts [ :output ] . puts "Predicates"
218220 repository . each_predicate do |predicate |
219221 opts [ :output ] . puts predicate . to_ntriples
220222 end
221223 end ,
222- options : [
223- RDF ::CLI ::Option . new ( symbol : :output_format , on : [ ] )
224- ]
224+ option_use : { output_format : :disabled }
225225 } ,
226226 serialize : {
227227 description : "Serialize using output-format (or N-Triples)" ,
@@ -239,6 +239,7 @@ def to_hash
239239 } ,
240240 subjects : {
241241 parse : true ,
242+ control : :none ,
242243 description : "Serialize each parsed subject to N-Triples" ,
243244 help : "subjects [options] [args...]\n returns unique subjects serialized in N-Triples format" ,
244245 lambda : -> ( argv , opts ) do
@@ -247,20 +248,17 @@ def to_hash
247248 opts [ :output ] . puts subject . to_ntriples
248249 end
249250 end ,
250- options : [
251- RDF ::CLI ::Option . new ( symbol : :output_format , on : [ ] )
252- ]
251+ option_use : { output_format : :disabled }
253252 } ,
254253 validate : {
255254 description : "Validate parsed input" ,
255+ control : :none ,
256256 parse : true ,
257257 help : "validate [options] [args...]\n validates parsed input (may also be used with --validate)" ,
258258 lambda : -> ( argv , opts ) do
259259 opts [ :output ] . puts "Input is " + ( repository . valid? ? "" : "in" ) + "valid"
260260 end ,
261- options : [
262- RDF ::CLI ::Option . new ( symbol : :output_format , on : [ ] )
263- ]
261+ option_use : { output_format : :disabled }
264262 }
265263 }
266264
@@ -376,8 +374,15 @@ def self.options(argv, format: nil)
376374 # Replace any existing option with the same symbol
377375 cli_opts . delete_if { |cli_opt | cli_opt . symbol == option . symbol }
378376
379- # Add the option, unless `on` is empty
380- cli_opts . unshift ( option ) unless option . on . empty?
377+ # Add the option, unless disabled or removed
378+ cli_opts . unshift ( option )
379+ end
380+
381+ # Update usage of options for this command
382+ RDF ::CLI ::COMMANDS [ cmd . to_sym ] . fetch ( :option_use , { } ) . each do |sym , use |
383+ if opt = cli_opts . find { |cli_opt | cli_opt . symbol == sym }
384+ opt . use = use
385+ end
381386 end
382387 end
383388
@@ -392,7 +397,7 @@ def self.options(argv, format: nil)
392397
393398 if format == :json
394399 # Return options
395- OPTIONS . map ( &:to_hash )
400+ cli_opts . map ( &:to_hash )
396401 else
397402 options . banner = "Usage: #{ self . basename } command+ [options] [args...]"
398403
@@ -437,9 +442,10 @@ def self.usage(options, cmd_opts = {}, banner: nil)
437442 # @param [Array<String>] args
438443 # @param [IO] output
439444 # @param [OptionParser] option_parser
445+ # @param [Hash{Symbol => Hash{Symbol => Array[String]}}] messages used for confeying non primary-output which is structured.
440446 # @param [Hash{Symbol => Object}] options
441447 # @return [Boolean]
442- def self . exec ( args , output : $stdout, option_parser : nil , **options )
448+ def self . exec ( args , output : $stdout, option_parser : nil , messages : { } , **options )
443449 option_parser ||= self . options ( args )
444450 options [ :logger ] ||= option_parser . options [ :logger ]
445451 output . set_encoding ( Encoding ::UTF_8 ) if output . respond_to? ( :set_encoding ) && RUBY_PLATFORM == "java"
@@ -470,7 +476,7 @@ def self.exec(args, output: $stdout, option_parser: nil, **options)
470476 COMMANDS [ c . to_sym ] . fetch ( :filter , { } ) . each do |opt , val |
471477 if options [ opt ] . to_s != val . to_s
472478 usage ( option_parser , banner : "Command #{ c . inspect } requires #{ opt } : #{ val } , not #{ options . fetch ( opt , 'null' ) } " )
473- return
479+ raise ArgumentError , "Incompatible command #{ c } used with option #{ opt } = #{ options [ opt ] } "
474480 end
475481 end
476482 end
@@ -496,7 +502,7 @@ def self.exec(args, output: $stdout, option_parser: nil, **options)
496502
497503 # Run each command in sequence
498504 cmds . each do |command |
499- COMMANDS [ command . to_sym ] [ :lambda ] . call ( args , output : output , **options )
505+ COMMANDS [ command . to_sym ] [ :lambda ] . call ( args , output : output , **options . merge ( messages : messages ) )
500506 end
501507
502508 if options [ :statistics ]
0 commit comments