relaton-cli 1.20.5 → 1.20.6
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/.gitignore +1 -0
- data/CLAUDE.md +96 -0
- data/docs/README.adoc +6 -2
- data/lib/relaton/cli/command.rb +35 -0
- data/lib/relaton/cli/subcommand_collection.rb +15 -1
- data/lib/relaton/cli/subcommand_db.rb +6 -0
- data/lib/relaton/cli/version.rb +1 -1
- data/relaton-cli.gemspec +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7ff8803a958b14fe70492cc25af28bfa118794bccc3228ae36212123209c2ab0
|
|
4
|
+
data.tar.gz: db4c4530d596210a187b2ddd2f750fef9c19cc10a07c7f19ecd8ab663485ad05
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f577e86bfc2f730ada8e74220dc37523837b0e6d286df337a4a1e5bb33501cbbcf783867c27fad946f1726c727ccbbf1493116ac6c8957b5031ac06792eeaed
|
|
7
|
+
data.tar.gz: c4ac8ee7cc37f9ac217d451a34bcee4bee6b4efe7036e92c160db6dd30d88b1f845ccb07d27f53a8b6e5a597663683f5537e3e1d85bde8942ac336f0c2128df3
|
data/.gitignore
CHANGED
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
relaton-cli is a Ruby CLI tool for managing bibliographic references to standards (ISO, IEC, IETF, NIST, etc.). It provides commands to fetch, convert, and organize standards metadata in XML, YAML, BibTeX, and HTML formats. Part of the broader Relaton/Metanorma ecosystem.
|
|
8
|
+
|
|
9
|
+
## Common Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Install dependencies
|
|
13
|
+
bundle install
|
|
14
|
+
|
|
15
|
+
# Run all tests
|
|
16
|
+
bundle exec rspec
|
|
17
|
+
|
|
18
|
+
# Run a single test file
|
|
19
|
+
bundle exec rspec spec/relaton/cli/command_spec.rb
|
|
20
|
+
|
|
21
|
+
# Run a specific test by line number
|
|
22
|
+
bundle exec rspec spec/relaton/cli/command_spec.rb:42
|
|
23
|
+
|
|
24
|
+
# Build the gem
|
|
25
|
+
bundle exec rake build
|
|
26
|
+
|
|
27
|
+
# Lint (RuboCop, inherits from Ribose OSS guide)
|
|
28
|
+
bundle exec rubocop
|
|
29
|
+
bundle exec rubocop -a # auto-fix
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Architecture
|
|
33
|
+
|
|
34
|
+
### Entry Point & CLI Framework
|
|
35
|
+
|
|
36
|
+
The executable `exe/relaton` calls `Relaton::Cli.start(ARGV)` which routes to `Relaton::Cli::Command`, a Thor-based command class. Thor handles argument parsing, option definitions, and subcommand routing.
|
|
37
|
+
|
|
38
|
+
### Command Structure
|
|
39
|
+
|
|
40
|
+
- `lib/relaton/cli/command.rb` — Main Thor command class with top-level commands (fetch, extract, concatenate, split, yaml2xml, xml2yaml, xml2html, yaml2html, convert, fetch-data)
|
|
41
|
+
- `lib/relaton/cli/subcommand_collection.rb` — `relaton collection` subcommands (create, info, list, get, find, fetch, import, export)
|
|
42
|
+
- `lib/relaton/cli/subcommand_db.rb` — `relaton db` subcommands (create, mv, clear, fetch, fetch_all, doctype)
|
|
43
|
+
|
|
44
|
+
### Option Forwarding Pattern
|
|
45
|
+
|
|
46
|
+
`Command#fetch` and `SubcommandDb#fetch` use the shared `fetch_document` helper (in `Relaton::Cli` private methods at the bottom of `command.rb`). This helper transforms Thor's kebab-case option keys to snake_case symbols via `gsub("-", "_").to_sym` and splats them as `**dup_opts` to `Relaton.db.fetch` / `Relaton.db.fetch_std`. Adding a new Thor option to these commands automatically forwards it to the underlying library with no method changes needed.
|
|
47
|
+
|
|
48
|
+
`SubcommandCollection#fetch` calls `Relaton.db.fetch` directly (not through `fetch_document`), so new options must be explicitly forwarded there.
|
|
49
|
+
|
|
50
|
+
Current fetch options that use this pattern: `--no-cache`, `--all-parts`, `--keep-year`, `--publication-date-before`, `--publication-date-after`.
|
|
51
|
+
|
|
52
|
+
### Core Data Classes
|
|
53
|
+
|
|
54
|
+
- `lib/relaton/bibdata.rb` — `Relaton::Bibdata` wraps `RelatonBib::BibliographicItem`, adding URL type handling and serialization to XML/YAML/Hash. Uses `method_missing` to delegate to the underlying bibitem.
|
|
55
|
+
- `lib/relaton/bibcollection.rb` — `Relaton::Bibcollection` represents a collection of bibliographic items with title/author/doctype metadata. Handles XML/YAML round-tripping.
|
|
56
|
+
- `lib/relaton/element_finder.rb` — Mixin providing XPath utilities with namespace handling.
|
|
57
|
+
|
|
58
|
+
### Converters (Template Method Pattern)
|
|
59
|
+
|
|
60
|
+
- `lib/relaton/cli/base_convertor.rb` — Abstract base defining the conversion flow (convert_and_write, write_to_file_collection)
|
|
61
|
+
- `lib/relaton/cli/xml_convertor.rb` — XML → YAML conversion
|
|
62
|
+
- `lib/relaton/cli/yaml_convertor.rb` — YAML → XML conversion (includes processor detection via doctype)
|
|
63
|
+
- `lib/relaton/cli/xml_to_html_renderer.rb` — Renders XML/YAML to HTML using Liquid templates from `templates/`
|
|
64
|
+
|
|
65
|
+
### File Operations
|
|
66
|
+
|
|
67
|
+
`lib/relaton/cli/relaton_file.rb` — Static methods for extract (pull bibdata from Metanorma XML), concatenate (combine files into a collection), and split (break a collection into individual files).
|
|
68
|
+
|
|
69
|
+
### Database (Singleton)
|
|
70
|
+
|
|
71
|
+
`Relaton::Cli::RelatonDb` (in `lib/relaton/cli.rb`) is a Singleton managing a `Relaton::Db` instance. DB path is persisted in `~/.relaton/dbpath`. The `relaton` gem's registry auto-discovers 30+ standard-body processors.
|
|
72
|
+
|
|
73
|
+
### Processor Detection
|
|
74
|
+
|
|
75
|
+
`Relaton::Cli.processor(doc)` and `.parse_xml(doc)` detect the correct processor (ISO, IEC, IETF, etc.) from a document's `docidentifier` element type attribute, falling back to prefix matching.
|
|
76
|
+
|
|
77
|
+
## Test Structure
|
|
78
|
+
|
|
79
|
+
- `spec/acceptance/` — End-to-end CLI integration tests using `rspec-command`
|
|
80
|
+
- `spec/relaton/cli/` — Unit tests for command, converters, subcommands, DB
|
|
81
|
+
- `spec/relaton/` — Unit tests for Bibcollection and Bibdata
|
|
82
|
+
- `spec/support/` — Test setup: SimpleCov, WebMock, VCR, equivalent-xml matchers
|
|
83
|
+
- `spec/fixtures/` and `spec/vcr_cassettes/` — Test data and recorded HTTP responses
|
|
84
|
+
|
|
85
|
+
Tests use VCR cassettes to replay HTTP interactions with standards registries. WebMock blocks real HTTP requests in tests.
|
|
86
|
+
|
|
87
|
+
## Key Dependencies
|
|
88
|
+
|
|
89
|
+
- `relaton ~> 1.20.0` — Core library providing DB, registry, and all standard-body processors
|
|
90
|
+
- `thor` / `thor-hollaback` — CLI framework
|
|
91
|
+
- `liquid ~> 5` — HTML template rendering
|
|
92
|
+
- `nokogiri` (transitive via relaton) — XML parsing
|
|
93
|
+
|
|
94
|
+
## Ruby Version
|
|
95
|
+
|
|
96
|
+
Requires Ruby >= 3.0.0 (set in gemspec and `.rubocop.yml`).
|
data/docs/README.adoc
CHANGED
|
@@ -42,7 +42,7 @@ suports an additional `-x` or `--extension` options to use different extension.
|
|
|
42
42
|
|
|
43
43
|
[source,console]
|
|
44
44
|
----
|
|
45
|
-
$ relaton fetch CODE -t TYPE -f FORMAT -y YEAR -r RETRIES --all-parts --keep-year --no-cache
|
|
45
|
+
$ relaton fetch CODE -t TYPE -f FORMAT -y YEAR -r RETRIES --all-parts --keep-year --no-cache --publication-date-before DATE --publication-date-after DATE
|
|
46
46
|
----
|
|
47
47
|
|
|
48
48
|
Fetch the Relaton XML entry corresponding to the document identifier `CODE`.
|
|
@@ -54,6 +54,8 @@ Fetch the Relaton XML entry corresponding to the document identifier `CODE`.
|
|
|
54
54
|
* `--all-parts` fetch all parts.
|
|
55
55
|
* `--keep-year` undated reference should return an actual reference with year.
|
|
56
56
|
* `--no-cache` do not use cache.
|
|
57
|
+
* `--publication-date-before DATE` fetch only documents published before the specified date. Accepted formats: `YYYY`, `YYYY-MM`, `YYYY-MM-DD`.
|
|
58
|
+
* `--publication-date-after DATE` fetch only documents published after the specified date. Accepted formats: `YYYY`, `YYYY-MM`, `YYYY-MM-DD`.
|
|
57
59
|
|
|
58
60
|
=== relaton fetch-data
|
|
59
61
|
|
|
@@ -358,7 +360,7 @@ Full-text search through a collection or all collections.
|
|
|
358
360
|
==== relaton collection fetch
|
|
359
361
|
|
|
360
362
|
----
|
|
361
|
-
$ relaton collection fetch CODE -t TYPE -y YEAR -c COLLECTION -d DIRECTORY
|
|
363
|
+
$ relaton collection fetch CODE -t TYPE -y YEAR -c COLLECTION -d DIRECTORY --publication-date-before DATE --publication-date-after DATE
|
|
362
364
|
----
|
|
363
365
|
|
|
364
366
|
Fetch the Relaton XML entry corresponding to the document identifier `CODE` and save it into `COLLECTION`.
|
|
@@ -367,6 +369,8 @@ Fetch the Relaton XML entry corresponding to the document identifier `CODE` and
|
|
|
367
369
|
* `YEAR` is optional, and specifies the year of publication of the standard.
|
|
368
370
|
* `COLLECTION` - a name of a collection.
|
|
369
371
|
* `DIRECTORY` - optional, and specifies a path to a directory with collections. The default value is `$HOME/.relaton/collections`.
|
|
372
|
+
* `--publication-date-before DATE` fetch only documents published before the specified date. Accepted formats: `YYYY`, `YYYY-MM`, `YYYY-MM-DD`.
|
|
373
|
+
* `--publication-date-after DATE` fetch only documents published after the specified date. Accepted formats: `YYYY`, `YYYY-MM`, `YYYY-MM-DD`.
|
|
370
374
|
|
|
371
375
|
==== relaton collection export
|
|
372
376
|
|
data/lib/relaton/cli/command.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "date"
|
|
1
2
|
require "relaton/cli/relaton_file"
|
|
2
3
|
require "relaton/cli/xml_convertor"
|
|
3
4
|
require "relaton/cli/yaml_convertor"
|
|
@@ -31,6 +32,12 @@ module Relaton
|
|
|
31
32
|
option :retries, aliases: :r, type: :numeric,
|
|
32
33
|
desc: "Number of network retries. Default 1."
|
|
33
34
|
option :"no-cache", type: :boolean, desc: "Ignore cache"
|
|
35
|
+
option :"publication-date-before",
|
|
36
|
+
desc: "Fetch only documents published before the specified date " \
|
|
37
|
+
"(e.g. 2008, 2008-02, or 2008-02-02)"
|
|
38
|
+
option :"publication-date-after",
|
|
39
|
+
desc: "Fetch only documents published after the specified date " \
|
|
40
|
+
"(e.g. 2002, 2002-01, or 2002-01-01)"
|
|
34
41
|
|
|
35
42
|
def fetch(code)
|
|
36
43
|
io = IO.new($stdout.fcntl(::Fcntl::F_DUPFD), mode: "w:UTF-8")
|
|
@@ -174,6 +181,30 @@ module Relaton
|
|
|
174
181
|
|
|
175
182
|
private
|
|
176
183
|
|
|
184
|
+
DATE_FILTER_FORMAT = /\A\d{4}(-\d{2}(-\d{2})?)?\z/
|
|
185
|
+
|
|
186
|
+
def parse_date_option(value, name)
|
|
187
|
+
return unless value
|
|
188
|
+
|
|
189
|
+
unless value.match?(DATE_FILTER_FORMAT)
|
|
190
|
+
raise ArgumentError,
|
|
191
|
+
"Invalid #{name}: #{value.inspect}. Expected YYYY, YYYY-MM, or YYYY-MM-DD."
|
|
192
|
+
end
|
|
193
|
+
parts = value.split("-").map(&:to_i)
|
|
194
|
+
Date.new(*parts.concat([1] * (3 - parts.size)))
|
|
195
|
+
rescue Date::Error
|
|
196
|
+
raise ArgumentError,
|
|
197
|
+
"Invalid #{name}: #{value.inspect}. Date components are out of range."
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def validate_date_range(date_after, date_before)
|
|
201
|
+
return unless date_after && date_before
|
|
202
|
+
return if date_after < date_before
|
|
203
|
+
|
|
204
|
+
raise ArgumentError,
|
|
205
|
+
"Invalid date range: --publication-date-after (#{date_after}) must be before --publication-date-before (#{date_before})."
|
|
206
|
+
end
|
|
207
|
+
|
|
177
208
|
# @param code [String]
|
|
178
209
|
# @param options [Hash]
|
|
179
210
|
# @option options [String] :type
|
|
@@ -183,6 +214,10 @@ module Relaton
|
|
|
183
214
|
def fetch_document(code, options) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/AbcSize,Metrics/MethodLength
|
|
184
215
|
year = options[:year]&.to_s
|
|
185
216
|
dup_opts = options.dup.transform_keys { |k| k.to_s.gsub("-", "_").to_sym }
|
|
217
|
+
%i[publication_date_before publication_date_after].each do |key|
|
|
218
|
+
dup_opts[key] = parse_date_option(dup_opts[key], key.to_s.tr("_", "-").prepend("--")) if dup_opts[key]
|
|
219
|
+
end
|
|
220
|
+
validate_date_range dup_opts[:publication_date_after], dup_opts[:publication_date_before]
|
|
186
221
|
if (processor = Relaton::Registry.instance.by_type options[:type]&.upcase)
|
|
187
222
|
doc = Relaton.db.fetch_std code, year, processor.short, **dup_opts
|
|
188
223
|
elsif options[:type] then return
|
|
@@ -102,13 +102,27 @@ module Relaton
|
|
|
102
102
|
desc: "Type of standard to get bibliographic entry for"
|
|
103
103
|
option :year, aliases: :y, type: :numeric,
|
|
104
104
|
desc: "Year the standard was published"
|
|
105
|
+
option :"publication-date-before",
|
|
106
|
+
desc: "Fetch only documents published before the specified date " \
|
|
107
|
+
"(e.g. 2008, 2008-02, or 2008-02-02)"
|
|
108
|
+
option :"publication-date-after",
|
|
109
|
+
desc: "Fetch only documents published after the specified date " \
|
|
110
|
+
"(e.g. 2002, 2002-01, or 2002-01-01)"
|
|
105
111
|
option :collection, aliases: :c, required: true,
|
|
106
112
|
desc: "Collection to store a document"
|
|
107
113
|
option :dir, aliases: :d, desc: "Directory with collections. Default is " \
|
|
108
114
|
"$HOME/.relaton/collections."
|
|
109
115
|
|
|
110
116
|
def fetch(code) # rubocop:disable Metrics/AbcSize
|
|
111
|
-
|
|
117
|
+
opts = {}
|
|
118
|
+
if options[:"publication-date-before"]
|
|
119
|
+
opts[:publication_date_before] = parse_date_option(options[:"publication-date-before"], "--publication-date-before")
|
|
120
|
+
end
|
|
121
|
+
if options[:"publication-date-after"]
|
|
122
|
+
opts[:publication_date_after] = parse_date_option(options[:"publication-date-after"], "--publication-date-after")
|
|
123
|
+
end
|
|
124
|
+
validate_date_range opts[:publication_date_after], opts[:publication_date_before]
|
|
125
|
+
doc = Relaton.db.fetch(code, options[:year]&.to_s, **opts)
|
|
112
126
|
if doc
|
|
113
127
|
colfile = File.join directory, options[:collection]
|
|
114
128
|
coll = read_collection colfile
|
|
@@ -40,6 +40,12 @@ module Relaton
|
|
|
40
40
|
"Default xml."
|
|
41
41
|
option :year, aliases: :y, type: :numeric, desc: "Year the standard " \
|
|
42
42
|
"was published"
|
|
43
|
+
option :"publication-date-before",
|
|
44
|
+
desc: "Fetch only documents published before the specified date " \
|
|
45
|
+
"(e.g. 2008, 2008-02, or 2008-02-02)"
|
|
46
|
+
option :"publication-date-after",
|
|
47
|
+
desc: "Fetch only documents published after the specified date " \
|
|
48
|
+
"(e.g. 2002, 2002-01, or 2002-01-01)"
|
|
43
49
|
|
|
44
50
|
def fetch(code)
|
|
45
51
|
io = IO.new($stdout.fcntl(::Fcntl::F_DUPFD), mode: "w:UTF-8")
|
data/lib/relaton/cli/version.rb
CHANGED
data/relaton-cli.gemspec
CHANGED
|
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
|
|
|
23
23
|
spec.required_ruby_version = ">= 3.0.0"
|
|
24
24
|
|
|
25
25
|
spec.add_runtime_dependency "liquid", "~> 5"
|
|
26
|
-
spec.add_runtime_dependency "relaton", "~> 1.20.
|
|
26
|
+
spec.add_runtime_dependency "relaton", "~> 1.20.2"
|
|
27
27
|
spec.add_runtime_dependency "thor"
|
|
28
28
|
spec.add_runtime_dependency "thor-hollaback"
|
|
29
29
|
|
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: 1.20.
|
|
4
|
+
version: 1.20.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-02-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: liquid
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 1.20.
|
|
33
|
+
version: 1.20.2
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 1.20.
|
|
40
|
+
version: 1.20.2
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: thor
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -97,6 +97,7 @@ files:
|
|
|
97
97
|
- ".rspec"
|
|
98
98
|
- ".rubocop.yml"
|
|
99
99
|
- CHANGELOG.md
|
|
100
|
+
- CLAUDE.md
|
|
100
101
|
- Gemfile
|
|
101
102
|
- LICENSE
|
|
102
103
|
- Rakefile
|