Module: Puppet::ModuleTool

Extended by:
Util::Colors
Defined in:
lib/puppet/module_tool.rb,
lib/puppet/module_tool/errors.rb,
lib/puppet/module_tool/metadata.rb,
lib/puppet/module_tool/checksums.rb,
lib/puppet/module_tool/dependency.rb,
lib/puppet/module_tool/applications.rb,
lib/puppet/module_tool/local_tarball.rb,
lib/puppet/module_tool/install_directory.rb,
lib/puppet/module_tool/installed_modules.rb,
lib/puppet/module_tool/contents_description.rb,
lib/puppet/module_tool/applications/searcher.rb,
lib/puppet/module_tool/applications/unpacker.rb,
lib/puppet/module_tool/applications/upgrader.rb,
lib/puppet/module_tool/applications/installer.rb,
lib/puppet/module_tool/applications/application.rb,
lib/puppet/module_tool/applications/checksummer.rb,
lib/puppet/module_tool/applications/uninstaller.rb

Defined Under Namespace

Modules: Applications, Errors, Shared, Tar Classes: Checksums, ContentsDescription, Dependency, InstallDirectory, InstalledModules, LocalTarball, Metadata

Constant Summary collapse

ARTIFACTS =

Directory and names that should not be checksummed.

['pkg', /^\./, /^~/, /^#/, 'coverage', 'checksums.json', 'REVISION']
FULL_MODULE_NAME_PATTERN =
/\A([^-\/|.]+)[-|\/](.+)\z/
REPOSITORY_URL =
Puppet.settings[:module_repository]

Constants included from Util::Colors

Util::Colors::BG_BLUE, Util::Colors::BG_CYAN, Util::Colors::BG_GREEN, Util::Colors::BG_HBLUE, Util::Colors::BG_HCYAN, Util::Colors::BG_HGREEN, Util::Colors::BG_HMAGENTA, Util::Colors::BG_HRED, Util::Colors::BG_HWHITE, Util::Colors::BG_HYELLOW, Util::Colors::BG_MAGENTA, Util::Colors::BG_RED, Util::Colors::BG_WHITE, Util::Colors::BG_YELLOW, Util::Colors::BLACK, Util::Colors::BLUE, Util::Colors::CYAN, Util::Colors::Colormap, Util::Colors::GREEN, Util::Colors::HBLACK, Util::Colors::HBLUE, Util::Colors::HCYAN, Util::Colors::HGREEN, Util::Colors::HMAGENTA, Util::Colors::HRED, Util::Colors::HWHITE, Util::Colors::HYELLOW, Util::Colors::MAGENTA, Util::Colors::RED, Util::Colors::RESET, Util::Colors::WHITE, Util::Colors::YELLOW

Class Method Summary collapse

Methods included from Util::Colors

colorize, console_color, html_color

Class Method Details

.artifact?(path) ⇒ Boolean

Is this a directory that shouldn't be checksummed?

TODO: Should this be part of Checksums? TODO: Rename this method to reflect its purpose? TODO: Shouldn't this be used when building packages too?

Returns:

  • (Boolean)

22
23
24
25
26
27
28
29
# File 'lib/puppet/module_tool.rb', line 22

def self.artifact?(path)
  case File.basename(path)
  when *ARTIFACTS
    true
  else
    false
  end
end

.build_tree(mods, dir) ⇒ Object


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/puppet/module_tool.rb', line 91

def self.build_tree(mods, dir)
  mods.each do |mod|
    version_string = mod[:version].to_s.sub(/^(?!v)/, 'v')

    if mod[:action] == :upgrade
      previous_version = mod[:previous_version].to_s.sub(/^(?!v)/, 'v')
      version_string = "#{previous_version} -> #{version_string}"
    end

    mod[:text] = "#{mod[:name]} (#{colorize(:cyan, version_string)})"
    mod[:text] += " [#{mod[:path]}]" unless mod[:path].to_s == dir.to_s

    deps = (mod[:dependencies] || [])
    deps.sort! { |a, b| a[:name] <=> b[:name] }
    build_tree(deps, dir)
  end
end

.environment_from_options(options) ⇒ Puppet::Node::Environment

Given a hash of options, we should discover or create a Node::Environment instance that reflects the provided options.

Generally speaking, the `:modulepath` parameter should supersede all others, the `:environment` parameter should follow after that, and we should default to Puppet's current environment.

Parameters:

  • options ({Symbol => Object})

    the options to derive environment from

Returns:


146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/puppet/module_tool.rb', line 146

def self.environment_from_options(options)
  if options[:modulepath]
    path = options[:modulepath].split(File::PATH_SEPARATOR)
    Puppet::Node::Environment.create(:anonymous, path, '')
  elsif options[:environment].is_a?(Puppet::Node::Environment)
    options[:environment]
  elsif options[:environment]
    # This use of looking up an environment is correct since it honours
    # a request to get a particular environment via environment name.
    Puppet.lookup(:environments).get!(options[:environment])
  else
    Puppet.lookup(:current_environment)
  end
end

.find_module_root(path) ⇒ Pathname?

Find the module root when given a path by checking each directory up from its current location until it finds one that satisfies is_module_root?

Parameters:

  • path (Pathname, String)

    path to start from

Returns:

  • (Pathname, nil)

    the root path of the module directory or nil if we cannot find one


48
49
50
51
52
53
54
55
56
# File 'lib/puppet/module_tool.rb', line 48

def self.find_module_root(path)
  path = Pathname.new(path) if path.class == String

  path.expand_path.ascend do |p|
    return p if is_module_root?(p)
  end

  nil
end

.format_tree(nodes, level = 0) ⇒ Object

Builds a formatted tree from a list of node hashes containing :text and :dependencies keys.


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/puppet/module_tool.rb', line 71

def self.format_tree(nodes, level = 0)
  str = ''
  nodes.each_with_index do |node, i|
    last_node = nodes.length - 1 == i
    deps = node[:dependencies] || []

    str << (indent = "  " * level)
    str << (last_node ? "" : "")
    str << ""
    str << (deps.empty? ? "" : "")
    str << " #{node[:text]}\n"

    branch = format_tree(deps, level + 1)
    branch.gsub!(/^#{indent} /, indent + '') unless last_node
    str << branch
  end

  return str
end

.is_module_root?(path) ⇒ Boolean

Analyse path to see if it is a module root directory by detecting a file named 'metadata.json'

Parameters:

  • path (Pathname, String)

    path to analyse

Returns:

  • (Boolean)

    true if the path is a module root, false otherwise


63
64
65
66
67
# File 'lib/puppet/module_tool.rb', line 63

def self.is_module_root?(path)
  path = Pathname.new(path) if path.class == String

  FileTest.file?(path + 'metadata.json')
end

.parse_module_dependency(where, dep) ⇒ Array(String, SemanticPuppet::VersionRange, String)

Handles parsing of module dependency expressions into proper SemanticPuppet::VersionRanges, including reasonable error handling.

Parameters:

  • where (String)

    a description of the thing we're parsing the dependency expression for

  • dep (Hash)

    the dependency description to parse

Returns:

  • (Array(String, SemanticPuppet::VersionRange, String))

    a tuple of the dependent module's name, the version range dependency, and the unparsed range expression.


170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/puppet/module_tool.rb', line 170

def self.parse_module_dependency(where, dep)
  dep_name = dep['name'].tr('/', '-')
  range = dep['version_requirement'] || '>= 0.0.0'

  begin
    parsed_range = Module.parse_range(range)
  rescue ArgumentError => e
    Puppet.debug "Error in #{where} parsing dependency #{dep_name} (#{e.message}); using empty range."
    parsed_range = SemanticPuppet::VersionRange::EMPTY_RANGE
  end

  [ dep_name, parsed_range, range ]
end

.set_option_defaults(options) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

TODO:

Validate the above note…

Note:

Unfortunately the whole point of this method is the side effect of

modifying the options parameter. This same hash is referenced both when_invoked and when_rendering. For this reason, we are not returning a duplicate. An :environment_instance and a :target_dir are added/updated in the options parameter.

Parameters:

  • options (Hash<Symbol,String>)

    This hash will contain any command-line arguments that are not Settings, as those will have already been extracted by the underlying application code.


123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/puppet/module_tool.rb', line 123

def self.set_option_defaults(options)
  current_environment = environment_from_options(options)

  modulepath = [options[:target_dir]] + current_environment.full_modulepath

  face_environment = current_environment.override_with(:modulepath => modulepath.compact)

  options[:environment_instance] = face_environment

  # Note: environment will have expanded the path
  options[:target_dir] = face_environment.full_modulepath.first

end

.username_and_modname_from(full_module_name) ⇒ Object

Return the username and modname for a given full_module_name, or raise an ArgumentError if the argument isn't parseable.


33
34
35
36
37
38
39
40
# File 'lib/puppet/module_tool.rb', line 33

def self.username_and_modname_from(full_module_name)
  matcher = full_module_name.match(FULL_MODULE_NAME_PATTERN)
  if matcher
    return matcher.captures
  else
    raise ArgumentError, _("Not a valid full name: %{full_module_name}") % { full_module_name: full_module_name }
  end
end