protopack 0.0.7 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|