bolt 2.40.2 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Puppetfile +19 -17
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +25 -0
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +6 -8
- data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +7 -3
- data/lib/bolt/analytics.rb +3 -2
- data/lib/bolt/applicator.rb +11 -1
- data/lib/bolt/bolt_option_parser.rb +3 -113
- data/lib/bolt/catalog.rb +10 -29
- data/lib/bolt/cli.rb +54 -155
- data/lib/bolt/config.rb +62 -239
- data/lib/bolt/config/options.rb +58 -97
- data/lib/bolt/config/transport/local.rb +1 -0
- data/lib/bolt/config/transport/options.rb +8 -1
- data/lib/bolt/config/transport/orch.rb +1 -0
- data/lib/bolt/executor.rb +15 -5
- data/lib/bolt/inventory.rb +3 -2
- data/lib/bolt/inventory/group.rb +35 -4
- data/lib/bolt/inventory/inventory.rb +1 -1
- data/lib/bolt/logger.rb +115 -11
- data/lib/bolt/module.rb +10 -2
- data/lib/bolt/module_installer.rb +4 -2
- data/lib/bolt/module_installer/resolver.rb +65 -12
- data/lib/bolt/module_installer/specs/forge_spec.rb +8 -2
- data/lib/bolt/module_installer/specs/git_spec.rb +17 -2
- data/lib/bolt/outputter/human.rb +9 -5
- data/lib/bolt/outputter/json.rb +16 -16
- data/lib/bolt/outputter/rainbow.rb +3 -3
- data/lib/bolt/pal.rb +94 -14
- data/lib/bolt/pal/yaml_plan.rb +8 -2
- data/lib/bolt/pal/yaml_plan/evaluator.rb +7 -19
- data/lib/bolt/pal/yaml_plan/step.rb +3 -24
- data/lib/bolt/pal/yaml_plan/step/upload.rb +2 -2
- data/lib/bolt/pal/yaml_plan/transpiler.rb +6 -1
- data/lib/bolt/plugin.rb +3 -3
- data/lib/bolt/plugin/cache.rb +7 -7
- data/lib/bolt/plugin/module.rb +0 -23
- data/lib/bolt/plugin/puppet_connect_data.rb +77 -0
- data/lib/bolt/plugin/puppetdb.rb +1 -1
- data/lib/bolt/project.rb +54 -81
- data/lib/bolt/project_manager.rb +4 -3
- data/lib/bolt/project_manager/module_migrator.rb +6 -5
- data/lib/bolt/rerun.rb +1 -1
- data/lib/bolt/result.rb +6 -1
- data/lib/bolt/shell/bash.rb +9 -4
- data/lib/bolt/shell/bash/tmpdir.rb +4 -1
- data/lib/bolt/shell/powershell.rb +9 -5
- data/lib/bolt/shell/powershell/snippets.rb +37 -150
- data/lib/bolt/task.rb +1 -1
- data/lib/bolt/transport/base.rb +0 -9
- data/lib/bolt/transport/docker.rb +1 -125
- data/lib/bolt/transport/docker/connection.rb +86 -161
- data/lib/bolt/transport/local.rb +1 -9
- data/lib/bolt/transport/orch/connection.rb +1 -1
- data/lib/bolt/transport/ssh.rb +1 -2
- data/lib/bolt/transport/ssh/connection.rb +1 -1
- data/lib/bolt/validator.rb +2 -2
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/config.rb +1 -1
- data/lib/bolt_server/transport_app.rb +48 -31
- data/lib/bolt_spec/bolt_context.rb +9 -4
- data/lib/bolt_spec/plans.rb +1 -109
- data/libexec/bolt_catalog +1 -1
- data/modules/aggregate/plans/count.pp +21 -0
- data/modules/aggregate/plans/targets.pp +21 -0
- data/modules/puppet_connect/plans/test_input_data.pp +67 -0
- data/modules/puppetdb_fact/plans/init.pp +10 -0
- metadata +28 -19
- data/modules/aggregate/plans/nodes.pp +0 -36
@@ -63,12 +63,12 @@ module Bolt
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def start_spin
|
66
|
-
return unless @spin && @stream.isatty
|
67
|
-
@
|
66
|
+
return unless @spin && @stream.isatty && !@spinning
|
67
|
+
@spinning = true
|
68
68
|
@spin_thread = Thread.new do
|
69
69
|
loop do
|
70
|
-
@stream.print(colorize(:rainbow, @pinwheel.rotate!.first + "\b"))
|
71
70
|
sleep(0.1)
|
71
|
+
@stream.print(colorize(:rainbow, @pinwheel.rotate!.first + "\b"))
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
data/lib/bolt/pal.rb
CHANGED
@@ -153,8 +153,10 @@ module Bolt
|
|
153
153
|
Dir.children(path).select { |name| Puppet::Module.is_module_directory?(name, path) }
|
154
154
|
end
|
155
155
|
if modules.include?(project.name)
|
156
|
-
Bolt::Logger.warn_once(
|
157
|
-
|
156
|
+
Bolt::Logger.warn_once(
|
157
|
+
"project_shadows_module",
|
158
|
+
"The project '#{project.name}' shadows an existing module of the same name"
|
159
|
+
)
|
158
160
|
end
|
159
161
|
end
|
160
162
|
|
@@ -213,6 +215,7 @@ module Bolt
|
|
213
215
|
def with_bolt_executor(executor, inventory, pdb_client = nil, applicator = nil, &block)
|
214
216
|
setup
|
215
217
|
opts = {
|
218
|
+
bolt_project: @project,
|
216
219
|
bolt_executor: executor,
|
217
220
|
bolt_inventory: inventory,
|
218
221
|
bolt_pdb_client: pdb_client,
|
@@ -357,19 +360,52 @@ module Bolt
|
|
357
360
|
Bolt::Task.from_task_signature(task)
|
358
361
|
end
|
359
362
|
|
363
|
+
def list_plans_with_cache(filter_content: false)
|
364
|
+
# Don't filter content yet, so that if users update their plan filters
|
365
|
+
# we don't need to refresh the cache
|
366
|
+
plan_names = list_plans(filter_content: false).map(&:first)
|
367
|
+
plan_cache = if @project
|
368
|
+
Bolt::Util.read_optional_json_file(@project.plan_cache_file, 'Plan cache file')
|
369
|
+
else
|
370
|
+
{}
|
371
|
+
end
|
372
|
+
updated = false
|
373
|
+
|
374
|
+
plan_list = plan_names.each_with_object([]) do |plan_name, list|
|
375
|
+
info = plan_cache[plan_name] || get_plan_info(plan_name, with_mtime: true)
|
376
|
+
|
377
|
+
# If the plan is a 'local' plan (in the project itself, or the
|
378
|
+
# modules/ directory) then verify it hasn't been updated since we
|
379
|
+
# cached it. If it has been updated, refresh the cache and use the
|
380
|
+
# new data.
|
381
|
+
if info['file'] &&
|
382
|
+
(File.mtime(info.dig('file', 'path')) <=> info.dig('file', 'mtime')) != 0
|
383
|
+
info = get_plan_info(plan_name, with_mtime: true)
|
384
|
+
updated = true
|
385
|
+
plan_cache[plan_name] = info
|
386
|
+
end
|
387
|
+
|
388
|
+
list << [plan_name] unless info['private']
|
389
|
+
end
|
390
|
+
|
391
|
+
File.write(@project.plan_cache_file, plan_cache.to_json) if updated
|
392
|
+
|
393
|
+
filter_content ? filter_content(plan_list, @project&.plans) : plan_list
|
394
|
+
end
|
395
|
+
|
360
396
|
def list_plans(filter_content: false)
|
361
397
|
in_bolt_compiler do |compiler|
|
362
398
|
errors = []
|
363
399
|
plans = compiler.list_plans(nil, errors).map { |plan| [plan.name] }.sort
|
364
400
|
errors.each do |error|
|
365
|
-
|
401
|
+
Bolt::Logger.warn("plan_load_error", error.details['original_error'])
|
366
402
|
end
|
367
403
|
|
368
404
|
filter_content ? filter_content(plans, @project&.plans) : plans
|
369
405
|
end
|
370
406
|
end
|
371
407
|
|
372
|
-
def get_plan_info(plan_name)
|
408
|
+
def get_plan_info(plan_name, with_mtime: false)
|
373
409
|
plan_sig = in_bolt_compiler do |compiler|
|
374
410
|
compiler.plan_signature(plan_name)
|
375
411
|
end
|
@@ -412,16 +448,28 @@ module Bolt
|
|
412
448
|
params[name]['default_value'] = defaults[name] if defaults.key?(name)
|
413
449
|
params[name]['description'] = param.text unless param.text.empty?
|
414
450
|
else
|
415
|
-
|
451
|
+
Bolt::Logger.warn(
|
452
|
+
"missing_plan_parameter",
|
453
|
+
"The documented parameter '#{name}' does not exist in signature for plan '#{plan.name}'"
|
454
|
+
)
|
416
455
|
end
|
417
456
|
end
|
418
457
|
|
419
|
-
|
420
|
-
|
458
|
+
privie = plan.tag(:private)&.text
|
459
|
+
unless privie.nil? || %w[true false].include?(privie.downcase)
|
460
|
+
msg = "Plan #{plan_name} key 'private' must be a boolean, received: #{privie}"
|
461
|
+
raise Bolt::Error.new(msg, 'bolt/invalid-plan')
|
462
|
+
end
|
463
|
+
|
464
|
+
pp_info = {
|
465
|
+
'name' => plan_name,
|
421
466
|
'description' => description,
|
422
|
-
'parameters'
|
423
|
-
'module'
|
467
|
+
'parameters' => parameters,
|
468
|
+
'module' => mod
|
424
469
|
}
|
470
|
+
pp_info.merge!({ 'private' => privie&.downcase == 'true' }) unless privie.nil?
|
471
|
+
pp_info.merge!(get_plan_mtime(plan.file)) if with_mtime
|
472
|
+
pp_info
|
425
473
|
|
426
474
|
# If it's a YAML plan, fall back to limited data
|
427
475
|
else
|
@@ -444,12 +492,32 @@ module Bolt
|
|
444
492
|
params[name]['default_value'] = param.value unless param.value.nil?
|
445
493
|
params[name]['description'] = param.description if param.description
|
446
494
|
end
|
447
|
-
|
448
|
-
|
495
|
+
|
496
|
+
yaml_info = {
|
497
|
+
'name' => plan_name,
|
449
498
|
'description' => plan.description,
|
450
|
-
'parameters'
|
451
|
-
'module'
|
499
|
+
'parameters' => parameters,
|
500
|
+
'module' => mod
|
452
501
|
}
|
502
|
+
yaml_info.merge!({ 'private' => plan.private }) unless plan.private.nil?
|
503
|
+
yaml_info.merge!(get_plan_mtime(yaml_path)) if with_mtime
|
504
|
+
yaml_info
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
def get_plan_mtime(path)
|
509
|
+
# If the plan is from the project modules/ directory, or is in the
|
510
|
+
# project itself, include the last mtime of the file so we can compare
|
511
|
+
# if the plan has been updated since it was cached.
|
512
|
+
if @project &&
|
513
|
+
File.exist?(path) &&
|
514
|
+
(path.include?(File.join(@project.path, 'modules')) ||
|
515
|
+
path.include?(@project.plans_path.to_s))
|
516
|
+
|
517
|
+
{ 'file' => { 'mtime' => File.mtime(path),
|
518
|
+
'path' => path } }
|
519
|
+
else
|
520
|
+
{}
|
453
521
|
end
|
454
522
|
end
|
455
523
|
|
@@ -490,16 +558,28 @@ module Bolt
|
|
490
558
|
end
|
491
559
|
end
|
492
560
|
|
493
|
-
def generate_types
|
561
|
+
def generate_types(cache: false)
|
494
562
|
require 'puppet/face/generate'
|
495
563
|
in_bolt_compiler do
|
496
564
|
generator = Puppet::Generate::Type
|
497
565
|
inputs = generator.find_inputs(:pcore)
|
498
566
|
FileUtils.mkdir_p(@resource_types)
|
567
|
+
cache_plan_info if @project && cache
|
499
568
|
generator.generate(inputs, @resource_types, true)
|
500
569
|
end
|
501
570
|
end
|
502
571
|
|
572
|
+
def cache_plan_info
|
573
|
+
# plan_name is an array here
|
574
|
+
plans_info = list_plans(filter_content: false).map do |plan_name,|
|
575
|
+
data = get_plan_info(plan_name, with_mtime: true)
|
576
|
+
{ plan_name => data }
|
577
|
+
end.reduce({}, :merge)
|
578
|
+
|
579
|
+
FileUtils.touch(@project.plan_cache_file)
|
580
|
+
File.write(@project.plan_cache_file, plans_info.to_json)
|
581
|
+
end
|
582
|
+
|
503
583
|
def run_task(task_name, targets, params, executor, inventory, description = nil)
|
504
584
|
in_task_compiler(executor, inventory) do |compiler|
|
505
585
|
params = params.merge('_bolt_api_call' => true, '_catch_errors' => true)
|
data/lib/bolt/pal/yaml_plan.rb
CHANGED
@@ -6,10 +6,10 @@ require 'bolt/pal/yaml_plan/step'
|
|
6
6
|
module Bolt
|
7
7
|
class PAL
|
8
8
|
class YamlPlan
|
9
|
-
PLAN_KEYS = Set['parameters', 'steps', 'return', 'version', 'description']
|
9
|
+
PLAN_KEYS = Set['parameters', 'private', 'steps', 'return', 'version', 'description']
|
10
10
|
VAR_NAME_PATTERN = /\A[a-z_][a-z0-9_]*\z/.freeze
|
11
11
|
|
12
|
-
attr_reader :name, :parameters, :steps, :return, :description
|
12
|
+
attr_reader :name, :parameters, :private, :steps, :return, :description
|
13
13
|
|
14
14
|
def initialize(name, plan)
|
15
15
|
# Top-level plan keys aren't allowed to be Puppet code, so force them
|
@@ -30,6 +30,12 @@ module Bolt
|
|
30
30
|
Parameter.new(param, definition)
|
31
31
|
end.freeze
|
32
32
|
|
33
|
+
@private = plan['private']
|
34
|
+
unless @private.nil? || @private.is_a?(TrueClass) || @private.is_a?(FalseClass)
|
35
|
+
msg = "Plan #{@name} key 'private' must be a boolean, received: #{@private.inspect}"
|
36
|
+
raise Bolt::Error.new(msg, "bolt/invalid-plan")
|
37
|
+
end
|
38
|
+
|
33
39
|
# Validate top level plan keys
|
34
40
|
top_level_keys = plan.keys.to_set
|
35
41
|
unless PLAN_KEYS.superset?(top_level_keys)
|
@@ -24,7 +24,7 @@ module Bolt
|
|
24
24
|
|
25
25
|
def task_step(scope, step)
|
26
26
|
task = step['task']
|
27
|
-
targets = step['targets']
|
27
|
+
targets = step['targets']
|
28
28
|
description = step['description']
|
29
29
|
params = step['parameters'] || {}
|
30
30
|
|
@@ -48,7 +48,7 @@ module Bolt
|
|
48
48
|
|
49
49
|
def script_step(scope, step)
|
50
50
|
script = step['script']
|
51
|
-
targets = step['targets']
|
51
|
+
targets = step['targets']
|
52
52
|
description = step['description']
|
53
53
|
arguments = step['arguments'] || []
|
54
54
|
|
@@ -64,7 +64,7 @@ module Bolt
|
|
64
64
|
|
65
65
|
def command_step(scope, step)
|
66
66
|
command = step['command']
|
67
|
-
targets = step['targets']
|
67
|
+
targets = step['targets']
|
68
68
|
description = step['description']
|
69
69
|
|
70
70
|
args = [command, targets]
|
@@ -73,9 +73,9 @@ module Bolt
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def upload_step(scope, step)
|
76
|
-
source = step['upload']
|
76
|
+
source = step['upload']
|
77
77
|
destination = step['destination']
|
78
|
-
targets = step['targets']
|
78
|
+
targets = step['targets']
|
79
79
|
description = step['description']
|
80
80
|
|
81
81
|
args = [source, destination, targets]
|
@@ -86,7 +86,7 @@ module Bolt
|
|
86
86
|
def download_step(scope, step)
|
87
87
|
source = step['download']
|
88
88
|
destination = step['destination']
|
89
|
-
targets = step['targets']
|
89
|
+
targets = step['targets']
|
90
90
|
description = step['description']
|
91
91
|
|
92
92
|
args = [source, destination, targets]
|
@@ -99,7 +99,7 @@ module Bolt
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def resources_step(scope, step)
|
102
|
-
targets = step['targets']
|
102
|
+
targets = step['targets']
|
103
103
|
|
104
104
|
# TODO: Only call apply_prep when needed
|
105
105
|
scope.call_function('apply_prep', targets)
|
@@ -154,18 +154,6 @@ module Bolt
|
|
154
154
|
# This is the method that Puppet calls to evaluate the plan. The name
|
155
155
|
# makes more sense for .pp plans.
|
156
156
|
def evaluate_block_with_bindings(closure_scope, args_hash, plan)
|
157
|
-
if plan.steps.any? { |step| step.body.key?('target') }
|
158
|
-
msg = "The 'target' parameter for YAML plan steps is deprecated and will be removed "\
|
159
|
-
"in a future version of Bolt. Use the 'targets' parameter instead."
|
160
|
-
Bolt::Logger.deprecation_warning("Using 'target' parameter for YAML plan steps, not 'targets'", msg)
|
161
|
-
end
|
162
|
-
|
163
|
-
if plan.steps.any? { |step| step.body.key?('source') }
|
164
|
-
msg = "The 'source' parameter for YAML plan upload steps is deprecated and will be removed "\
|
165
|
-
"in a future version of Bolt. Use the 'upload' parameter instead."
|
166
|
-
Bolt::Logger.deprecation_warning("Using 'source' parameter for YAML upload steps, not 'upload'", msg)
|
167
|
-
end
|
168
|
-
|
169
157
|
plan_result = closure_scope.with_local_scope(args_hash) do |scope|
|
170
158
|
plan.steps.each do |step|
|
171
159
|
step_result = dispatch_step(scope, step)
|
@@ -9,19 +9,17 @@ module Bolt
|
|
9
9
|
attr_reader :name, :type, :body, :targets
|
10
10
|
|
11
11
|
def self.allowed_keys
|
12
|
-
Set['name', 'description', '
|
12
|
+
Set['name', 'description', 'targets']
|
13
13
|
end
|
14
14
|
|
15
15
|
STEP_KEYS = %w[
|
16
16
|
command
|
17
|
-
destination
|
18
17
|
download
|
19
18
|
eval
|
20
19
|
message
|
21
20
|
plan
|
22
21
|
resources
|
23
22
|
script
|
24
|
-
source
|
25
23
|
task
|
26
24
|
upload
|
27
25
|
].freeze
|
@@ -34,13 +32,7 @@ module Bolt
|
|
34
32
|
when 1
|
35
33
|
type = type_keys.first
|
36
34
|
else
|
37
|
-
|
38
|
-
type = 'upload'
|
39
|
-
elsif type_keys.to_set == Set['download', 'destination']
|
40
|
-
type = 'download'
|
41
|
-
else
|
42
|
-
raise step_error("Multiple action keys detected: #{type_keys.inspect}", step_body['name'], step_number)
|
43
|
-
end
|
35
|
+
raise step_error("Multiple action keys detected: #{type_keys.inspect}", step_body['name'], step_number)
|
44
36
|
end
|
45
37
|
|
46
38
|
step_class = const_get("Bolt::PAL::YamlPlan::Step::#{type.capitalize}")
|
@@ -51,7 +43,7 @@ module Bolt
|
|
51
43
|
def initialize(step_body)
|
52
44
|
@name = step_body['name']
|
53
45
|
@description = step_body['description']
|
54
|
-
@targets = step_body['targets']
|
46
|
+
@targets = step_body['targets']
|
55
47
|
@body = step_body
|
56
48
|
end
|
57
49
|
|
@@ -96,19 +88,6 @@ module Bolt
|
|
96
88
|
# Ensure all required keys are present
|
97
89
|
missing_keys = required_keys - body.keys
|
98
90
|
|
99
|
-
# Handle cases where steps with a required 'targets' key are using the deprecated
|
100
|
-
# 'target' key instead.
|
101
|
-
# TODO: Remove this when 'target' is removed
|
102
|
-
if body.include?('target')
|
103
|
-
missing_keys -= ['targets']
|
104
|
-
end
|
105
|
-
|
106
|
-
# Handle cases where upload step uses deprecated 'source' key instead of 'upload'
|
107
|
-
# TODO: Remove when 'source' is removed
|
108
|
-
if body.include?('source')
|
109
|
-
missing_keys -= ['upload']
|
110
|
-
end
|
111
|
-
|
112
91
|
if missing_keys.any?
|
113
92
|
error_message = "The #{step_type.inspect} step requires: #{missing_keys.to_a.inspect} key(s)"
|
114
93
|
err = step_error(error_message, body['name'], step_number)
|
@@ -6,7 +6,7 @@ module Bolt
|
|
6
6
|
class Step
|
7
7
|
class Upload < Step
|
8
8
|
def self.allowed_keys
|
9
|
-
super + Set['
|
9
|
+
super + Set['destination', 'upload']
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.required_keys
|
@@ -15,7 +15,7 @@ module Bolt
|
|
15
15
|
|
16
16
|
def initialize(step_body)
|
17
17
|
super
|
18
|
-
@source = step_body['upload']
|
18
|
+
@source = step_body['upload']
|
19
19
|
@destination = step_body['destination']
|
20
20
|
end
|
21
21
|
|
@@ -30,6 +30,7 @@ module Bolt
|
|
30
30
|
plan_string = String.new('')
|
31
31
|
plan_string << "# #{plan_object.description}\n" if plan_object.description
|
32
32
|
plan_string << "# WARNING: This is an autogenerated plan. It may not behave as expected.\n"
|
33
|
+
plan_string << "# @private #{plan_object.private}\n" unless plan_object.private.nil?
|
33
34
|
plan_string << "#{param_descriptions}\n" unless param_descriptions.empty?
|
34
35
|
|
35
36
|
plan_string << "plan #{plan_object.name}("
|
@@ -64,7 +65,11 @@ module Bolt
|
|
64
65
|
raise Bolt::FileError.new(msg, @plan_path)
|
65
66
|
end
|
66
67
|
|
67
|
-
|
68
|
+
begin
|
69
|
+
Bolt::PAL::YamlPlan::Loader.from_string(@modulename, file_contents, @plan_path)
|
70
|
+
rescue Puppet::PreformattedError, StandardError => e
|
71
|
+
raise PALError.from_preformatted_error(e)
|
72
|
+
end
|
68
73
|
end
|
69
74
|
|
70
75
|
def validate_path
|
data/lib/bolt/plugin.rb
CHANGED
@@ -139,7 +139,7 @@ module Bolt
|
|
139
139
|
plugins
|
140
140
|
end
|
141
141
|
|
142
|
-
RUBY_PLUGINS = %w[task prompt env_var puppetdb].freeze
|
142
|
+
RUBY_PLUGINS = %w[task prompt env_var puppetdb puppet_connect_data].freeze
|
143
143
|
BUILTIN_PLUGINS = %w[task terraform pkcs7 prompt vault aws_inventory puppetdb azure_inventory
|
144
144
|
yaml env_var gcloud_inventory].freeze
|
145
145
|
DEFAULT_PLUGIN_HOOKS = { 'puppet_library' => { 'plugin' => 'puppet_agent', 'stop_service' => true } }.freeze
|
@@ -170,7 +170,7 @@ module Bolt
|
|
170
170
|
end
|
171
171
|
|
172
172
|
def modules
|
173
|
-
@modules ||= Bolt::Module.discover(@pal.full_modulepath)
|
173
|
+
@modules ||= Bolt::Module.discover(@pal.full_modulepath, @config.project)
|
174
174
|
end
|
175
175
|
|
176
176
|
def add_plugin(plugin)
|
@@ -297,7 +297,7 @@ module Bolt
|
|
297
297
|
def resolve_single_reference(reference)
|
298
298
|
plugin_cache = if cache?(reference)
|
299
299
|
cache = Bolt::Plugin::Cache.new(reference,
|
300
|
-
@config.project.
|
300
|
+
@config.project.plugin_cache_file,
|
301
301
|
@config.plugin_cache)
|
302
302
|
entry = cache.read_and_clean_cache
|
303
303
|
return entry unless entry.nil?
|
data/lib/bolt/plugin/cache.rb
CHANGED
@@ -7,11 +7,11 @@ require 'bolt/util'
|
|
7
7
|
module Bolt
|
8
8
|
class Plugin
|
9
9
|
class Cache
|
10
|
-
attr_reader :reference, :
|
10
|
+
attr_reader :reference, :plugin_cache_file, :default_config, :id
|
11
11
|
|
12
|
-
def initialize(reference,
|
12
|
+
def initialize(reference, plugin_cache_file, default_config)
|
13
13
|
@reference = reference
|
14
|
-
@
|
14
|
+
@plugin_cache_file = plugin_cache_file
|
15
15
|
@default_config = default_config
|
16
16
|
end
|
17
17
|
|
@@ -32,21 +32,21 @@ module Bolt
|
|
32
32
|
unmodified = false if expired
|
33
33
|
expired
|
34
34
|
end
|
35
|
-
File.write(
|
35
|
+
File.write(plugin_cache_file, cache.to_json) unless cache.empty? || unmodified
|
36
36
|
|
37
37
|
cache.dig(id, 'result')
|
38
38
|
end
|
39
39
|
|
40
40
|
private def cache
|
41
|
-
@cache ||= Bolt::Util.read_optional_json_file(@
|
41
|
+
@cache ||= Bolt::Util.read_optional_json_file(@plugin_cache_file, 'cache')
|
42
42
|
end
|
43
43
|
|
44
44
|
def write_cache(result)
|
45
45
|
cache.merge!({ id => { 'result' => result,
|
46
46
|
'mtime' => Time.now,
|
47
47
|
'ttl' => ttl } })
|
48
|
-
FileUtils.touch(
|
49
|
-
File.write(
|
48
|
+
FileUtils.touch(plugin_cache_file)
|
49
|
+
File.write(plugin_cache_file, cache.to_json)
|
50
50
|
end
|
51
51
|
|
52
52
|
def validate
|