Module: Bolt::PlanCreator

Defined in:
lib/bolt/plan_creator.rb

Class Method Summary collapse

Class Method Details

.create_plan(plans_path, plan_name, is_puppet: false, script: nil) ⇒ Object

Create a new plan from the plan templates based on which language the user configured, and whether the plan wraps a script.

Parameters:

  • plans_path (string)

    The path to the new plan

  • plan_name (string)

    The name of the new plan

  • is_puppet (boolean) (defaults to: false)

    Whether to create a Puppet language plan

  • script (string) (defaults to: nil)

    A reference to a script for the new plan to run

[View source]

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/bolt/plan_creator.rb', line 62

def self.create_plan(plans_path, plan_name, is_puppet: false, script: nil)
  _, name_segments, basename = segment_plan_name(plan_name)
  dir_path = plans_path.join(*name_segments)

  begin
    FileUtils.mkdir_p(dir_path)
  rescue Errno::EEXIST => e
    raise Bolt::Error.new(
      "#{e.message}; unable to create plan directory '#{dir_path}'",
      'bolt/existing-file-error'
    )
  end

  type = is_puppet ? 'pp' : 'yaml'
  plan_path = dir_path + "#{basename}.#{type}"
  plan_template = if is_puppet && script
                    puppet_script_plan(plan_name, script)
                  elsif is_puppet
                    puppet_plan(plan_name)
                  elsif script
                    yaml_script_plan(script)
                  else
                    yaml_plan(plan_name)
                  end
  begin
    File.write(plan_path, plan_template)
  rescue Errno::EACCES => e
    raise Bolt::FileError.new(
      "#{e.message}; unable to create plan",
      plan_path
    )
  end

  { name: plan_name, path: plan_path }
end

.segment_plan_name(plan_name) ⇒ Object

[View source]

98
99
100
101
102
103
104
105
106
# File 'lib/bolt/plan_creator.rb', line 98

def self.segment_plan_name(plan_name)
  prefix, *name_segments, basename = plan_name.split('::')

  # If the plan name is just the project name, then create an 'init' plan.
  # Otherwise, use the last name segment for the plan's filename.
  basename ||= 'init'

  [prefix, name_segments, basename]
end

.validate_plan_name(project, plan_name) ⇒ Object

[View source]

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/bolt/plan_creator.rb', line 10

def self.validate_plan_name(project, plan_name)
  if project.name.nil?
    raise Bolt::Error.new(
      "Project directory '#{project.path}' is not a named project. Unable to create "\
      "a project-level plan. To name a project, set the 'name' key in the 'bolt-project.yaml' "\
      "configuration file.",
      "bolt/unnamed-project-error"
    )
  end

  if plan_name !~ Bolt::Module::CONTENT_NAME_REGEX
    message = <<~MESSAGE.chomp
      Invalid plan name '#{plan_name}'. Plan names are composed of one or more name segments
      separated by double colons '::'.

      Each name segment must begin with a lowercase letter, and can only include lowercase
      letters, digits, and underscores.

      Examples of valid plan names:
          - #{project.name}
          - #{project.name}::my_plan
    MESSAGE

    raise Bolt::ValidationError, message
  end

  prefix, _, basename = segment_plan_name(plan_name)

  unless prefix == project.name
    message = "Incomplete plan name: A plan name must be prefixed with the name of the "\
      "project or module. Did you mean '#{project.name}::#{plan_name}'?"

    raise Bolt::ValidationError, message
  end

  %w[pp yaml].each do |ext|
    next unless (path = project.plans_path + "#{basename}.#{ext}").exist?
    raise Bolt::Error.new(
      "A plan with the name '#{plan_name}' already exists at '#{path}', nothing to do.",
      'bolt/existing-plan-error'
    )
  end
end