schema-model 0.6.11 → 0.7.1
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/.github/workflows/ci.yml +93 -0
- data/.github/workflows/release.yml +93 -0
- data/.release-please-manifest.json +3 -0
- data/.rubocop.yml +70 -8
- data/.ruby-version +1 -1
- data/ARCHITECTURE.md +135 -0
- data/CHANGELOG.md +9 -0
- data/CLAUDE.md +83 -0
- data/Gemfile +1 -2
- data/Gemfile.lock +79 -47
- data/README.md +361 -85
- data/lib/schema/active_model_validations.rb +14 -14
- data/lib/schema/array_headers.rb +6 -4
- data/lib/schema/arrays.rb +11 -13
- data/lib/schema/associations/dynamic_types.rb +3 -5
- data/lib/schema/associations/has_many.rb +2 -4
- data/lib/schema/associations/has_one.rb +3 -5
- data/lib/schema/associations/schema_creator.rb +2 -2
- data/lib/schema/csv_parser.rb +1 -1
- data/lib/schema/model.rb +26 -21
- data/lib/schema/parsers/array.rb +2 -2
- data/lib/schema/parsers/common.rb +6 -8
- data/lib/schema/parsers/hash.rb +1 -1
- data/lib/schema/parsers/json.rb +1 -1
- data/lib/schema/parsing_errors.rb +1 -1
- data/lib/schema/utils.rb +5 -5
- data/lib/schema/version.rb +6 -0
- data/lib/schema-model.rb +1 -0
- data/release-please-config.json +12 -0
- data/schema-model.gemspec +8 -4
- data/script/coverage_badge.rb +49 -0
- metadata +17 -12
- data/.cursor-rules +0 -39
- data/.travis.yml +0 -14
- data/Rakefile +0 -11
- data/docs/ARCHITECTURE.md +0 -171
- data/script/bundle_install_all_versions +0 -8
- data/script/rspec_all_versions +0 -5
data/lib/schema/arrays.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Schema
|
|
|
15
15
|
|
|
16
16
|
def to_empty_array
|
|
17
17
|
data = []
|
|
18
|
-
schema.
|
|
18
|
+
schema.each_value do |field_options|
|
|
19
19
|
next if field_options[:alias_of]
|
|
20
20
|
|
|
21
21
|
data <<
|
|
@@ -24,8 +24,6 @@ module Schema
|
|
|
24
24
|
const_get(field_options[:class_name]).to_empty_array
|
|
25
25
|
when :has_many
|
|
26
26
|
field_options[:size].times.map { const_get(field_options[:class_name]).to_empty_array }
|
|
27
|
-
else
|
|
28
|
-
nil
|
|
29
27
|
end
|
|
30
28
|
end
|
|
31
29
|
data
|
|
@@ -33,16 +31,16 @@ module Schema
|
|
|
33
31
|
|
|
34
32
|
def to_headers(prefix = nil)
|
|
35
33
|
headers = []
|
|
36
|
-
schema.
|
|
34
|
+
schema.each_value do |field_options|
|
|
37
35
|
next if field_options[:alias_of]
|
|
38
36
|
|
|
39
37
|
headers <<
|
|
40
38
|
case field_options[:type]
|
|
41
39
|
when :has_one
|
|
42
|
-
const_get(field_options[:class_name]).to_headers(prefix
|
|
40
|
+
const_get(field_options[:class_name]).to_headers("#{prefix}#{field_options[:key]}.")
|
|
43
41
|
when :has_many
|
|
44
42
|
field_options[:size].times.map do |i|
|
|
45
|
-
const_get(field_options[:class_name]).to_headers(prefix.to_s + field_options[:key] + "[#{i +1}].")
|
|
43
|
+
const_get(field_options[:class_name]).to_headers(prefix.to_s + field_options[:key] + "[#{i + 1}].")
|
|
46
44
|
end
|
|
47
45
|
else
|
|
48
46
|
prefix.to_s + field_options[:key]
|
|
@@ -54,7 +52,7 @@ module Schema
|
|
|
54
52
|
|
|
55
53
|
def to_a
|
|
56
54
|
data = []
|
|
57
|
-
self.class.schema.
|
|
55
|
+
self.class.schema.each_value do |field_options|
|
|
58
56
|
next if field_options[:alias_of]
|
|
59
57
|
|
|
60
58
|
value = public_send(field_options[:getter])
|
|
@@ -76,7 +74,7 @@ module Schema
|
|
|
76
74
|
end
|
|
77
75
|
|
|
78
76
|
def update_attributes_with_array(array, mapped_headers, offset = nil)
|
|
79
|
-
self.class.schema.
|
|
77
|
+
self.class.schema.each_value do |field_options|
|
|
80
78
|
next unless (mapped_field = mapped_headers[field_options[:name]])
|
|
81
79
|
|
|
82
80
|
if offset
|
|
@@ -103,7 +101,7 @@ module Schema
|
|
|
103
101
|
end
|
|
104
102
|
|
|
105
103
|
def update_nested_has_one_associations_from_array(array, mapped_headers, current_offset = nil)
|
|
106
|
-
self.class.schema.
|
|
104
|
+
self.class.schema.each_value do |field_options|
|
|
107
105
|
next unless field_options[:type] == :has_one
|
|
108
106
|
next unless (mapped_model = mapped_headers[field_options[:name]])
|
|
109
107
|
|
|
@@ -115,7 +113,7 @@ module Schema
|
|
|
115
113
|
end
|
|
116
114
|
|
|
117
115
|
def update_nested_has_many_associations_from_array(array, mapped_headers)
|
|
118
|
-
self.class.schema.
|
|
116
|
+
self.class.schema.each_value do |field_options|
|
|
119
117
|
next unless field_options[:type] == :has_many
|
|
120
118
|
next unless (mapped_model = mapped_headers[field_options[:name]])
|
|
121
119
|
|
|
@@ -136,10 +134,10 @@ module Schema
|
|
|
136
134
|
|
|
137
135
|
def largest_number_of_indexes_from_map(mapped_model)
|
|
138
136
|
size = 0
|
|
139
|
-
mapped_model.
|
|
137
|
+
mapped_model.each_value do |info|
|
|
140
138
|
if info[:indexes]
|
|
141
|
-
size = info[:indexes].size if info[:indexes]
|
|
142
|
-
|
|
139
|
+
size = info[:indexes].size if info[:indexes].size > size
|
|
140
|
+
elsif info.is_a?(Hash)
|
|
143
141
|
new_size = largest_number_of_indexes_from_map(info)
|
|
144
142
|
size = new_size if new_size > size
|
|
145
143
|
end
|
|
@@ -19,8 +19,8 @@ module Schema
|
|
|
19
19
|
kls
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def default_type(options = {}, &
|
|
23
|
-
add_type(:default, options, &
|
|
22
|
+
def default_type(options = {}, &)
|
|
23
|
+
add_type(:default, options, &)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def dynamic_types
|
|
@@ -34,9 +34,7 @@ module Schema
|
|
|
34
34
|
private
|
|
35
35
|
|
|
36
36
|
def schema_dynamic_type_class_name(type)
|
|
37
|
-
::Schema::Utils.classify_name(schema_name.to_s)
|
|
38
|
-
'AssociationType' +
|
|
39
|
-
::Schema::Utils.classify_name(type.to_s)
|
|
37
|
+
"#{::Schema::Utils.classify_name(schema_name.to_s)}AssociationType#{::Schema::Utils.classify_name(type.to_s)}"
|
|
40
38
|
end
|
|
41
39
|
|
|
42
40
|
def schema_add_dynamic_type(type, class_name)
|
|
@@ -10,12 +10,11 @@ module Schema
|
|
|
10
10
|
|
|
11
11
|
# no-doc
|
|
12
12
|
module ClassMethods
|
|
13
|
-
# rubocop:disable Naming/PredicateName
|
|
14
13
|
def has_many(name, options = {}, &block)
|
|
15
14
|
options = ::Schema::Utils.add_association_class(self, name, :has_many, options)
|
|
16
15
|
|
|
17
16
|
class_eval(
|
|
18
|
-
<<-STR, __FILE__, __LINE__ + 1
|
|
17
|
+
<<-STR, __FILE__, __LINE__ + 1
|
|
19
18
|
def #{options[:getter]}
|
|
20
19
|
#{options[:instance_variable]}
|
|
21
20
|
end
|
|
@@ -32,7 +31,7 @@ module Schema
|
|
|
32
31
|
#{options[:instance_variable]} ||= []
|
|
33
32
|
#{options[:instance_variable]} << #{name}_schema_creator.create_schema(self, v, nil, skip_fields)
|
|
34
33
|
end
|
|
35
|
-
STR
|
|
34
|
+
STR
|
|
36
35
|
)
|
|
37
36
|
|
|
38
37
|
kls = const_get(options[:class_name])
|
|
@@ -44,7 +43,6 @@ STR
|
|
|
44
43
|
add_aliases(name, options)
|
|
45
44
|
kls
|
|
46
45
|
end
|
|
47
|
-
# rubocop:enable Naming/PredicateName
|
|
48
46
|
end
|
|
49
47
|
end
|
|
50
48
|
end
|
|
@@ -10,12 +10,11 @@ module Schema
|
|
|
10
10
|
|
|
11
11
|
# no-doc
|
|
12
12
|
module ClassMethods
|
|
13
|
-
# rubocop:disable Naming/PredicateName
|
|
14
13
|
def has_one(name, options = {}, &block)
|
|
15
14
|
options = ::Schema::Utils.add_association_class(self, name, :has_one, options)
|
|
16
15
|
|
|
17
16
|
class_eval(
|
|
18
|
-
<<-STR, __FILE__, __LINE__ + 1
|
|
17
|
+
<<-STR, __FILE__, __LINE__ + 1
|
|
19
18
|
def #{options[:getter]}
|
|
20
19
|
#{options[:instance_variable]}
|
|
21
20
|
end
|
|
@@ -27,19 +26,18 @@ module Schema
|
|
|
27
26
|
def #{options[:setter]}(v, skip_fields = [])
|
|
28
27
|
#{options[:instance_variable]} = #{name}_schema_creator.create_schema(self, v, nil, skip_fields)
|
|
29
28
|
end
|
|
30
|
-
STR
|
|
29
|
+
STR
|
|
31
30
|
)
|
|
32
31
|
|
|
33
32
|
kls = const_get(options[:class_name])
|
|
34
33
|
kls.class_eval(&block) if block
|
|
35
34
|
if options[:default]
|
|
36
|
-
options[:default_code] = options[:class_name]
|
|
35
|
+
options[:default_code] = "#{options[:class_name]}.new"
|
|
37
36
|
::Schema::Utils.add_association_default_methods(self, options)
|
|
38
37
|
end
|
|
39
38
|
add_aliases(name, options)
|
|
40
39
|
kls
|
|
41
40
|
end
|
|
42
|
-
# rubocop:enable Naming/PredicateName
|
|
43
41
|
end
|
|
44
42
|
end
|
|
45
43
|
end
|
|
@@ -27,7 +27,7 @@ module Schema
|
|
|
27
27
|
add_parsing_error(base_schema, error_name, INVALID) unless schema.parsing_errors.empty?
|
|
28
28
|
schema
|
|
29
29
|
elsif !data.nil?
|
|
30
|
-
add_parsing_error(base_schema, error_name,
|
|
30
|
+
add_parsing_error(base_schema, error_name, INCOMPATIBLE)
|
|
31
31
|
nil
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -42,7 +42,7 @@ module Schema
|
|
|
42
42
|
schema
|
|
43
43
|
end
|
|
44
44
|
elsif !list.nil?
|
|
45
|
-
add_parsing_error(base_schema, @schema_name,
|
|
45
|
+
add_parsing_error(base_schema, @schema_name, INCOMPATIBLE)
|
|
46
46
|
nil
|
|
47
47
|
end
|
|
48
48
|
end
|
data/lib/schema/csv_parser.rb
CHANGED
|
@@ -32,7 +32,7 @@ module Schema
|
|
|
32
32
|
|
|
33
33
|
def get_mapped_headers(mapped_headers)
|
|
34
34
|
indexed_headers = []
|
|
35
|
-
mapped_headers.
|
|
35
|
+
mapped_headers.each_value do |info|
|
|
36
36
|
if (index = info[:index])
|
|
37
37
|
indexed_headers << @headers[index]
|
|
38
38
|
elsif (indexes = info[:indexes])
|
data/lib/schema/model.rb
CHANGED
|
@@ -69,7 +69,7 @@ module Schema
|
|
|
69
69
|
|
|
70
70
|
add_value_to_class_method(:schema, name => options)
|
|
71
71
|
add_attribute_methods(name, options)
|
|
72
|
-
::Schema::Utils.add_attribute_default_methods(self, options) if options.
|
|
72
|
+
::Schema::Utils.add_attribute_default_methods(self, options) if options.key?(:default)
|
|
73
73
|
add_aliases(name, options)
|
|
74
74
|
end
|
|
75
75
|
|
|
@@ -82,7 +82,8 @@ module Schema
|
|
|
82
82
|
config[:schema_includes] = config[:schema_includes] + [mod]
|
|
83
83
|
redefine_class_method(:schema_config, config.freeze)
|
|
84
84
|
include mod
|
|
85
|
-
|
|
85
|
+
|
|
86
|
+
schema.each_value do |field_options|
|
|
86
87
|
next unless field_options[:association]
|
|
87
88
|
|
|
88
89
|
const_get(field_options[:class_name]).schema_include(mod)
|
|
@@ -91,7 +92,7 @@ module Schema
|
|
|
91
92
|
|
|
92
93
|
def add_attribute_methods(name, options)
|
|
93
94
|
class_eval(
|
|
94
|
-
<<-STR, __FILE__, __LINE__ + 1
|
|
95
|
+
<<-STR, __FILE__, __LINE__ + 1
|
|
95
96
|
def #{options[:getter]}
|
|
96
97
|
#{options[:instance_variable]}
|
|
97
98
|
end
|
|
@@ -99,7 +100,11 @@ module Schema
|
|
|
99
100
|
def #{options[:setter]}(v)
|
|
100
101
|
#{options[:instance_variable]} = #{options[:parser]}(#{name.inspect}, parsing_errors, v)
|
|
101
102
|
end
|
|
102
|
-
|
|
103
|
+
|
|
104
|
+
def #{options[:getter]}_was_set?
|
|
105
|
+
instance_variable_defined?(:#{options[:instance_variable]})
|
|
106
|
+
end
|
|
107
|
+
STR
|
|
103
108
|
)
|
|
104
109
|
end
|
|
105
110
|
|
|
@@ -123,18 +128,18 @@ STR
|
|
|
123
128
|
|
|
124
129
|
def as_json(opts = {})
|
|
125
130
|
self.class.schema.each_with_object({}) do |(field_name, field_options), memo|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
131
|
+
next if field_options[:alias_of]
|
|
132
|
+
|
|
133
|
+
value = public_send(field_options[:getter])
|
|
134
|
+
next if value.nil? && !opts[:include_nils]
|
|
135
|
+
next if opts[:select_filter] && !opts[:select_filter].call(field_name, value, field_options)
|
|
136
|
+
next if opts[:reject_filter]&.call(field_name, value, field_options)
|
|
137
|
+
|
|
138
|
+
memo[field_name] = if value.is_a?(Array)
|
|
139
|
+
value.map { |e| e.as_json(opts) }
|
|
140
|
+
else
|
|
141
|
+
value.respond_to?(:as_json) ? value.as_json(opts) : value
|
|
142
|
+
end
|
|
138
143
|
end
|
|
139
144
|
end
|
|
140
145
|
|
|
@@ -156,12 +161,12 @@ STR
|
|
|
156
161
|
private
|
|
157
162
|
|
|
158
163
|
def get_schema(data)
|
|
159
|
-
|
|
160
|
-
break unless key.is_a?(Symbol)
|
|
164
|
+
return self.class.schema_with_string_keys unless data.is_a?(Hash)
|
|
161
165
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
166
|
+
first_key = data.each_key.first
|
|
167
|
+
return self.class.schema_with_string_keys unless first_key.is_a?(Symbol)
|
|
168
|
+
|
|
169
|
+
self.class.schema
|
|
165
170
|
end
|
|
166
171
|
|
|
167
172
|
def update_model_attributes(schema, data, skip_fields)
|
data/lib/schema/parsers/array.rb
CHANGED
|
@@ -15,10 +15,10 @@ module Schema
|
|
|
15
15
|
return data
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
parsing_errors.add(field_name, ::Schema::ParsingErrors::
|
|
18
|
+
parsing_errors.add(field_name, ::Schema::ParsingErrors::INCOMPATIBLE)
|
|
19
19
|
nil
|
|
20
20
|
else
|
|
21
|
-
parsing_errors.add(field_name, ::Schema::ParsingErrors::
|
|
21
|
+
parsing_errors.add(field_name, ::Schema::ParsingErrors::INCOMPATIBLE)
|
|
22
22
|
nil
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -6,11 +6,10 @@ module Schema
|
|
|
6
6
|
module Parsers
|
|
7
7
|
# Schema::Parsers::Common are parser methods for basic types
|
|
8
8
|
module Common
|
|
9
|
-
INTEGER_REGEX = /^[-+]?(?:[1-9]\d*|0)(?:\.0+)
|
|
10
|
-
FLOAT_REGEX = /^[-+]?(?:[1-9]\d*|0)(?:\.\d+)?([Ee]-?\d+)
|
|
11
|
-
BOOLEAN_REGEX = /^(?:1|t|true|on|y|yes)$/i
|
|
9
|
+
INTEGER_REGEX = /^[-+]?(?:[1-9]\d*|0)(?:\.0+)?$/
|
|
10
|
+
FLOAT_REGEX = /^[-+]?(?:[1-9]\d*|0)(?:\.\d+)?([Ee]-?\d+)?$/
|
|
11
|
+
BOOLEAN_REGEX = /^(?:1|t|true|on|y|yes)$/i
|
|
12
12
|
|
|
13
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
14
13
|
def parse_integer(field_name, parsing_errors, value)
|
|
15
14
|
case value
|
|
16
15
|
when Integer
|
|
@@ -23,7 +22,7 @@ module Schema
|
|
|
23
22
|
nil
|
|
24
23
|
end
|
|
25
24
|
when Float
|
|
26
|
-
parsing_errors.add(field_name, ::Schema::ParsingErrors::
|
|
25
|
+
parsing_errors.add(field_name, ::Schema::ParsingErrors::INCOMPATIBLE) if (value % 1) > 0.0
|
|
27
26
|
value.to_i
|
|
28
27
|
when nil
|
|
29
28
|
nil
|
|
@@ -32,14 +31,13 @@ module Schema
|
|
|
32
31
|
nil
|
|
33
32
|
end
|
|
34
33
|
end
|
|
35
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
36
34
|
|
|
37
35
|
def parse_string(field_name, parsing_errors, value)
|
|
38
36
|
case value
|
|
39
37
|
when String
|
|
40
38
|
value
|
|
41
39
|
when ::Hash, ::Array
|
|
42
|
-
parsing_errors.add(field_name, ::Schema::ParsingErrors::
|
|
40
|
+
parsing_errors.add(field_name, ::Schema::ParsingErrors::INCOMPATIBLE)
|
|
43
41
|
nil
|
|
44
42
|
when nil
|
|
45
43
|
nil
|
|
@@ -54,7 +52,7 @@ module Schema
|
|
|
54
52
|
when String
|
|
55
53
|
value.empty? ? nil : value
|
|
56
54
|
when ::Hash, ::Array
|
|
57
|
-
parsing_errors.add(field_name, ::Schema::ParsingErrors::
|
|
55
|
+
parsing_errors.add(field_name, ::Schema::ParsingErrors::INCOMPATIBLE)
|
|
58
56
|
nil
|
|
59
57
|
when nil
|
|
60
58
|
nil
|
data/lib/schema/parsers/hash.rb
CHANGED
data/lib/schema/parsers/json.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Schema
|
|
|
4
4
|
# Schema::ParsingErrors is a collection of parsing error messages
|
|
5
5
|
module ParsingErrors
|
|
6
6
|
INVALID = 'invalid'
|
|
7
|
-
|
|
7
|
+
INCOMPATIBLE = 'incompatible'
|
|
8
8
|
UNKNOWN = 'unknown'
|
|
9
9
|
UNKNOWN_ATTRIBUTE = 'unknown_attribute'
|
|
10
10
|
UNHANDLED_TYPE = 'unhandled_type'
|
data/lib/schema/utils.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Schema
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def association_options(schema_name, schema_type, options)
|
|
28
|
-
options[:class_name] ||=
|
|
28
|
+
options[:class_name] ||= "Schema#{classify_name(schema_type.to_s)}#{classify_name(schema_name.to_s)}"
|
|
29
29
|
options[:association] = true
|
|
30
30
|
options[:aliases] = [options[:alias]] if options.key?(:alias)
|
|
31
31
|
options[:hash_key_field] ||= :id if options[:from] == :hash
|
|
@@ -58,7 +58,7 @@ module Schema
|
|
|
58
58
|
|
|
59
59
|
def add_attribute_default_methods(kls, options)
|
|
60
60
|
kls.class_eval(
|
|
61
|
-
|
|
61
|
+
<<-STR, __FILE__, __LINE__ + 1
|
|
62
62
|
def #{options[:default_method]}
|
|
63
63
|
#{options[:default].inspect}
|
|
64
64
|
end
|
|
@@ -70,13 +70,13 @@ module Schema
|
|
|
70
70
|
#{options[:instance_variable]}
|
|
71
71
|
end
|
|
72
72
|
end
|
|
73
|
-
STR
|
|
73
|
+
STR
|
|
74
74
|
)
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def add_association_default_methods(kls, options)
|
|
78
78
|
kls.class_eval(
|
|
79
|
-
|
|
79
|
+
<<-STR, __FILE__, __LINE__ + 1
|
|
80
80
|
def #{options[:default_method]}
|
|
81
81
|
#{options[:default_code]}
|
|
82
82
|
end
|
|
@@ -84,7 +84,7 @@ STR
|
|
|
84
84
|
def #{options[:getter]}
|
|
85
85
|
#{options[:instance_variable]} ||= #{options[:default_method]}
|
|
86
86
|
end
|
|
87
|
-
STR
|
|
87
|
+
STR
|
|
88
88
|
)
|
|
89
89
|
end
|
|
90
90
|
end
|
data/lib/schema-model.rb
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
|
|
3
|
+
"bootstrap-sha": "de8a6c418c6b662696e48b7af3b2d8ad55fb3b4e",
|
|
4
|
+
"packages": {
|
|
5
|
+
".": {
|
|
6
|
+
"release-type": "ruby",
|
|
7
|
+
"package-name": "schema-model",
|
|
8
|
+
"version-file": "lib/schema/version.rb",
|
|
9
|
+
"include-component-in-tag": false
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
data/schema-model.gemspec
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'lib/schema/version'
|
|
4
|
+
|
|
3
5
|
Gem::Specification.new do |s|
|
|
4
6
|
s.name = 'schema-model'
|
|
5
|
-
s.version =
|
|
7
|
+
s.version = Schema::VERSION
|
|
6
8
|
s.licenses = ['MIT']
|
|
7
|
-
s.summary = '
|
|
8
|
-
s.description = '
|
|
9
|
+
s.summary = 'Data transformation, validation, and type safety for Ruby'
|
|
10
|
+
s.description = 'A flexible DSL for defining strongly-typed data models with automatic parsing, ' \
|
|
11
|
+
'nested associations, dynamic types, and ActiveModel validations'
|
|
9
12
|
s.authors = ['Doug Youch']
|
|
10
13
|
s.email = 'dougyouch@gmail.com'
|
|
11
14
|
s.homepage = 'https://github.com/dougyouch/schema'
|
|
@@ -13,5 +16,6 @@ Gem::Specification.new do |s|
|
|
|
13
16
|
s.bindir = 'bin'
|
|
14
17
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
15
18
|
|
|
16
|
-
s.
|
|
19
|
+
s.add_dependency 'inheritance-helper'
|
|
20
|
+
s.metadata['rubygems_mfa_required'] = 'true'
|
|
17
21
|
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Renders a shields-style SVG badge from SimpleCov's .last_run.json.
|
|
5
|
+
# script/coverage_badge.rb coverage/.last_run.json coverage.svg # line coverage
|
|
6
|
+
# script/coverage_badge.rb coverage/.last_run.json branches.svg branch # branch coverage
|
|
7
|
+
|
|
8
|
+
require 'json'
|
|
9
|
+
|
|
10
|
+
input, output, metric = ARGV
|
|
11
|
+
abort "usage: #{$PROGRAM_NAME} <.last_run.json> <out.svg> [line|branch]" unless input && output
|
|
12
|
+
|
|
13
|
+
result = JSON.parse(File.read(input)).fetch('result')
|
|
14
|
+
title = metric == 'branch' ? 'branches' : 'coverage'
|
|
15
|
+
percent = (metric == 'branch' ? result.fetch('branch') : result['line'] || result.fetch('covered_percent')).to_f
|
|
16
|
+
label = "#{percent.floor(1)}%"
|
|
17
|
+
|
|
18
|
+
color =
|
|
19
|
+
if percent >= 95 then '#4c1'
|
|
20
|
+
elsif percent >= 90 then '#97ca00'
|
|
21
|
+
elsif percent >= 80 then '#dfb317'
|
|
22
|
+
elsif percent >= 70 then '#fe7d37'
|
|
23
|
+
else '#e05d44'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# ~7px per character at 11px Verdana, plus padding
|
|
27
|
+
left_width = 63
|
|
28
|
+
right_width = (label.length * 7) + 10
|
|
29
|
+
width = left_width + right_width
|
|
30
|
+
|
|
31
|
+
File.write(output, <<~SVG)
|
|
32
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="#{width}" height="20" role="img" aria-label="#{title}: #{label}">
|
|
33
|
+
<title>#{title}: #{label}</title>
|
|
34
|
+
<linearGradient id="s" x2="0" y2="100%">
|
|
35
|
+
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
36
|
+
<stop offset="1" stop-opacity=".1"/>
|
|
37
|
+
</linearGradient>
|
|
38
|
+
<clipPath id="r"><rect width="#{width}" height="20" rx="3" fill="#fff"/></clipPath>
|
|
39
|
+
<g clip-path="url(#r)">
|
|
40
|
+
<rect width="#{left_width}" height="20" fill="#555"/>
|
|
41
|
+
<rect x="#{left_width}" width="#{right_width}" height="20" fill="#{color}"/>
|
|
42
|
+
<rect width="#{width}" height="20" fill="url(#s)"/>
|
|
43
|
+
</g>
|
|
44
|
+
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
|
|
45
|
+
<text x="#{left_width / 2}" y="14">#{title}</text>
|
|
46
|
+
<text x="#{left_width + (right_width / 2)}" y="14">#{label}</text>
|
|
47
|
+
</g>
|
|
48
|
+
</svg>
|
|
49
|
+
SVG
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: schema-model
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Doug Youch
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: inheritance-helper
|
|
@@ -23,26 +23,29 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '0'
|
|
26
|
-
description:
|
|
26
|
+
description: A flexible DSL for defining strongly-typed data models with automatic
|
|
27
|
+
parsing, nested associations, dynamic types, and ActiveModel validations
|
|
27
28
|
email: dougyouch@gmail.com
|
|
28
29
|
executables:
|
|
29
30
|
- schema-json2csv
|
|
30
31
|
extensions: []
|
|
31
32
|
extra_rdoc_files: []
|
|
32
33
|
files:
|
|
33
|
-
- ".
|
|
34
|
+
- ".github/workflows/ci.yml"
|
|
35
|
+
- ".github/workflows/release.yml"
|
|
34
36
|
- ".gitignore"
|
|
37
|
+
- ".release-please-manifest.json"
|
|
35
38
|
- ".rubocop.yml"
|
|
36
39
|
- ".ruby-gemset"
|
|
37
40
|
- ".ruby-version"
|
|
38
|
-
-
|
|
41
|
+
- ARCHITECTURE.md
|
|
42
|
+
- CHANGELOG.md
|
|
43
|
+
- CLAUDE.md
|
|
39
44
|
- Gemfile
|
|
40
45
|
- Gemfile.lock
|
|
41
46
|
- LICENSE.txt
|
|
42
47
|
- README.md
|
|
43
|
-
- Rakefile
|
|
44
48
|
- bin/schema-json2csv
|
|
45
|
-
- docs/ARCHITECTURE.md
|
|
46
49
|
- lib/schema-model.rb
|
|
47
50
|
- lib/schema/active_model_validations.rb
|
|
48
51
|
- lib/schema/all.rb
|
|
@@ -63,15 +66,17 @@ files:
|
|
|
63
66
|
- lib/schema/parsers/json.rb
|
|
64
67
|
- lib/schema/parsing_errors.rb
|
|
65
68
|
- lib/schema/utils.rb
|
|
69
|
+
- lib/schema/version.rb
|
|
66
70
|
- lib/schema_validator.rb
|
|
71
|
+
- release-please-config.json
|
|
67
72
|
- schema-model.gemspec
|
|
68
|
-
- script/bundle_install_all_versions
|
|
69
73
|
- script/console
|
|
70
|
-
- script/
|
|
74
|
+
- script/coverage_badge.rb
|
|
71
75
|
homepage: https://github.com/dougyouch/schema
|
|
72
76
|
licenses:
|
|
73
77
|
- MIT
|
|
74
|
-
metadata:
|
|
78
|
+
metadata:
|
|
79
|
+
rubygems_mfa_required: 'true'
|
|
75
80
|
rdoc_options: []
|
|
76
81
|
require_paths:
|
|
77
82
|
- lib
|
|
@@ -86,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
86
91
|
- !ruby/object:Gem::Version
|
|
87
92
|
version: '0'
|
|
88
93
|
requirements: []
|
|
89
|
-
rubygems_version:
|
|
94
|
+
rubygems_version: 4.0.20
|
|
90
95
|
specification_version: 4
|
|
91
|
-
summary:
|
|
96
|
+
summary: Data transformation, validation, and type safety for Ruby
|
|
92
97
|
test_files: []
|
data/.cursor-rules
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# Cursor Rules Configuration
|
|
2
|
-
|
|
3
|
-
# Ignore common development and system files
|
|
4
|
-
ignore {
|
|
5
|
-
".git/"
|
|
6
|
-
".DS_Store"
|
|
7
|
-
"*.log"
|
|
8
|
-
"tmp/"
|
|
9
|
-
"node_modules/"
|
|
10
|
-
"coverage/"
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
# Define common code block markers
|
|
14
|
-
markers {
|
|
15
|
-
start "# START"
|
|
16
|
-
end "# END"
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
# Define language-specific comment styles
|
|
20
|
-
comments {
|
|
21
|
-
ruby "#"
|
|
22
|
-
javascript "//"
|
|
23
|
-
python "#"
|
|
24
|
-
html "<!--"
|
|
25
|
-
css "/*"
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
# Define safe edit boundaries
|
|
29
|
-
boundaries {
|
|
30
|
-
function_start "^(def|function|class) "
|
|
31
|
-
block_start "^(if|while|for|begin|module) "
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
# Define merge conflict markers to avoid
|
|
35
|
-
conflicts {
|
|
36
|
-
start "<<<<<<< "
|
|
37
|
-
middle "======="
|
|
38
|
-
end ">>>>>>> "
|
|
39
|
-
}
|
data/.travis.yml
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
env:
|
|
2
|
-
global:
|
|
3
|
-
- CC_TEST_REPORTER_ID=f06234974aa4c4c52d14cb9ef800df79de52013c38e1d149fd04f2284e722f57
|
|
4
|
-
rvm:
|
|
5
|
-
- 3.1.0
|
|
6
|
-
language: ruby
|
|
7
|
-
before_script:
|
|
8
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
|
9
|
-
- chmod +x ./cc-test-reporter
|
|
10
|
-
- ./cc-test-reporter before-build
|
|
11
|
-
script:
|
|
12
|
-
- bundle exec rspec
|
|
13
|
-
after_script:
|
|
14
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|