metanorma-release 0.2.6 → 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/commands/aggregate.rb +26 -1
- 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/version.rb +1 -1
- data/lib/metanorma/release.rb +1 -0
- metadata +2 -1
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)
|
|
@@ -9,7 +9,7 @@ module Metanorma
|
|
|
9
9
|
:source, :organizations, :topic, :repos, :repo_pattern, :local_path,
|
|
10
10
|
:channels, :stages, :output_dir, :file_routing, :cache_dir,
|
|
11
11
|
:data_dir, :include_drafts, :concurrency, :min_documents, :token,
|
|
12
|
-
:create_zip,
|
|
12
|
+
:create_zip, :org,
|
|
13
13
|
keyword_init: true
|
|
14
14
|
)
|
|
15
15
|
|
|
@@ -18,9 +18,11 @@ module Metanorma
|
|
|
18
18
|
|
|
19
19
|
def initialize(config)
|
|
20
20
|
@config = config
|
|
21
|
+
@org_config = nil
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def call
|
|
25
|
+
load_org_config
|
|
24
26
|
result = run_aggregation
|
|
25
27
|
return result unless result.publications.any?
|
|
26
28
|
|
|
@@ -54,6 +56,7 @@ module Metanorma
|
|
|
54
56
|
min_documents: merged[:min_documents],
|
|
55
57
|
token: merged[:token],
|
|
56
58
|
create_zip: merged[:create_zip],
|
|
59
|
+
org: merged[:org],
|
|
57
60
|
)
|
|
58
61
|
end
|
|
59
62
|
|
|
@@ -82,6 +85,7 @@ module Metanorma
|
|
|
82
85
|
min_documents: cli_options[:min_documents] || file_data["min_documents"],
|
|
83
86
|
token: cli_options[:token],
|
|
84
87
|
create_zip: cli_options[:create_zip],
|
|
88
|
+
org: file_data["org"],
|
|
85
89
|
}
|
|
86
90
|
end
|
|
87
91
|
|
|
@@ -163,6 +167,27 @@ module Metanorma
|
|
|
163
167
|
rescue LoadError
|
|
164
168
|
warn " (relaton gem not available — bibliography skipped)"
|
|
165
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
|
|
166
191
|
end
|
|
167
192
|
end
|
|
168
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
|
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,7 +1,7 @@
|
|
|
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.
|
|
@@ -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
|