-
Notifications
You must be signed in to change notification settings - Fork 0
/
check_data.rb
executable file
·123 lines (113 loc) · 3.16 KB
/
check_data.rb
1
2
3
4
5
6
7
8
9
10
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env ruby
# frozen_string_literal: true
require "yaml"
require "relaton_iso_bib"
def fix_doctype(hash)
if hash["doctype"].is_a? String
hash["doctype"] = { "type" => hash["doctype"] }
end
end
#
# Compare elements of source and destination
#
# @param [Array, String, Hash] src source element
# @param [Array, String, Hash] dest destination element
#
# @return [Array<Hash, Array, String, false>, false] not equal elements
#
def compare(src, dest) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
if !src.is_a?(dest.class) && !(dest.is_a?(Array) || src.is_a?(Array)) &&
!((dest.is_a?(Hash) && dest["content"]) || (src.is_a?(Hash) && src["content"]))
return ["- #{src.to_s[0..70]}#{src.to_s.size > 70 ? '...' : ''}",
"+ #{dest.to_s[0..70]}#{dest.to_s.size > 70 ? '...' : ''}"]
elsif dest.is_a?(Array)
return compare src, dest.first
elsif src.is_a?(Array)
return compare src.first, dest
elsif dest.is_a?(Hash) && dest["content"] && src.is_a?(String)
return compare src, dest["content"]
elsif src.is_a?(Hash) && src["content"] && dest.is_a?(String)
return compare src["content"], dest
end
case src
when Array
result = src.map.with_index { |s, i| compare s, array(dest)[i] }
compact result
when String
src != dest && ["- #{src}", "+ #{dest}"]
when Hash
result = src.map do |k, v|
res = compare v, dest[k]
{ k => res } if res && !res.empty?
end
compact result
end
end
#
# Remove falsey values from array
#
# @param [Array<Hash, Array, String, false>] arr error messages
#
# @return [Array<Hash, Array, String>] error messages without falsey values
#
def compact(arr)
result = arr.select { |v| v }
return unless result.any?
result
end
def array(arg)
arg.is_a?(Array) ? arg : [arg]
end
#
# Prints diff between source and destination
#
# @param [Hash, Array] messages diff messages
# @param [String] indent indentation
#
# @return [<Type>] <description>
#
def print_msg(messages, indent = '') # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
if messages.is_a? Hash
messages.each do |k, v|
puts "#{indent}#{k}:"
if v.is_a?(String)
puts "#{indent} #{v}"
else
print_msg v, "#{indent} "
end
end
else
messages.each do |msg|
if msg.is_a? String
puts "#{indent}#{msg}"
else
print_msg msg, indent
end
end
end
end
path = ARGV.first || "static/*.{yaml,yml}"
errors = false
Dir[path].each do |f|
yaml = YAML.load_file(f)
fix_doctype yaml
hash = RelatonIsoBib::HashConverter.hash_to_bib yaml
item = RelatonIsoBib::IsoBibliographicItem.new(**hash)
if (messages = compare(yaml, item.to_hash))&.any?
errors = true
puts "Parsing #{f} failed. Parsed content doesn't match to source."
print_msg messages
puts
end
primary_id = item.docidentifier.detect(&:primary)
unless primary_id
errors = true
puts "Parsing #{f} failed. No primary id."
end
rescue ArgumentError, NoMethodError, TypeError => e
errors = true
puts "Parsing #{f} failed. Error: #{e.message}."
puts e.backtrace
puts
end
exit(1) if errors