module FalkorLib::Puppet::Modules

Management of Puppet Modules operations

Public Instance Methods

_get_classdefs(moduledir = Dir.pwd, type = 'classes') click to toggle source
# File lib/falkorlib/puppet/modules.rb, line 61
def _get_classdefs(moduledir = Dir.pwd, type = 'classes')
  name = File.basename( moduledir )
  error "The module #{name} does not exist" unless File.directory?( moduledir )
  t = case type
      when /class*/i
        'class'
      when /def*/
        'define'
      else
        ''
      end
  error "Undefined type #{type}" if t.empty?
  result = []
  Dir["#{moduledir}/manifests/**/*.pp"].each do |ppfile|
    #puts "=> testing #{ppfile}"
    File.read(ppfile).scan(/^[ \t]*#{t}[\s]+([0-9a-zA-z:-]+).*$/).each do |line|
      result << line[0]
    end
  end
  result.uniq!
  result.sort
end
classes(moduledir = Dir.pwd) click to toggle source

Find the classes of a given module

# File lib/falkorlib/puppet/modules.rb, line 361
def classes(moduledir = Dir.pwd)
  _get_classdefs(moduledir, 'classes')
end
definitions(moduledir = Dir.pwd) click to toggle source

Find the definitions of a given module

# File lib/falkorlib/puppet/modules.rb, line 368
def definitions(moduledir = Dir.pwd)
  _get_classdefs(moduledir, 'definitions')
end
deps(moduledir = Dir.pwd) click to toggle source

Find the dependencies of a given module

# File lib/falkorlib/puppet/modules.rb, line 375
def deps(moduledir = Dir.pwd)
  name = File.basename( moduledir )
  error "The module #{name} does not exist" unless File.directory?( moduledir )

  result    = []
  result2   = []
  resulttmp = []

  result << name

  while result != result2
    resulttmp = result.dup
    (result - result2).each do |_x|
      Dir["#{moduledir}/**/*.pp"].each do |ppfile|
        File.read(ppfile).scan(/^\s*(include|require|class\s*{)\s*["']?(::)?([0-9a-zA-Z:{$}\-]*)["']?/) do |_m|
          next if Regexp.last_match(3).nil?
          entry = Regexp.last_match(3).split('::').first
          result << entry unless entry.nil? || entry.empty?
        end
      end
    end
    result.uniq!
    result2 = resulttmp.dup
  end
  result.delete name.to_s
  result
end
init(rootdir = Dir.pwd, name = '', _options = {}) click to toggle source

Initialize a new Puppet Module named ‘name` in `rootdir`. Supported options:

  • :no_iteraction [boolean]

# File lib/falkorlib/puppet/modules.rb, line 90
def init(rootdir = Dir.pwd, name = '', _options = {})
  config = {}
  #login = `whoami`.chomp
  config[:name] = name unless name.empty?
  moduledir     = rootdir
  #name.empty? ? rootdir : File.join(rootdir, name)
  FalkorLib::Config::Puppet::Modules::DEFAULTS[:metadata].each do |k, v|
    next if v.is_a?(Array) || (k == :license)
    next if (k == :name) && !name.empty?
    default_answer = case k
                     when :project_page
                       (config[:source].nil?) ? v : config[:source]
                     when :name
                       File.basename(rootdir).gsub(/^puppet-/, '')
                     when :issues_url
                       (config[:project_page].nil?) ? v : "#{config[:project_page]}/issues"
                     when :forge_url
                       v + '/' + config[:name].tr('-', '/')
                     when :description
                       (config[:summary].nil?) ? v : (config[:summary]).to_s
                     when :source
                       (v.empty?) ? "https://github.com/#{config[:name].gsub(/\//, '/puppet-')}" : v
                     else
                       v
                     end
    config[k.to_sym] = ask( "\t" + Kernel.format("%-20s", "Module #{k}"), default_answer)
  end
  config[:shortname] = name = config[:name].gsub(/.*[-\/]/, '')
  config[:docs_project] = ask("\tRead the Docs (RTFD) project:", config[:name].downcase.gsub(/\//, '-puppet-'))
  tags = ask("\tKeywords (comma-separated list of tags)", config[:shortname])
  config[:tags] = tags.split(',')
  list_license    = FalkorLib::Config::Puppet::Modules::DEFAULTS[:licenses]
  default_license = FalkorLib::Config::Puppet::Modules::DEFAULTS[:metadata][:license]
  idx = list_license.index(default_license) unless default_license.nil?
  license = select_from(list_license,
                        'Select the license index for the Puppet module:',
                        (idx.nil?) ? 1 : idx + 1)
  config[:license] = license unless license.empty?
  puts "\t" + format("%-20s", "Module License:") + config[:license]

  # Supported platforms
  config[:platforms] = [ 'debian' ]
  config[:dependencies] = [{
    "name" => "puppetlabs-stdlib",
    "version_requirement" => ">=4.19.0 <5.0.0"
  }]
  config[:params] = %w(ensure protocol port packagename)
  #ap config
  # Bootstrap the directory
  templatedir = File.join( FalkorLib.templates, 'puppet', 'modules')
  init_from_template(templatedir, moduledir, config, :erb_exclude => [ 'templates\/[^\/]*variables\.erb$' ],
                                                     :no_interaction => true)
  # Rename the files / element templatename
  Dir["#{moduledir}/**/*"].each do |e|
    next unless e =~ /templatename/
    info "renaming #{e}"
    newname = e.gsub(/templatename/, name.to_s)
    run %( mv #{e} #{newname} )
  end
  # Update docs directory
  run %( ln -s ../README.md #{moduledir}/docs/overview.md )
  info "Generating the License file"
  authors = (config[:author].empty?) ? 'UNKNOWN' : config[:author]
  Dir.chdir(moduledir) do
    run %( licgen #{config[:license].downcase} #{authors} )
  end
  info "Initialize RVM"
  init_rvm(moduledir)
  unless FalkorLib::Git.init?(moduledir)
    init_gitflow = FalkorLib::Git.command?('flow')
    warn "Git #{(init_gitflow) ? '[Flow]' : ''} is not initialized in #{moduledir}."
    a = ask("Proceed to git-flow initialization (Y|n)", 'Yes')
    return if a =~ /n.*/i
    (init_gitflow) ? FalkorLib::GitFlow.init(moduledir) : FalkorLib::Git.init(moduledir)
  end

  # Propose to commit the key files
  if FalkorLib::Git.init?(moduledir)
    if FalkorLib::GitFlow.init?(moduledir)
      info "=> preparing git-flow feature for the newly created module '#{config[:name]}'"
      FalkorLib::GitFlow.start('feature', "bootstrapping", moduledir)
    end
    [ 'metadata.json',
      'docs/', 'mkdocs.yml', 'LICENSE', '.gitignore', '.pmtignore',
      '.ruby-version', '.ruby-gemset', 'Gemfile',
      'tests/vagrant/', 'Rakefile', 'Vagrantfile' ].each do |f|
      FalkorLib::Git.add(File.join(moduledir, f))
    end
  end
end
metadata(moduledir = Dir.pwd, options = { :use_symbols => true, :extras => true, :no_interaction => false }) click to toggle source

Retrieves the metadata from the metadata.json file in ‘moduledir`. Supported options:

:use_symbols [boolean]: convert all keys to symbols
:extras  [boolean]: add extra keys
# File lib/falkorlib/puppet/modules.rb, line 241
def metadata(moduledir = Dir.pwd, options = {
  :use_symbols => true,
  :extras => true,
  :no_interaction => false
})
  add_extras = (options[:extras].nil?) ? true : options[:extras]
  name = File.basename( moduledir )
  error "The module #{name} does not exist" unless File.directory?( moduledir )
  jsonfile = File.join( moduledir, 'metadata.json')
  error "Unable to find #{jsonfile}" unless File.exist?( jsonfile )
  metadata = JSON.parse( IO.read( jsonfile ) )
  metadata["docs_project"] = ask("\tRead the Docs (RTFD) project:", (metadata['name'].downcase.gsub(/\//, '-puppet-')).to_s) if metadata["docs_project"].nil?
  if add_extras
    metadata[:shortname] = name.gsub(/.*-/, '')
    metadata[:platforms] = []
    metadata["operatingsystem_support"].each do |e|
      metadata[:platforms] << e["operatingsystem"].downcase unless e["operatingsystem"].nil?
    end
    # Analyse params
    params_manifest = File.join(moduledir, 'manifests', 'params.pp')
    if File.exist?(params_manifest)
      params = []
      File.read(params_manifest).scan(/^\s*\$(.*)\s*=/) do |_m|
        params << Regexp.last_match(1).gsub(/\s+$/, '') unless Regexp.last_match(1).nil?
      end
      metadata[:params] = params.uniq
    end
  end
  if options[:use_symbols]
    # convert string keys to symbols
    metadata.keys.each do |k|
      metadata[(begin
                  k.to_sym
                rescue
                  k
                end) || k] = metadata.delete(k)
    end
  end
  metadata
end
parse(moduledir = Dir.pwd, options = { :no_interaction => false }) click to toggle source

Parse a given modules to collect information Supported options:

:no_interaction [boolean]: do not interact
# File lib/falkorlib/puppet/modules.rb, line 186
def parse(moduledir = Dir.pwd, options = {
  :no_interaction => false
})
  name = File.basename(moduledir)
  metadata = metadata(moduledir, :use_symbols => false,
                                 :extras         => false,
                                 :no_interaction => options[:no_interaction])
  puts metadata.to_yaml
  # error "The module #{name} does not exist" unless File.directory?( moduledir )
  jsonfile = File.join( moduledir, 'metadata.json')
  # error "Unable to find #{jsonfile}" unless File.exist?( jsonfile )
  # metadata = JSON.parse( IO.read( jsonfile ) )
  #ref = JSON.pretty_generate( metadata )
  metadata["classes"]     = classes(moduledir)
  metadata["definitions"] = definitions(moduledir)
  deps        = deps(moduledir)
  #listed_deps = metadata["dependencies"]
  missed_deps = []
  metadata["dependencies"].each do |dep|
    lib = dep["name"].gsub(/^[^\/-]+[\/-]/, '')
    if deps.include?( lib )
      deps.delete( lib )
    else
      unless lib =~ /stdlib/
        warn "The library '#{dep['name']}' is not analyzed as part of the #{metadata['shortname']} module"
        missed_deps << dep
      end
    end
  end
  unless deps.empty?
    deps.each do |l|
      next if [name, metadata["name"], name.gsub(/.*-/, ''), metadata["name"].gsub(/.*-/, '') ].include?( l )
      warn "The module '#{l}' is missing in the dependencies thus added"
      login   = ask("[Github] login for the module '#{l}'")
      version = ask("Version requirement (ex: '>=1.0.0 <2.0.0' or '1.2.3' or '1.x')")
      metadata["dependencies"] << {
        "name"                => "#{login}/#{l}",
        "version_requirement" => version.to_s
      }
    end
  end
  content = JSON.pretty_generate( metadata )
  info "Metadata configuration for the module '#{name}'"
  puts content
  show_diff_and_write(content, jsonfile, :no_interaction => options[:no_interaction],
                                         :json_pretty_format => true)
  metadata
end
upgrade(moduledir = Dir.pwd, options = { :no_interaction => false, :only => nil, :exclude => [] }) click to toggle source

Upgrade the key files (README etc.) of the puppet module hosted in ‘moduledir` with the latest version of the FalkorLib template Supported options:

:no_interaction [boolean]: do not interact
:only [Array of string]: update only the listed files
:exclude [Array of string]: exclude from the upgrade the listed
                            files

return the number of considered files

# File lib/falkorlib/puppet/modules.rb, line 293
def upgrade(moduledir = Dir.pwd,
            options = {
              :no_interaction => false,
              :only    => nil,
              :exclude => []
            })
  metadata = metadata(moduledir)
  templatedir = File.join( FalkorLib.templates, 'puppet', 'modules')
  i = 0
  update_from_erb = [
    'README.md',
    'docs/contacts.md',
    'docs/contributing/index.md', 'docs/contributing/layout.md', 'docs/contributing/setup.md', 'docs/contributing/versioning.md',
    'docs/index.md', 'docs/rtfd.md', 'docs/vagrant.md'
  ]
  (update_from_erb + [ 'Gemfile', 'Rakefile', 'Vagrantfile', 'tests/vagrant/bootstrap.sh', 'tests/vagrant/config.yaml', 'tests/vagrant/puppet_modules_setup.rb' ]).each do |f|
    next unless options[:exclude].nil? || !options[:exclude].include?( f )
    next unless options[:only].nil?    || options[:only].include?(f)
    info "Upgrade the content of #{f}"
    ans = (options[:no_interaction]) ? 'Yes' : ask(cyan("==> procceed? (Y|n)"), 'Yes')
    next if ans =~ /n.*/i
    if update_from_erb.include?(f)
      puts "=> updating #{f}.erb"
      i += write_from_erb_template(File.join(templatedir, "#{f}.erb"),
                                   File.join(moduledir, f),
                                   metadata,
                                   options)
    else
      i += write_from_template(f, moduledir,
                               :no_interaction => options[:no_interaction],
                               :srcdir => templatedir)

    end
  end
  i
end
upgrade_from_template(moduledir = Dir.pwd, subdir = 'tests', options = { :no_interaction => false }) click to toggle source

initializes or update the (tests/specs/etc.) sub-directory of the ‘moduledir` using the correcponding ERB files. Supported options:

:no_interaction [boolean]: do not interactww

returns the number of considered files

# File lib/falkorlib/puppet/modules.rb, line 337
def upgrade_from_template(moduledir = Dir.pwd,
                          subdir = 'tests',
                          options = {
                            :no_interaction => false
                          })
  metadata = metadata(moduledir)
  ap metadata
  i = 0
  templatedir = File.join( FalkorLib.templates, 'puppet', 'modules', subdir)
  error "Unable to find the template directory '#{templatedir}" unless File.directory?( templatedir )
  Dir["#{templatedir}/**/*.erb"].each do |erbfile|
    f = File.join(subdir, File.basename(erbfile, '.erb'))
    info "Upgrade the content of #{f}"
    ans = (options[:no_interaction]) ? 'Yes' : ask(cyan("==> procceed? (Y|n)"), 'Yes')
    next if ans =~ /n.*/i
    i += write_from_erb_template(erbfile, File.join(moduledir, f), metadata, options)
  end
  i
end