Module: FalkorLib::Puppet::Modules

Defined in:
lib/falkorlib/puppet/modules.rb

Overview

Management of Puppet Modules operations

Class Method Summary collapse

Class Method Details

._get_classdefs(moduledir = Dir.pwd, type = 'classes') ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/falkorlib/puppet/modules.rb', line 62

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) ⇒ Object

Find the classes of a given module



362
363
364
# File 'lib/falkorlib/puppet/modules.rb', line 362

def classes(moduledir = Dir.pwd)
  _get_classdefs(moduledir, 'classes')
end

.definitions(moduledir = Dir.pwd) ⇒ Object

Find the definitions of a given module



369
370
371
# File 'lib/falkorlib/puppet/modules.rb', line 369

def definitions(moduledir = Dir.pwd)
  _get_classdefs(moduledir, 'definitions')
end

.deps(moduledir = Dir.pwd) ⇒ Object

Find the dependencies of a given module



376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
# File 'lib/falkorlib/puppet/modules.rb', line 376

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 = {}) ⇒ Object

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

  • :no_iteraction [boolean]



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/falkorlib/puppet/modules.rb', line 91

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 }) ⇒ Object

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


242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/falkorlib/puppet/modules.rb', line 242

def (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 )
   = JSON.parse( IO.read( jsonfile ) )
  ["docs_project"] = ask("\tRead the Docs (RTFD) project:", (['name'].downcase.gsub(/\//, '-puppet-')).to_s) if ["docs_project"].nil?
  if add_extras
    [:shortname] = name.gsub(/.*-/, '')
    [:platforms] = []
    ["operatingsystem_support"].each do |e|
      [: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
      [:params] = params.uniq
    end
  end
  if options[:use_symbols]
    # convert string keys to symbols
    .keys.each do |k|
      [(begin
                  k.to_sym
                rescue
                  k
                end) || k] = .delete(k)
    end
  end
  
end

.parse(moduledir = Dir.pwd, options = { :no_interaction => false }) ⇒ Object

Parse a given modules to collect information Supported options:

:no_interaction [boolean]: do not interact


187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/falkorlib/puppet/modules.rb', line 187

def parse(moduledir = Dir.pwd, options = {
  :no_interaction => false
})
  name = File.basename(moduledir)
   = (moduledir, :use_symbols => false,
                                 :extras         => false,
                                 :no_interaction => options[:no_interaction])
  puts .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 )
  ["classes"]     = classes(moduledir)
  ["definitions"] = definitions(moduledir)
  deps        = deps(moduledir)
  #listed_deps = metadata["dependencies"]
  missed_deps = []
  ["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 #{['shortname']} module"
        missed_deps << dep
      end
    end
  end
  unless deps.empty?
    deps.each do |l|
      next if [name, ["name"], name.gsub(/.*-/, ''), ["name"].gsub(/.*-/, '') ].include?( l )
      warn "The module '#{l}' is missing in the dependencies thus added"
         = 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')")
      ["dependencies"] << {
        "name"                => "#{}/#{l}",
        "version_requirement" => version.to_s
      }
    end
  end
  content = JSON.pretty_generate(  )
  info "Metadata configuration for the module '#{name}'"
  puts content
  show_diff_and_write(content, jsonfile, :no_interaction => options[:no_interaction],
                                         :json_pretty_format => true)
  
end

.upgrade(moduledir = Dir.pwd, options = { :no_interaction => false, :only => nil, :exclude => [] }) ⇒ Object

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



294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/falkorlib/puppet/modules.rb', line 294

def upgrade(moduledir = Dir.pwd,
            options = {
              :no_interaction => false,
              :only    => nil,
              :exclude => []
            })
   = (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),
                                   ,
                                   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 }) ⇒ Object

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



338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
# File 'lib/falkorlib/puppet/modules.rb', line 338

def upgrade_from_template(moduledir = Dir.pwd,
                          subdir = 'tests',
                          options = {
                            :no_interaction => false
                          })
   = (moduledir)
  ap 
  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), , options)
  end
  i
end