Skip to content

Commit

Permalink
Finish 0.0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
gkellogg committed Oct 29, 2023
2 parents b3932e7 + 3e43347 commit 860c431
Show file tree
Hide file tree
Showing 14 changed files with 815 additions and 43 deletions.
23 changes: 6 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,17 @@ jobs:
tests:
name: Ruby ${{ matrix.ruby }}
if: "contains(github.event.commits[0].message, '[ci skip]') == false"
runs-on: ubuntu-latest
runs-on: macos-latest
env:
CI: true
ALLOW_FAILURES: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'jruby' }}
strategy:
fail-fast: false
matrix:
ruby:
- 2.6
- 2.7
- "3.0"
- 3.1
- ruby-head
- jruby
ruby: ['3.0', 3.1, 3.2, ruby-head, jruby]
steps:
- name: Clone repository
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
Expand All @@ -38,8 +32,8 @@ jobs:
- name: Run tests
run: ruby --version; bundle exec rspec spec || $ALLOW_FAILURES
- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v1.1.2
if: "matrix.ruby == '3.0'"
uses: coverallsapp/github-action@v2
if: "matrix.ruby == '3.2'"
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
wintests:
Expand All @@ -56,7 +50,7 @@ jobs:
- 3.1
steps:
- name: Clone repository
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
Expand All @@ -65,8 +59,3 @@ jobs:
run: bundle install --jobs 4 --retry 3
- name: Run tests
run: ruby --version; bundle exec rspec spec || $ALLOW_FAILURES
- name: Coveralls GitHub Action
uses: coverallsapp/github-action@v1.1.2
if: "matrix.ruby == '3.0'"
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/generate-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
name: Update gh-pages with docs
steps:
- name: Clone repository
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

Ruby [YAML-LD][] reader/writer for RDF.rb

