protopack 0.0.7 → 0.0.9
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 +4 -4
- data/lib/protopack.rb +3 -3
- data/lib/protopack/exporter.rb +40 -0
- data/lib/protopack/package.rb +1 -3
- data/lib/protopack/package_item.rb +5 -0
- data/lib/protopack/styled_yaml.rb +124 -0
- data/lib/protopack/version.rb +1 -1
- data/protopack.gemspec +2 -1
- data/spec/protopack/package_spec.rb +26 -26
- data/spec/spec_helper.rb +1 -2
- metadata +29 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78a62b7195e16bf1e652f062893e09fa386c3cdd
|
4
|
+
data.tar.gz: 387c89d2bd400de745cd6c740f5527c7db73845f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22c529ff5dda2505ec3dc2da67de63d0a3786c1542f69ffb6897628cf116785130759e447a8eccb62bed1a7d13101ba68a26e1c2062278ee74c80638720e80d0
|
7
|
+
data.tar.gz: 30411c3d7f5e79b69330bfc4271cb9113d32450feefc494fcd29f6cf31528f9ab188afd233b15ef2cc2ddc45cd99d141a724b735c2a2c34c338ccb067eb411bd
|
data/lib/protopack.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Protopack
|
2
|
+
class Exporter
|
3
|
+
def maybe_name_methods ; %i{ export_name full_name presentation_name name } ; end
|
4
|
+
def name_method obj ; maybe_name_methods.detect { |m| obj.respond_to?(m) && obj.send(m) } ; end
|
5
|
+
def array_assoc list ; list.map { |item| to_attributes item } ; end
|
6
|
+
def clean_yaml hsh ; StyledYAML.dump(clean_attrs hsh) ; end
|
7
|
+
def no_name? obj_id ; raise "no name for object: #{obj_id.inspect}" if obj_id.blank? ; end
|
8
|
+
def default_export_config ; { fields: [], associations: [] } ; end
|
9
|
+
def export_config obj ; default_export_config.merge obj.protopack_export_config ; end
|
10
|
+
def to_attributes obj ; obj.slice(*export_config(obj)[:fields]).merge build_association_table obj ; end
|
11
|
+
def to_yaml obj, meta={} ; clean_yaml to_package obj, meta ; end
|
12
|
+
def remove_blanks attrs ; attrs.recursively_remove_by_value! { |v| (v != false) && v.blank? } ; end
|
13
|
+
def styled_literal str ; str.is_a?(String) ? StyledYAML.literal(str) : str ; end
|
14
|
+
def clean_attrs attrs ; remove_blanks(attrs).recursively_replace_values { |k,v| styled_literal v } ; end
|
15
|
+
|
16
|
+
def build_association_table obj
|
17
|
+
export_config(obj)[:associations].inject({ }) { |table, name|
|
18
|
+
assoc = obj.send name
|
19
|
+
next table if assoc.blank? || assoc.empty?
|
20
|
+
attrs = (assoc.respond_to?(:each)) ? array_assoc(assoc) : to_attributes(assoc)
|
21
|
+
table["#{name}_attributes"] = attrs
|
22
|
+
table
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_package obj, meta={ }
|
27
|
+
obj_name = obj.send(name_method obj)
|
28
|
+
obj_id = obj_name.to_s.gsub(/_/, '-')
|
29
|
+
|
30
|
+
no_name? obj_id
|
31
|
+
|
32
|
+
hsh = {
|
33
|
+
id: obj_id,
|
34
|
+
description: obj_name,
|
35
|
+
type: obj.class.name,
|
36
|
+
attributes: to_attributes(obj),
|
37
|
+
}.deep_merge(meta).recursively_stringify_keys!
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/protopack/package.rb
CHANGED
@@ -10,9 +10,7 @@ class Protopack::Package
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def items
|
13
|
-
config.items.map { |item_file|
|
14
|
-
Protopack::PackageItem.new(Hashie::Mash.new(YAML.load(File.read(item_file))))
|
15
|
-
}
|
13
|
+
config.items.map { |item_file| Protopack::PackageItem.load(item_file) }
|
16
14
|
end
|
17
15
|
|
18
16
|
def item id
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'psych'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
# Public: A Psych extension to enable choosing output styles for specific
|
5
|
+
# objects.
|
6
|
+
#
|
7
|
+
# Thanks to Tenderlove for help in <http://stackoverflow.com/q/9640277/11687>
|
8
|
+
#
|
9
|
+
# Gist: https://gist.github.com/mislav/2023978
|
10
|
+
#
|
11
|
+
# Examples
|
12
|
+
#
|
13
|
+
# data = {
|
14
|
+
# response: { body: StyledYAML.literal(json_string), status: 200 },
|
15
|
+
# person: StyledYAML.inline({ 'name' => 'Stevie', 'age' => 12 }),
|
16
|
+
# array: StyledYAML.inline(%w[ apples bananas oranges ])
|
17
|
+
# }
|
18
|
+
#
|
19
|
+
# StyledYAML.dump data, $stdout
|
20
|
+
#
|
21
|
+
module Protopack::StyledYAML
|
22
|
+
# Tag strings to be output using literal style
|
23
|
+
def self.literal obj
|
24
|
+
obj.extend LiteralScalar
|
25
|
+
return obj
|
26
|
+
end
|
27
|
+
|
28
|
+
# http://www.yaml.org/spec/1.2/spec.html#id2795688
|
29
|
+
module LiteralScalar
|
30
|
+
def yaml_style() Psych::Nodes::Scalar::LITERAL end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Tag Hashes or Arrays to be output all on one line
|
34
|
+
def self.inline obj
|
35
|
+
case obj
|
36
|
+
when Hash then obj.extend FlowMapping
|
37
|
+
when Array then obj.extend FlowSequence
|
38
|
+
else
|
39
|
+
warn "#{self}: unrecognized type to inline (#{obj.class.name})"
|
40
|
+
end
|
41
|
+
return obj
|
42
|
+
end
|
43
|
+
|
44
|
+
# http://www.yaml.org/spec/1.2/spec.html#id2790832
|
45
|
+
module FlowMapping
|
46
|
+
def yaml_style() Psych::Nodes::Mapping::FLOW end
|
47
|
+
end
|
48
|
+
|
49
|
+
# http://www.yaml.org/spec/1.2/spec.html#id2790320
|
50
|
+
module FlowSequence
|
51
|
+
def yaml_style() Psych::Nodes::Sequence::FLOW end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Custom tree builder class to recognize scalars tagged with `yaml_style`
|
55
|
+
class TreeBuilder < Psych::TreeBuilder
|
56
|
+
attr_writer :next_sequence_or_mapping_style
|
57
|
+
|
58
|
+
def initialize(*args)
|
59
|
+
super
|
60
|
+
@next_sequence_or_mapping_style = nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def next_sequence_or_mapping_style default_style
|
64
|
+
style = @next_sequence_or_mapping_style || default_style
|
65
|
+
@next_sequence_or_mapping_style = nil
|
66
|
+
style
|
67
|
+
end
|
68
|
+
|
69
|
+
def scalar value, anchor, tag, plain, quoted, style
|
70
|
+
if style_any?(style) and value.respond_to?(:yaml_style) and style = value.yaml_style
|
71
|
+
if style_literal? style
|
72
|
+
plain = false
|
73
|
+
quoted = true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
super
|
77
|
+
end
|
78
|
+
|
79
|
+
def style_any?(style) Psych::Nodes::Scalar::ANY == style end
|
80
|
+
|
81
|
+
def style_literal?(style) Psych::Nodes::Scalar::LITERAL == style end
|
82
|
+
|
83
|
+
%w[sequence mapping].each do |type|
|
84
|
+
class_eval <<-RUBY
|
85
|
+
def start_#{type}(anchor, tag, implicit, style)
|
86
|
+
style = next_sequence_or_mapping_style(style)
|
87
|
+
super
|
88
|
+
end
|
89
|
+
RUBY
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Custom tree class to handle Hashes and Arrays tagged with `yaml_style`
|
94
|
+
class YAMLTree < Psych::Visitors::YAMLTree
|
95
|
+
%w[String Hash Array Psych_Set Psych_Omap].each do |klass|
|
96
|
+
class_eval <<-RUBY
|
97
|
+
def visit_#{klass} o
|
98
|
+
if o.respond_to? :yaml_style
|
99
|
+
@emitter.next_sequence_or_mapping_style = o.yaml_style
|
100
|
+
end
|
101
|
+
super
|
102
|
+
end
|
103
|
+
RUBY
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# A Psych.dump alternative that uses the custom TreeBuilder
|
108
|
+
def self.dump obj, io = nil, options = {}
|
109
|
+
real_io = io || StringIO.new(''.encode('utf-8'))
|
110
|
+
visitor = YAMLTree.new(options, TreeBuilder.new)
|
111
|
+
visitor << obj
|
112
|
+
ast = visitor.tree
|
113
|
+
|
114
|
+
begin
|
115
|
+
ast.yaml real_io
|
116
|
+
rescue
|
117
|
+
# The `yaml` method was introduced in later versions, so fall back to
|
118
|
+
# constructing a visitor
|
119
|
+
Psych::Visitors::Emitter.new(real_io).accept ast
|
120
|
+
end
|
121
|
+
|
122
|
+
io ? io : real_io.string
|
123
|
+
end
|
124
|
+
end
|
data/lib/protopack/version.rb
CHANGED
data/protopack.gemspec
CHANGED
@@ -16,7 +16,8 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.homepage = "https://github.com/conanite/protopack"
|
17
17
|
|
18
18
|
gem.add_dependency 'hashie'
|
19
|
-
gem.
|
19
|
+
gem.add_dependency 'aduki', '~> 0.2.6', '>= 0.2.6'
|
20
|
+
gem.add_development_dependency 'rspec'
|
20
21
|
|
21
22
|
gem.files = `git ls-files`.split($/)
|
22
23
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -11,29 +11,29 @@ describe Protopack::Package do
|
|
11
11
|
}
|
12
12
|
|
13
13
|
it "should find all the packages" do
|
14
|
-
Protopack::Package.all.map(&:name).join(" ").
|
14
|
+
expect(Protopack::Package.all.map(&:name).join(" ")).to eq "advanced-widgets standard-widgets"
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should find a given package" do
|
18
18
|
p = Protopack::Package.find("standard-widgets")
|
19
|
-
p.name.
|
19
|
+
expect(p.name).to eq "standard-widgets"
|
20
20
|
|
21
|
-
p.title.en.
|
22
|
-
p.title.fr.
|
21
|
+
expect(p.title.en).to eq "Standard Widgets"
|
22
|
+
expect(p.title.fr).to eq "Widgets standards"
|
23
23
|
|
24
|
-
p.description.en.
|
25
|
-
p.description.fr.
|
24
|
+
expect(p.description.en).to eq "Use these widgets for everyday widgeting"
|
25
|
+
expect(p.description.fr).to eq "Ces widgets sont utilisables pour votre widgeting quotidien"
|
26
26
|
|
27
|
-
p.authors.
|
27
|
+
expect(p.authors).to eq %w{ baz titi Z }
|
28
28
|
|
29
|
-
p.updated.
|
29
|
+
expect(p.updated).to eq Date.parse("2013-03-15")
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should install all items from a package" do
|
33
33
|
p = Protopack::Package.find("standard-widgets")
|
34
34
|
p.apply_all
|
35
35
|
|
36
|
-
Widget.all.map(&:colour).
|
36
|
+
expect(Widget.all.map(&:colour)).to eq %w{ red blue yellow black green }
|
37
37
|
end
|
38
38
|
|
39
39
|
it "should install all items from a package, overwriting existing items, respecting #ordinal property" do
|
@@ -43,12 +43,12 @@ describe Protopack::Package do
|
|
43
43
|
p = Protopack::Package.find("standard-widgets")
|
44
44
|
p.apply_all
|
45
45
|
|
46
|
-
Widget.all.map(&:colour).
|
47
|
-
Widget.all[0].height.
|
48
|
-
Widget.all[1].height.
|
49
|
-
Widget.all[2].height.
|
50
|
-
Widget.all[3].height.
|
51
|
-
Widget.all[4].height.
|
46
|
+
expect(Widget.all.map(&:colour)).to eq %w{ blue green red yellow black }
|
47
|
+
expect(Widget.all[0].height).to eq 'elephant'
|
48
|
+
expect(Widget.all[1].height).to eq 'zebra'
|
49
|
+
expect(Widget.all[2].height).to eq 'tiger'
|
50
|
+
expect(Widget.all[3].height).to eq 'hyena'
|
51
|
+
expect(Widget.all[4].height).to eq 'camel'
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should install all items from a package subject to filtering" do
|
@@ -57,10 +57,10 @@ describe Protopack::Package do
|
|
57
57
|
|
58
58
|
Protopack::Package.find("standard-widgets").apply_all { |x| x.region == "Africa" }
|
59
59
|
|
60
|
-
Widget.all.map(&:colour).
|
61
|
-
Widget.all[0].height.
|
62
|
-
Widget.all[1].height.
|
63
|
-
Widget.all[2].height.
|
60
|
+
expect(Widget.all.map(&:colour)).to eq %w{ blue green yellow }
|
61
|
+
expect(Widget.all[0].height).to eq 'elephant'
|
62
|
+
expect(Widget.all[1].height).to eq 'zebra'
|
63
|
+
expect(Widget.all[2].height).to eq 'hyena'
|
64
64
|
end
|
65
65
|
|
66
66
|
it "should install only missing items from a package, not overwriting existing items" do
|
@@ -70,18 +70,18 @@ describe Protopack::Package do
|
|
70
70
|
p = Protopack::Package.find("standard-widgets")
|
71
71
|
p.apply_missing
|
72
72
|
|
73
|
-
Widget.all.map(&:colour).
|
74
|
-
Widget.all[0].height.
|
75
|
-
Widget.all[1].height.
|
76
|
-
Widget.all[2].height.
|
77
|
-
Widget.all[3].height.
|
78
|
-
Widget.all[4].height.
|
73
|
+
expect(Widget.all.map(&:colour)).to eq %w{ blue green red yellow black}
|
74
|
+
expect(Widget.all[0].height).to eq "not specified"
|
75
|
+
expect(Widget.all[1].height).to eq "not specified"
|
76
|
+
expect(Widget.all[2].height).to eq 'tiger'
|
77
|
+
expect(Widget.all[3].height).to eq 'hyena'
|
78
|
+
expect(Widget.all[4].height).to eq 'camel'
|
79
79
|
end
|
80
80
|
|
81
81
|
it "looks up namespaced class names" do
|
82
82
|
p = Protopack::Package.find("advanced-widgets")
|
83
83
|
p.apply_missing
|
84
84
|
|
85
|
-
Wot::Zit.all.map(&:colour).sort.
|
85
|
+
expect(Wot::Zit.all.map(&:colour).sort).to eq %w{ lavender magenta }
|
86
86
|
end
|
87
87
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -12,7 +12,7 @@ require File.expand_path('../../lib/protopack', __FILE__)
|
|
12
12
|
#
|
13
13
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
14
14
|
RSpec.configure do |config|
|
15
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
|
+
# config.treat_symbols_as_metadata_keys_with_true_values = true
|
16
16
|
config.run_all_when_everything_filtered = true
|
17
17
|
config.filter_run :focus
|
18
18
|
|
@@ -24,4 +24,3 @@ RSpec.configure do |config|
|
|
24
24
|
end
|
25
25
|
|
26
26
|
load(File.dirname(__FILE__) + '/models.rb')
|
27
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protopack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Conan Dalton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -25,19 +25,39 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: aduki
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
34
|
-
|
33
|
+
version: 0.2.6
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 0.2.6
|
37
|
+
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
37
40
|
requirements:
|
38
41
|
- - "~>"
|
39
42
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
43
|
+
version: 0.2.6
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.2.6
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
41
61
|
description: " Create objects from object definitions stored as files, like test fixtures,
|
42
62
|
only intended for production use. "
|
43
63
|
email:
|
@@ -53,8 +73,10 @@ files:
|
|
53
73
|
- README.md
|
54
74
|
- Rakefile
|
55
75
|
- lib/protopack.rb
|
76
|
+
- lib/protopack/exporter.rb
|
56
77
|
- lib/protopack/package.rb
|
57
78
|
- lib/protopack/package_item.rb
|
79
|
+
- lib/protopack/styled_yaml.rb
|
58
80
|
- lib/protopack/version.rb
|
59
81
|
- protopack.gemspec
|
60
82
|
- spec/models.rb
|
@@ -89,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
111
|
version: '0'
|
90
112
|
requirements: []
|
91
113
|
rubyforge_project:
|
92
|
-
rubygems_version: 2.2.
|
114
|
+
rubygems_version: 2.5.2.3
|
93
115
|
signing_key:
|
94
116
|
specification_version: 4
|
95
117
|
summary: Store packages of object prototypes on-disk as YML; this gem allows you scan
|