relaton-nist 2.0.0 → 2.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 44c34385848a8014460e7001487ae66c504889a55d4d43e7825436af1ed8b447
4
- data.tar.gz: 5a8484fe85b73b539de8d247193359a0004586644163dea56c7d31aa67c15afd
3
+ metadata.gz: 44c06fc2b378b7ac0ad228f82dbfe6d962d5cd22fb27fa8c6f19cfcde20589f7
4
+ data.tar.gz: 96e9c89fdf092af8933e65dc02b98f4d19d70593de2b12a18a18740d85b47d27
5
5
  SHA512:
6
- metadata.gz: 53e6e72ccf31a11324e4258bef3a0239820af979ecf415f366936f4c7a15cb1564d3a26dd91812bccba3b87c9163b2ce6e76f6a83342a1d017b48c0be4a6989d
7
- data.tar.gz: a2c5b41f673d8c6efd526d57f5c12b79d9e2c36db3609bbdf9d4059baea2dd183914d5ea873d2524bed998e41837b605b51919e4f5bfeed3e4d2e93c37ced2aa
6
+ metadata.gz: ca9c2ecb226ceec065fd82db6ce7d4584a0c11176364235102a97c5e3673fb156b60f68631afb5655c91bd313a1d370fe2377ec8c5c6498f06b46e57a478f459
7
+ data.tar.gz: 76bcdb75f303654bbb08bb9cc70c1859795d4ea41d73ee1db0b6f854a595b4871d2038ce169146c8112c08f6fad4631d33b80445b024ae56ff71dd1d7100107c
data/CLAUDE.md CHANGED
@@ -82,6 +82,21 @@ errors = schema.validate(file)
82
82
 
83
83
  Tests use VCR with WebMock. Cassettes are stored in `spec/vcr_cassettes/` and re-record every 7 days.
84
84
 
