mn-requirements 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f81b57e8350c7018f06bb68420de8d7b409b7f9ff4b81eb0d98d06f484e246e
|
4
|
+
data.tar.gz: 771ba5edb39491ad133dfc2d8cacaba2e11a0eba8b95389a2d834ddd84d0227a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38d500ecb762b731b2ef373c55c67b0cfef8e4a93bfcf4619d629c6fe69fae635c4362502bf3235a94f3b5cfbab7248fcd5e7110c42640916bd4e3b3b33e21dc
|
7
|
+
data.tar.gz: 8d5c5b770acd55b9b0006345f3c743e863239257c353626e4f56f0cb50dc218f9512338080e30bec75160e89b61bf85b747296ead049480812625799cc3fc74e
|
@@ -197,9 +197,9 @@ module Metanorma
|
|
197
197
|
end
|
198
198
|
|
199
199
|
def requirement_description_parse(node, out)
|
200
|
-
lbl = "
|
201
|
-
recommend_class(node.parent) == "
|
202
|
-
lbl = "
|
200
|
+
lbl = "description"
|
201
|
+
recommend_class(node.parent) == "recommend" and
|
202
|
+
lbl = "statement"
|
203
203
|
out << "<tr><th>#{@labels['modspec'][lbl]}</th>" \
|
204
204
|
"<td>#{node.children.to_xml}</td></tr>"
|
205
205
|
out
|
@@ -1,3 +1,10 @@
|
|
1
|
+
class Nokogiri::XML::Document
|
2
|
+
def reqt_iter(&block)
|
3
|
+
xpath("//xmlns:requirement | //xmlns:recommendation | //xmlns:permission")
|
4
|
+
.each_with_object({}, &block)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
1
8
|
module Metanorma
|
2
9
|
class Requirements
|
3
10
|
class Modspec < Default
|
@@ -36,10 +43,9 @@ module Metanorma
|
|
36
43
|
end
|
37
44
|
|
38
45
|
def reqtlabels(doc)
|
39
|
-
doc.
|
40
|
-
.
|
41
|
-
|
42
|
-
end
|
46
|
+
doc.reqt_iter do |r, m|
|
47
|
+
l = r.at(ns("./identifier"))&.text and m[l] = r["id"]
|
48
|
+
end
|
43
49
|
end
|
44
50
|
|
45
51
|
# embedded reqts xref to reqts via label lookup
|
@@ -64,30 +70,23 @@ module Metanorma
|
|
64
70
|
end
|
65
71
|
|
66
72
|
def reqt_ids(docxml)
|
67
|
-
docxml.
|
68
|
-
.
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
+
docxml.reqt_iter do |r, m|
|
74
|
+
id = r.at(ns("./identifier")) or next
|
75
|
+
m[id.text] =
|
76
|
+
{ id: r["id"], lbl: @xrefs.anchor(r["id"], :xref, false) }
|
77
|
+
end
|
73
78
|
end
|
74
79
|
|
75
80
|
def reqt_links_test(docxml)
|
76
|
-
docxml.
|
77
|
-
.each_with_object({}) do |r, m|
|
78
|
-
reqt_links_test1(r, m)
|
79
|
-
end
|
81
|
+
docxml.reqt_iter { |r, m| reqt_links_test1(r, m) }
|
80
82
|
end
|
81
83
|
|
82
84
|
def reqt_links_test1(reqt, acc)
|
83
|
-
|
84
|
-
verification).include?(reqt["type"])
|
85
|
-
|
85
|
+
%w(conformanceclass verification).include?(reqt["type"]) or return
|
86
86
|
subj = reqt_extract_target(reqt)
|
87
87
|
id = reqt.at(ns("./identifier")) or return
|
88
88
|
lbl = @xrefs.anchor(@reqt_ids[id.text.strip][:id], :xref, false)
|
89
|
-
|
90
|
-
|
89
|
+
(subj && lbl) or return
|
91
90
|
acc[subj.text] = { lbl: lbl, id: reqt["id"] }
|
92
91
|
end
|
93
92
|
|
@@ -110,23 +109,20 @@ module Metanorma
|
|
110
109
|
|
111
110
|
# we have not implemented multiple levels of nesting of classes
|
112
111
|
def reqt_links_class(docxml)
|
113
|
-
docxml.
|
114
|
-
.
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
.each do |r1|
|
120
|
-
m = reqt_links_class1(id, r, r1, m)
|
121
|
-
end
|
112
|
+
docxml.reqt_iter do |r, m|
|
113
|
+
%w(class conformanceclass).include?(r["type"]) or next
|
114
|
+
id = r.at(ns("./identifier")) or next
|
115
|
+
r.xpath(ns("./requirement | ./recommendation | ./permission"))
|
116
|
+
.each do |r1|
|
117
|
+
m = reqt_links_class1(id, r, r1, m)
|
122
118
|
end
|
119
|
+
end
|
123
120
|
end
|
124
121
|
|
125
122
|
def reqt_links_class1(id, parent_reqt, reqt, acc)
|
126
123
|
id1 = reqt.at(ns("./identifier")) or return acc
|
127
124
|
lbl = @xrefs.anchor(@reqt_ids[id.text.strip][:id], :xref, false)
|
128
|
-
return acc
|
129
|
-
|
125
|
+
lbl or return acc
|
130
126
|
acc[id1.text] = { lbl: lbl, id: parent_reqt["id"] }
|
131
127
|
acc
|
132
128
|
end
|
@@ -139,10 +135,7 @@ module Metanorma
|
|
139
135
|
end
|
140
136
|
|
141
137
|
def reqt_id_base_init(docxml)
|
142
|
-
docxml.
|
143
|
-
.each_with_object({}) do |r, m|
|
144
|
-
m[r["id"]] = reqt_extract_id_base(r)&.text
|
145
|
-
end
|
138
|
+
docxml.reqt_iter { |r, m| m[r["id"]] = reqt_extract_id_base(r)&.text }
|
146
139
|
end
|
147
140
|
|
148
141
|
def reqt_id_base_inherit(ret, class2reqt)
|
@@ -1,10 +1,15 @@
|
|
1
|
+
require "tsort"
|
2
|
+
|
1
3
|
module Metanorma
|
2
4
|
class Requirements
|
3
5
|
class Modspec < Default
|
4
6
|
def validate(reqt, log)
|
7
|
+
@fatalerrors = []
|
5
8
|
@log ||= log
|
6
9
|
@ids ||= reqt_links(reqt.document)
|
10
|
+
reqt_cycles_validate
|
7
11
|
reqt_link_validate(reqt)
|
12
|
+
@fatalerrors
|
8
13
|
end
|
9
14
|
|
10
15
|
def nested_reqt?(reqt)
|
@@ -109,17 +114,26 @@ module Metanorma
|
|
109
114
|
.each_with_object({ id: {}, class: {}, label: {} }) do |r, m|
|
110
115
|
next if nested_reqt?(r)
|
111
116
|
|
112
|
-
reqt_links1(r, m)
|
117
|
+
reqt_links1(r, m, type2validate(r), reqt_links_struct(r))
|
113
118
|
end
|
114
119
|
end
|
115
120
|
|
116
|
-
def reqt_links1(reqt, hash)
|
117
|
-
|
118
|
-
a = reqt_links_struct(reqt)
|
119
|
-
hash[:id][reqt["id"]] = a
|
121
|
+
def reqt_links1(reqt, hash, type, struct)
|
122
|
+
hash[:id][reqt["id"]] = struct
|
120
123
|
hash[:class][type] ||= []
|
121
|
-
hash[:class][type] <<
|
122
|
-
hash
|
124
|
+
hash[:class][type] << struct
|
125
|
+
reqt_links1_label(reqt, hash, struct)
|
126
|
+
end
|
127
|
+
|
128
|
+
def reqt_links1_label(reqt, hash, struct)
|
129
|
+
return hash unless struct[:label]
|
130
|
+
|
131
|
+
if hash[:label][struct[:label]]
|
132
|
+
msg = "Modspec identifier #{struct[:label]} is used more than once"
|
133
|
+
@log.add("Requirements", reqt, msg)
|
134
|
+
@fatalerrors << msg
|
135
|
+
end
|
136
|
+
hash[:label][struct[:label]] = reqt["id"]
|
123
137
|
hash
|
124
138
|
end
|
125
139
|
|
@@ -140,6 +154,54 @@ module Metanorma
|
|
140
154
|
indirect_dependency: classif_tag(reqt, "indirect-dependency"),
|
141
155
|
implements: classif_tag(reqt, "implements") }
|
142
156
|
end
|
157
|
+
|
158
|
+
def reqt_cycles_validate
|
159
|
+
@cycles_validated and return
|
160
|
+
@cycles_validated = true
|
161
|
+
%i(child dependency indirect_dependency implements).each do |x|
|
162
|
+
reqt_cycles_validate1(x)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def reqt_cycles_validate1(link)
|
167
|
+
arr = TSHash.new(@ids[:id].values)
|
168
|
+
arr.link = link
|
169
|
+
TSort.each_strongly_connected_component(
|
170
|
+
lambda { |&b| arr.tsort_each_node(&b) },
|
171
|
+
lambda { |n, &b| arr.tsort_each_child(n, &b) },
|
172
|
+
) do |c|
|
173
|
+
c.size == 1 and next
|
174
|
+
log_cycle(link, c)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def log_cycle(link, path)
|
179
|
+
@log.add("Requirements", nil, <<~MSG
|
180
|
+
Cycle in Modspec linkages through #{link}: #{(path << path.first).join(' => ')}
|
181
|
+
MSG
|
182
|
+
)
|
183
|
+
end
|
184
|
+
|
185
|
+
class TSHash
|
186
|
+
include TSort
|
187
|
+
attr_accessor :link
|
188
|
+
|
189
|
+
def initialize(arr)
|
190
|
+
@hash = arr.each_with_object({}) do |v, m|
|
191
|
+
m[v[:label]] = v
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def tsort_each_node(&block)
|
196
|
+
@hash.keys.each(&block)
|
197
|
+
end
|
198
|
+
|
199
|
+
def tsort_each_child(node, &block)
|
200
|
+
(@hash[node] || {})[@link]&.each(&block)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def reqt_cycles_validate_dependency; end
|
143
205
|
end
|
144
206
|
end
|
145
207
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mn-requirements
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-11-
|
11
|
+
date: 2022-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: isodoc-i18n
|