[![Gem Version](https://badge.fury.io/rb/yaml-ld.png)](https://rubygems.org/gems/yaml-ld)
[![Build Status](https://secure.travis-ci.org/ruby-rdf/yaml-ld.png?branch=develop)](https://github.com/ruby-rdf/yaml-ld/actions?query=workflow%3ACI)
[![Gem Version](https://badge.fury.io/rb/yaml-ld.svg)](https://rubygems.org/gems/yaml-ld)
[![Build Status](https://github.com/ruby-rdf/yaml-ld/workflows/CI/badge.svg?branch=develop)](https://github.com/ruby-rdf/yaml-ld/actions?query=workflow%3ACI)
[![Coverage Status](https://coveralls.io/repos/ruby-rdf/yaml-ld/badge.svg?branch=develop)](https://coveralls.io/github/ruby-rdf/yaml-ld?branch=develop)
[![Gitter chat](https://badges.gitter.im/ruby-rdf.png)](https://gitter.im/gitterHQ/gitter)

Expand Down Expand Up @@ -102,12 +102,17 @@ In addition to the input, both a `context` and `frame` may be specified using ei
* [Psych](https://rubygems.org/gems/psych) (>= 4.0)
* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.2)

### Ubuntu limitation

As of October 2023, Ubuntu distributions are running with libyaml 0.2.1, which does not support YAML 1.2. The minimum version needed is libyaml 0.2.5.

## Installation
The recommended installation method is via [RubyGems](https://rubygems.org/).
To install the latest official release of the `JSON-LD` gem, do:

% [sudo] gem install yaml-ld


## Download
To get a local working copy of the development repository, do:

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.2
0.0.3
14 changes: 14 additions & 0 deletions examples/countries-alias.yamlld
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
%YAML 1.2
---
"@context":
"@vocab": "http://schema.org/"
"countries": "http://publication.europa.eu/resource/authority/country/"
"@graph":
- &ITA
"@id": countries:ITA
- "@id": http://people.example/Homer
name: Homer Simpson
nationality: *ITA
- "@id": http://people.example/Lisa
name: Lisa Simpson
nationality: *ITA
8 changes: 7 additions & 1 deletion examples/xsd.yamlld
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,10 @@
name: !string Gregg Kellogg
homepage: https://greggkellogg.net/
depiction: http://www.gravatar.com/avatar/42f948adff3afaa52249d963117af7c8
date: !date "2022-08-08"
date: !date "2022-08-08"

{
"@context": {"@vocab": "http://xmlns.com/foaf/0.1/"},
"name": {
"@value": "Gregg Kellogg", "@type": "http://www.w3.org/2001/XMLSchema#string",}
}
7 changes: 7 additions & 0 deletions lib/yaml_ld.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,11 @@ module YAML_LD
# YAML-LD profiles
YAML_LD_NS = "http://www.w3.org/ns/yaml-ld#"
PROFILES = %w(extended).map {|p| YAML_LD_NS + p}.freeze

class Error < JSON::LD::JsonLdError
class InvalidEncoding < YAML_LD::Error; @code = "invalid encoding"; end
class MappingKeyError < YAML_LD::Error; @code = "mapping-key-error"; end
class ProfileError < YAML_LD::Error; @code = "profile-error"; end
end

end
50 changes: 44 additions & 6 deletions lib/yaml_ld/representation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ def load_stream(yaml, filename: nil, fallback: [], **options)
end

result.is_a?(Array) && result.empty? ? fallback : result
rescue Psych::SyntaxError => e
msg = filename ? "file: #{filename} #{e.message}" : e.message
if yaml.respond_to?(:read)
msg << "Content:\n" + yaml.tap(:rewind).read
end
if e.message.match?(/invalid leading UTF-8 octet/)
raise YAML_LD::Error::InvalidEncoding, msg
else
raise JSON::LD::JsonLdError::LoadingDocumentFailed, msg
end
end
module_function :load_stream

Expand Down Expand Up @@ -100,18 +110,46 @@ def deep_dup(obj)
def as_jsonld_ir(node, **options)
# Scans scalars for built-in classes
@ss ||= Psych::ScalarScanner.new(Psych::ClassLoader::Restricted.new([], %i()))

# Record in-scope anchors to check for circular alias references.
in_scope_anchors = options[:in_scope_anchors] ||= {}

case node
when Psych::Nodes::Stream
node.children.map {|n| as_jsonld_ir(n, **options)}
when Psych::Nodes::Document then as_jsonld_ir(node.children.first, **options)
when Psych::Nodes::Sequence then node.children.map {|n| as_jsonld_ir(n, **options)}
when Psych::Nodes::Document
as_jsonld_ir(node.children.first, named_nodes: {}, **options)
when Psych::Nodes::Sequence
value = []
if node.anchor
options = options.merge(in_scope_anchors: in_scope_anchors.merge(node.anchor => true))
options[:named_nodes][node.anchor] = value
end
node.children.each {|n| value << as_jsonld_ir(n, **options)}
value
when Psych::Nodes::Mapping
node.children.each_slice(2).inject({}) do |memo, (k,v)|
memo.merge(as_jsonld_ir(k) => as_jsonld_ir(v, **options))
value = {}
if node.anchor
options = options.merge(in_scope_anchors: in_scope_anchors.merge(node.anchor => true))
options[:named_nodes][node.anchor] = value
end
node.children.each_slice(2) do |k, v|
key = as_jsonld_ir(k)
raise YAML_LD::Error::MappingKeyError, "mapping key #{k} (#{key.inspect}) not a string" unless key.is_a?(String)
value[as_jsonld_ir(k)] = as_jsonld_ir(v, **options)
end
value
when ::Psych::Nodes::Scalar
value = scan_scalar(node, **options)
if node.anchor
options = options.merge(in_scope_anchors: in_scope_anchors.merge(node.anchor => true))
options[:named_nodes][node.anchor] = value
end
when ::Psych::Nodes::Scalar then scan_scalar(node, **options)
value
when ::Psych::Nodes::Alias
# FIXME
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "anchor for *#{node.anchor} not found" unless options[:named_nodes].key?(node.anchor)
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "anchor for *#{node.anchor} creates a cycle" if in_scope_anchors.key?(node.anchor)
options[:named_nodes][node.anchor]
end
end
module_function :as_jsonld_ir
Expand Down
34 changes: 30 additions & 4 deletions script/parse
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,51 @@ def run(input, options)
puts "output saved in #{output_dir}"
return
end
options[:extendedYAML] = options[:parser_options][:extendedYAML]
reader_class = RDF::Reader.for(options[:input_format].to_sym)
raise "Reader not found for #{options[:input_format]}" unless reader_class

start = Time.new
if options[:flatten]
output = YAML_LD::API.flatten(input, options.delete(:context), **options)
secs = Time.new - start
options[:output].puts output
if options[:output_format] == :jsonld
ir = YAML_LD::Representation.load(input, **options[:parser_options])
options[:output].puts ir.to_json(JSON::LD::JSON_STATE)
else
options[:output].puts output
end
puts "Flattened in #{secs} seconds."
elsif options[:expand]
options = options.merge(expandContext: options.delete(:context)) if options.key?(:context)
output = YAML_LD::API.expand(input, **options)
secs = Time.new - start
options[:output].puts output
if options[:output_format] == :jsonld
ir = YAML_LD::Representation.load(output, **options[:parser_options])
options[:output].puts ir.to_json(JSON::LD::JSON_STATE)
else
options[:output].puts output
end
puts "Expanded in #{secs} seconds."
elsif options[:compact]
output = YAML_LD::API.compact(input, options[:context], **options)
secs = Time.new - start
options[:output].puts output
if options[:output_format] == :jsonld
ir = YAML_LD::Representation.load(output, **options[:parser_options])
options[:output].puts ir.to_json(JSON::LD::JSON_STATE)
else
options[:output].puts output
end
puts "Compacted in #{secs} seconds."
elsif options[:frame]
output = YAML_LD::API.frame(input, options[:frame], **options)
secs = Time.new - start
options[:output].puts output
if options[:output_format] == :jsonld
ir = YAML_LD::Representation.load(output, **options[:parser_options])
options[:output].puts ir.to_json(JSON::LD::JSON_STATE)
else
options[:output].puts output
end
puts "Framed in #{secs} seconds."
elsif options[:translate] && %i(jsonld yamlld).include?(options[:output_format])
# Translate between formats
Expand All @@ -68,6 +89,9 @@ def run(input, options)
ir.to_json(JSON::LD::JSON_STATE) :
YAML_LD::Representation.dump(ir, version: [1,2], **options[:parser_options])
)
elsif options[:inspect]
psych_internal = Psych.parse_stream(input)
options[:output].puts psych_internal.ai
else
r = reader_class.new(input, **options[:parser_options])
if options[:output_format] == :none
Expand Down Expand Up @@ -124,6 +148,7 @@ OPT_ARGS = [
["--frame", GetoptLong::REQUIRED_ARGUMENT, "Frame input, option value is frame to use"],
["--help", "-?", GetoptLong::NO_ARGUMENT, "This message"],
["--input-format", GetoptLong::REQUIRED_ARGUMENT, "Format of input, if not YAML-LD"],
["--inspect", GetoptLong::NO_ARGUMENT, "Parse and dump IR format"],
["--output", "-o", GetoptLong::REQUIRED_ARGUMENT, "Where to store output (default STDOUT)"],
["--profile", GetoptLong::NO_ARGUMENT, "Run profiler with output to doc/profiles/"],
["--quiet", GetoptLong::NO_ARGUMENT, "Reduce output"],
Expand Down Expand Up @@ -164,6 +189,7 @@ opts.each do |opt, arg|
when '--frame' then options[:frame] = arg
when "--help" then usage
when '--input-format' then options[:input_format] = arg.to_sym
when '--inspect' then options[:inspect] = true
when '--output' then options[:output] = File.open(arg, "w")
when '--profile' then options[:profile] = true
when '--quiet'
Expand Down
Loading

0 comments on commit 860c431

Please sign in to comment.