metanorma-release 0.2.5 → 0.2.8
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/lib/metanorma/release/channel.rb +4 -1
- data/lib/metanorma/release/channel_filter.rb +2 -2
- data/lib/metanorma/release/cli.rb +2 -0
- data/lib/metanorma/release/commands/aggregate.rb +31 -2
- data/lib/metanorma/release/commands/release_command.rb +52 -5
- data/lib/metanorma/release/config.rb +33 -7
- data/lib/metanorma/release/org_config.rb +76 -0
- data/lib/metanorma/release/site.rb +89 -21
- data/lib/metanorma/release/version.rb +1 -1
- data/lib/metanorma/release.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 33318ed83e806c7f0f7e4d16c3095762cf64f3558214a6775549c2dd5bd74302
|
|
4
|
+
data.tar.gz: 3d72e6618afb935951e22b19284299dad2adc3c7940cd87735fb47bb3f13b650
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eff37e2e0d375443613b578fabf7f47a51b007557ff602995105c020fe8a67034b755514d5f75d9e915189b8a189b1b32b3439ea632e478413556bd2bebc4575
|
|
7
|
+
data.tar.gz: fa1201421381243f2e7b1ef363c621afe636b4d684493a29b53a333f44417093f32bae0cc1ee0c99a4a9f6722177b28e6e457811909680ca631dd871d4ac0143
|
|
@@ -23,7 +23,10 @@ module Metanorma
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def matches?(filter_channels)
|
|
26
|
-
filter_channels.any?
|
|
26
|
+
filter_channels.any? do |c|
|
|
27
|
+
fc = Channel.new(c)
|
|
28
|
+
eql?(fc) || @name.start_with?("#{fc.name}/")
|
|
29
|
+
end
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
def self.parse(channel_string)
|
|
@@ -18,7 +18,7 @@ module Metanorma
|
|
|
18
18
|
return true if @all_channels
|
|
19
19
|
|
|
20
20
|
parsed = manifest_channels.map { |c| Channel.new(c) }
|
|
21
|
-
parsed.any? { |mc|
|
|
21
|
+
parsed.any? { |mc| mc.matches?(@channels) }
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
private
|
|
@@ -29,7 +29,7 @@ module Metanorma
|
|
|
29
29
|
release_channels = (release_metadata["channels"] || []).map do |c|
|
|
30
30
|
Channel.new(c)
|
|
31
31
|
end
|
|
32
|
-
release_channels.any? { |rc|
|
|
32
|
+
release_channels.any? { |rc| rc.matches?(@channels) }
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def stage_match?(release_metadata)
|
|
@@ -82,6 +82,7 @@ module Metanorma
|
|
|
82
82
|
option :file_routing, type: :string, default: "by-document",
|
|
83
83
|
desc: "File routing (by-document|flat|by-format)"
|
|
84
84
|
option :cache_dir, type: :string, desc: "Cache directory"
|
|
85
|
+
option :data_dir, type: :string, desc: "Write flattened documents.json for site generators"
|
|
85
86
|
option :include_drafts, type: :boolean, default: false,
|
|
86
87
|
desc: "Include draft releases"
|
|
87
88
|
option :concurrency, type: :numeric, default: 4
|
|
@@ -101,6 +102,7 @@ module Metanorma
|
|
|
101
102
|
output_dir: options[:output_dir],
|
|
102
103
|
file_routing: options[:file_routing],
|
|
103
104
|
cache_dir: options[:cache_dir],
|
|
105
|
+
data_dir: options[:data_dir],
|
|
104
106
|
include_drafts: options[:include_drafts],
|
|
105
107
|
concurrency: options[:concurrency],
|
|
106
108
|
min_documents: options[:min_documents],
|
|
@@ -8,7 +8,8 @@ module Metanorma
|
|
|
8
8
|
Config = Struct.new(
|
|
9
9
|
:source, :organizations, :topic, :repos, :repo_pattern, :local_path,
|
|
10
10
|
:channels, :stages, :output_dir, :file_routing, :cache_dir,
|
|
11
|
-
:include_drafts, :concurrency, :min_documents, :token,
|
|
11
|
+
:data_dir, :include_drafts, :concurrency, :min_documents, :token,
|
|
12
|
+
:create_zip, :org,
|
|
12
13
|
keyword_init: true
|
|
13
14
|
)
|
|
14
15
|
|
|
@@ -17,14 +18,17 @@ module Metanorma
|
|
|
17
18
|
|
|
18
19
|
def initialize(config)
|
|
19
20
|
@config = config
|
|
21
|
+
@org_config = nil
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
def call
|
|
25
|
+
load_org_config
|
|
23
26
|
result = run_aggregation
|
|
24
27
|
return result unless result.publications.any?
|
|
25
28
|
|
|
26
29
|
index = build_index(result)
|
|
27
|
-
site = Site.new(index: index, output_dir: @config.output_dir
|
|
30
|
+
site = Site.new(index: index, output_dir: @config.output_dir,
|
|
31
|
+
data_dir: @config.data_dir)
|
|
28
32
|
site.write!
|
|
29
33
|
site.enrich!
|
|
30
34
|
site.package! if @config.create_zip
|
|
@@ -46,11 +50,13 @@ module Metanorma
|
|
|
46
50
|
output_dir: merged[:output_dir],
|
|
47
51
|
file_routing: merged[:file_routing],
|
|
48
52
|
cache_dir: merged[:cache_dir] || DEFAULT_CACHE_DIR,
|
|
53
|
+
data_dir: merged[:data_dir],
|
|
49
54
|
include_drafts: merged[:include_drafts],
|
|
50
55
|
concurrency: merged[:concurrency],
|
|
51
56
|
min_documents: merged[:min_documents],
|
|
52
57
|
token: merged[:token],
|
|
53
58
|
create_zip: merged[:create_zip],
|
|
59
|
+
org: merged[:org],
|
|
54
60
|
)
|
|
55
61
|
end
|
|
56
62
|
|
|
@@ -73,11 +79,13 @@ module Metanorma
|
|
|
73
79
|
output_dir: cli_options[:output_dir] || file_data["output_dir"],
|
|
74
80
|
file_routing: cli_options[:file_routing] || file_data["file_routing"],
|
|
75
81
|
cache_dir: cli_options[:cache_dir] || file_data["cache_dir"],
|
|
82
|
+
data_dir: cli_options[:data_dir] || file_data["data_dir"],
|
|
76
83
|
include_drafts: cli_options[:include_drafts] || file_data["include_drafts"],
|
|
77
84
|
concurrency: cli_options[:concurrency] || file_data["concurrency"],
|
|
78
85
|
min_documents: cli_options[:min_documents] || file_data["min_documents"],
|
|
79
86
|
token: cli_options[:token],
|
|
80
87
|
create_zip: cli_options[:create_zip],
|
|
88
|
+
org: file_data["org"],
|
|
81
89
|
}
|
|
82
90
|
end
|
|
83
91
|
|
|
@@ -159,6 +167,27 @@ module Metanorma
|
|
|
159
167
|
rescue LoadError
|
|
160
168
|
warn " (relaton gem not available — bibliography skipped)"
|
|
161
169
|
end
|
|
170
|
+
|
|
171
|
+
def load_org_config
|
|
172
|
+
return unless @config.org
|
|
173
|
+
|
|
174
|
+
ref = OrgConfig.parse_ref(@config.org)
|
|
175
|
+
local_path = OrgConfig.remote_path(ref)
|
|
176
|
+
@org_config = File.exist?(local_path) ? OrgConfig.from_file(local_path) : fetch_org_config_from_github(ref)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def fetch_org_config_from_github(ref)
|
|
180
|
+
require "octokit"
|
|
181
|
+
token = @config.token || ENV.fetch("GITHUB_TOKEN", nil)
|
|
182
|
+
client = token ? Octokit::Client.new(access_token: token) : Octokit::Client.new
|
|
183
|
+
remote = OrgConfig.remote_path(ref)
|
|
184
|
+
contents = client.contents("#{ref.owner}/#{ref.repo}", path: remote)
|
|
185
|
+
decoded = Base64.decode64(contents[:content])
|
|
186
|
+
OrgConfig.from_yaml(decoded)
|
|
187
|
+
rescue StandardError => e
|
|
188
|
+
warn " (org config not loaded from #{ref.owner}/#{ref.repo}: #{e.message})"
|
|
189
|
+
OrgConfig.defaults
|
|
190
|
+
end
|
|
162
191
|
end
|
|
163
192
|
end
|
|
164
193
|
end
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "yaml"
|
|
4
|
+
|
|
3
5
|
module Metanorma
|
|
4
6
|
module Release
|
|
5
7
|
class ReleaseCommand
|
|
@@ -14,7 +16,8 @@ module Metanorma
|
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
def call
|
|
17
|
-
|
|
19
|
+
org_config = load_org_config
|
|
20
|
+
config = load_config(org_config: org_config)
|
|
18
21
|
options = { token: @config.token }
|
|
19
22
|
publisher = PlatformFactory.build_publisher(@config.platform, options)
|
|
20
23
|
channel_override = Channel.parse_list(@config.channels) if @config.channels
|
|
@@ -45,15 +48,59 @@ module Metanorma
|
|
|
45
48
|
|
|
46
49
|
private
|
|
47
50
|
|
|
48
|
-
def load_config
|
|
51
|
+
def load_config(org_config: nil)
|
|
49
52
|
if @config.config_source && File.exist?(@config.config_source)
|
|
50
|
-
Metanorma::Release::Config.from_file(@config.config_source)
|
|
53
|
+
Metanorma::Release::Config.from_file(@config.config_source, org_config: org_config)
|
|
51
54
|
elsif @config.manifest && File.exist?(@config.manifest)
|
|
52
|
-
Metanorma::Release::Config.from_file(@config.manifest)
|
|
55
|
+
Metanorma::Release::Config.from_file(@config.manifest, org_config: org_config)
|
|
53
56
|
else
|
|
54
|
-
Metanorma::Release::Config.defaults
|
|
57
|
+
Metanorma::Release::Config.defaults(org_config: org_config)
|
|
55
58
|
end
|
|
56
59
|
end
|
|
60
|
+
|
|
61
|
+
def load_org_config
|
|
62
|
+
path = find_config_path
|
|
63
|
+
return nil unless path
|
|
64
|
+
|
|
65
|
+
org_ref = extract_org_ref(path)
|
|
66
|
+
return nil unless org_ref
|
|
67
|
+
|
|
68
|
+
resolve_org_config(org_ref)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def find_config_path
|
|
72
|
+
if @config.config_source && File.exist?(@config.config_source)
|
|
73
|
+
@config.config_source
|
|
74
|
+
elsif @config.manifest && File.exist?(@config.manifest)
|
|
75
|
+
@config.manifest
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def extract_org_ref(path)
|
|
80
|
+
raw = YAML.safe_load_file(path, permitted_classes: [Symbol]) || {}
|
|
81
|
+
raw["org"]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def resolve_org_config(org_ref)
|
|
85
|
+
ref = OrgConfig.parse_ref(org_ref)
|
|
86
|
+
local_path = OrgConfig.remote_path(ref)
|
|
87
|
+
return OrgConfig.from_file(local_path) if File.exist?(local_path)
|
|
88
|
+
|
|
89
|
+
fetch_org_config_from_github(ref)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def fetch_org_config_from_github(ref)
|
|
93
|
+
require "octokit"
|
|
94
|
+
token = @config.token || ENV.fetch("GITHUB_TOKEN", nil)
|
|
95
|
+
client = token ? Octokit::Client.new(access_token: token) : Octokit::Client.new
|
|
96
|
+
remote = OrgConfig.remote_path(ref)
|
|
97
|
+
contents = client.contents("#{ref.owner}/#{ref.repo}", path: remote)
|
|
98
|
+
decoded = Base64.decode64(contents[:content])
|
|
99
|
+
OrgConfig.from_yaml(decoded)
|
|
100
|
+
rescue StandardError => e
|
|
101
|
+
warn " (org config not loaded from #{ref.owner}/#{ref.repo}: #{e.message})"
|
|
102
|
+
OrgConfig.defaults
|
|
103
|
+
end
|
|
57
104
|
end
|
|
58
105
|
end
|
|
59
106
|
end
|
|
@@ -5,26 +5,31 @@ require "yaml"
|
|
|
5
5
|
module Metanorma
|
|
6
6
|
module Release
|
|
7
7
|
class Config
|
|
8
|
-
def self.from_yaml(yaml_string)
|
|
8
|
+
def self.from_yaml(yaml_string, org_config: nil)
|
|
9
9
|
data = YAML.safe_load(yaml_string, permitted_classes: [Symbol])
|
|
10
|
-
new(data || {})
|
|
10
|
+
new(data || {}, org_config: org_config)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def self.from_file(path)
|
|
13
|
+
def self.from_file(path, org_config: nil)
|
|
14
14
|
unless File.exist?(path)
|
|
15
15
|
raise ArgumentError,
|
|
16
16
|
"Config file not found: #{path}"
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
from_yaml(File.read(path))
|
|
19
|
+
from_yaml(File.read(path), org_config: org_config)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def self.defaults
|
|
23
|
-
new({})
|
|
22
|
+
def self.defaults(org_config: nil)
|
|
23
|
+
new({}, org_config: org_config)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def initialize(data)
|
|
26
|
+
def initialize(data, org_config: nil)
|
|
27
27
|
@data = data
|
|
28
|
+
@org_config = org_config
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def org
|
|
32
|
+
@data["org"]
|
|
28
33
|
end
|
|
29
34
|
|
|
30
35
|
def channels
|
|
@@ -77,6 +82,15 @@ module Metanorma
|
|
|
77
82
|
rule_channels = resolve_routing_rules(publication)
|
|
78
83
|
return rule_channels if rule_channels
|
|
79
84
|
|
|
85
|
+
org_rule_channels = resolve_org_routing_rules(publication)
|
|
86
|
+
return org_rule_channels if org_rule_channels
|
|
87
|
+
|
|
88
|
+
local_default = routing_default
|
|
89
|
+
return local_default unless local_default == ["public"] && @org_config
|
|
90
|
+
|
|
91
|
+
org_default = @org_config&.routing_default
|
|
92
|
+
return org_default unless org_default.nil? || org_default.empty?
|
|
93
|
+
|
|
80
94
|
default_channels
|
|
81
95
|
end
|
|
82
96
|
|
|
@@ -99,6 +113,18 @@ module Metanorma
|
|
|
99
113
|
end
|
|
100
114
|
nil
|
|
101
115
|
end
|
|
116
|
+
|
|
117
|
+
def resolve_org_routing_rules(publication)
|
|
118
|
+
return nil unless @org_config
|
|
119
|
+
|
|
120
|
+
@org_config.routing_rules.each do |rule|
|
|
121
|
+
match = true
|
|
122
|
+
match &&= Array(rule["stage"]).map(&:to_s).include?(publication.stage.to_s) if rule["stage"]
|
|
123
|
+
match &&= Array(rule["doctype"]).map(&:to_s).include?(publication.doctype.to_s) if rule["doctype"]
|
|
124
|
+
return rule["channels"] if match && rule["channels"]
|
|
125
|
+
end
|
|
126
|
+
nil
|
|
127
|
+
end
|
|
102
128
|
end
|
|
103
129
|
end
|
|
104
130
|
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "yaml"
|
|
4
|
+
|
|
5
|
+
module Metanorma
|
|
6
|
+
module Release
|
|
7
|
+
class OrgConfig
|
|
8
|
+
Ref = Struct.new(:owner, :repo, :name, keyword_init: true)
|
|
9
|
+
|
|
10
|
+
def self.parse_ref(org_string)
|
|
11
|
+
parts = org_string.to_s.split("#", 2)
|
|
12
|
+
slug = parts[0].to_s.strip
|
|
13
|
+
segments = slug.split("/", 2)
|
|
14
|
+
raise ArgumentError, "Invalid org reference: #{org_string}" unless segments.length == 2
|
|
15
|
+
|
|
16
|
+
Ref.new(owner: segments[0], repo: segments[1], name: parts[1]&.strip)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.default_config_name
|
|
20
|
+
"channels"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.remote_path(ref)
|
|
24
|
+
name = ref.name || default_config_name
|
|
25
|
+
".metanorma/#{name}.yml"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.from_yaml(yaml_string)
|
|
29
|
+
data = YAML.safe_load(yaml_string, permitted_classes: [Symbol])
|
|
30
|
+
new(data || {})
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.from_file(path)
|
|
34
|
+
raise ArgumentError, "Org config file not found: #{path}" unless File.exist?(path)
|
|
35
|
+
|
|
36
|
+
from_yaml(File.read(path))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.defaults
|
|
40
|
+
new({})
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def initialize(data)
|
|
44
|
+
@data = data
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def channels
|
|
48
|
+
@data.fetch("channels", [])
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def routing_default
|
|
52
|
+
dig_defaults_routing("default") || []
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def routing_rules
|
|
56
|
+
dig_defaults_routing("rules") || []
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def valid_channel?(name)
|
|
60
|
+
return true if channels.empty?
|
|
61
|
+
|
|
62
|
+
ch = Channel.new(name)
|
|
63
|
+
channels.any? do |valid|
|
|
64
|
+
valid_ch = Channel.new(valid)
|
|
65
|
+
ch.eql?(valid_ch) || ch.name.start_with?("#{valid_ch.name}/") || valid_ch.name.start_with?("#{ch.name}/")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def dig_defaults_routing(key)
|
|
72
|
+
@data.dig("defaults", "routing", key)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -9,9 +9,10 @@ module Metanorma
|
|
|
9
9
|
class Site
|
|
10
10
|
attr_reader :index, :output_dir
|
|
11
11
|
|
|
12
|
-
def initialize(index:, output_dir:)
|
|
12
|
+
def initialize(index:, output_dir:, data_dir: nil)
|
|
13
13
|
@index = index
|
|
14
14
|
@output_dir = output_dir
|
|
15
|
+
@data_dir = data_dir
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def write!
|
|
@@ -22,22 +23,49 @@ module Metanorma
|
|
|
22
23
|
def enrich!
|
|
23
24
|
return if index.empty?
|
|
24
25
|
|
|
25
|
-
documents =
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
documents = enrich_documents
|
|
27
|
+
write_relaton_index(documents)
|
|
28
|
+
write_data_file(documents) if @data_dir
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def package!(zip_path: nil)
|
|
32
|
+
require "zip"
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
path = zip_path || "#{output_dir}.zip"
|
|
35
|
+
Zip::File.open(path, Zip::File::CREATE) do |zipfile|
|
|
36
|
+
Dir.glob("#{output_dir}/**/*").each do |file|
|
|
37
|
+
next if File.directory?(file)
|
|
31
38
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
39
|
+
entry_name = file.sub("#{File.dirname(output_dir)}/", "")
|
|
40
|
+
zipfile.add(entry_name, file)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
path
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def enrich_documents
|
|
49
|
+
index.publications.map do |pub|
|
|
50
|
+
enrich_publication(pub)
|
|
36
51
|
rescue StandardError => e
|
|
37
52
|
warn " Skip #{pub.identifier}: #{e.message}"
|
|
38
53
|
pub.to_h
|
|
39
54
|
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def enrich_publication(pub)
|
|
58
|
+
rxl_file = pub.files.find { |f| f.format == "rxl" }
|
|
59
|
+
return pub.to_h unless rxl_file
|
|
40
60
|
|
|
61
|
+
rxl_path = File.join(output_dir, rxl_file.path)
|
|
62
|
+
return pub.to_h unless File.exist?(rxl_path)
|
|
63
|
+
|
|
64
|
+
bib = Relaton::Bib::Item.from_xml(File.read(rxl_path))
|
|
65
|
+
pub.to_h.merge("bibliographic" => bib.to_h)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def write_relaton_index(documents)
|
|
41
69
|
dest = File.join(output_dir, "relaton")
|
|
42
70
|
FileUtils.mkdir_p(dest)
|
|
43
71
|
index_data = { "root" => { "title" => "Document Registry",
|
|
@@ -47,19 +75,59 @@ module Metanorma
|
|
|
47
75
|
File.write(File.join(dest, "index.yaml"), YAML.dump(index_data))
|
|
48
76
|
end
|
|
49
77
|
|
|
50
|
-
def
|
|
51
|
-
|
|
78
|
+
def write_data_file(documents)
|
|
79
|
+
FileUtils.mkdir_p(@data_dir)
|
|
80
|
+
items = documents.compact.map { |doc| flatten_for_site(doc) }
|
|
81
|
+
File.write(File.join(@data_dir, "documents.json"),
|
|
82
|
+
JSON.pretty_generate({ "items" => items }))
|
|
83
|
+
end
|
|
52
84
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
85
|
+
def flatten_for_site(doc)
|
|
86
|
+
bib = doc["bibliographic"] || {}
|
|
87
|
+
doc_id = resolve_doc_id(bib, doc)
|
|
88
|
+
{
|
|
89
|
+
"slug" => doc["id"],
|
|
90
|
+
"id" => doc_id,
|
|
91
|
+
"title" => doc["title"].to_s,
|
|
92
|
+
"abstract" => extract_abstract(bib),
|
|
93
|
+
"stage" => (doc["stage"] || "published").to_s.downcase,
|
|
94
|
+
"doctype" => extract_doctype(bib) || doc.fetch("doctype", ""),
|
|
95
|
+
"edition" => doc["edition"],
|
|
96
|
+
"date" => extract_date(doc),
|
|
97
|
+
"channels" => doc["channels"] || [],
|
|
98
|
+
"formats" => doc["formats"] || [],
|
|
99
|
+
"files" => doc["files"] || [],
|
|
100
|
+
}
|
|
101
|
+
end
|
|
57
102
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
103
|
+
def resolve_doc_id(bib, doc)
|
|
104
|
+
extract_primary_id(bib) || doc["identifier"] || doc["id"]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def extract_primary_id(bib)
|
|
108
|
+
ids = bib["docidentifier"]
|
|
109
|
+
return nil unless ids&.any?
|
|
110
|
+
|
|
111
|
+
primary = ids.find { |di| di["primary"] == true } || ids.first
|
|
112
|
+
primary["content"]
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def extract_doctype(bib)
|
|
116
|
+
bib.dig("ext", "doctype", "content")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def extract_abstract(bib)
|
|
120
|
+
abstracts = bib["abstract"]
|
|
121
|
+
return nil unless abstracts&.any?
|
|
122
|
+
|
|
123
|
+
abstracts.first["content"]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def extract_date(doc)
|
|
127
|
+
release_date = doc.dig("source", "releaseDate")
|
|
128
|
+
return nil unless release_date
|
|
129
|
+
|
|
130
|
+
release_date.to_s.split(/[T ]/).first
|
|
63
131
|
end
|
|
64
132
|
end
|
|
65
133
|
end
|
data/lib/metanorma/release.rb
CHANGED
|
@@ -11,6 +11,7 @@ module Metanorma
|
|
|
11
11
|
autoload :Index, "metanorma/release/index"
|
|
12
12
|
autoload :Site, "metanorma/release/site"
|
|
13
13
|
autoload :Channel, "metanorma/release/channel"
|
|
14
|
+
autoload :OrgConfig, "metanorma/release/org_config"
|
|
14
15
|
autoload :Config, "metanorma/release/config"
|
|
15
16
|
autoload :ContentHash, "metanorma/release/content_hash"
|
|
16
17
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: metanorma-release
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.8
|
|
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-05-
|
|
11
|
+
date: 2026-05-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: relaton-bib
|
|
@@ -102,6 +102,7 @@ files:
|
|
|
102
102
|
- lib/metanorma/release/file_routing.rb
|
|
103
103
|
- lib/metanorma/release/index.rb
|
|
104
104
|
- lib/metanorma/release/interfaces.rb
|
|
105
|
+
- lib/metanorma/release/org_config.rb
|
|
105
106
|
- lib/metanorma/release/platform.rb
|
|
106
107
|
- lib/metanorma/release/platform/github.rb
|
|
107
108
|
- lib/metanorma/release/platform/github/manifest_reader.rb
|