Skip to content

Commit

Permalink
Finish 3.2.9
Browse files Browse the repository at this point in the history
  • Loading branch information
gkellogg committed Aug 7, 2022
2 parents bf54bb7 + 1c26cfd commit 9dcc68b
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 16 deletions.
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
3.2.8
3.2.9
34 changes: 29 additions & 5 deletions lib/rdf/cli.rb
Expand Up @@ -25,6 +25,7 @@
rdf/xsd
shacl
shex
yaml_ld
).each do |ser|
begin
require ser
Expand Down Expand Up @@ -177,7 +178,10 @@ def to_hash
# * `parse` Boolean value to determine if input files should automatically be parsed into `repository`.
# * `help` used for the CLI help output.
# * `lambda` code run to execute command.
# * `filter` Option values that must match for command to be used
# * `filter` value is a Hash whose keys are matched against selected command options. All specified `key/value` pairs are compared against the equivalent key in the current invocation.
# If an Array, option value (as a string) must match any value of the array (as a string)
# If a Proc, it is passed the option value and must return `true`.
# Otherwise, the option value (as a string) must equal the `value` (as a string).
# * `control` Used to indicate how (if) command is displayed
# * `repository` Use this repository, if set
# * `options` an optional array of `RDF::CLI::Option` describing command-specific options.
Expand Down Expand Up @@ -505,9 +509,22 @@ def self.exec(args, output: $stdout, option_parser: nil, messages: {}, **options
# Make sure any selected command isn't filtered out
cmds.each do |c|
COMMANDS[c.to_sym].fetch(:filter, {}).each do |opt, val|
if options[opt].to_s != val.to_s
usage(option_parser, banner: "Command #{c.inspect} requires #{opt}: #{val}, not #{options.fetch(opt, 'null')}")
raise ArgumentError, "Incompatible command #{c} used with option #{opt}=#{options[opt]}"
case val
when Array
unless val.map(&:to_s).include?(options[opt].to_s)
usage(option_parser, banner: "Command #{c.inspect} requires #{opt} in #{val.map(&:to_s).inspect}, not #{options.fetch(opt, 'null')}")
raise ArgumentError, "Incompatible command #{c} used with option #{opt}=#{options[opt]}"
end
when Proc
unless val.call(options[opt])
usage(option_parser, banner: "Command #{c.inspect} #{opt} inconsistent with #{options.fetch(opt, 'null')}")
raise ArgumentError, "Incompatible command #{c} used with option #{opt}=#{options[opt]}"
end
else
unless val.to_s == options[opt].to_s
usage(option_parser, banner: "Command #{c.inspect} requires compatible value for #{opt}, not #{options.fetch(opt, 'null')}")
raise ArgumentError, "Incompatible command #{c} used with option #{opt}=#{options[opt]}"
end
end
end

Expand Down Expand Up @@ -594,7 +611,14 @@ def self.commands(format: nil, **options)
# Subset commands based on filter options
cmds = COMMANDS.reject do |k, c|
c.fetch(:filter, {}).any? do |opt, val|
options.merge(format: format)[opt].to_s != val.to_s
case val
when Array
!val.map(&:to_s).include?(options[opt].to_s)
when Proc
!val.call(options[opt])
else
val.to_s != options[opt].to_s
end
end
end

Expand Down
3 changes: 2 additions & 1 deletion lib/rdf/model/literal/date.rb
Expand Up @@ -3,10 +3,11 @@ module RDF; class Literal
# A date literal.
#
# @see http://www.w3.org/TR/xmlschema11-2/#date
# @see https://www.w3.org/TR/xmlschema11-2/#rf-lexicalMappings-datetime
# @since 0.2.1
class Date < Temporal
DATATYPE = RDF::URI("http://www.w3.org/2001/XMLSchema#date")
GRAMMAR = %r(\A(-?\d{4}-\d{2}-\d{2})((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)?\Z).freeze
GRAMMAR = %r(\A(#{YEARFRAG}-#{MONTHFRAG}-#{DAYFRAG})(#{TZFRAG})?\z).freeze
FORMAT = '%Y-%m-%d'.freeze

##
Expand Down
14 changes: 13 additions & 1 deletion lib/rdf/model/literal/datetime.rb
Expand Up @@ -3,10 +3,22 @@ module RDF; class Literal
# A date/time literal.
#
# @see http://www.w3.org/TR/xmlschema11-2/#dateTime
# @see https://www.w3.org/TR/xmlschema11-2/#rf-lexicalMappings-datetime
# @since 0.2.1
class DateTime < Temporal
DATATYPE = RDF::URI("http://www.w3.org/2001/XMLSchema#dateTime")
GRAMMAR = %r(\A(-?(?:\d{4}|[1-9]\d{4,})-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?)((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)?\Z).freeze
GRAMMAR = %r(\A
(#{YEARFRAG}
-#{MONTHFRAG}
-#{DAYFRAG}
T
(?:
(?:
#{HOURFRAG}
:#{MINUTEFRAG}
:#{SECONDFRAG})
| #{EODFRAG}))
(#{TZFRAG})?\z)x.freeze
FORMAT = '%Y-%m-%dT%H:%M:%S.%L'.freeze

##
Expand Down
9 changes: 9 additions & 0 deletions lib/rdf/model/literal/temporal.rb
Expand Up @@ -10,6 +10,15 @@ class Temporal < Literal
|(?:(?<si>-)?PT(?<hr>\d{1,2})H(?:(?<mi>\d{1,2})M)?)
\z)x.freeze

YEARFRAG = %r(-?(?:(?:[1-9]\d{3,})|(?:0\d{3})))
MONTHFRAG = %r((?:(?:0[1-9])|(?:1[0-2])))
DAYFRAG = %r((?:(?:0[1-9])|(?:[12]\d)|(?:3[01])))
HOURFRAG = %r((?:[01]\d)|(?:2[0-3]))
MINUTEFRAG = %r([0-5]\d)
SECONDFRAG = %r([0-5]\d(?:\.\d+)?)
EODFRAG = %r(24:00:00(?:\.0+)?)
TZFRAG = %r((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)

##
# Compares this literal to `other` for sorting purposes.
#
Expand Down
3 changes: 2 additions & 1 deletion lib/rdf/model/literal/time.rb
Expand Up @@ -8,10 +8,11 @@ module RDF; class Literal
# following time zone indicator.
#
# @see http://www.w3.org/TR/xmlschema11-2/#time
# @see https://www.w3.org/TR/xmlschema11-2/#rf-lexicalMappings-datetime
# @since 0.2.1
class Time < Temporal
DATATYPE = RDF::URI("http://www.w3.org/2001/XMLSchema#time")
GRAMMAR = %r(\A(\d{2}:\d{2}:\d{2}(?:\.\d+)?)((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)?\Z).freeze
GRAMMAR = %r(\A((?:#{HOURFRAG}:#{MINUTEFRAG}:#{SECONDFRAG})|#{EODFRAG})(#{TZFRAG})?\z).freeze
FORMAT = '%H:%M:%S.%L'.freeze

##
Expand Down
38 changes: 31 additions & 7 deletions spec/cli_spec.rb
Expand Up @@ -248,13 +248,37 @@
end
end

it "complains if filtered command is attempted" do
RDF::CLI.add_command(:filtered, filter: {output_format: :nquads})
expect do
expect do
RDF::CLI.exec(["filtered"], output_format: :ntriples)
end.to raise_error(ArgumentError)
end.to write(%(Command "filtered" requires output_format: nquads, not ntriples)).to(:output)
describe "filter" do
context "complains if filtered command is attempted" do
before(:each) {RDF::CLI::COMMANDS.delete(:filtered)}

it "single value" do
RDF::CLI.add_command(:filtered, filter: {output_format: :nquads})
expect do
expect do
RDF::CLI.exec(["filtered"], output_format: :ntriples)
end.to raise_error(ArgumentError)
end.to write(%(Command "filtered" requires compatible value for output_format, not ntriples)).to(:output)
end

it "Array of values" do
RDF::CLI.add_command(:filtered, filter: {output_format: %i{nquads turtle}})
expect do
expect do
RDF::CLI.exec(["filtered"], output_format: :ntriples)
end.to raise_error(ArgumentError)
end.to write(%(Command "filtered" requires output_format in ["nquads", "turtle"], not ntriples)).to(:output)
end

it "Proc" do
RDF::CLI.add_command(:filtered, filter: {output_format: ->(v) {v == :nquads}})
expect do
expect do
RDF::CLI.exec(["filtered"], output_format: :ntriples)
end.to raise_error(ArgumentError)
end.to write(%(Command "filtered" output_format inconsistent with ntriples)).to(:output)
end
end
end

it "uses repository specified in command" do
Expand Down

0 comments on commit 9dcc68b

Please sign in to comment.