circuitdata 0.6.4 → 0.7.0
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 +5 -5
- data/README.md +25 -122
- data/Rakefile +4 -6
- data/lib/circuitdata.rb +32 -120
- data/lib/circuitdata/bury/bury.rb +61 -0
- data/lib/circuitdata/dereferencer.rb +49 -17
- data/lib/circuitdata/exposed_area.rb +84 -0
- data/lib/circuitdata/json_schema.rb +14 -0
- data/lib/circuitdata/json_validator.rb +56 -0
- data/lib/circuitdata/json_validator/json_schema_error_parser.rb +57 -0
- data/lib/circuitdata/material_validator.rb +40 -0
- data/lib/circuitdata/product.rb +125 -0
- data/lib/circuitdata/product_id_validator.rb +81 -0
- data/lib/circuitdata/profile.rb +31 -69
- data/lib/circuitdata/schema.rb +145 -0
- data/lib/circuitdata/schema_files/schema_v1_dereferenced.json +107155 -0
- data/lib/circuitdata/schema_files/v1/ottp_circuitdata_schema.json +68 -5307
- data/lib/circuitdata/schema_files/v1/ottp_circuitdata_schema_generics.json +23 -0
- data/lib/circuitdata/schema_files/v1/ottp_circuitdata_schema_materials.json +99 -0
- data/lib/circuitdata/schema_files/v1/ottp_circuitdata_schema_products.json +779 -0
- data/lib/circuitdata/schema_files/v1/ottp_circuitdata_schema_profiles_and_capabilities.json +323 -0
- data/lib/circuitdata/summary.rb +96 -0
- data/lib/circuitdata/validator.rb +28 -0
- data/lib/circuitdata/version.rb +2 -1
- metadata +113 -20
- data/lib/circuitdata/bk_comparer.rb +0 -106
- data/lib/circuitdata/compatibility_checker.rb +0 -160
- data/lib/circuitdata/file_comparer.rb +0 -276
- data/lib/circuitdata/schema_files/v1/ottp_circuitdata_schema_definitions.json +0 -1249
- data/lib/circuitdata/schema_files/v1/ottp_circuitdata_skeleton_schema.json +0 -94
- data/lib/circuitdata/schema_files/v1/ottp_schema_definitions.json +0 -102
- data/lib/circuitdata/tools.rb +0 -207
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cee57a28b38b2f4e09b6e27af0140b0d6bfe02287ec8e6452519c7f4106e9d84
|
4
|
+
data.tar.gz: 02ed3d0c396aab1df49448c3ee9f78977ff16c7483384240b94729178068710b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acd38a087dcfe90a368ab15d491f272cc00af1b9addc9749723e80cd626e766b5ed01aa92e87df54b38565b25c0ebf73666fd4085f3c8af1f93b7d7a23ddc57a
|
7
|
+
data.tar.gz: 87eb841eb3ab9d350f8e1bc7f7278b450771f278cc9c0713527c16bab3e9097c2c916cfe1e60106e12717b9d26fc00bb9c5f929f9a9a0a4fb09c281c09f84468
|
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# Circuitdata
|
2
|
+
|
2
3
|
This gem provides helper functions that allows you to do schema checks and control files up against each other according to the [CircuitData Language](https://circuitdata.org)
|
3
4
|
|
4
5
|
## Installation
|
6
|
+
|
5
7
|
Add this line to your application's Gemfile:
|
6
8
|
|
7
9
|
```ruby
|
@@ -9,153 +11,38 @@ gem 'circuitdata'
|
|
9
11
|
```
|
10
12
|
|
11
13
|
And then execute:
|
14
|
+
|
12
15
|
```bash
|
13
16
|
$ bundle
|
14
17
|
```
|
15
18
|
|
16
19
|
Or install it yourself as:
|
20
|
+
|
17
21
|
```bash
|
18
22
|
$ gem install circuitdata
|
19
23
|
```
|
20
24
|
|
21
25
|
## Usage
|
26
|
+
|
22
27
|
If not in rails
|
28
|
+
|
23
29
|
```
|
24
30
|
require 'circuitdata'
|
25
31
|
```
|
26
32
|
|
27
33
|
### Commands
|
28
34
|
|
29
|
-
#### `Circuitdata.compatibility_checker`
|
30
|
-
|
31
|
-
Test one file against the schema
|
32
|
-
```ruby
|
33
|
-
Circuitdata.compatibility_checker('testfile-product.json')
|
34
|
-
```
|
35
|
-
When valid gives:
|
36
|
-
```ruby
|
37
|
-
{
|
38
|
-
:error => false,
|
39
|
-
:errormessage => "",
|
40
|
-
:validationserrors => {},
|
41
|
-
:restrictederrors => {},
|
42
|
-
:enforcederrors => {},
|
43
|
-
:capabilitieserrors => {}
|
44
|
-
}
|
45
|
-
```
|
46
|
-
|
47
|
-
Test two files up against each other (one must be a product file).
|
48
|
-
```ruby
|
49
|
-
Circuitdata.compatibility_checker('testfile-product.json','testfile-profile-restricted.json')
|
50
|
-
```
|
51
|
-
|
52
|
-
When invalid results in:
|
53
|
-
```ruby
|
54
|
-
{
|
55
|
-
:error => true,
|
56
|
-
:errormessage => "The product to check did not meet the requirements",
|
57
|
-
:validationserrors => {},
|
58
|
-
:restrictederrors => {
|
59
|
-
"#/open_trade_transfer_package/products/testproduct/printed_circuits_fabrication_data/board/thickness" => [
|
60
|
-
"of type number matched the disallowed schema"
|
61
|
-
]
|
62
|
-
},
|
63
|
-
:enforcederrors => {},
|
64
|
-
:capabilitieserrors => {}
|
65
|
-
}
|
66
|
-
```
|
67
|
-
|
68
|
-
Turn off validation against the schema
|
69
|
-
```ruby
|
70
|
-
Circuitdata.compatibility_checker( 'testfile-product.json', 'testfile-profile-restricted.json', false )
|
71
|
-
```
|
72
|
-
Gives:
|
73
|
-
```ruby
|
74
|
-
{
|
75
|
-
:error => true,
|
76
|
-
:errormessage => "The product to check did not meet the requirements",
|
77
|
-
:validationserrors => {},
|
78
|
-
:restrictederrors => {
|
79
|
-
"#/open_trade_transfer_package/products/testproduct/printed_circuits_fabrication_data/board/thickness" => ["of type number matched the disallowed schema"]
|
80
|
-
},
|
81
|
-
:enforcederrors => {},
|
82
|
-
:capabilitieserrors => {}
|
83
|
-
}
|
84
|
-
|
85
|
-
```
|
86
|
-
|
87
|
-
#### `Circuitdata.compare_files`
|
88
|
-
|
89
|
-
Run a test with several files against each other and get a complete list of values and conflicts, and a summary
|
90
|
-
```ruby
|
91
|
-
product1 = File.join(__dir__, 'test/test_data/test_product1.json')
|
92
|
-
profile_restricted = File.join(__dir__, 'test/test_data/testfile-profile-restricted.json')
|
93
|
-
profile_default = File.join(__dir__, 'test/test_data/testfile-profile-default.json')
|
94
|
-
file_hash = {product1: product1, restricted: profile_restricted, default: profile_default}
|
95
|
-
|
96
|
-
Circuitdata.compare_files(file_hash, true)
|
97
|
-
```
|
98
|
-
|
99
|
-
Results in:
|
100
|
-
```ruby
|
101
|
-
{
|
102
|
-
:error=>false,
|
103
|
-
:message=>nil,
|
104
|
-
:conflict=>false,
|
105
|
-
:product_name=>"testproduct",
|
106
|
-
:columns=>[
|
107
|
-
:summary,
|
108
|
-
:product1,
|
109
|
-
:restricted,
|
110
|
-
:default
|
111
|
-
],
|
112
|
-
:master_column=>nil,
|
113
|
-
:rows=>{
|
114
|
-
:rigid_conductive_layer=>{
|
115
|
-
:count=>{
|
116
|
-
:product1=>{
|
117
|
-
:value=>11,
|
118
|
-
:conflict=>false,
|
119
|
-
:conflicts_with=>[],
|
120
|
-
:conflict_message=>[]
|
121
|
-
},
|
122
|
-
:restricted=>{
|
123
|
-
:value=>nil,
|
124
|
-
:conflict=>false,
|
125
|
-
:conflicts_with=>[],
|
126
|
-
:conflict_message=>[]
|
127
|
-
},
|
128
|
-
:default=>{
|
129
|
-
:value=>nil,
|
130
|
-
:conflict=>false,
|
131
|
-
:conflicts_with=>[],
|
132
|
-
:conflict_message=>[]
|
133
|
-
},
|
134
|
-
:summary=>{
|
135
|
-
:value=>11,
|
136
|
-
:conflict=>false,
|
137
|
-
:conflicts_with=>[:product1],
|
138
|
-
:conflict_message=>[]
|
139
|
-
}
|
140
|
-
}
|
141
|
-
# ...
|
142
|
-
}
|
143
|
-
}
|
144
|
-
}
|
145
|
-
```
|
146
|
-
|
147
35
|
#### `Circuitdata.dereferenced_schema`
|
148
36
|
|
149
37
|
This returns the JSON schema used internally to validate the Circuit Data information. It
|
150
38
|
returns the schema without any usage of `$ref` so that it can be utilized without any knowledge of the internal paths.
|
151
39
|
|
152
|
-
#### `Circuitdata::Profile.schema`
|
153
|
-
|
154
|
-
Returns a subset of the Circuit Data schema that relates to profiles. This is a schema without any `$ref`s.
|
155
40
|
#### `Circuitdata::Profile.questions`
|
41
|
+
|
156
42
|
Returns a list of grouped questions that can be used for populating an input interface related to profiles.
|
157
43
|
|
158
44
|
Example output:
|
45
|
+
|
159
46
|
```ruby
|
160
47
|
[
|
161
48
|
{
|
@@ -172,7 +59,7 @@ Example output:
|
|
172
59
|
uom: ["um"],
|
173
60
|
description: "The roughness of the copper foil."
|
174
61
|
},
|
175
|
-
path: "/open_trade_transfer_package/profiles/
|
62
|
+
path: "/open_trade_transfer_package/profiles/default/printed_circuits_fabrication_data/rigid_conductive_layer/copper_foil_roughness"
|
176
63
|
}
|
177
64
|
},
|
178
65
|
]
|
@@ -180,5 +67,21 @@ Example output:
|
|
180
67
|
# ...
|
181
68
|
]
|
182
69
|
```
|
70
|
+
|
71
|
+
### Validation
|
72
|
+
|
73
|
+
To validate a CircuitData JSON file the `Validator` can be used. This will check that a file matches the schema defined in the CircuitData language as well as logical issues. An example of a logical issue is missing layers in the layers list for a product.
|
74
|
+
|
75
|
+
The following is an example of using the `Validator`:
|
76
|
+
|
77
|
+
```
|
78
|
+
validator = Circuitdata::Validator.new(json_file_contents)
|
79
|
+
if !validator.valid?
|
80
|
+
puts validator.errors.inspect
|
81
|
+
end
|
82
|
+
# ...
|
83
|
+
```
|
84
|
+
|
183
85
|
## License
|
86
|
+
|
184
87
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
data/lib/circuitdata.rb
CHANGED
@@ -1,132 +1,44 @@
|
|
1
1
|
module Circuitdata
|
2
2
|
# SHOULD ONLY HOUSE COMMON FUNCTIONS ONLY
|
3
|
-
require 'active_support/all'
|
4
|
-
require 'json-schema'
|
5
|
-
require_relative './circuitdata/file_comparer'
|
6
|
-
require_relative './circuitdata/compatibility_checker'
|
7
|
-
require_relative './circuitdata/dereferencer'
|
8
|
-
require_relative './circuitdata/profile'
|
9
|
-
require_relative './circuitdata/tools'
|
10
3
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
if file.is_a? Hash
|
39
|
-
begin
|
40
|
-
data = file
|
41
|
-
data.deep_symbolize_keys!
|
42
|
-
rescue
|
43
|
-
error = true
|
44
|
-
message = "Could not convert the Hash into JSON"
|
45
|
-
end
|
46
|
-
else
|
47
|
-
begin
|
48
|
-
open(file) do |f|
|
49
|
-
data = JSON.parse(f.read, symbolize_names: true)
|
50
|
-
end
|
51
|
-
rescue
|
52
|
-
error = true
|
53
|
-
message = "Could not read the file"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
return error, message, data
|
4
|
+
require "active_support/all"
|
5
|
+
require_relative "./circuitdata/version"
|
6
|
+
require_relative "./circuitdata/json_schema"
|
7
|
+
require_relative "./circuitdata/dereferencer"
|
8
|
+
require_relative "./circuitdata/profile"
|
9
|
+
require_relative "./circuitdata/schema"
|
10
|
+
require_relative "./circuitdata/product"
|
11
|
+
require_relative "./circuitdata/validator"
|
12
|
+
require_relative "./circuitdata/json_validator"
|
13
|
+
require_relative "./circuitdata/material_validator"
|
14
|
+
require_relative "./circuitdata/product_id_validator"
|
15
|
+
require_relative "./circuitdata/bury/bury"
|
16
|
+
require_relative "./circuitdata/product_id_validator"
|
17
|
+
require_relative "./circuitdata/exposed_area"
|
18
|
+
require_relative "./circuitdata/summary"
|
19
|
+
|
20
|
+
SCHEMA_BASE_PATH = File.join(__dir__, "circuitdata/schema_files/v1")
|
21
|
+
SCHEMA_FULL_PATH = File.join(SCHEMA_BASE_PATH, "..", "schema_v1_dereferenced.json")
|
22
|
+
DEFINITIONS_FULL_PATH = File.join(
|
23
|
+
SCHEMA_BASE_PATH, "ottp_circuitdata_schema_definitions.json"
|
24
|
+
)
|
25
|
+
def self.dereferenced_schema(schema_file_path: SCHEMA_FULL_PATH)
|
26
|
+
schema_cache[schema_file_path] ||= Dereferencer.dereference(
|
27
|
+
schema(schema_file_path: schema_file_path),
|
28
|
+
File.dirname(schema_file_path)
|
29
|
+
)
|
57
30
|
end
|
58
31
|
|
59
|
-
|
60
|
-
error, message, validations_errors = false, nil, {}
|
32
|
+
private
|
61
33
|
|
62
|
-
|
63
|
-
validated = JSON::Validator.fully_validate(SCHEMA_FULL_PATH, content, :errors_as_objects => true)
|
64
|
-
rescue JSON::Schema::ReadFailed
|
65
|
-
error = true
|
66
|
-
message = "Could not read the validating schema"
|
67
|
-
rescue JSON::Schema::SchemaError
|
68
|
-
error = true
|
69
|
-
message = "There is something was wrong with the validating schema"
|
70
|
-
end
|
71
|
-
unless error
|
72
|
-
if validated.count > 0
|
73
|
-
error = true
|
74
|
-
message = "Could not validate the file against the CircuitData json schema"
|
75
|
-
validated.each do |val_error|
|
76
|
-
validations_errors[val_error[:fragment]] = [] unless validations_errors.has_key? val_error[:fragment]
|
77
|
-
begin
|
78
|
-
keep = val_error[:message].match("^(The\\sproperty\\s\\'[\\s\\S]*\\'\\s)([\\s\\S]*)(\\sin\\sschema\\sfile[\\s\\S]*)$").captures[1]
|
79
|
-
rescue
|
80
|
-
keep = val_error[:message]
|
81
|
-
end
|
82
|
-
validations_errors[val_error[:fragment]] << keep
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
return error, message, validations_errors
|
87
|
-
end
|
88
|
-
|
89
|
-
def self.schema
|
34
|
+
def self.schema(schema_file_path: SCHEMA_FULL_PATH)
|
90
35
|
JSON.parse(
|
91
|
-
File.read(
|
92
|
-
symbolize_names: true
|
36
|
+
File.read(schema_file_path),
|
37
|
+
symbolize_names: true,
|
93
38
|
)
|
94
39
|
end
|
95
40
|
|
96
|
-
def self.
|
97
|
-
|
98
|
-
schema,
|
99
|
-
File.dirname(Circuitdata::SCHEMA_FULL_PATH)
|
100
|
-
)
|
101
|
-
end
|
102
|
-
|
103
|
-
def self.compare_files(file_hash, validate_origins=false)
|
104
|
-
comparer = FileComparer.new(file_hash, validate_origins)
|
105
|
-
comparer.compare
|
106
|
-
end
|
107
|
-
|
108
|
-
def self.compatibility_checker(product_file, check_file=nil, validate_origins=false)
|
109
|
-
checker = CompatibilityChecker.new(product_file, check_file, validate_origins)
|
110
|
-
checker.start_check
|
111
|
-
end
|
112
|
-
|
113
|
-
def self.create_documentation()
|
114
|
-
docu = Tools.new()
|
115
|
-
ra = docu.create_structure
|
116
|
-
docu.create_documentation(ra)
|
117
|
-
end
|
118
|
-
|
119
|
-
def self.test
|
120
|
-
product1 = File.join(File.dirname(__FILE__), '../test/test_data/test_product1.json')
|
121
|
-
product2 = File.join(File.dirname(__FILE__), '../test/test_data/test_product2.json')
|
122
|
-
profile_restricted = File.join(File.dirname(__FILE__), '../test/test_data/testfile-profile-restricted.json')
|
123
|
-
profile_enforced = File.join(File.dirname(__FILE__), '../test/test_data/testfile-profile-enforced.json')
|
124
|
-
profile_default = File.join(File.dirname(__FILE__), '../test/test_data/testfile-profile-default.json')
|
125
|
-
capabilities = File.join(File.dirname(__FILE__), '../test/test_data/testfile-capability.json')
|
126
|
-
|
127
|
-
# THEN TEST THE COMPARE FILES:
|
128
|
-
puts "Testing file comparison"
|
129
|
-
file_hash = {product1: product1, product2: product2, restricted: profile_restricted, enforced: profile_enforced, default: profile_default, capability: capabilities}
|
130
|
-
Circuitdata.compare_files(file_hash, true)
|
41
|
+
def self.schema_cache
|
42
|
+
@schema_cache ||= {}
|
131
43
|
end
|
132
44
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Circuitdata
|
2
|
+
module Bury
|
3
|
+
class InvalidDataError < StandardError; end
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def bury(data, *path, value)
|
7
|
+
current_data = data
|
8
|
+
path[0..-2].each_with_index do |part, i|
|
9
|
+
current_data = next_level(part, path[i + 1], current_data)
|
10
|
+
end
|
11
|
+
if !value.nil?
|
12
|
+
current_data[path.last] = value
|
13
|
+
else
|
14
|
+
current_data.delete(path.last)
|
15
|
+
end
|
16
|
+
data
|
17
|
+
end
|
18
|
+
|
19
|
+
def dig(data, *path)
|
20
|
+
current_data = data
|
21
|
+
path.each do |part|
|
22
|
+
current_data = next_level(part, nil, current_data, initialize_missing: false)
|
23
|
+
return nil if current_data.nil?
|
24
|
+
end
|
25
|
+
current_data
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def find_matching_hash(data, partial_hash)
|
31
|
+
unless data.is_a?(Array)
|
32
|
+
fail InvalidDataError, "parent of #{partial_hash} is not an array"
|
33
|
+
end
|
34
|
+
data.find do |el|
|
35
|
+
partial_hash.all? { |k, v| el[k] == v }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def next_level(part, next_part, current_data, initialize_missing: true)
|
40
|
+
if part.is_a?(Hash)
|
41
|
+
existing_hash = find_matching_hash(current_data, part)
|
42
|
+
if !existing_hash
|
43
|
+
return nil unless initialize_missing
|
44
|
+
new_data = part.dup
|
45
|
+
current_data.push(new_data)
|
46
|
+
new_data
|
47
|
+
else
|
48
|
+
existing_hash
|
49
|
+
end
|
50
|
+
elsif current_data[part].nil?
|
51
|
+
return nil unless initialize_missing
|
52
|
+
next_is_array = next_part.is_a?(Integer) || next_part.is_a?(Hash)
|
53
|
+
current_data[part] = next_is_array ? [] : {}
|
54
|
+
current_data[part]
|
55
|
+
else
|
56
|
+
current_data[part]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|