ast-template 7.0.0 → 7.1.3
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
- checksums.yaml.gz.sig +0 -0
- data/LICENSE.md +13 -0
- data/README.md +281 -0
- data/lib/ast/template/version.rb +5 -3
- data/lib/ast/template.rb +571 -257
- data/lib/ast-template.rb +7 -1
- data/sig/ast/template.rbs +8 -0
- data.tar.gz.sig +0 -0
- metadata +251 -13
- metadata.gz.sig +0 -0
data/lib/ast/template.rb
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'ast/merge'
|
|
5
|
+
require_relative 'template/version'
|
|
5
6
|
|
|
6
7
|
module Ast
|
|
7
8
|
module Template
|
|
@@ -17,17 +18,156 @@ module Ast
|
|
|
17
18
|
SESSION_COMMAND_TRANSPORT_VERSION = 1
|
|
18
19
|
SESSION_COMMAND_PAYLOAD_TRANSPORT_VERSION = 1
|
|
19
20
|
SESSION_INVOCATION_TRANSPORT_VERSION = 1
|
|
21
|
+
README_FAMILY_LANGUAGE_ORDER = %w[go ruby rust typescript].freeze
|
|
22
|
+
README_FAMILY_LANGUAGE_LABELS = {
|
|
23
|
+
'go' => 'Go',
|
|
24
|
+
'ruby' => 'Ruby',
|
|
25
|
+
'rust' => 'Rust',
|
|
26
|
+
'typescript' => 'TypeScript'
|
|
27
|
+
}.freeze
|
|
20
28
|
|
|
21
29
|
class << self
|
|
30
|
+
def readme_family_language_aliases(self_language, language_order = README_FAMILY_LANGUAGE_ORDER)
|
|
31
|
+
self_id = self_language.to_s
|
|
32
|
+
alternatives = language_order.map(&:to_s).reject { |language| language == self_id }
|
|
33
|
+
aliases = {
|
|
34
|
+
'SELF_LANG' => README_FAMILY_LANGUAGE_LABELS.fetch(self_id, self_id),
|
|
35
|
+
'SELF_LANG_ID' => self_id
|
|
36
|
+
}
|
|
37
|
+
alternatives.each_with_index do |language, index|
|
|
38
|
+
alias_prefix = "IMP_LANG#{index + 1}"
|
|
39
|
+
aliases[alias_prefix] = README_FAMILY_LANGUAGE_LABELS.fetch(language, language)
|
|
40
|
+
aliases["#{alias_prefix}_ID"] = language
|
|
41
|
+
end
|
|
42
|
+
aliases
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def readme_family_token_values(family_metadata)
|
|
46
|
+
family = Ast::Merge.normalize_value(family_metadata || {})
|
|
47
|
+
self_entry = family.fetch(:self, {})
|
|
48
|
+
self_id = self_entry.fetch(:id).to_s
|
|
49
|
+
implementations = Array(family[:implementations]).each_with_object({}) do |entry, memo|
|
|
50
|
+
normalized_entry = Ast::Merge.normalize_value(entry)
|
|
51
|
+
memo[normalized_entry[:id].to_s] = normalized_entry
|
|
52
|
+
end
|
|
53
|
+
aliases = readme_family_language_aliases(self_id)
|
|
54
|
+
tokens = {
|
|
55
|
+
'FAMILY_SECTION_HEADING' => family[:section_heading].to_s,
|
|
56
|
+
'FAMILY_DESCRIPTION' => family[:description].to_s,
|
|
57
|
+
'SELF_PACKAGE_ROOT' => self_entry[:package_root].to_s,
|
|
58
|
+
'SELF_PACKAGE_MANAGER' => self_entry[:package_manager].to_s
|
|
59
|
+
}.merge(aliases)
|
|
60
|
+
|
|
61
|
+
README_FAMILY_LANGUAGE_ORDER.reject { |language| language == self_id }.each_with_index do |language, index|
|
|
62
|
+
implementation = implementations.fetch(language, {})
|
|
63
|
+
alias_prefix = "IMP_LANG#{index + 1}"
|
|
64
|
+
tokens["#{alias_prefix}_PACKAGE_ROOT"] = implementation[:package_root].to_s
|
|
65
|
+
tokens["#{alias_prefix}_PACKAGE_MANAGER"] = implementation[:package_manager].to_s
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
tokens
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def render_readme_family_section(template_partial, family_metadata, config = nil)
|
|
72
|
+
replacements = readme_family_token_values(family_metadata).transform_keys { |key| "SM|#{key}" }
|
|
73
|
+
Ast::Merge.resolve_template_tokens(template_partial.to_s, replacements, config)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def apply_readme_family_section(template_partial, package_metadata, family_metadata, destination_content,
|
|
77
|
+
config = nil)
|
|
78
|
+
package_entry = Ast::Merge.normalize_value(package_metadata || {})
|
|
79
|
+
family = Ast::Merge.normalize_value(family_metadata || {})
|
|
80
|
+
rendered_section = render_readme_family_section(template_partial, family, config).rstrip
|
|
81
|
+
base_content = if destination_content.nil?
|
|
82
|
+
"# #{package_entry[:name]}\n\n#{package_entry[:summary]}\n"
|
|
83
|
+
else
|
|
84
|
+
destination_content.to_s
|
|
85
|
+
end
|
|
86
|
+
content = replace_or_insert_markdown_heading_section(
|
|
87
|
+
base_content,
|
|
88
|
+
family[:section_heading].to_s,
|
|
89
|
+
2,
|
|
90
|
+
rendered_section
|
|
91
|
+
)
|
|
92
|
+
{
|
|
93
|
+
content: content,
|
|
94
|
+
changed: content != base_content
|
|
95
|
+
}
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def apply_readme_family_sections_to_package_directories(root, template_partial, packages, config = nil)
|
|
99
|
+
run_readme_family_sections_for_package_directories(root, template_partial, packages, true, config)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def plan_readme_family_sections_for_package_directories(root, template_partial, packages, config = nil)
|
|
103
|
+
run_readme_family_sections_for_package_directories(root, template_partial, packages, false, config)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def run_readme_family_section_command(command, config = nil)
|
|
107
|
+
normalized = Ast::Merge.normalize_value(command || {})
|
|
108
|
+
mode = normalized.fetch(:mode, 'plan').to_s
|
|
109
|
+
write_changes = %w[apply reapply].include?(mode)
|
|
110
|
+
{
|
|
111
|
+
profile_name: normalized.fetch(:profile_name, '').to_s,
|
|
112
|
+
mode: mode,
|
|
113
|
+
runner: run_readme_family_sections_for_package_directories(
|
|
114
|
+
normalized.fetch(:root, '').to_s,
|
|
115
|
+
normalized.fetch(:template_partial, '').to_s,
|
|
116
|
+
Array(normalized[:packages]),
|
|
117
|
+
write_changes,
|
|
118
|
+
config
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def run_readme_family_sections_for_package_directories(root, template_partial, packages, write_changes,
|
|
124
|
+
config = nil)
|
|
125
|
+
report = {
|
|
126
|
+
package_count: packages.length,
|
|
127
|
+
changed_count: 0,
|
|
128
|
+
created_count: 0,
|
|
129
|
+
entries: []
|
|
130
|
+
}
|
|
131
|
+
packages.each do |package_entry|
|
|
132
|
+
normalized_entry = Ast::Merge.normalize_value(package_entry)
|
|
133
|
+
readme_path = normalized_entry.fetch(:readme_path).to_s
|
|
134
|
+
full_path = File.join(root.to_s, readme_path.split('/'))
|
|
135
|
+
created = !File.exist?(full_path)
|
|
136
|
+
destination_content = created ? nil : File.read(full_path)
|
|
137
|
+
application = apply_readme_family_section(
|
|
138
|
+
template_partial,
|
|
139
|
+
normalized_entry.fetch(:package, {}),
|
|
140
|
+
normalized_entry.fetch(:family, {}),
|
|
141
|
+
destination_content,
|
|
142
|
+
config
|
|
143
|
+
)
|
|
144
|
+
if application[:changed]
|
|
145
|
+
if write_changes
|
|
146
|
+
FileUtils.mkdir_p(File.dirname(full_path))
|
|
147
|
+
File.write(full_path, application[:content])
|
|
148
|
+
end
|
|
149
|
+
report[:changed_count] += 1
|
|
150
|
+
report[:created_count] += 1 if created
|
|
151
|
+
end
|
|
152
|
+
report[:entries] << {
|
|
153
|
+
id: normalized_entry.fetch(:id).to_s,
|
|
154
|
+
readme_path: readme_path,
|
|
155
|
+
changed: application[:changed],
|
|
156
|
+
created: created && application[:changed]
|
|
157
|
+
}
|
|
158
|
+
end
|
|
159
|
+
report
|
|
160
|
+
end
|
|
161
|
+
|
|
22
162
|
def merge_prepared_content_from_registry(registry, entry)
|
|
23
|
-
family = entry.dig(:classification, :family) || entry.dig(
|
|
163
|
+
family = entry.dig(:classification, :family) || entry.dig('classification', 'family')
|
|
24
164
|
adapter = registry[family.to_s]
|
|
25
165
|
unless adapter
|
|
26
166
|
return {
|
|
27
167
|
ok: false,
|
|
28
168
|
diagnostics: [{
|
|
29
|
-
severity:
|
|
30
|
-
category:
|
|
169
|
+
severity: 'error',
|
|
170
|
+
category: 'configuration_error',
|
|
31
171
|
message: "missing family adapter for #{family}"
|
|
32
172
|
}],
|
|
33
173
|
policies: []
|
|
@@ -48,7 +188,7 @@ module Ast
|
|
|
48
188
|
{
|
|
49
189
|
mode: normalized_mode,
|
|
50
190
|
adapter_families: registered_adapter_families(registry),
|
|
51
|
-
diagnostics: Array(result&.dig(:apply_result, :diagnostics) || result&.dig(
|
|
191
|
+
diagnostics: Array(result&.dig(:apply_result, :diagnostics) || result&.dig('apply_result', 'diagnostics')),
|
|
52
192
|
runner_report: Ast::Merge.report_template_directory_runner(entries, result)
|
|
53
193
|
}
|
|
54
194
|
end
|
|
@@ -60,31 +200,54 @@ module Ast
|
|
|
60
200
|
end
|
|
61
201
|
|
|
62
202
|
registry = {}
|
|
63
|
-
if include_family.call(
|
|
203
|
+
if include_family.call('markdown')
|
|
64
204
|
begin
|
|
65
|
-
require
|
|
66
|
-
registry[
|
|
67
|
-
|
|
205
|
+
require 'markly-merge'
|
|
206
|
+
registry['markdown'] = lambda do |entry|
|
|
207
|
+
{
|
|
208
|
+
ok: true,
|
|
209
|
+
output: Markly::Merge::SmartMerger.new(
|
|
210
|
+
entry[:prepared_template_content],
|
|
211
|
+
entry[:destination_content],
|
|
212
|
+
add_template_only_nodes: true
|
|
213
|
+
).merge,
|
|
214
|
+
diagnostics: [],
|
|
215
|
+
policies: []
|
|
216
|
+
}
|
|
68
217
|
end
|
|
69
218
|
rescue LoadError
|
|
219
|
+
begin
|
|
220
|
+
require 'markdown-merge'
|
|
221
|
+
registry['markdown'] = lambda do |entry|
|
|
222
|
+
Markdown::Merge.merge_markdown(entry[:prepared_template_content], entry[:destination_content], 'markdown')
|
|
223
|
+
end
|
|
224
|
+
rescue LoadError
|
|
225
|
+
end
|
|
70
226
|
end
|
|
71
227
|
end
|
|
72
|
-
if include_family.call(
|
|
228
|
+
if include_family.call('toml')
|
|
73
229
|
begin
|
|
74
|
-
require
|
|
75
|
-
registry[
|
|
76
|
-
Toml::Merge.merge_toml(entry[:prepared_template_content], entry[:destination_content],
|
|
230
|
+
require 'toml-merge'
|
|
231
|
+
registry['toml'] = lambda do |entry|
|
|
232
|
+
Toml::Merge.merge_toml(entry[:prepared_template_content], entry[:destination_content], 'toml')
|
|
77
233
|
end
|
|
78
234
|
rescue LoadError
|
|
79
235
|
end
|
|
80
236
|
end
|
|
81
|
-
if include_family.call(
|
|
237
|
+
if include_family.call('ruby')
|
|
82
238
|
begin
|
|
83
|
-
require
|
|
84
|
-
registry[
|
|
85
|
-
|
|
239
|
+
require 'prism-merge'
|
|
240
|
+
registry['ruby'] = lambda do |entry|
|
|
241
|
+
Prism::Merge.merge_ruby(entry[:prepared_template_content], entry[:destination_content], 'ruby')
|
|
86
242
|
end
|
|
87
243
|
rescue LoadError
|
|
244
|
+
begin
|
|
245
|
+
require 'ruby-merge'
|
|
246
|
+
registry['ruby'] = lambda do |entry|
|
|
247
|
+
Ruby::Merge.merge_ruby(entry[:prepared_template_content], entry[:destination_content], 'ruby')
|
|
248
|
+
end
|
|
249
|
+
rescue LoadError
|
|
250
|
+
end
|
|
88
251
|
end
|
|
89
252
|
end
|
|
90
253
|
|
|
@@ -102,7 +265,7 @@ module Ast
|
|
|
102
265
|
end
|
|
103
266
|
|
|
104
267
|
def plan_template_directory_session_from_directories(template_root, destination_root,
|
|
105
|
-
|
|
268
|
+
context, default_strategy, overrides, replacements, config = nil)
|
|
106
269
|
entries = Ast::Merge.plan_template_tree_execution_from_directories(
|
|
107
270
|
template_root,
|
|
108
271
|
destination_root,
|
|
@@ -116,7 +279,7 @@ module Ast
|
|
|
116
279
|
end
|
|
117
280
|
|
|
118
281
|
def apply_template_directory_session_to_directory(template_root, destination_root,
|
|
119
|
-
|
|
282
|
+
context, default_strategy, overrides, replacements, config = nil, &merge_callback)
|
|
120
283
|
result = Ast::Merge.apply_template_tree_execution_to_directory(
|
|
121
284
|
template_root,
|
|
122
285
|
destination_root,
|
|
@@ -131,7 +294,7 @@ module Ast
|
|
|
131
294
|
end
|
|
132
295
|
|
|
133
296
|
def reapply_template_directory_session_to_directory(template_root, destination_root,
|
|
134
|
-
|
|
297
|
+
context, default_strategy, overrides, replacements, config = nil, &merge_callback)
|
|
135
298
|
result = Ast::Merge.apply_template_tree_execution_to_directory(
|
|
136
299
|
template_root,
|
|
137
300
|
destination_root,
|
|
@@ -146,7 +309,7 @@ module Ast
|
|
|
146
309
|
end
|
|
147
310
|
|
|
148
311
|
def apply_template_directory_session_with_registry_to_directory(template_root, destination_root,
|
|
149
|
-
|
|
312
|
+
context, default_strategy, overrides, replacements, registry, config = nil)
|
|
150
313
|
result = Ast::Merge.apply_template_tree_execution_to_directory(
|
|
151
314
|
template_root,
|
|
152
315
|
destination_root,
|
|
@@ -162,7 +325,7 @@ module Ast
|
|
|
162
325
|
end
|
|
163
326
|
|
|
164
327
|
def apply_template_directory_session_with_default_registry_to_directory(template_root, destination_root,
|
|
165
|
-
|
|
328
|
+
context, default_strategy, overrides, replacements, allowed_families = nil, config = nil)
|
|
166
329
|
registry = default_family_merge_adapter_registry(allowed_families)
|
|
167
330
|
apply_template_directory_session_with_registry_to_directory(
|
|
168
331
|
template_root,
|
|
@@ -178,9 +341,9 @@ module Ast
|
|
|
178
341
|
|
|
179
342
|
def required_families(entries)
|
|
180
343
|
Array(entries).filter_map do |entry|
|
|
181
|
-
next unless (entry[:execution_action] || entry[
|
|
344
|
+
next unless (entry[:execution_action] || entry['execution_action']).to_s == 'merge_prepared_content'
|
|
182
345
|
|
|
183
|
-
entry.dig(:classification, :family) || entry.dig(
|
|
346
|
+
entry.dig(:classification, :family) || entry.dig('classification', 'family')
|
|
184
347
|
end.uniq.sort
|
|
185
348
|
end
|
|
186
349
|
|
|
@@ -197,7 +360,7 @@ module Ast
|
|
|
197
360
|
end
|
|
198
361
|
|
|
199
362
|
def report_adapter_capabilities_from_directories(template_root, destination_root,
|
|
200
|
-
|
|
363
|
+
context, default_strategy, overrides, replacements, registry, config = nil)
|
|
201
364
|
entries = Ast::Merge.plan_template_tree_execution_from_directories(
|
|
202
365
|
template_root,
|
|
203
366
|
destination_root,
|
|
@@ -211,7 +374,7 @@ module Ast
|
|
|
211
374
|
end
|
|
212
375
|
|
|
213
376
|
def report_default_adapter_capabilities_from_directories(template_root, destination_root,
|
|
214
|
-
|
|
377
|
+
context, default_strategy, overrides, replacements, allowed_families = nil, config = nil)
|
|
215
378
|
report_adapter_capabilities_from_directories(
|
|
216
379
|
template_root,
|
|
217
380
|
destination_root,
|
|
@@ -232,7 +395,7 @@ module Ast
|
|
|
232
395
|
end
|
|
233
396
|
|
|
234
397
|
def plan_template_directory_session_envelope_from_directories(template_root, destination_root,
|
|
235
|
-
|
|
398
|
+
context, default_strategy, overrides, replacements, allowed_families = nil, config = nil)
|
|
236
399
|
report_template_directory_session_envelope(
|
|
237
400
|
plan_template_directory_session_from_directories(
|
|
238
401
|
template_root,
|
|
@@ -257,7 +420,7 @@ module Ast
|
|
|
257
420
|
end
|
|
258
421
|
|
|
259
422
|
def apply_template_directory_session_envelope_with_default_registry_to_directory(template_root, destination_root,
|
|
260
|
-
|
|
423
|
+
context, default_strategy, overrides, replacements, allowed_families = nil, config = nil)
|
|
261
424
|
report_template_directory_session_envelope(
|
|
262
425
|
apply_template_directory_session_with_default_registry_to_directory(
|
|
263
426
|
template_root,
|
|
@@ -283,84 +446,92 @@ module Ast
|
|
|
283
446
|
end
|
|
284
447
|
|
|
285
448
|
def report_template_directory_session_status(envelope)
|
|
286
|
-
session_report = envelope[:session_report] || envelope[
|
|
287
|
-
adapter_capabilities = envelope[:adapter_capabilities] || envelope[
|
|
288
|
-
runner_report = session_report[:runner_report] || session_report[
|
|
289
|
-
plan_report = runner_report[:plan_report] || runner_report[
|
|
290
|
-
entries = Array(plan_report[:entries] || plan_report[
|
|
291
|
-
plan_summary = plan_report[:summary] || plan_report[
|
|
292
|
-
apply_report = runner_report[:apply_report] || runner_report[
|
|
293
|
-
apply_entries = Array(apply_report[:entries] || apply_report[
|
|
294
|
-
apply_summary = apply_report[:summary] || apply_report[
|
|
449
|
+
session_report = envelope[:session_report] || envelope['session_report'] || {}
|
|
450
|
+
adapter_capabilities = envelope[:adapter_capabilities] || envelope['adapter_capabilities'] || {}
|
|
451
|
+
runner_report = session_report[:runner_report] || session_report['runner_report'] || {}
|
|
452
|
+
plan_report = runner_report[:plan_report] || runner_report['plan_report'] || {}
|
|
453
|
+
entries = Array(plan_report[:entries] || plan_report['entries'])
|
|
454
|
+
plan_summary = plan_report[:summary] || plan_report['summary'] || {}
|
|
455
|
+
apply_report = runner_report[:apply_report] || runner_report['apply_report'] || {}
|
|
456
|
+
apply_entries = Array(apply_report[:entries] || apply_report['entries'])
|
|
457
|
+
apply_summary = apply_report[:summary] || apply_report['summary'] || {}
|
|
295
458
|
blocked_paths = (entries + apply_entries).filter_map do |entry|
|
|
296
|
-
status = entry[:status] || entry[
|
|
297
|
-
destination_path = entry[:destination_path] || entry[
|
|
298
|
-
destination_path if status.to_s ==
|
|
459
|
+
status = entry[:status] || entry['status']
|
|
460
|
+
destination_path = entry[:destination_path] || entry['destination_path']
|
|
461
|
+
destination_path if status.to_s == 'blocked' && destination_path
|
|
299
462
|
end.uniq.sort
|
|
300
463
|
missing_families = Array(
|
|
301
|
-
adapter_capabilities[:missing_families] || adapter_capabilities[
|
|
464
|
+
adapter_capabilities[:missing_families] || adapter_capabilities['missing_families']
|
|
302
465
|
).map(&:to_s).sort
|
|
303
466
|
|
|
304
467
|
{
|
|
305
|
-
mode: (session_report[:mode] || session_report[
|
|
306
|
-
ready:
|
|
468
|
+
mode: (session_report[:mode] || session_report['mode']).to_s,
|
|
469
|
+
ready: !(adapter_capabilities[:ready] || adapter_capabilities['ready']).nil? && blocked_paths.empty?,
|
|
307
470
|
missing_families: missing_families,
|
|
308
471
|
blocked_paths: blocked_paths,
|
|
309
|
-
planned_write_count: plan_summary.fetch(:create, plan_summary.fetch(
|
|
310
|
-
plan_summary.fetch(:update, plan_summary.fetch(
|
|
311
|
-
written_count: apply_summary.fetch(:written, apply_summary.fetch(
|
|
472
|
+
planned_write_count: plan_summary.fetch(:create, plan_summary.fetch('create', 0)) +
|
|
473
|
+
plan_summary.fetch(:update, plan_summary.fetch('update', 0)),
|
|
474
|
+
written_count: apply_summary.fetch(:written, apply_summary.fetch('written', 0))
|
|
312
475
|
}
|
|
313
476
|
end
|
|
314
477
|
|
|
315
478
|
def template_directory_session_status_envelope(status)
|
|
316
479
|
{
|
|
317
|
-
kind:
|
|
480
|
+
kind: 'template_directory_session_status',
|
|
318
481
|
version: SESSION_STATUS_TRANSPORT_VERSION,
|
|
319
482
|
status: deep_dup(status)
|
|
320
483
|
}
|
|
321
484
|
end
|
|
322
485
|
|
|
323
486
|
def import_template_directory_session_status_envelope(envelope)
|
|
324
|
-
|
|
325
|
-
|
|
487
|
+
unless envelope[:kind] == 'template_directory_session_status'
|
|
488
|
+
return [nil,
|
|
489
|
+
{ category: 'kind_mismatch',
|
|
490
|
+
message: 'expected template_directory_session_status envelope kind.' }]
|
|
491
|
+
end
|
|
492
|
+
unless envelope[:version] == SESSION_STATUS_TRANSPORT_VERSION
|
|
493
|
+
return [nil,
|
|
494
|
+
{ category: 'unsupported_version',
|
|
495
|
+
message: "unsupported template_directory_session_status envelope version #{envelope[:version]}." }]
|
|
496
|
+
end
|
|
326
497
|
|
|
327
498
|
[deep_dup(envelope[:status]), nil]
|
|
328
499
|
end
|
|
329
500
|
|
|
330
501
|
def report_template_directory_session_diagnostics(mode, entries, adapter_capabilities, result = nil)
|
|
331
502
|
missing_families = Array(
|
|
332
|
-
adapter_capabilities[:missing_families] || adapter_capabilities[
|
|
503
|
+
adapter_capabilities[:missing_families] || adapter_capabilities['missing_families']
|
|
333
504
|
).map(&:to_s)
|
|
334
505
|
blocked_apply_paths = Array(
|
|
335
|
-
result&.dig(:apply_report, :entries) || result&.dig(
|
|
506
|
+
result&.dig(:apply_report, :entries) || result&.dig('apply_report', 'entries')
|
|
336
507
|
).filter_map do |entry|
|
|
337
|
-
destination_path = entry[:destination_path] || entry[
|
|
338
|
-
status = entry[:status] || entry[
|
|
339
|
-
destination_path if status.to_s ==
|
|
508
|
+
destination_path = entry[:destination_path] || entry['destination_path']
|
|
509
|
+
status = entry[:status] || entry['status']
|
|
510
|
+
destination_path if status.to_s == 'blocked' && destination_path
|
|
340
511
|
end
|
|
341
512
|
|
|
342
513
|
diagnostics = Array(entries).flat_map do |entry|
|
|
343
|
-
path = entry[:destination_path] || entry[
|
|
344
|
-
|
|
345
|
-
family = entry.dig(:classification, :family) || entry.dig(
|
|
514
|
+
path = entry[:destination_path] || entry['destination_path'] ||
|
|
515
|
+
entry[:logical_destination_path] || entry['logical_destination_path']
|
|
516
|
+
family = entry.dig(:classification, :family) || entry.dig('classification', 'family')
|
|
346
517
|
result_entries = []
|
|
347
|
-
block_reason = entry[:block_reason] || entry[
|
|
348
|
-
if (entry[:blocked] || entry[
|
|
518
|
+
block_reason = entry[:block_reason] || entry['block_reason']
|
|
519
|
+
if (entry[:blocked] || entry['blocked']) && block_reason.to_s == 'unresolved_tokens'
|
|
349
520
|
result_entries << {
|
|
350
|
-
severity:
|
|
351
|
-
category:
|
|
352
|
-
reason:
|
|
521
|
+
severity: 'error',
|
|
522
|
+
category: 'configuration_error',
|
|
523
|
+
reason: 'unresolved_tokens',
|
|
353
524
|
path: path,
|
|
354
525
|
message: "unresolved template tokens block #{path}"
|
|
355
526
|
}
|
|
356
527
|
end
|
|
357
|
-
if (entry[:execution_action] || entry[
|
|
358
|
-
|
|
359
|
-
|
|
528
|
+
if (entry[:execution_action] || entry['execution_action']).to_s == 'merge_prepared_content' &&
|
|
529
|
+
missing_families.include?(family.to_s) &&
|
|
530
|
+
(result.nil? || blocked_apply_paths.empty? || blocked_apply_paths.include?(path))
|
|
360
531
|
result_entries << {
|
|
361
|
-
severity:
|
|
362
|
-
category:
|
|
363
|
-
reason:
|
|
532
|
+
severity: 'error',
|
|
533
|
+
category: 'configuration_error',
|
|
534
|
+
reason: 'missing_family_adapter',
|
|
364
535
|
path: path,
|
|
365
536
|
family: family.to_s,
|
|
366
537
|
message: "missing family adapter for #{family} blocks #{path}"
|
|
@@ -378,21 +549,29 @@ module Ast
|
|
|
378
549
|
|
|
379
550
|
def template_directory_session_diagnostics_envelope(diagnostics)
|
|
380
551
|
{
|
|
381
|
-
kind:
|
|
552
|
+
kind: 'template_directory_session_diagnostics',
|
|
382
553
|
version: SESSION_DIAGNOSTICS_TRANSPORT_VERSION,
|
|
383
554
|
diagnostics: deep_dup(diagnostics)
|
|
384
555
|
}
|
|
385
556
|
end
|
|
386
557
|
|
|
387
558
|
def import_template_directory_session_diagnostics_envelope(envelope)
|
|
388
|
-
|
|
389
|
-
|
|
559
|
+
unless envelope[:kind] == 'template_directory_session_diagnostics'
|
|
560
|
+
return [nil,
|
|
561
|
+
{ category: 'kind_mismatch',
|
|
562
|
+
message: 'expected template_directory_session_diagnostics envelope kind.' }]
|
|
563
|
+
end
|
|
564
|
+
unless envelope[:version] == SESSION_DIAGNOSTICS_TRANSPORT_VERSION
|
|
565
|
+
return [nil,
|
|
566
|
+
{ category: 'unsupported_version',
|
|
567
|
+
message: "unsupported template_directory_session_diagnostics envelope version #{envelope[:version]}." }]
|
|
568
|
+
end
|
|
390
569
|
|
|
391
570
|
[deep_dup(envelope[:diagnostics]), nil]
|
|
392
571
|
end
|
|
393
572
|
|
|
394
573
|
def plan_template_directory_session_diagnostics_from_directories(template_root, destination_root,
|
|
395
|
-
|
|
574
|
+
context, default_strategy, overrides, replacements, allowed_families = nil, config = nil)
|
|
396
575
|
entries = Ast::Merge.plan_template_tree_execution_from_directories(
|
|
397
576
|
template_root,
|
|
398
577
|
destination_root,
|
|
@@ -410,7 +589,7 @@ module Ast
|
|
|
410
589
|
end
|
|
411
590
|
|
|
412
591
|
def apply_template_directory_session_diagnostics_with_default_registry_to_directory(template_root, destination_root,
|
|
413
|
-
|
|
592
|
+
context, default_strategy, overrides, replacements, allowed_families = nil, config = nil)
|
|
414
593
|
registry = default_family_merge_adapter_registry(allowed_families)
|
|
415
594
|
result = Ast::Merge.apply_template_tree_execution_to_directory(
|
|
416
595
|
template_root,
|
|
@@ -440,7 +619,7 @@ module Ast
|
|
|
440
619
|
end
|
|
441
620
|
|
|
442
621
|
def plan_template_directory_session_outcome_from_directories(template_root, destination_root,
|
|
443
|
-
|
|
622
|
+
context, default_strategy, overrides, replacements, allowed_families = nil, config = nil)
|
|
444
623
|
report_template_directory_session_outcome(
|
|
445
624
|
plan_template_directory_session_from_directories(
|
|
446
625
|
template_root,
|
|
@@ -477,7 +656,7 @@ module Ast
|
|
|
477
656
|
end
|
|
478
657
|
|
|
479
658
|
def apply_template_directory_session_outcome_with_default_registry_to_directory(template_root, destination_root,
|
|
480
|
-
|
|
659
|
+
context, default_strategy, overrides, replacements, allowed_families = nil, config = nil)
|
|
481
660
|
registry = default_family_merge_adapter_registry(allowed_families)
|
|
482
661
|
result = Ast::Merge.apply_template_tree_execution_to_directory(
|
|
483
662
|
template_root,
|
|
@@ -507,7 +686,7 @@ module Ast
|
|
|
507
686
|
end
|
|
508
687
|
|
|
509
688
|
def reapply_template_directory_session_outcome_with_default_registry_to_directory(template_root, destination_root,
|
|
510
|
-
|
|
689
|
+
context, default_strategy, overrides, replacements, allowed_families = nil, config = nil)
|
|
511
690
|
registry = default_family_merge_adapter_registry(allowed_families)
|
|
512
691
|
result = Ast::Merge.apply_template_tree_execution_to_directory(
|
|
513
692
|
template_root,
|
|
@@ -537,9 +716,9 @@ module Ast
|
|
|
537
716
|
end
|
|
538
717
|
|
|
539
718
|
def run_template_directory_session_with_default_registry_to_directory(mode, template_root, destination_root,
|
|
540
|
-
|
|
719
|
+
context, default_strategy, overrides, replacements, allowed_families = nil, config = nil)
|
|
541
720
|
case mode.to_s
|
|
542
|
-
when
|
|
721
|
+
when 'plan'
|
|
543
722
|
plan_template_directory_session_outcome_from_directories(
|
|
544
723
|
template_root,
|
|
545
724
|
destination_root,
|
|
@@ -550,7 +729,7 @@ module Ast
|
|
|
550
729
|
allowed_families,
|
|
551
730
|
config
|
|
552
731
|
)
|
|
553
|
-
when
|
|
732
|
+
when 'apply'
|
|
554
733
|
apply_template_directory_session_outcome_with_default_registry_to_directory(
|
|
555
734
|
template_root,
|
|
556
735
|
destination_root,
|
|
@@ -561,7 +740,7 @@ module Ast
|
|
|
561
740
|
allowed_families,
|
|
562
741
|
config
|
|
563
742
|
)
|
|
564
|
-
when
|
|
743
|
+
when 'reapply'
|
|
565
744
|
reapply_template_directory_session_outcome_with_default_registry_to_directory(
|
|
566
745
|
template_root,
|
|
567
746
|
destination_root,
|
|
@@ -587,40 +766,40 @@ module Ast
|
|
|
587
766
|
end
|
|
588
767
|
normalized = deep_dup(request[:resolved_options])
|
|
589
768
|
run_template_directory_session_with_default_registry_to_directory(
|
|
590
|
-
normalized[:mode] || normalized[
|
|
591
|
-
normalized[:template_root] || normalized[
|
|
592
|
-
normalized[:destination_root] || normalized[
|
|
593
|
-
normalized[:context] || normalized[
|
|
594
|
-
normalized[:default_strategy] || normalized[
|
|
595
|
-
normalized[:overrides] || normalized[
|
|
596
|
-
normalized[:replacements] || normalized[
|
|
597
|
-
normalized[:allowed_families] || normalized[
|
|
598
|
-
normalized[:config] || normalized[
|
|
769
|
+
normalized[:mode] || normalized['mode'],
|
|
770
|
+
normalized[:template_root] || normalized['template_root'],
|
|
771
|
+
normalized[:destination_root] || normalized['destination_root'],
|
|
772
|
+
normalized[:context] || normalized['context'] || {},
|
|
773
|
+
normalized[:default_strategy] || normalized['default_strategy'],
|
|
774
|
+
normalized[:overrides] || normalized['overrides'] || [],
|
|
775
|
+
normalized[:replacements] || normalized['replacements'] || {},
|
|
776
|
+
normalized[:allowed_families] || normalized['allowed_families'],
|
|
777
|
+
normalized[:config] || normalized['config']
|
|
599
778
|
)
|
|
600
779
|
end
|
|
601
780
|
|
|
602
781
|
def report_template_directory_session_options_configuration(options)
|
|
603
782
|
normalized = deep_dup(options)
|
|
604
783
|
diagnostics = []
|
|
605
|
-
unless (normalized[:destination_root] || normalized[
|
|
784
|
+
unless (normalized[:destination_root] || normalized['destination_root']).to_s.length.positive?
|
|
606
785
|
diagnostics << {
|
|
607
|
-
severity:
|
|
608
|
-
category:
|
|
609
|
-
reason:
|
|
610
|
-
message:
|
|
786
|
+
severity: 'error',
|
|
787
|
+
category: 'configuration_error',
|
|
788
|
+
reason: 'missing_destination_root',
|
|
789
|
+
message: 'missing destination_root for template session'
|
|
611
790
|
}
|
|
612
791
|
end
|
|
613
|
-
unless (normalized[:template_root] || normalized[
|
|
792
|
+
unless (normalized[:template_root] || normalized['template_root']).to_s.length.positive?
|
|
614
793
|
diagnostics << {
|
|
615
|
-
severity:
|
|
616
|
-
category:
|
|
617
|
-
reason:
|
|
618
|
-
message:
|
|
794
|
+
severity: 'error',
|
|
795
|
+
category: 'configuration_error',
|
|
796
|
+
reason: 'missing_template_root',
|
|
797
|
+
message: 'missing template_root for template session'
|
|
619
798
|
}
|
|
620
799
|
end
|
|
621
800
|
diagnostics.sort_by! { |entry| entry[:reason] }
|
|
622
801
|
{
|
|
623
|
-
mode: normalize_session_mode(normalized[:mode] || normalized[
|
|
802
|
+
mode: normalize_session_mode(normalized[:mode] || normalized['mode']),
|
|
624
803
|
ready: diagnostics.empty?,
|
|
625
804
|
diagnostics: diagnostics
|
|
626
805
|
}
|
|
@@ -630,7 +809,7 @@ module Ast
|
|
|
630
809
|
normalized = deep_dup(options)
|
|
631
810
|
configuration = report_template_directory_session_options_configuration(normalized)
|
|
632
811
|
{
|
|
633
|
-
request_kind:
|
|
812
|
+
request_kind: 'options',
|
|
634
813
|
mode: configuration[:mode],
|
|
635
814
|
ready: configuration[:ready],
|
|
636
815
|
diagnostics: deep_dup(configuration[:diagnostics]),
|
|
@@ -644,13 +823,13 @@ module Ast
|
|
|
644
823
|
diagnostics = report_template_directory_session_options_configuration(normalized_overrides)[:diagnostics]
|
|
645
824
|
profile = normalized_profiles[profile_name.to_s] || normalized_profiles[profile_name.to_sym]
|
|
646
825
|
mode = normalize_session_mode(
|
|
647
|
-
normalized_overrides[:mode] || normalized_overrides[
|
|
826
|
+
normalized_overrides[:mode] || normalized_overrides['mode'] || profile&.[](:mode) || profile&.[]('mode')
|
|
648
827
|
)
|
|
649
828
|
unless profile
|
|
650
829
|
diagnostics << {
|
|
651
|
-
severity:
|
|
652
|
-
category:
|
|
653
|
-
reason:
|
|
830
|
+
severity: 'error',
|
|
831
|
+
category: 'configuration_error',
|
|
832
|
+
reason: 'missing_profile',
|
|
654
833
|
message: "unknown template session profile: #{profile_name}"
|
|
655
834
|
}
|
|
656
835
|
end
|
|
@@ -665,14 +844,16 @@ module Ast
|
|
|
665
844
|
def report_template_directory_session_profile_request(profiles, profile_name, overrides)
|
|
666
845
|
configuration = report_template_directory_session_profile_configuration(profiles, profile_name, overrides)
|
|
667
846
|
{
|
|
668
|
-
request_kind:
|
|
847
|
+
request_kind: 'profile',
|
|
669
848
|
profile_name: profile_name.to_s,
|
|
670
849
|
mode: configuration[:mode],
|
|
671
850
|
ready: configuration[:ready],
|
|
672
851
|
diagnostics: deep_dup(configuration[:diagnostics]),
|
|
673
|
-
resolved_options: configuration[:ready]
|
|
674
|
-
|
|
675
|
-
|
|
852
|
+
resolved_options: if configuration[:ready]
|
|
853
|
+
compact_session_request_options(
|
|
854
|
+
resolve_template_directory_session_options(profiles, profile_name, overrides)
|
|
855
|
+
)
|
|
856
|
+
end
|
|
676
857
|
}
|
|
677
858
|
end
|
|
678
859
|
|
|
@@ -693,24 +874,32 @@ module Ast
|
|
|
693
874
|
|
|
694
875
|
def template_directory_session_outcome_envelope(outcome)
|
|
695
876
|
{
|
|
696
|
-
kind:
|
|
877
|
+
kind: 'template_directory_session_outcome',
|
|
697
878
|
version: SESSION_OUTCOME_TRANSPORT_VERSION,
|
|
698
879
|
outcome: deep_dup(outcome)
|
|
699
880
|
}
|
|
700
881
|
end
|
|
701
882
|
|
|
702
883
|
def import_template_directory_session_outcome_envelope(envelope)
|
|
703
|
-
|
|
704
|
-
|
|
884
|
+
unless envelope[:kind] == 'template_directory_session_outcome'
|
|
885
|
+
return [nil,
|
|
886
|
+
{ category: 'kind_mismatch',
|
|
887
|
+
message: 'expected template_directory_session_outcome envelope kind.' }]
|
|
888
|
+
end
|
|
889
|
+
unless envelope[:version] == SESSION_OUTCOME_TRANSPORT_VERSION
|
|
890
|
+
return [nil,
|
|
891
|
+
{ category: 'unsupported_version',
|
|
892
|
+
message: "unsupported template_directory_session_outcome envelope version #{envelope[:version]}." }]
|
|
893
|
+
end
|
|
705
894
|
|
|
706
895
|
[deep_dup(envelope[:outcome]), nil]
|
|
707
896
|
end
|
|
708
897
|
|
|
709
898
|
def run_template_directory_session_request(request)
|
|
710
899
|
normalized = deep_dup(request)
|
|
711
|
-
unless normalized[:ready] || normalized[
|
|
712
|
-
mode = normalized[:mode] || normalized[
|
|
713
|
-
diagnostics = normalized[:diagnostics] || normalized[
|
|
900
|
+
unless normalized[:ready] || normalized['ready']
|
|
901
|
+
mode = normalized[:mode] || normalized['mode']
|
|
902
|
+
diagnostics = normalized[:diagnostics] || normalized['diagnostics'] || []
|
|
714
903
|
return report_template_directory_session_configuration_outcome(
|
|
715
904
|
mode,
|
|
716
905
|
{ mode: mode, ready: false, diagnostics: diagnostics }
|
|
@@ -718,130 +907,151 @@ module Ast
|
|
|
718
907
|
end
|
|
719
908
|
|
|
720
909
|
run_template_directory_session_with_options(
|
|
721
|
-
normalized[:resolved_options] || normalized[
|
|
910
|
+
normalized[:resolved_options] || normalized['resolved_options']
|
|
722
911
|
)
|
|
723
912
|
end
|
|
724
913
|
|
|
725
914
|
def template_directory_session_request_envelope(request)
|
|
726
915
|
{
|
|
727
|
-
kind:
|
|
916
|
+
kind: 'template_directory_session_request',
|
|
728
917
|
version: SESSION_REQUEST_TRANSPORT_VERSION,
|
|
729
918
|
request: deep_dup(request)
|
|
730
919
|
}
|
|
731
920
|
end
|
|
732
921
|
|
|
733
922
|
def import_template_directory_session_request_envelope(envelope)
|
|
734
|
-
|
|
735
|
-
|
|
923
|
+
unless envelope[:kind] == 'template_directory_session_request'
|
|
924
|
+
return [nil,
|
|
925
|
+
{ category: 'kind_mismatch',
|
|
926
|
+
message: 'expected template_directory_session_request envelope kind.' }]
|
|
927
|
+
end
|
|
928
|
+
unless envelope[:version] == SESSION_REQUEST_TRANSPORT_VERSION
|
|
929
|
+
return [nil,
|
|
930
|
+
{ category: 'unsupported_version',
|
|
931
|
+
message: "unsupported template_directory_session_request envelope version #{envelope[:version]}." }]
|
|
932
|
+
end
|
|
736
933
|
|
|
737
934
|
[deep_dup(envelope[:request]), nil]
|
|
738
935
|
end
|
|
739
936
|
|
|
740
937
|
def run_template_directory_session_runner_request(request, profiles = {})
|
|
741
938
|
normalized = deep_dup(request)
|
|
742
|
-
request_kind = normalized[:request_kind] || normalized[
|
|
743
|
-
if request_kind.to_s ==
|
|
939
|
+
request_kind = normalized[:request_kind] || normalized['request_kind']
|
|
940
|
+
if request_kind.to_s == 'profile'
|
|
744
941
|
return run_template_directory_session_request(
|
|
745
942
|
report_template_directory_session_profile_request(
|
|
746
943
|
profiles,
|
|
747
|
-
normalized[:profile_name] || normalized[
|
|
748
|
-
normalized[:overrides] || normalized[
|
|
944
|
+
normalized[:profile_name] || normalized['profile_name'],
|
|
945
|
+
normalized[:overrides] || normalized['overrides'] || {}
|
|
749
946
|
)
|
|
750
947
|
)
|
|
751
948
|
end
|
|
752
949
|
|
|
753
950
|
run_template_directory_session_request(
|
|
754
951
|
report_template_directory_session_options_request(
|
|
755
|
-
normalized[:options] || normalized[
|
|
952
|
+
normalized[:options] || normalized['options'] || {}
|
|
756
953
|
)
|
|
757
954
|
)
|
|
758
955
|
end
|
|
759
956
|
|
|
760
957
|
def template_directory_session_runner_request_envelope(request)
|
|
761
958
|
{
|
|
762
|
-
kind:
|
|
959
|
+
kind: 'template_directory_session_runner_request',
|
|
763
960
|
version: SESSION_RUNNER_REQUEST_TRANSPORT_VERSION,
|
|
764
961
|
request: deep_dup(request)
|
|
765
962
|
}
|
|
766
963
|
end
|
|
767
964
|
|
|
768
965
|
def import_template_directory_session_runner_request_envelope(envelope)
|
|
769
|
-
|
|
770
|
-
|
|
966
|
+
unless envelope[:kind] == 'template_directory_session_runner_request'
|
|
967
|
+
return [nil,
|
|
968
|
+
{ category: 'kind_mismatch',
|
|
969
|
+
message: 'expected template_directory_session_runner_request envelope kind.' }]
|
|
970
|
+
end
|
|
971
|
+
unless envelope[:version] == SESSION_RUNNER_REQUEST_TRANSPORT_VERSION
|
|
972
|
+
return [nil,
|
|
973
|
+
{ category: 'unsupported_version',
|
|
974
|
+
message: "unsupported template_directory_session_runner_request envelope version #{envelope[:version]}." }]
|
|
975
|
+
end
|
|
771
976
|
|
|
772
977
|
[deep_dup(envelope[:request]), nil]
|
|
773
978
|
end
|
|
774
979
|
|
|
775
980
|
def report_template_directory_session_runner_input(input)
|
|
776
981
|
normalized = deep_dup(input)
|
|
777
|
-
request_kind = (normalized[:request_kind] || normalized[
|
|
982
|
+
request_kind = (normalized[:request_kind] || normalized['request_kind']).to_s
|
|
778
983
|
options = {
|
|
779
|
-
mode: normalized[:mode] || normalized[
|
|
780
|
-
template_root: normalized[:template_root] || normalized[
|
|
781
|
-
destination_root: normalized[:destination_root] || normalized[
|
|
782
|
-
context: normalized[:context] || normalized[
|
|
783
|
-
default_strategy: normalized[:default_strategy] || normalized[
|
|
784
|
-
overrides: normalized[:overrides] || normalized[
|
|
785
|
-
replacements: normalized[:replacements] || normalized[
|
|
786
|
-
allowed_families: normalized.key?(:allowed_families) || normalized.key?(
|
|
787
|
-
|
|
984
|
+
mode: normalized[:mode] || normalized['mode'],
|
|
985
|
+
template_root: normalized[:template_root] || normalized['template_root'],
|
|
986
|
+
destination_root: normalized[:destination_root] || normalized['destination_root'],
|
|
987
|
+
context: normalized[:context] || normalized['context'] || {},
|
|
988
|
+
default_strategy: normalized[:default_strategy] || normalized['default_strategy'] || 'merge',
|
|
989
|
+
overrides: normalized[:overrides] || normalized['overrides'] || [],
|
|
990
|
+
replacements: normalized[:replacements] || normalized['replacements'] || {},
|
|
991
|
+
allowed_families: if normalized.key?(:allowed_families) || normalized.key?('allowed_families')
|
|
992
|
+
normalized[:allowed_families] || normalized['allowed_families']
|
|
993
|
+
end
|
|
788
994
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
995
|
+
if request_kind == 'profile'
|
|
996
|
+
return {
|
|
997
|
+
request_kind: 'profile',
|
|
998
|
+
profile_name: normalized[:profile_name] || normalized['profile_name'],
|
|
999
|
+
overrides: begin
|
|
1000
|
+
sparse = {
|
|
1001
|
+
mode: normalized[:mode] || normalized['mode'],
|
|
1002
|
+
template_root: normalized[:template_root] || normalized['template_root'],
|
|
1003
|
+
destination_root: normalized[:destination_root] || normalized['destination_root']
|
|
1004
|
+
}
|
|
1005
|
+
context = normalized[:context] || normalized['context']
|
|
1006
|
+
sparse[:context] = context if context.is_a?(Hash) && (context[:project_name] || context['project_name'])
|
|
1007
|
+
strategy = normalized[:default_strategy] || normalized['default_strategy']
|
|
1008
|
+
sparse[:default_strategy] = strategy if strategy && strategy != 'merge'
|
|
1009
|
+
overrides = normalized[:overrides] || normalized['overrides']
|
|
1010
|
+
sparse[:overrides] = overrides if overrides.is_a?(Array) && !overrides.empty?
|
|
1011
|
+
replacements = normalized[:replacements] || normalized['replacements']
|
|
1012
|
+
sparse[:replacements] = replacements if replacements.is_a?(Hash) && !replacements.empty?
|
|
1013
|
+
allowed_families = normalized.key?(:allowed_families) ? normalized[:allowed_families] : normalized['allowed_families']
|
|
1014
|
+
sparse[:allowed_families] = allowed_families unless allowed_families.nil?
|
|
1015
|
+
sparse
|
|
1016
|
+
end
|
|
1017
|
+
}
|
|
1018
|
+
end
|
|
811
1019
|
|
|
812
1020
|
{
|
|
813
|
-
request_kind:
|
|
1021
|
+
request_kind: 'options',
|
|
814
1022
|
options: options
|
|
815
1023
|
}
|
|
816
1024
|
end
|
|
817
1025
|
|
|
818
1026
|
def report_template_directory_session_runner_payload(payload)
|
|
819
1027
|
normalized = deep_dup(payload)
|
|
820
|
-
request_kind = normalized[:request_kind] || normalized[
|
|
1028
|
+
request_kind = normalized[:request_kind] || normalized['request_kind']
|
|
821
1029
|
request_kind = if request_kind.to_s.empty?
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
1030
|
+
if normalized.key?(:profile_name) || normalized.key?('profile_name') ||
|
|
1031
|
+
normalized.key?(:default_profile_name) || normalized.key?('default_profile_name')
|
|
1032
|
+
'profile'
|
|
1033
|
+
else
|
|
1034
|
+
'options'
|
|
1035
|
+
end
|
|
1036
|
+
else
|
|
1037
|
+
request_kind.to_s
|
|
1038
|
+
end
|
|
827
1039
|
|
|
828
1040
|
result = {
|
|
829
1041
|
request_kind: request_kind,
|
|
830
|
-
mode: normalized[:mode] || normalized[
|
|
831
|
-
template_root: normalized[:template_root] || normalized[
|
|
832
|
-
destination_root: normalized[:destination_root] || normalized[
|
|
833
|
-
context: normalized[:context] || normalized[
|
|
834
|
-
default_strategy: normalized[:default_strategy] || normalized[
|
|
835
|
-
overrides: normalized[:overrides] || normalized[
|
|
836
|
-
replacements: normalized[:replacements] || normalized[
|
|
837
|
-
allowed_families: if normalized.key?(:allowed_families) || normalized.key?(
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
nil
|
|
841
|
-
end
|
|
1042
|
+
mode: normalized[:mode] || normalized['mode'],
|
|
1043
|
+
template_root: normalized[:template_root] || normalized['template_root'],
|
|
1044
|
+
destination_root: normalized[:destination_root] || normalized['destination_root'],
|
|
1045
|
+
context: normalized[:context] || normalized['context'] || {},
|
|
1046
|
+
default_strategy: normalized[:default_strategy] || normalized['default_strategy'] || 'merge',
|
|
1047
|
+
overrides: normalized[:overrides] || normalized['overrides'] || [],
|
|
1048
|
+
replacements: normalized[:replacements] || normalized['replacements'] || {},
|
|
1049
|
+
allowed_families: if normalized.key?(:allowed_families) || normalized.key?('allowed_families')
|
|
1050
|
+
normalized.key?(:allowed_families) ? normalized[:allowed_families] : normalized['allowed_families']
|
|
1051
|
+
end
|
|
842
1052
|
}
|
|
843
|
-
profile_name = normalized[:profile_name] || normalized[
|
|
844
|
-
|
|
1053
|
+
profile_name = normalized[:profile_name] || normalized['profile_name'] ||
|
|
1054
|
+
normalized[:default_profile_name] || normalized['default_profile_name']
|
|
845
1055
|
result[:profile_name] = profile_name if profile_name
|
|
846
1056
|
result
|
|
847
1057
|
end
|
|
@@ -857,60 +1067,72 @@ module Ast
|
|
|
857
1067
|
|
|
858
1068
|
def template_directory_session_runner_payload_envelope(payload)
|
|
859
1069
|
{
|
|
860
|
-
kind:
|
|
1070
|
+
kind: 'template_directory_session_runner_payload',
|
|
861
1071
|
version: SESSION_RUNNER_PAYLOAD_TRANSPORT_VERSION,
|
|
862
1072
|
payload: deep_dup(payload)
|
|
863
1073
|
}
|
|
864
1074
|
end
|
|
865
1075
|
|
|
866
1076
|
def import_template_directory_session_runner_payload_envelope(envelope)
|
|
867
|
-
|
|
868
|
-
|
|
1077
|
+
unless envelope[:kind] == 'template_directory_session_runner_payload'
|
|
1078
|
+
return [nil,
|
|
1079
|
+
{ category: 'kind_mismatch',
|
|
1080
|
+
message: 'expected template_directory_session_runner_payload envelope kind.' }]
|
|
1081
|
+
end
|
|
1082
|
+
unless envelope[:version] == SESSION_RUNNER_PAYLOAD_TRANSPORT_VERSION
|
|
1083
|
+
return [nil,
|
|
1084
|
+
{ category: 'unsupported_version',
|
|
1085
|
+
message: "unsupported template_directory_session_runner_payload envelope version #{envelope[:version]}." }]
|
|
1086
|
+
end
|
|
869
1087
|
|
|
870
1088
|
[deep_dup(envelope[:payload]), nil]
|
|
871
1089
|
end
|
|
872
1090
|
|
|
873
1091
|
def run_template_directory_session_entrypoint(entrypoint, profiles = {})
|
|
874
1092
|
normalized = deep_dup(entrypoint)
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
1093
|
+
if normalized[:payload] || normalized['payload']
|
|
1094
|
+
return run_template_directory_session_runner_payload(
|
|
1095
|
+
normalized[:payload] || normalized['payload'],
|
|
1096
|
+
profiles
|
|
1097
|
+
)
|
|
1098
|
+
end
|
|
879
1099
|
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
1100
|
+
if normalized[:request] || normalized['request']
|
|
1101
|
+
return run_template_directory_session_runner_request(
|
|
1102
|
+
normalized[:request] || normalized['request'],
|
|
1103
|
+
profiles
|
|
1104
|
+
)
|
|
1105
|
+
end
|
|
884
1106
|
|
|
885
1107
|
report_template_directory_session_configuration_outcome(
|
|
886
|
-
|
|
887
|
-
{ mode:
|
|
1108
|
+
'plan',
|
|
1109
|
+
{ mode: 'plan', ready: false, diagnostics: [] }
|
|
888
1110
|
)
|
|
889
1111
|
end
|
|
890
1112
|
|
|
891
1113
|
def report_template_directory_session_entrypoint(entrypoint)
|
|
892
1114
|
normalized = deep_dup(entrypoint)
|
|
893
|
-
if normalized[:payload] || normalized[
|
|
1115
|
+
if normalized[:payload] || normalized['payload']
|
|
894
1116
|
return {
|
|
895
|
-
source_kind:
|
|
1117
|
+
source_kind: 'payload',
|
|
896
1118
|
runner_request: report_template_directory_session_runner_input(
|
|
897
1119
|
report_template_directory_session_runner_payload(
|
|
898
|
-
normalized[:payload] || normalized[
|
|
1120
|
+
normalized[:payload] || normalized['payload']
|
|
899
1121
|
)
|
|
900
1122
|
)
|
|
901
1123
|
}
|
|
902
1124
|
end
|
|
903
1125
|
|
|
904
|
-
if normalized[:request] || normalized[
|
|
1126
|
+
if normalized[:request] || normalized['request']
|
|
905
1127
|
return {
|
|
906
|
-
source_kind:
|
|
907
|
-
runner_request: normalized[:request] || normalized[
|
|
1128
|
+
source_kind: 'request',
|
|
1129
|
+
runner_request: normalized[:request] || normalized['request']
|
|
908
1130
|
}
|
|
909
1131
|
end
|
|
910
1132
|
|
|
911
1133
|
{
|
|
912
|
-
source_kind:
|
|
913
|
-
runner_request: { request_kind:
|
|
1134
|
+
source_kind: '',
|
|
1135
|
+
runner_request: { request_kind: 'options' }
|
|
914
1136
|
}
|
|
915
1137
|
end
|
|
916
1138
|
|
|
@@ -1000,28 +1222,36 @@ module Ast
|
|
|
1000
1222
|
|
|
1001
1223
|
def template_directory_session_inspection_envelope(inspection)
|
|
1002
1224
|
{
|
|
1003
|
-
kind:
|
|
1225
|
+
kind: 'template_directory_session_inspection',
|
|
1004
1226
|
version: SESSION_INSPECTION_TRANSPORT_VERSION,
|
|
1005
1227
|
inspection: deep_dup(inspection)
|
|
1006
1228
|
}
|
|
1007
1229
|
end
|
|
1008
1230
|
|
|
1009
1231
|
def import_template_directory_session_inspection_envelope(envelope)
|
|
1010
|
-
|
|
1011
|
-
|
|
1232
|
+
unless envelope[:kind] == 'template_directory_session_inspection'
|
|
1233
|
+
return [nil,
|
|
1234
|
+
{ category: 'kind_mismatch',
|
|
1235
|
+
message: 'expected template_directory_session_inspection envelope kind.' }]
|
|
1236
|
+
end
|
|
1237
|
+
unless envelope[:version] == SESSION_INSPECTION_TRANSPORT_VERSION
|
|
1238
|
+
return [nil,
|
|
1239
|
+
{ category: 'unsupported_version',
|
|
1240
|
+
message: "unsupported template_directory_session_inspection envelope version #{envelope[:version]}." }]
|
|
1241
|
+
end
|
|
1012
1242
|
|
|
1013
1243
|
[deep_dup(envelope[:inspection]), nil]
|
|
1014
1244
|
end
|
|
1015
1245
|
|
|
1016
1246
|
def run_template_directory_session_dispatch(operation, entrypoint, profiles = {})
|
|
1017
1247
|
case operation.to_s
|
|
1018
|
-
when
|
|
1248
|
+
when 'inspect'
|
|
1019
1249
|
{
|
|
1020
1250
|
operation: operation.to_s,
|
|
1021
1251
|
inspection: report_template_directory_session_inspection(entrypoint, profiles),
|
|
1022
1252
|
outcome: nil
|
|
1023
1253
|
}
|
|
1024
|
-
when
|
|
1254
|
+
when 'run'
|
|
1025
1255
|
{
|
|
1026
1256
|
operation: operation.to_s,
|
|
1027
1257
|
inspection: nil,
|
|
@@ -1035,10 +1265,10 @@ module Ast
|
|
|
1035
1265
|
def run_template_directory_session_command(command, profiles = {})
|
|
1036
1266
|
normalized = deep_dup(command)
|
|
1037
1267
|
run_template_directory_session_dispatch(
|
|
1038
|
-
normalized[:operation] || normalized[
|
|
1268
|
+
normalized[:operation] || normalized['operation'],
|
|
1039
1269
|
{
|
|
1040
|
-
payload: normalized[:payload] || normalized[
|
|
1041
|
-
request: normalized[:request] || normalized[
|
|
1270
|
+
payload: normalized[:payload] || normalized['payload'],
|
|
1271
|
+
request: normalized[:request] || normalized['request']
|
|
1042
1272
|
},
|
|
1043
1273
|
profiles
|
|
1044
1274
|
)
|
|
@@ -1048,19 +1278,19 @@ module Ast
|
|
|
1048
1278
|
normalized = deep_dup(command)
|
|
1049
1279
|
run_template_directory_session_command(
|
|
1050
1280
|
{
|
|
1051
|
-
operation: normalized[:operation] || normalized[
|
|
1281
|
+
operation: normalized[:operation] || normalized['operation'],
|
|
1052
1282
|
payload: {
|
|
1053
|
-
request_kind: normalized[:request_kind] || normalized[
|
|
1054
|
-
default_profile_name: normalized[:default_profile_name] || normalized[
|
|
1055
|
-
profile_name: normalized[:profile_name] || normalized[
|
|
1056
|
-
mode: normalized[:mode] || normalized[
|
|
1057
|
-
template_root: normalized[:template_root] || normalized[
|
|
1058
|
-
destination_root: normalized[:destination_root] || normalized[
|
|
1059
|
-
context: normalized[:context] || normalized[
|
|
1060
|
-
default_strategy: normalized[:default_strategy] || normalized[
|
|
1061
|
-
overrides: normalized[:overrides] || normalized[
|
|
1062
|
-
replacements: normalized[:replacements] || normalized[
|
|
1063
|
-
allowed_families: normalized.key?(:allowed_families) ? normalized[:allowed_families] : normalized[
|
|
1283
|
+
request_kind: normalized[:request_kind] || normalized['request_kind'],
|
|
1284
|
+
default_profile_name: normalized[:default_profile_name] || normalized['default_profile_name'],
|
|
1285
|
+
profile_name: normalized[:profile_name] || normalized['profile_name'],
|
|
1286
|
+
mode: normalized[:mode] || normalized['mode'],
|
|
1287
|
+
template_root: normalized[:template_root] || normalized['template_root'],
|
|
1288
|
+
destination_root: normalized[:destination_root] || normalized['destination_root'],
|
|
1289
|
+
context: normalized[:context] || normalized['context'],
|
|
1290
|
+
default_strategy: normalized[:default_strategy] || normalized['default_strategy'],
|
|
1291
|
+
overrides: normalized[:overrides] || normalized['overrides'],
|
|
1292
|
+
replacements: normalized[:replacements] || normalized['replacements'],
|
|
1293
|
+
allowed_families: normalized.key?(:allowed_families) ? normalized[:allowed_families] : normalized['allowed_families']
|
|
1064
1294
|
}
|
|
1065
1295
|
},
|
|
1066
1296
|
profiles
|
|
@@ -1069,7 +1299,7 @@ module Ast
|
|
|
1069
1299
|
|
|
1070
1300
|
def run_template_directory_session(invocation, profiles = {})
|
|
1071
1301
|
normalized = deep_dup(invocation)
|
|
1072
|
-
if normalized[:payload] || normalized[
|
|
1302
|
+
if normalized[:payload] || normalized['payload'] || normalized[:request] || normalized['request']
|
|
1073
1303
|
return run_template_directory_session_command(normalized, profiles)
|
|
1074
1304
|
end
|
|
1075
1305
|
|
|
@@ -1078,76 +1308,108 @@ module Ast
|
|
|
1078
1308
|
|
|
1079
1309
|
def template_directory_session_entrypoint_envelope(entrypoint)
|
|
1080
1310
|
{
|
|
1081
|
-
kind:
|
|
1311
|
+
kind: 'template_directory_session_entrypoint',
|
|
1082
1312
|
version: SESSION_ENTRYPOINT_TRANSPORT_VERSION,
|
|
1083
1313
|
entrypoint: deep_dup(entrypoint)
|
|
1084
1314
|
}
|
|
1085
1315
|
end
|
|
1086
1316
|
|
|
1087
1317
|
def import_template_directory_session_entrypoint_envelope(envelope)
|
|
1088
|
-
|
|
1089
|
-
|
|
1318
|
+
unless envelope[:kind] == 'template_directory_session_entrypoint'
|
|
1319
|
+
return [nil,
|
|
1320
|
+
{ category: 'kind_mismatch',
|
|
1321
|
+
message: 'expected template_directory_session_entrypoint envelope kind.' }]
|
|
1322
|
+
end
|
|
1323
|
+
unless envelope[:version] == SESSION_ENTRYPOINT_TRANSPORT_VERSION
|
|
1324
|
+
return [nil,
|
|
1325
|
+
{ category: 'unsupported_version',
|
|
1326
|
+
message: "unsupported template_directory_session_entrypoint envelope version #{envelope[:version]}." }]
|
|
1327
|
+
end
|
|
1090
1328
|
|
|
1091
1329
|
[deep_dup(envelope[:entrypoint]), nil]
|
|
1092
1330
|
end
|
|
1093
1331
|
|
|
1094
1332
|
def template_directory_session_command_envelope(command)
|
|
1095
1333
|
{
|
|
1096
|
-
kind:
|
|
1334
|
+
kind: 'template_directory_session_command',
|
|
1097
1335
|
version: SESSION_COMMAND_TRANSPORT_VERSION,
|
|
1098
1336
|
command: deep_dup(command)
|
|
1099
1337
|
}
|
|
1100
1338
|
end
|
|
1101
1339
|
|
|
1102
1340
|
def import_template_directory_session_command_envelope(envelope)
|
|
1103
|
-
|
|
1104
|
-
|
|
1341
|
+
unless envelope[:kind] == 'template_directory_session_command'
|
|
1342
|
+
return [nil,
|
|
1343
|
+
{ category: 'kind_mismatch',
|
|
1344
|
+
message: 'expected template_directory_session_command envelope kind.' }]
|
|
1345
|
+
end
|
|
1346
|
+
unless envelope[:version] == SESSION_COMMAND_TRANSPORT_VERSION
|
|
1347
|
+
return [nil,
|
|
1348
|
+
{ category: 'unsupported_version',
|
|
1349
|
+
message: "unsupported template_directory_session_command envelope version #{envelope[:version]}." }]
|
|
1350
|
+
end
|
|
1105
1351
|
|
|
1106
1352
|
[deep_dup(envelope[:command]), nil]
|
|
1107
1353
|
end
|
|
1108
1354
|
|
|
1109
1355
|
def template_directory_session_command_payload_envelope(payload)
|
|
1110
1356
|
{
|
|
1111
|
-
kind:
|
|
1357
|
+
kind: 'template_directory_session_command_payload',
|
|
1112
1358
|
version: SESSION_COMMAND_PAYLOAD_TRANSPORT_VERSION,
|
|
1113
1359
|
payload: deep_dup(payload)
|
|
1114
1360
|
}
|
|
1115
1361
|
end
|
|
1116
1362
|
|
|
1117
1363
|
def import_template_directory_session_command_payload_envelope(envelope)
|
|
1118
|
-
|
|
1119
|
-
|
|
1364
|
+
unless envelope[:kind] == 'template_directory_session_command_payload'
|
|
1365
|
+
return [nil,
|
|
1366
|
+
{ category: 'kind_mismatch',
|
|
1367
|
+
message: 'expected template_directory_session_command_payload envelope kind.' }]
|
|
1368
|
+
end
|
|
1369
|
+
unless envelope[:version] == SESSION_COMMAND_PAYLOAD_TRANSPORT_VERSION
|
|
1370
|
+
return [nil,
|
|
1371
|
+
{ category: 'unsupported_version',
|
|
1372
|
+
message: "unsupported template_directory_session_command_payload envelope version #{envelope[:version]}." }]
|
|
1373
|
+
end
|
|
1120
1374
|
|
|
1121
1375
|
[deep_dup(envelope[:payload]), nil]
|
|
1122
1376
|
end
|
|
1123
1377
|
|
|
1124
1378
|
def template_directory_session_invocation_envelope(invocation)
|
|
1125
1379
|
{
|
|
1126
|
-
kind:
|
|
1380
|
+
kind: 'template_directory_session_invocation',
|
|
1127
1381
|
version: SESSION_INVOCATION_TRANSPORT_VERSION,
|
|
1128
1382
|
invocation: deep_dup(invocation)
|
|
1129
1383
|
}
|
|
1130
1384
|
end
|
|
1131
1385
|
|
|
1132
1386
|
def import_template_directory_session_invocation_envelope(envelope)
|
|
1133
|
-
|
|
1134
|
-
|
|
1387
|
+
unless envelope[:kind] == 'template_directory_session_invocation'
|
|
1388
|
+
return [nil,
|
|
1389
|
+
{ category: 'kind_mismatch',
|
|
1390
|
+
message: 'expected template_directory_session_invocation envelope kind.' }]
|
|
1391
|
+
end
|
|
1392
|
+
unless envelope[:version] == SESSION_INVOCATION_TRANSPORT_VERSION
|
|
1393
|
+
return [nil,
|
|
1394
|
+
{ category: 'unsupported_version',
|
|
1395
|
+
message: "unsupported template_directory_session_invocation envelope version #{envelope[:version]}." }]
|
|
1396
|
+
end
|
|
1135
1397
|
|
|
1136
1398
|
[deep_dup(envelope[:invocation]), nil]
|
|
1137
1399
|
end
|
|
1138
1400
|
|
|
1139
1401
|
def report_session_request_from_runner_request(request, profiles = {})
|
|
1140
1402
|
normalized = deep_dup(request)
|
|
1141
|
-
if (normalized[:request_kind] || normalized[
|
|
1403
|
+
if (normalized[:request_kind] || normalized['request_kind']).to_s == 'profile'
|
|
1142
1404
|
return report_template_directory_session_profile_request(
|
|
1143
1405
|
profiles,
|
|
1144
|
-
normalized[:profile_name] || normalized[
|
|
1145
|
-
normalized[:overrides] || normalized[
|
|
1406
|
+
normalized[:profile_name] || normalized['profile_name'],
|
|
1407
|
+
normalized[:overrides] || normalized['overrides'] || {}
|
|
1146
1408
|
)
|
|
1147
1409
|
end
|
|
1148
1410
|
|
|
1149
1411
|
report_template_directory_session_options_request(
|
|
1150
|
-
normalized[:options] || normalized[
|
|
1412
|
+
normalized[:options] || normalized['options'] || {}
|
|
1151
1413
|
)
|
|
1152
1414
|
end
|
|
1153
1415
|
|
|
@@ -1158,22 +1420,22 @@ module Ast
|
|
|
1158
1420
|
normalized_profile = deep_dup(profile)
|
|
1159
1421
|
normalized_overrides = deep_dup(overrides)
|
|
1160
1422
|
{
|
|
1161
|
-
mode: normalized_overrides[:mode] || normalized_overrides[
|
|
1162
|
-
normalized_profile[:mode] || normalized_profile[
|
|
1163
|
-
template_root: normalized_overrides[:template_root] || normalized_overrides[
|
|
1164
|
-
destination_root: normalized_overrides[:destination_root] || normalized_overrides[
|
|
1165
|
-
context: normalized_overrides[:context] || normalized_overrides[
|
|
1166
|
-
normalized_profile[:context] || normalized_profile[
|
|
1167
|
-
default_strategy: normalized_overrides[:default_strategy] || normalized_overrides[
|
|
1168
|
-
normalized_profile[:default_strategy] || normalized_profile[
|
|
1169
|
-
overrides: normalized_overrides[:overrides] || normalized_overrides[
|
|
1170
|
-
normalized_profile[:overrides] || normalized_profile[
|
|
1171
|
-
replacements: normalized_overrides[:replacements] || normalized_overrides[
|
|
1172
|
-
normalized_profile[:replacements] || normalized_profile[
|
|
1173
|
-
allowed_families: normalized_overrides[:allowed_families] || normalized_overrides[
|
|
1174
|
-
normalized_profile[:allowed_families] || normalized_profile[
|
|
1175
|
-
config: normalized_overrides[:config] || normalized_overrides[
|
|
1176
|
-
normalized_profile[:config] || normalized_profile[
|
|
1423
|
+
mode: normalized_overrides[:mode] || normalized_overrides['mode'] ||
|
|
1424
|
+
normalized_profile[:mode] || normalized_profile['mode'],
|
|
1425
|
+
template_root: normalized_overrides[:template_root] || normalized_overrides['template_root'],
|
|
1426
|
+
destination_root: normalized_overrides[:destination_root] || normalized_overrides['destination_root'],
|
|
1427
|
+
context: normalized_overrides[:context] || normalized_overrides['context'] ||
|
|
1428
|
+
normalized_profile[:context] || normalized_profile['context'] || {},
|
|
1429
|
+
default_strategy: normalized_overrides[:default_strategy] || normalized_overrides['default_strategy'] ||
|
|
1430
|
+
normalized_profile[:default_strategy] || normalized_profile['default_strategy'],
|
|
1431
|
+
overrides: normalized_overrides[:overrides] || normalized_overrides['overrides'] ||
|
|
1432
|
+
normalized_profile[:overrides] || normalized_profile['overrides'] || [],
|
|
1433
|
+
replacements: normalized_overrides[:replacements] || normalized_overrides['replacements'] ||
|
|
1434
|
+
normalized_profile[:replacements] || normalized_profile['replacements'] || {},
|
|
1435
|
+
allowed_families: normalized_overrides[:allowed_families] || normalized_overrides['allowed_families'] ||
|
|
1436
|
+
normalized_profile[:allowed_families] || normalized_profile['allowed_families'],
|
|
1437
|
+
config: normalized_overrides[:config] || normalized_overrides['config'] ||
|
|
1438
|
+
normalized_profile[:config] || normalized_profile['config']
|
|
1177
1439
|
}
|
|
1178
1440
|
end
|
|
1179
1441
|
|
|
@@ -1191,19 +1453,71 @@ module Ast
|
|
|
1191
1453
|
|
|
1192
1454
|
private
|
|
1193
1455
|
|
|
1456
|
+
def replace_or_insert_markdown_heading_section(content, heading_text, heading_level, replacement)
|
|
1457
|
+
normalized = content.to_s.rstrip
|
|
1458
|
+
return "#{replacement}\n" if normalized.empty?
|
|
1459
|
+
|
|
1460
|
+
lines = normalized.split("\n")
|
|
1461
|
+
heading = "#{'#' * heading_level} #{heading_text}"
|
|
1462
|
+
heading_index = lines.index { |line| line.strip == heading }
|
|
1463
|
+
if heading_index
|
|
1464
|
+
section_end = lines.length
|
|
1465
|
+
((heading_index + 1)...lines.length).each do |index|
|
|
1466
|
+
level = markdown_heading_level(lines[index])
|
|
1467
|
+
if level.positive? && level <= heading_level
|
|
1468
|
+
section_end = index
|
|
1469
|
+
break
|
|
1470
|
+
end
|
|
1471
|
+
end
|
|
1472
|
+
output_lines = lines[0...heading_index] + replacement.split("\n")
|
|
1473
|
+
output_lines << '' if section_end < lines.length && lines[section_end] != ''
|
|
1474
|
+
output_lines += lines[section_end..]
|
|
1475
|
+
return "#{output_lines.join("\n")}\n"
|
|
1476
|
+
end
|
|
1477
|
+
|
|
1478
|
+
insert_at = readme_family_section_insert_index(lines)
|
|
1479
|
+
output_lines = lines[0...insert_at]
|
|
1480
|
+
output_lines << '' if output_lines.any? && output_lines.last != ''
|
|
1481
|
+
output_lines += replacement.split("\n")
|
|
1482
|
+
output_lines << '' if insert_at < lines.length && lines[insert_at] != ''
|
|
1483
|
+
output_lines += lines[insert_at..]
|
|
1484
|
+
"#{output_lines.join("\n")}\n"
|
|
1485
|
+
end
|
|
1486
|
+
|
|
1487
|
+
def markdown_heading_level(line)
|
|
1488
|
+
match = line.to_s.strip.match(/\A(#+)\s/)
|
|
1489
|
+
match && match[1].length <= 6 ? match[1].length : 0
|
|
1490
|
+
end
|
|
1491
|
+
|
|
1492
|
+
def readme_family_section_insert_index(lines)
|
|
1493
|
+
index = 0
|
|
1494
|
+
if markdown_heading_level(lines[0]) == 1
|
|
1495
|
+
index = 1
|
|
1496
|
+
index += 1 while index < lines.length && lines[index] == ''
|
|
1497
|
+
end
|
|
1498
|
+
while index < lines.length
|
|
1499
|
+
if lines[index] == ''
|
|
1500
|
+
index += 1 while index < lines.length && lines[index] == ''
|
|
1501
|
+
return index
|
|
1502
|
+
end
|
|
1503
|
+
index += 1
|
|
1504
|
+
end
|
|
1505
|
+
lines.length
|
|
1506
|
+
end
|
|
1507
|
+
|
|
1194
1508
|
def deep_dup(value)
|
|
1195
1509
|
Ast::Merge.deep_dup(value)
|
|
1196
1510
|
end
|
|
1197
1511
|
|
|
1198
1512
|
def normalize_session_mode(mode)
|
|
1199
1513
|
normalized_mode = mode.to_s
|
|
1200
|
-
MODES.include?(normalized_mode) ? normalized_mode :
|
|
1514
|
+
MODES.include?(normalized_mode) ? normalized_mode : 'plan'
|
|
1201
1515
|
end
|
|
1202
1516
|
|
|
1203
1517
|
def compact_session_request_options(options)
|
|
1204
1518
|
normalized = deep_dup(options)
|
|
1205
1519
|
normalized.delete(:config)
|
|
1206
|
-
normalized.delete(
|
|
1520
|
+
normalized.delete('config')
|
|
1207
1521
|
normalized
|
|
1208
1522
|
end
|
|
1209
1523
|
end
|