85
+ ### Test Data Stubbing
86
+
87
+ Tests pre-load both the NIST index and CSRC pubs-export data from local fixtures in `before(:suite)` (see `spec/support/webmock.rb`), avoiding all HTTP requests for these data sources. VCR is configured to ignore both `index-v1.zip` and `pubs-export` requests (`spec/support/vcr.rb`).
88
+
89
+ - **Index**: A `Relaton::Index::Type` instance is created with `@index` set directly from `spec/fixtures/index-v1.zip`, then injected into `Relaton::Index.pool`. Run `rake spec:update_index` to refresh.
90
+ - **PubsExport**: The `PubsExport` singleton's `@data` is set directly from `spec/fixtures/pubs-export.zip`. Run `rake spec:update_pubs_export` to refresh.
91
+
92
+ To apply the index stubbing pattern to other relaton gems:
93
+
94
+ 1. Add `spec:update_index` rake task (downloads `index-v1.zip` from the gem's GitHub data repo)
95
+ 2. Run `rake spec:update_index` to create `spec/fixtures/index-v1.zip`
96
+ 3. In `spec/support/webmock.rb`: parse the zip once, create a `Type` instance with `@index` set directly, override `actual?` to return `true`, inject into `Relaton::Index.pool`
97
+ 4. In `spec/support/vcr.rb`: add `ignore_request` for `index-v1.zip`
98
+ 5. Remove any `allow_any_instance_of(Relaton::Index::Type)` workarounds from specs
99
+
85
100
  ## Key Dependencies
86
101
 
87
102
  - `relaton-bib` — base bibliographic models and shared mixins
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in relaton_nist.gemspec
4
4
  gemspec
5
5
 
6
+
6
7
  gem "equivalent-xml", "~> 0.6"
7
8
  gem "pry-byebug"
8
9
  gem "rake", "~> 13.0"
data/README.adoc CHANGED
@@ -405,6 +405,25 @@ refer to the https://github.com/relaton/relaton-logger#usage[relaton-logger]
405
405
  documentation.
406
406
 
407
407
 
408
+ == Development
409
+
410
+ === Updating test fixtures
411
+
412
+ The test suite uses local copies of the NIST index and CSRC pubs-export data
413
+ to avoid network requests. To update the fixtures:
414
+
415
+ [source,sh]
416
+ ----
417
+ $ rake spec:update_index
418
+ $ rake spec:update_pubs_export
419
+ ----
420
+
421
+ `spec:update_index` downloads the latest `index-v1.zip` from the
422
+ https://github.com/relaton/relaton-data-nist[relaton-data-nist] repository.
423
+
424
+ `spec:update_pubs_export` downloads the latest `pubs-export.zip` from
425
+ the NIST Cybersecurity Resource Center (CSRC).
426
+
408
427
  == Contributing
409
428
 
410
429
  Bug reports and pull requests are welcome.
data/Rakefile CHANGED
@@ -4,3 +4,45 @@ require "rspec/core/rake_task"
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  task :default => :spec
7
+
8
+ namespace :spec do
9
+ desc "Download latest NIST index fixture from relaton-data-nist"
10
+ task :update_index do
11
+ require "net/http"
12
+ require "uri"
13
+
14
+ url = "https://raw.githubusercontent.com/relaton/relaton-data-nist/data-v2/index-v1.zip"
15
+ dest = File.join(__dir__, "spec", "fixtures", "index-v1.zip")
16
+
17
+ puts "Downloading #{url} ..."
18
+ uri = URI.parse(url)
19
+ response = Net::HTTP.get_response(uri)
20
+
21
+ if response.is_a?(Net::HTTPSuccess)
22
+ File.binwrite(dest, response.body)
23
+ puts "Updated #{dest} (#{response.body.bytesize} bytes)"
24
+ else
25
+ abort "Failed to download: HTTP #{response.code}"
26
+ end
27
+ end
28
+
29
+ desc "Download latest NIST pubs-export fixture from CSRC"
30
+ task :update_pubs_export do
31
+ require "net/http"
32
+ require "uri"
33
+
34
+ url = "https://csrc.nist.gov/CSRC/media/feeds/metanorma/pubs-export.zip"
35
+ dest = File.join(__dir__, "spec", "fixtures", "pubs-export.zip")
36
+
37
+ puts "Downloading #{url} ..."
38
+ uri = URI.parse(url)
39
+ response = Net::HTTP.get_response(uri)
40
+
41
+ if response.is_a?(Net::HTTPSuccess)
42
+ File.binwrite(dest, response.body)
43
+ puts "Updated #{dest} (#{response.body.bytesize} bytes)"
44
+ else
45
+ abort "Failed to download: HTTP #{response.code}"
46
+ end
47
+ end
48
+ end
data/grammars/biblio.rng CHANGED
@@ -2015,15 +2015,11 @@ provided that it is not the entire bibliographic item that is so related</a:docu
2015
2015
  <a:documentation>A version of the bibliographic item (within an edition). Can be used for drafts</a:documentation>
2016
2016
  <element name="version">
2017
2017
  <optional>
2018
- <ref name="revision-date">
2019
- <a:documentation>The date at which the current version of the bibliographic item was produced</a:documentation>
2020
- </ref>
2021
- </optional>
2022
- <optional>
2023
- <ref name="draft">
2024
- <a:documentation>The identifier for the current draft of the bibliographic item</a:documentation>
2025
- </ref>
2018
+ <attribute name="type">
2019
+ <a:documentation>Versioning scheme, in case of multiple versioning schemes</a:documentation>
2020
+ </attribute>
2026
2021
  </optional>
2022
+ <text/>
2027
2023
  </element>
2028
2024
  </define>
2029
2025
  <define name="vedition">
@@ -1,6 +1,7 @@
1
1
  module Relaton
2
2
  module Nist
3
3
  class Bibdata < Item
4
+ model ItemData
4
5
  include Bib::BibdataShared
5
6
  end
6
7
  end
@@ -1,6 +1,7 @@
1
1
  module Relaton
2
2
  module Nist
3
3
  class Bibitem < Item
4
+ model ItemData
4
5
  include Bib::BibitemShared
5
6
  end
6
7
  end
@@ -4,17 +4,13 @@ require_relative "comment_period"
4
4
  module Relaton
5
5
  module Nist
6
6
  class Ext < Bib::Ext
7
- attribute :schema_version, method: :get_schema_version
8
7
  attribute :doctype, Doctype
9
8
  attribute :commentperiod, CommentPeriod
10
9
 
11
- xml do
12
- map_element "commentperiod", to: :commentperiod
13
- end
10
+ xml { map_element "commentperiod", to: :commentperiod }
11
+ key_value { map_element "commentperiod", to: :commentperiod }
14
12
 
15
- def get_schema_version
16
- Relaton.schema_versions["relaton-model-nist"]
17
- end
13
+ def get_schema_version = Relaton.schema_versions["relaton-model-nist"]
18
14
  end
19
15
  end
20
16
  end
@@ -169,14 +169,32 @@ module Relaton
169
169
  #
170
170
  def sort_hits!
171
171
  @array.sort! do |a, b|
172
- code = a.hit[:code] <=> b.hit[:code]
173
- next code unless code.zero?
172
+ base_a, upd_a = base_and_update(a.hit[:code])
173
+ base_b, upd_b = base_and_update(b.hit[:code])
174
+
175
+ cmp = base_a <=> base_b
176
+ next cmp unless cmp.zero?
177
+
178
+ # Same base code: prefer higher /UpdN (latest update wins).
179
+ cmp = upd_b <=> upd_a
180
+ next cmp unless cmp.zero?
174
181
 
175
182
  b.hit[:release_date] <=> a.hit[:release_date]
176
183
  end
177
184
  self
178
185
  end
179
186
 
187
+ # Split a code like "NIST FIPS 140-2/Upd2" into ["NIST FIPS 140-2", 2].
188
+ # Codes without an update suffix return update 0.
189
+ def base_and_update(code)
190
+ code = code.to_s
191
+ if (m = code.match(%r{\A(.*?)/Upd(\d+)\z}))
192
+ [m[1], m[2].to_i]
193
+ else
194
+ [code, 0]
195
+ end
196
+ end
197
+
180
198
  def pubid(id = ref)
181
199
  Pubid::Nist::Identifier.parse(id).to_s
182
200
  rescue StandardError
@@ -230,12 +248,16 @@ module Relaton
230
248
  id.sub!(/(?:-draft\d*|\.\wpd)$/, "")
231
249
  id = id.gsub(".", " ").sub(/-Add(\d*)$/, ' Add\1') if id.match?(/-Add\d*$/)
232
250
  pid = ::Pubid::Nist::Identifier.parse(id)
233
- case json["iteration"]
234
- when "final"
235
- pid.stage = ::Pubid::Nist::Stage.new id: "f", type: "pd"
251
+
252
+ # Stage: URI is authoritative, fall back to iteration. "final" => no stage.
253
+ uri_stage = json["uri"] && json["uri"][%r{/(final|ipd|fpd|\dpd)(?:-\(\d+\))?(?:/|$)}, 1]
254
+ stage_src = uri_stage || json["iteration"]
255
+ case stage_src
256
+ when nil, "final"
257
+ # no stage — "final" means published
236
258
  when "fpd"
237
259
  pid.stage = ::Pubid::Nist::Stage.new id: "f", type: "pd"
238
- when /(\w)pd/
260
+ when /\A(\w)pd\z/
239
261
  pid.stage = ::Pubid::Nist::Stage.new id: Regexp.last_match(1), type: "pd"
240
262
  end
241
263
 
@@ -243,7 +265,7 @@ module Relaton
243
265
  pid.update = Pubid::Nist::Update.new number: upd if upd
244
266
  pid.to_s
245
267
  rescue StandardError
246
- id += " #{json["iteration"].sub('final', 'fpd')}" if json["iteration"]
268
+ id += " #{json["iteration"]}" if json["iteration"] && json["iteration"] != "final"
247
269
  id
248
270
  end
249
271
 
@@ -1,5 +1,5 @@
1
1
  module Relaton
2
2
  module Nist
3
- VERSION = "2.0.0".freeze
3
+ VERSION = "2.1.0".freeze
4
4
  end
5
5
  end
@@ -25,9 +25,9 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  spec.add_dependency "base64"
27
27
  spec.add_dependency "mechanize", "~> 2.0"
28
- spec.add_dependency "loc_mods", "~> 0.2.0"
28
+ spec.add_dependency "loc_mods", "~> 0.3.0"
29
29
  spec.add_dependency "pubid", "~> 1.15.6"
30
- spec.add_dependency "relaton-bib", "~> 2.0.0"
30
+ spec.add_dependency "relaton-bib", "~> 2.1.0"
31
31
  spec.add_dependency "relaton-core", "~> 0.0.13"
32
32
  spec.add_dependency "relaton-index", "~> 0.2.0"
33
33
  spec.add_dependency "rubyzip"
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: relaton-nist
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-05-04 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: base64
@@ -43,14 +44,14 @@ dependencies:
43
44
  requirements:
44
45
  - - "~>"
45
46
  - !ruby/object:Gem::Version
46
- version: 0.2.0
47
+ version: 0.3.0
47
48
  type: :runtime
48
49
  prerelease: false
49
50
  version_requirements: !ruby/object:Gem::Requirement
50
51
  requirements:
51
52
  - - "~>"
52
53
  - !ruby/object:Gem::Version
53
- version: 0.2.0
54
+ version: 0.3.0
54
55
  - !ruby/object:Gem::Dependency
55
56
  name: pubid
56
57
  requirement: !ruby/object:Gem::Requirement
@@ -71,14 +72,14 @@ dependencies:
71
72
  requirements:
72
73
  - - "~>"
73
74
  - !ruby/object:Gem::Version
74
- version: 2.0.0
75
+ version: 2.1.0
75
76
  type: :runtime
76
77
  prerelease: false
77
78
  version_requirements: !ruby/object:Gem::Requirement
78
79
  requirements:
79
80
  - - "~>"
80
81
  - !ruby/object:Gem::Version
81
- version: 2.0.0
82
+ version: 2.1.0
82
83
  - !ruby/object:Gem::Dependency
83
84
  name: relaton-core
84
85
  requirement: !ruby/object:Gem::Requirement
@@ -167,11 +168,12 @@ files:
167
168
  - lib/relaton/nist/series.yaml
168
169
  - lib/relaton/nist/util.rb
169
170
  - lib/relaton/nist/version.rb
170
- - relaton_nist.gemspec
171
+ - relaton-nist.gemspec
171
172
  homepage: https://github.com/metanorma/relaton-nist
172
173
  licenses:
173
174
  - MIT
174
175
  metadata: {}
176
+ post_install_message:
175
177
  rdoc_options: []
176
178
  require_paths:
177
179
  - lib
@@ -186,7 +188,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
188
  - !ruby/object:Gem::Version
187
189
  version: '0'
188
190
  requirements: []
189
- rubygems_version: 3.6.9
191
+ rubygems_version: 3.5.22
192
+ signing_key:
190
193
  specification_version: 4
191
194
  summary: 'Relaton::Nist: retrive NIST standards.'
192
195
  test_files: []