relaton-cli 3.0.0 → 3.0.1
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 +4 -4
- data/Gemfile +12 -0
- data/lib/relaton/cli/index_site_generator.rb +117 -8
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9e09dab74faf731f638fb7b31271e8dedd483dec7752b232ffe1d1ed82230bb4
|
|
4
|
+
data.tar.gz: d35d03f375a776575bfc86d58cf188b3da4f9120907562ceb9120b72083dfda3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f53553f7d991fb26fe8679ce9c5f898d8d33fa836cf7224e12ffaa1b831d0da27693916f9d99d3aab365f4698900e29c7b356c73bf7c497ffe3c453534ea000c
|
|
7
|
+
data.tar.gz: 5f9ddb547964442309a65aea8ba3b28959693ea4c373bb1594cdeafcae9bcc0c28957b68516613dbff917bd0aa7b5208adfacb6def16597e340352c536753fec
|
data/Gemfile
CHANGED
|
@@ -6,6 +6,17 @@ gemspec
|
|
|
6
6
|
# The single combined `relaton` gem lives at the repo root.
|
|
7
7
|
gem "relaton", path: "../.."
|
|
8
8
|
|
|
9
|
+
# parsanol 1.3.111 is the trivia-exempt release (parsanol#355): the
|
|
10
|
+
# emission-2 artifacts (pubid#614) parse parameter-shaped under it, so
|
|
11
|
+
# the pin rides it; the root gemspec floor carries the same story.
|
|
12
|
+
|
|
13
|
+
# The pubid 2.0.0 FINAL gem still ships emission-1 artifacts - under
|
|
14
|
+
# 1.3.111 its parses break exactly as parsanol#352 describes. The
|
|
15
|
+
# emission-2 set ships from 2.0.0.pre.alpha.64, so the pin names it;
|
|
16
|
+
# without it the resolver picks the final and every structured-corpus
|
|
17
|
+
# docid with a part+date fails ("Unknown parameter type: colon").
|
|
18
|
+
gem "pubid", "2.0.0.pre.alpha.64"
|
|
19
|
+
|
|
9
20
|
# https://github.com/rails/rails/issues/55886
|
|
10
21
|
# add openssl as an explicit gem to fix SSL verification issues in GHA.
|
|
11
22
|
# gem "openssl"
|
|
@@ -33,3 +44,4 @@ gem "webmock"
|
|
|
33
44
|
# (leptris#1742), pinned to match the relaton root bundle — the battery
|
|
34
45
|
# re-run accompanies this bump.
|
|
35
46
|
gem "leptris", "1.9.370.1"
|
|
47
|
+
|
|
@@ -127,7 +127,14 @@ module Relaton
|
|
|
127
127
|
# per row against 0.44 KB for the derived values alone — 543 MB vs 76 MB
|
|
128
128
|
# on a 177k-row corpus. Anything else derived from pubid must therefore
|
|
129
129
|
# be computed in `add` too; by write time the object is gone.
|
|
130
|
-
|
|
130
|
+
#
|
|
131
|
+
# `derived` marks an alias row (this document's other spellings, or a
|
|
132
|
+
# committed fetcher alias) as opposed to the document's own primary
|
|
133
|
+
# id — `indexed_rows` prunes a derived row whose render a document
|
|
134
|
+
# owns as its primary, so an alias can never repoint a spelling at
|
|
135
|
+
# the wrong file (`Type#add_or_update` keys on the rendered string
|
|
136
|
+
# and overwrites).
|
|
137
|
+
Row = Struct.new(:rendered, :file, :key, :id_hash, :derived)
|
|
131
138
|
|
|
132
139
|
attr_reader :rows
|
|
133
140
|
|
|
@@ -144,7 +151,24 @@ module Relaton
|
|
|
144
151
|
@rows = []
|
|
145
152
|
end
|
|
146
153
|
|
|
147
|
-
|
|
154
|
+
# Committed rows an id-sharing file already covers: the fetcher's
|
|
155
|
+
# aliases (a record-less registry's id pointing at the record-bearing
|
|
156
|
+
# document's file -- relaton-iana#8, #9). Carried as rows of their
|
|
157
|
+
# own so either spelling resolves to the one document.
|
|
158
|
+
def add_alias_rows(rows)
|
|
159
|
+
rows.each do |id_hash, file|
|
|
160
|
+
pubid = from_hash(id_hash)
|
|
161
|
+
next unless pubid
|
|
162
|
+
|
|
163
|
+
row = Row.new(pubid.to_s, file)
|
|
164
|
+
row.id_hash = id_hash
|
|
165
|
+
row.key = key_string(pubid)
|
|
166
|
+
row.derived = true
|
|
167
|
+
@rows << row
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def add(rendered, file, alias_ids = nil)
|
|
148
172
|
row = Row.new(rendered, file)
|
|
149
173
|
# Precompute the expensive derived values (root.number walk,
|
|
150
174
|
# lutaml to_hash) once during the streaming pass — computing
|
|
@@ -163,6 +187,43 @@ module Relaton
|
|
|
163
187
|
row.key = key_string(pubid)
|
|
164
188
|
end
|
|
165
189
|
@rows << row
|
|
190
|
+
add_rendered_alias_rows(pubid, hash, rendered, file, alias_ids)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# The document's other spellings as rows of their own, so every id
|
|
194
|
+
# the dataset prints resolves: the parse's canonical render of the
|
|
195
|
+
# primary ("ISO/IEC DIR 1" from the file's own
|
|
196
|
+
# "ISO/IEC Directives Part 1") and each further docidentifier's
|
|
197
|
+
# render. All point at the same file. A docid that does not parse
|
|
198
|
+
# is skipped, and one that renders as an already-added spelling of
|
|
199
|
+
# this document adds no second row. Cross-document collisions are
|
|
200
|
+
# not decided here — `indexed_rows` prunes a derived row whose
|
|
201
|
+
# spelling a document owns as its primary.
|
|
202
|
+
def add_rendered_alias_rows(pubid, primary_hash, rendered, file, alias_ids)
|
|
203
|
+
seen = { rendered => true }
|
|
204
|
+
canon = pubid&.to_s
|
|
205
|
+
if canon && !canon.empty? && !seen.key?(canon)
|
|
206
|
+
seen[canon] = true
|
|
207
|
+
push_derived_row(canon, file, primary_hash, key_string(pubid))
|
|
208
|
+
end
|
|
209
|
+
Array(alias_ids).each do |content|
|
|
210
|
+
alias_pubid = parse(content.to_s)
|
|
211
|
+
next unless alias_pubid
|
|
212
|
+
|
|
213
|
+
render = alias_pubid.to_s
|
|
214
|
+
next if render.empty? || seen.key?(render)
|
|
215
|
+
|
|
216
|
+
seen[render] = true
|
|
217
|
+
push_derived_row(render, file, alias_pubid.to_hash, key_string(alias_pubid))
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def push_derived_row(rendered, file, id_hash, key)
|
|
222
|
+
row = Row.new(rendered, file)
|
|
223
|
+
row.id_hash = id_hash
|
|
224
|
+
row.key = key
|
|
225
|
+
row.derived = true
|
|
226
|
+
@rows << row
|
|
166
227
|
end
|
|
167
228
|
|
|
168
229
|
def count
|
|
@@ -223,12 +284,36 @@ module Relaton
|
|
|
223
284
|
# `Relaton::Ieee::DataFetcher#build_index` already skips the same rows
|
|
224
285
|
# for the same reason and logs the loss; this matches it.
|
|
225
286
|
#
|
|
287
|
+
# A derived (alias) row is dropped when a document owns the spelling
|
|
288
|
+
# as its own primary id, or when an earlier alias row claimed it:
|
|
289
|
+
# `Type#add_or_update` keys id_lookup on the rendered string, so
|
|
290
|
+
# letting both publish would silently repoint the spelling at
|
|
291
|
+
# whichever file sorted last. The document's primary id — and, when
|
|
292
|
+
# two derived rows survive, the earlier document — wins.
|
|
293
|
+
#
|
|
226
294
|
# Memoized, and the single place the sort happens — `each_shard` and
|
|
227
295
|
# `write_monolith` previously sorted the corpus independently, so both
|
|
228
296
|
# ran on every build.
|
|
229
297
|
def indexed_rows
|
|
230
|
-
@indexed_rows ||=
|
|
231
|
-
|
|
298
|
+
@indexed_rows ||= begin
|
|
299
|
+
owned = {}
|
|
300
|
+
@rows.each { |row| owned[row.rendered] = true unless row.derived }
|
|
301
|
+
claimed = {}
|
|
302
|
+
@rows.reject { |row| row.id_hash.nil? }
|
|
303
|
+
.reject do |row|
|
|
304
|
+
next false unless row.derived
|
|
305
|
+
|
|
306
|
+
next true if owned.key?(row.rendered)
|
|
307
|
+
|
|
308
|
+
if claimed.key?(row.rendered)
|
|
309
|
+
true
|
|
310
|
+
else
|
|
311
|
+
claimed[row.rendered] = true
|
|
312
|
+
false
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
.sort_by { |row| [row.key, row.rendered] }
|
|
316
|
+
end
|
|
232
317
|
end
|
|
233
318
|
|
|
234
319
|
# Rows dropped by `indexed_rows` — reported so the loss is never silent.
|
|
@@ -504,12 +589,34 @@ module Relaton
|
|
|
504
589
|
# the same name carries plain strings, and one of those written into a
|
|
505
590
|
# row would break both the monolith (`yaml_nested` walks a Hash) and the
|
|
506
591
|
# consumer (`FileIO#deserialize_id` calls `from_hash`).
|
|
592
|
+
#
|
|
593
|
+
# The first id per file becomes the map; ids beyond the first are the
|
|
594
|
+
# fetcher's aliases onto that file (see .committed_alias_rows).
|
|
507
595
|
def read_committed_index(path)
|
|
508
596
|
rows = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
|
|
509
|
-
Array(rows).
|
|
510
|
-
|
|
597
|
+
@committed_rows = Array(rows).select do |row|
|
|
598
|
+
row.is_a?(Hash) && row[:id].is_a?(Hash) && row[:file]
|
|
599
|
+
end
|
|
600
|
+
@committed_rows.each_with_object({}) do |row, acc|
|
|
601
|
+
acc[row[:file]] ||= row[:id]
|
|
602
|
+
end
|
|
603
|
+
end
|
|
511
604
|
|
|
512
|
-
|
|
605
|
+
# `{ id hash => file }` for committed rows beyond each file's first --
|
|
606
|
+
# the fetcher's alias ids, which no data file of their own carries.
|
|
607
|
+
# Without this pass the machine index drops them (the file-keyed
|
|
608
|
+
# fallback resolves one id per file), and a spelling the corpus
|
|
609
|
+
# aliased stops resolving.
|
|
610
|
+
def committed_alias_rows
|
|
611
|
+
committed_index # force the load and @committed_rows
|
|
612
|
+
seen = {}
|
|
613
|
+
(@committed_rows || []).filter_map do |row|
|
|
614
|
+
if seen[row[:file]]
|
|
615
|
+
[row[:id], row[:file]]
|
|
616
|
+
else
|
|
617
|
+
seen[row[:file]] = true
|
|
618
|
+
nil
|
|
619
|
+
end
|
|
513
620
|
end
|
|
514
621
|
end
|
|
515
622
|
|
|
@@ -567,7 +674,8 @@ module Relaton
|
|
|
567
674
|
# The machine-index input: rendered primary docid + repo-relative
|
|
568
675
|
# path (clients prefix their own baseurl onto file).
|
|
569
676
|
def machine_record(item)
|
|
570
|
-
[item["id"], item["yaml_path"]
|
|
677
|
+
[item["id"], item["yaml_path"],
|
|
678
|
+
Array(item["docids"]).filter_map { |d| d["id"] if d.is_a?(Hash) }]
|
|
571
679
|
end
|
|
572
680
|
|
|
573
681
|
def write_machine_index_manifest(total)
|
|
@@ -659,6 +767,7 @@ module Relaton
|
|
|
659
767
|
detail << detail_record(doc) if emit_detail?
|
|
660
768
|
machine&.add(*machine_record(doc))
|
|
661
769
|
end
|
|
770
|
+
machine&.add_alias_rows(committed_alias_rows)
|
|
662
771
|
summary.flush
|
|
663
772
|
detail.flush
|
|
664
773
|
@machine_index = machine
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: relaton-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: liquid
|
|
@@ -44,14 +44,14 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - '='
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 3.0.
|
|
47
|
+
version: 3.0.1
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - '='
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: 3.0.
|
|
54
|
+
version: 3.0.1
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: relaton-render
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|