yaml_tools 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/tools/combine.rb +214 -0
- data/lib/tools/compare.rb +267 -0
- data/lib/tools/utility.rb +74 -0
- data/lib/yaml_tools.rb +5 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fe18af8ef1c5ccad515bc83b88c2a663d143e56d49a30efe748b772b9ff3572b
|
4
|
+
data.tar.gz: 6fc99c8e0aa6ef9385ba82a1999b763fcab26f1a6298f6f02c4228c932e8b23a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1c771e0e390a84bf7bac523e6a81f630ee46d20540b1b4bcd251c6840a6747b0d4a54059d4325f6c655ddbec95395730db98aae2dbcee67153d94e57a96b8b01
|
7
|
+
data.tar.gz: eb91e0ccc7c759123cee799b7b5422975a55dff273b6e965aba62a438f64aab246e9418a2e6ccff1fe9bea2eedb2bade562dcbaa668c2e2ea7f4640f4d6fc6da
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module YAMLTools
|
4
|
+
class Combiner
|
5
|
+
def combine_levels (s, d)
|
6
|
+
level = []
|
7
|
+
|
8
|
+
# Split into key/value pairs
|
9
|
+
sourceChildren = s.each_slice(2).to_a
|
10
|
+
differenceChildren = d.each_slice(2).to_a
|
11
|
+
|
12
|
+
sourceChildren.each {|sourcePair|
|
13
|
+
sourceKey = sourcePair[0]
|
14
|
+
sourceValue = sourcePair[1]
|
15
|
+
|
16
|
+
# Find difference pair
|
17
|
+
differencePairs = differenceChildren.find_all {|i| i[0].value == sourceKey.value}
|
18
|
+
|
19
|
+
if (differencePairs.length > 1) then
|
20
|
+
if (sourceKey.value == "<<") then
|
21
|
+
# Find merge key with matching alias
|
22
|
+
differencePair = differencePairs.find {|i|
|
23
|
+
(i[1].is_a?(Psych::Nodes::Alias) && i[1].anchor == sourceValue.anchor) ||
|
24
|
+
(i[1].is_a?(Psych::Nodes::Sequence) && i[1].children.any? {|a| a.is_a?(Psych::Nodes::Alias) && a.anchor == sourceValue.anchor})}
|
25
|
+
else
|
26
|
+
# Some ArchivesSpace files have duplicate keys so use the last one
|
27
|
+
differencePair = differencePairs.last
|
28
|
+
end
|
29
|
+
else
|
30
|
+
differencePair = differencePairs.first
|
31
|
+
end
|
32
|
+
|
33
|
+
if (differencePair == nil) then
|
34
|
+
# difference not found so copy node
|
35
|
+
level << sourceKey
|
36
|
+
level << sourceValue
|
37
|
+
else
|
38
|
+
differenceKey = differencePair[0]
|
39
|
+
differenceValue = differencePair[1]
|
40
|
+
|
41
|
+
if (differenceKey.value == '<<') then
|
42
|
+
# If aliases or sequences of aliases then merge
|
43
|
+
if ((sourceValue.is_a?(Psych::Nodes::Alias) || sourceValue.is_a?(Psych::Nodes::Sequence)) && (differenceValue.is_a?(Psych::Nodes::Alias) || differenceValue.is_a?(Psych::Nodes::Sequence))) then
|
44
|
+
if (sourceValue.is_a?(Psych::Nodes::Alias) && (differenceValue.is_a?(Psych::Nodes::Sequence) && differenceValue.children.all? {|a| a.is_a?(Psych::Nodes::Alias)})) then
|
45
|
+
# Merge aliases
|
46
|
+
if (differenceValue.children.none? {|a| a.anchor == sourceValue.anchor}) then
|
47
|
+
# Add alias to sequence
|
48
|
+
differenceValue.children = differenceValue.children << sourceValue
|
49
|
+
end
|
50
|
+
|
51
|
+
level.insert(0, sourceKey)
|
52
|
+
level.insert(1, differenceValue)
|
53
|
+
|
54
|
+
elsif (differenceValue.is_a?(Psych::Nodes::Alias) && (sourceValue.is_a?(Psych::Nodes::Sequence) && sourceValue.children.all? {|a| a.is_a?(Psych::Nodes::Alias)})) then
|
55
|
+
# Merge aliases
|
56
|
+
if (sourceValue.children.none? {|a| a.anchor == differenceValue.anchor}) then
|
57
|
+
# Add alias to sequence
|
58
|
+
sourceValue.children = sourceValue.children << differenceValue
|
59
|
+
end
|
60
|
+
|
61
|
+
level.insert(0, sourceKey)
|
62
|
+
level.insert(1, sourceValue)
|
63
|
+
elsif (sourceValue.is_a?(Psych::Nodes::Sequence) && differenceValue.is_a?(Psych::Nodes::Sequence))
|
64
|
+
newSequence = Psych::Nodes::Sequence.new(sourceValue.anchor, sourceValue.tag, sourceValue.implicit, Psych::Nodes::Sequence::FLOW)
|
65
|
+
|
66
|
+
newSequence.children
|
67
|
+
.concat(sourceValue.children, differenceValue.children)
|
68
|
+
.uniq! {|a| a.anchor}
|
69
|
+
|
70
|
+
level.insert(0, sourceKey)
|
71
|
+
level.insert(1, newSequence)
|
72
|
+
elsif (sourceValue.is_a?(Psych::Nodes::Alias) && differenceValue.is_a?(Psych::Nodes::Alias))
|
73
|
+
if (sourceValue.anchor == differenceValue.anchor) then
|
74
|
+
level.insert(0, sourceKey)
|
75
|
+
level.insert(1, sourceValue)
|
76
|
+
else
|
77
|
+
newSequence = Psych::Nodes::Sequence.new(sourceValue.anchor, sourceValue.tag, sourceValue.implicit, Psych::Nodes::Sequence::FLOW)
|
78
|
+
|
79
|
+
newSequence.children
|
80
|
+
.concat([sourceValue, differenceValue])
|
81
|
+
.uniq! {|a| a.anchor}
|
82
|
+
|
83
|
+
level.insert(0, sourceKey)
|
84
|
+
level.insert(1, newSequence)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
elsif (differenceValue.is_a?(Psych::Nodes::Mapping)) then
|
89
|
+
childLevel = combine_levels(sourceValue.children, differenceValue.children)
|
90
|
+
|
91
|
+
newMapping = Psych::Nodes::Mapping.new(sourceValue.anchor, sourceValue.tag, sourceValue.implicit, sourceValue.style)
|
92
|
+
|
93
|
+
if (childLevel.length > 0) then
|
94
|
+
newMapping.children.push(*childLevel)
|
95
|
+
end
|
96
|
+
|
97
|
+
level << differenceKey
|
98
|
+
level << newMapping
|
99
|
+
else
|
100
|
+
level << differenceKey
|
101
|
+
level << differenceValue
|
102
|
+
end
|
103
|
+
end
|
104
|
+
}
|
105
|
+
|
106
|
+
# Add all difference pairs that don't exist in the source
|
107
|
+
|
108
|
+
differenceChildren.each {|differencePair|
|
109
|
+
differenceKey = differencePair[0]
|
110
|
+
differenceValue = differencePair[1]
|
111
|
+
|
112
|
+
if (sourceChildren.none? {|i| i[0].value == differenceKey.value}) then
|
113
|
+
if (differenceKey.value == '<<') then
|
114
|
+
level.insert(0, differenceKey)
|
115
|
+
level.insert(1, differenceValue)
|
116
|
+
else
|
117
|
+
level << differenceKey
|
118
|
+
level << differenceValue
|
119
|
+
end
|
120
|
+
end
|
121
|
+
}
|
122
|
+
|
123
|
+
level
|
124
|
+
end
|
125
|
+
|
126
|
+
# def flatten_merge_keys(s)
|
127
|
+
# level = []
|
128
|
+
|
129
|
+
# sourceChildren = s.each_slice(2).to_a
|
130
|
+
|
131
|
+
# mergeKeys = sourceChildren.find_all {|i| i[0].value == "<<" }
|
132
|
+
|
133
|
+
# if (mergeKeys.length > 0) then
|
134
|
+
# if (mergeKeys.length == 1) then
|
135
|
+
# # Add merge key
|
136
|
+
# level << mergeKeys.first[0]
|
137
|
+
# level << mergeKeys.first[1]
|
138
|
+
# else
|
139
|
+
# newSequence = Psych::Nodes::Sequence.new(nil, nil, true, Psych::Nodes::Sequence::FLOW)
|
140
|
+
|
141
|
+
# mergeKeys.each {|m|
|
142
|
+
# if (m[1].is_a?(Psych::Nodes::Alias)) then
|
143
|
+
# newSequence.children << m[1]
|
144
|
+
# elsif (m[1].is_a?(Psych::Nodes::Sequence)) then
|
145
|
+
# newSequence.children.concat(m[1].children)
|
146
|
+
# end
|
147
|
+
# }
|
148
|
+
|
149
|
+
# level << Psych::Nodes::Scalar.new("<<")
|
150
|
+
# level << newSequence
|
151
|
+
# end
|
152
|
+
# end
|
153
|
+
|
154
|
+
# sourceChildren.each {|sourcePair|
|
155
|
+
# sourceKey = sourcePair[0]
|
156
|
+
# sourceValue = sourcePair[1]
|
157
|
+
|
158
|
+
# if (sourceValue.is_a?(Psych::Nodes::Mapping)) then
|
159
|
+
# childLevel = flatten_merge_keys(sourceValue.children)
|
160
|
+
|
161
|
+
# newMapping = Psych::Nodes::Mapping.new(sourceValue.anchor, sourceValue.tag, sourceValue.implicit, sourceValue.style)
|
162
|
+
|
163
|
+
# if (childLevel.length > 0) then
|
164
|
+
# newMapping.children.push(*childLevel)
|
165
|
+
# end
|
166
|
+
|
167
|
+
# level << sourceKey
|
168
|
+
# level << newMapping
|
169
|
+
# else
|
170
|
+
# if (sourceKey.value != "<<") then
|
171
|
+
# level << sourceKey
|
172
|
+
# level << sourceValue
|
173
|
+
# end
|
174
|
+
# end
|
175
|
+
# }
|
176
|
+
|
177
|
+
# level
|
178
|
+
# end
|
179
|
+
|
180
|
+
def combine_files(sourceFilePath, differenceFilePath)
|
181
|
+
sourceFile = File.open(sourceFilePath, "r")
|
182
|
+
differenceFile = File.open(differenceFilePath, "r")
|
183
|
+
|
184
|
+
begin
|
185
|
+
output = combine(sourceFile, differenceFile)
|
186
|
+
ensure
|
187
|
+
sourceFile.close
|
188
|
+
differenceFile.close
|
189
|
+
end
|
190
|
+
|
191
|
+
output
|
192
|
+
end
|
193
|
+
|
194
|
+
def combine(source, difference)
|
195
|
+
# Load files
|
196
|
+
sourceDocument = YAML.parse(source)
|
197
|
+
differenceDocument = YAML.parse(difference)
|
198
|
+
|
199
|
+
# Flatten merge keys for older ArchivesSpace files
|
200
|
+
sourceDocument = YAMLTools.flatten_merge_keys(sourceDocument.root.children)
|
201
|
+
differenceDocument = YAMLTools.flatten_merge_keys(differenceDocument.root.children)
|
202
|
+
|
203
|
+
@combined = combine_levels(sourceDocument, differenceDocument)
|
204
|
+
|
205
|
+
if (@combined.length > 0) then
|
206
|
+
output = YAMLTools.createDocument(@combined)
|
207
|
+
else
|
208
|
+
output = ''
|
209
|
+
end
|
210
|
+
|
211
|
+
output
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,267 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module YAMLTools
|
4
|
+
class Comparer
|
5
|
+
@source_anchors = {}
|
6
|
+
@modified_anchors = []
|
7
|
+
|
8
|
+
def processLevel (s, d, includeAnchorDependencies)
|
9
|
+
level = []
|
10
|
+
|
11
|
+
# Split into key/value pairs
|
12
|
+
sourceChildren = s.each_slice(2).to_a
|
13
|
+
destinationChildren = d.each_slice(2).to_a
|
14
|
+
|
15
|
+
# Add all anchors for this level for use when performing potential comparisons later
|
16
|
+
sourceChildren.find_all {|i| !i[1].is_a?(Psych::Nodes::Alias) && !i[1].anchor.nil?}.each {|i| @source_anchors[i[1].anchor] = i[1]}
|
17
|
+
|
18
|
+
destinationChildren.each {|destinationPair|
|
19
|
+
destinationKey = destinationPair[0]
|
20
|
+
destinationValue = destinationPair[1]
|
21
|
+
|
22
|
+
# Find source pair
|
23
|
+
sourcePairs = sourceChildren.find_all {|i| i[0].value == destinationKey.value}
|
24
|
+
|
25
|
+
if (sourcePairs.length > 1) then
|
26
|
+
if (destinationKey.value == "<<") then
|
27
|
+
# Find merge key with matching alias
|
28
|
+
sourcePair = sourcePairs.find {|i| i[1].is_a?(Psych::Nodes::Alias) && i[1].anchor == destinationValue.anchor}
|
29
|
+
else
|
30
|
+
# Some ArchivesSpace files have duplicate keys so use the last one
|
31
|
+
sourcePair = sourcePairs.last
|
32
|
+
end
|
33
|
+
else
|
34
|
+
sourcePair = sourcePairs.first
|
35
|
+
end
|
36
|
+
|
37
|
+
if (sourcePair == nil) then
|
38
|
+
# Source not found so copy node
|
39
|
+
level << destinationKey
|
40
|
+
level << destinationValue
|
41
|
+
else
|
42
|
+
sourceKey = sourcePair[0]
|
43
|
+
sourceValue = sourcePair[1]
|
44
|
+
|
45
|
+
if (sourceKey.value == "<<") then
|
46
|
+
# Handle merge keys specifically since they can be an individual alias or a sequence or aliases
|
47
|
+
|
48
|
+
if (sourceValue.is_a?(Psych::Nodes::Sequence)) then
|
49
|
+
if (destinationValue.is_a?(Psych::Nodes::Sequence)) then
|
50
|
+
if (sourceValue.children.length == destinationValue.children.length) then
|
51
|
+
# Compare sequences
|
52
|
+
sourceValue.children.each_with_index {|a, index|
|
53
|
+
if (a.anchor != destinationValue.children[index].anchor || (includeAnchorDependencies && @modified_anchors.include?(destinationValue.children[index].anchor))) then
|
54
|
+
# Different aliases or ordering
|
55
|
+
level << destinationKey
|
56
|
+
level << destinationValue
|
57
|
+
break
|
58
|
+
end
|
59
|
+
}
|
60
|
+
else
|
61
|
+
# Different number of aliases
|
62
|
+
level << destinationKey
|
63
|
+
level << destinationValue
|
64
|
+
end
|
65
|
+
elsif (destinationValue.is_a?(Psych::Nodes::Alias)) then
|
66
|
+
# Sequence of aliases overriden by single alias
|
67
|
+
level << destinationKey
|
68
|
+
level << destinationValue
|
69
|
+
else
|
70
|
+
# Bad data
|
71
|
+
end
|
72
|
+
elsif (sourceValue.is_a?(Psych::Nodes::Alias)) then
|
73
|
+
if (destinationValue.is_a?(Psych::Nodes::Sequence)) then
|
74
|
+
# Single alias overriden by sequence of aliases
|
75
|
+
level << destinationKey
|
76
|
+
level << destinationValue
|
77
|
+
elsif (destinationValue.is_a?(Psych::Nodes::Alias)) then
|
78
|
+
# Compare aliases
|
79
|
+
if (sourceValue.anchor != destinationValue.anchor || (includeAnchorDependencies && @modified_anchors.include?(destinationValue.anchor))) then
|
80
|
+
# Different aliases
|
81
|
+
level << destinationKey
|
82
|
+
level << destinationValue
|
83
|
+
end
|
84
|
+
else
|
85
|
+
# Bad data
|
86
|
+
end
|
87
|
+
else
|
88
|
+
# Bad data
|
89
|
+
end
|
90
|
+
elsif (destinationValue.is_a?(Psych::Nodes::Mapping)) then
|
91
|
+
childLevel = processLevel(sourceValue.children, destinationValue.children, includeAnchorDependencies)
|
92
|
+
|
93
|
+
if (childLevel.length > 0) then
|
94
|
+
newMapping = Psych::Nodes::Mapping.new(destinationValue.anchor, destinationValue.tag, destinationValue.implicit, destinationValue.style)
|
95
|
+
newMapping.children.push(*childLevel)
|
96
|
+
|
97
|
+
level << destinationKey
|
98
|
+
level << newMapping
|
99
|
+
|
100
|
+
if (destinationValue.anchor != nil) then
|
101
|
+
@modified_anchors << destinationValue.anchor
|
102
|
+
end
|
103
|
+
end
|
104
|
+
elsif (destinationValue.is_a?(Psych::Nodes::Scalar)) then
|
105
|
+
if (sourceValue.is_a?(Psych::Nodes::Scalar) && (destinationValue.value != sourceValue.value)) then
|
106
|
+
level << destinationKey
|
107
|
+
level << destinationValue
|
108
|
+
|
109
|
+
if destinationValue.anchor != nil then
|
110
|
+
@modified_anchors << destinationValue.anchor
|
111
|
+
end
|
112
|
+
elsif (sourceValue.is_a?(Psych::Nodes::Alias || (includeAnchorDependencies && @modified_anchors.include?(destinationValue.anchor)))) then
|
113
|
+
level << destinationKey
|
114
|
+
level << destinationValue
|
115
|
+
end
|
116
|
+
elsif (destinationValue.is_a?(Psych::Nodes::Alias)) then
|
117
|
+
if (sourceValue.is_a?(Psych::Nodes::Alias) && (destinationValue.anchor != sourceValue.anchor)) then
|
118
|
+
level << destinationKey
|
119
|
+
level << destinationValue
|
120
|
+
elsif (sourceValue.is_a?(Psych::Nodes::Scalar)) then
|
121
|
+
level << destinationKey
|
122
|
+
level << destinationValue
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
}
|
127
|
+
|
128
|
+
if (includeAnchorDependencies)
|
129
|
+
# Find source pairs where value is alias that don't exist in destination
|
130
|
+
# Look for aliases whose anchor was modified
|
131
|
+
sourceChildren.find_all {|i|
|
132
|
+
i[1].is_a?(Psych::Nodes::Alias) &&
|
133
|
+
!i[1].anchor.nil? &&
|
134
|
+
@modified_anchors.include?(i[1].anchor)
|
135
|
+
}.each {|sp|
|
136
|
+
dPair = destinationChildren.find_all {|i| i[0].value == sp[0].value}.last
|
137
|
+
|
138
|
+
if (dPair == nil) then
|
139
|
+
level << sp[0]
|
140
|
+
level << sp[1]
|
141
|
+
end
|
142
|
+
}
|
143
|
+
end
|
144
|
+
|
145
|
+
level
|
146
|
+
end
|
147
|
+
|
148
|
+
def processModifiedAnchors(s, anchors)
|
149
|
+
level = []
|
150
|
+
|
151
|
+
# Split into key/value pairs
|
152
|
+
sourceChildren = s.each_slice(2).to_a
|
153
|
+
|
154
|
+
sourceChildren.each {|sourcePair|
|
155
|
+
sourceKey = sourcePair[0]
|
156
|
+
sourceValue = sourcePair[1]
|
157
|
+
|
158
|
+
# Check if merge key
|
159
|
+
if (sourceKey.value == "<<") then
|
160
|
+
# Check if in modified_anchors
|
161
|
+
|
162
|
+
if (sourceValue.is_a?(Psych::Nodes::Sequence)) then
|
163
|
+
# Check each anchor in sequence
|
164
|
+
aliases = sourceValue.children.find_all {|a| anchors.include?(a.anchor)}
|
165
|
+
|
166
|
+
if (aliases.length > 0) then
|
167
|
+
if (aliases.length == 1) then
|
168
|
+
level << sourceKey
|
169
|
+
level << aliases[0]
|
170
|
+
else
|
171
|
+
newSequence = Psych::Nodes::Sequence.new(sourceValue.anchor, sourceValue.tag, sourceValue.implicit, sourceValue.style)
|
172
|
+
newSequence.children.push(*aliases)
|
173
|
+
|
174
|
+
level << sourceKey
|
175
|
+
level << newSequence
|
176
|
+
end
|
177
|
+
end
|
178
|
+
else
|
179
|
+
if (anchors.include?(sourceValue.anchor)) then
|
180
|
+
# Add the merge key and include in the level
|
181
|
+
level << sourceKey
|
182
|
+
level << sourceValue
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
next
|
187
|
+
elsif (sourceValue.is_a?(Psych::Nodes::Mapping)) then
|
188
|
+
childLevel = processModifiedAnchors(sourceValue.children, anchors)
|
189
|
+
|
190
|
+
if (childLevel.length > 0) then
|
191
|
+
newMapping = Psych::Nodes::Mapping.new(sourceValue.anchor, sourceValue.tag, sourceValue.implicit, sourceValue.style)
|
192
|
+
newMapping.children.push(*childLevel)
|
193
|
+
|
194
|
+
level << sourceKey
|
195
|
+
level << newMapping
|
196
|
+
|
197
|
+
# Add new anchors that are located
|
198
|
+
if (sourceValue.anchor != nil) then
|
199
|
+
@modified_anchors << sourceValue.anchor
|
200
|
+
end
|
201
|
+
end
|
202
|
+
elsif (sourceValue.is_a?(Psych::Nodes::Alias) && anchors.include?(sourceValue.anchor)) then
|
203
|
+
# Add the merge key and include in the level
|
204
|
+
level << sourceKey
|
205
|
+
level << sourceValue
|
206
|
+
end
|
207
|
+
}
|
208
|
+
|
209
|
+
level
|
210
|
+
end
|
211
|
+
|
212
|
+
def compare_files(sourceFilePath, destinationFilePath, includeAnchorDependencies = false)
|
213
|
+
sourceFile = File.open(sourceFilePath, "r")
|
214
|
+
differenceFile = File.open(destinationFilePath, "r")
|
215
|
+
|
216
|
+
begin
|
217
|
+
result = compare(sourceFile, differenceFile, includeAnchorDependencies)
|
218
|
+
ensure
|
219
|
+
sourceFile.close
|
220
|
+
differenceFile.close
|
221
|
+
end
|
222
|
+
|
223
|
+
result
|
224
|
+
end
|
225
|
+
|
226
|
+
def compare(source, destination, includeAnchorDependencies = false)
|
227
|
+
@source_anchors = {}
|
228
|
+
@modified_anchors = []
|
229
|
+
|
230
|
+
sourceDocument = YAML.parse(source)
|
231
|
+
destinationDocument = YAML.parse(destination)
|
232
|
+
|
233
|
+
# Flatten merge keys for older ArchivesSpace files
|
234
|
+
sourceRootLevel = YAMLTools.flatten_merge_keys(sourceDocument.root.children)
|
235
|
+
destinationRootLevel = YAMLTools.flatten_merge_keys(destinationDocument.root.children)
|
236
|
+
|
237
|
+
@differences = processLevel(sourceRootLevel, destinationRootLevel, includeAnchorDependencies)
|
238
|
+
|
239
|
+
if (includeAnchorDependencies) then
|
240
|
+
@current_modified_anchors = []
|
241
|
+
|
242
|
+
combiner = Combiner.new
|
243
|
+
|
244
|
+
loop do
|
245
|
+
@current_modified_anchors = @modified_anchors.clone
|
246
|
+
@modified_anchors = []
|
247
|
+
modified_anchor_additions = processModifiedAnchors(sourceRootLevel, @current_modified_anchors)
|
248
|
+
|
249
|
+
if (modified_anchor_additions.length > 0) then
|
250
|
+
mergedDifferences = combiner.combine_levels(@differences, modified_anchor_additions)
|
251
|
+
@differences = mergedDifferences
|
252
|
+
end
|
253
|
+
|
254
|
+
break if (@current_modified_anchors.length == 0)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
if (@differences.length > 0) then
|
259
|
+
output = YAMLTools.createDocument(@differences)
|
260
|
+
else
|
261
|
+
output = ''
|
262
|
+
end
|
263
|
+
|
264
|
+
output
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module YAMLTools
|
4
|
+
def self.createDocument(levels)
|
5
|
+
document = Psych::Nodes::Document.new()
|
6
|
+
documentRoot = Psych::Nodes::Mapping.new();
|
7
|
+
documentRoot.children.push(*levels)
|
8
|
+
document.children << documentRoot
|
9
|
+
|
10
|
+
stream = Psych::Nodes::Stream.new
|
11
|
+
stream.children << document
|
12
|
+
output = stream.to_yaml
|
13
|
+
|
14
|
+
# Remove initial document start
|
15
|
+
document_start = (output.index("---\n") || size - 1) + 4
|
16
|
+
output.slice!(0, document_start)
|
17
|
+
|
18
|
+
output
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.flatten_merge_keys(s)
|
22
|
+
level = []
|
23
|
+
|
24
|
+
sourceChildren = s.each_slice(2).to_a
|
25
|
+
|
26
|
+
mergeKeys = sourceChildren.find_all {|i| i[0].value == "<<" }
|
27
|
+
|
28
|
+
if (mergeKeys.length > 0) then
|
29
|
+
if (mergeKeys.length == 1) then
|
30
|
+
# Add merge key
|
31
|
+
level << mergeKeys.first[0]
|
32
|
+
level << mergeKeys.first[1]
|
33
|
+
else
|
34
|
+
newSequence = Psych::Nodes::Sequence.new(nil, nil, true, Psych::Nodes::Sequence::FLOW)
|
35
|
+
|
36
|
+
mergeKeys.each {|m|
|
37
|
+
if (m[1].is_a?(Psych::Nodes::Alias)) then
|
38
|
+
newSequence.children << m[1]
|
39
|
+
elsif (m[1].is_a?(Psych::Nodes::Sequence)) then
|
40
|
+
newSequence.children.concat(m[1].children)
|
41
|
+
end
|
42
|
+
}
|
43
|
+
|
44
|
+
level << Psych::Nodes::Scalar.new("<<")
|
45
|
+
level << newSequence
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
sourceChildren.each {|sourcePair|
|
50
|
+
sourceKey = sourcePair[0]
|
51
|
+
sourceValue = sourcePair[1]
|
52
|
+
|
53
|
+
if (sourceValue.is_a?(Psych::Nodes::Mapping)) then
|
54
|
+
childLevel = flatten_merge_keys(sourceValue.children)
|
55
|
+
|
56
|
+
newMapping = Psych::Nodes::Mapping.new(sourceValue.anchor, sourceValue.tag, sourceValue.implicit, sourceValue.style)
|
57
|
+
|
58
|
+
if (childLevel.length > 0) then
|
59
|
+
newMapping.children.push(*childLevel)
|
60
|
+
end
|
61
|
+
|
62
|
+
level << sourceKey
|
63
|
+
level << newMapping
|
64
|
+
else
|
65
|
+
if (sourceKey.value != "<<") then
|
66
|
+
level << sourceKey
|
67
|
+
level << sourceValue
|
68
|
+
end
|
69
|
+
end
|
70
|
+
}
|
71
|
+
|
72
|
+
level
|
73
|
+
end
|
74
|
+
end
|
data/lib/yaml_tools.rb
ADDED
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yaml_tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Atlas Systems, Inc.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-02-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.12'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.12'
|
27
|
+
description:
|
28
|
+
email:
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- lib/tools/combine.rb
|
34
|
+
- lib/tools/compare.rb
|
35
|
+
- lib/tools/utility.rb
|
36
|
+
- lib/yaml_tools.rb
|
37
|
+
homepage: https://github.com/AtlasSystems/yaml_tools
|
38
|
+
licenses:
|
39
|
+
- MIT
|
40
|
+
metadata: {}
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '2.5'
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '4'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubygems_version: 3.4.6
|
60
|
+
signing_key:
|
61
|
+
specification_version: 4
|
62
|
+
summary: Tools for YAML files.
|
63
|
+
test_files: []
|