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