class Mvp::PuppetfileParser
Public Class Methods
new(options = {})
click to toggle source
# File lib/mvp/puppetfile_parser.rb, line 3 def initialize(options = {}) @sources = {} @modules = [] @repo = nil end
Public Instance Methods
add_module(name, args)
click to toggle source
# File lib/mvp/puppetfile_parser.rb, line 68 def add_module(name, args) unless name.is_a? String $logger.warn "Non string module name in #{@repo[:repo_name]}/Puppetfile" return nil end name.gsub!('/', '-') case args when String, Symbol, NilClass @modules << { :module => name, :type => :forge, :source => :forge, :version => args, } when Hash @modules << parse_args(name, args) else $logger.warn "#{@repo[:repo_name]}/Puppetfile: Unknown format: mod('#{name}', #{args.inspect})" end end
canonical_git_repo(repo)
click to toggle source
# File lib/mvp/puppetfile_parser.rb, line 60 def canonical_git_repo(repo) return unless repo return unless repo.is_a? String repo.sub(/^git@github.com\:/, 'github.com/') .sub(/^(git|https?)\:\/\//, '') .sub(/\.git$/, '') end
canonical_name(name, repo)
click to toggle source
# File lib/mvp/puppetfile_parser.rb, line 52 def canonical_name(name, repo) return name if name.include?('-') repo = canonical_git_repo(repo) return @sources[repo] if @sources.include?(repo) name end
parse(repo)
click to toggle source
# File lib/mvp/puppetfile_parser.rb, line 22 def parse(repo) # This only works on Ruby 2.6+ return unless suitable? begin root = RubyVM::AbstractSyntaxTree.parse(repo[:content]) rescue SyntaxError => e $logger.warn "Syntax error in #{repo[:repo_name]}/Puppetfile" $logger.warn e.message end @repo = repo @modules = [] traverse(root) @modules.compact.map do |row| row[:repo_name] = repo[:repo_name] row[:md5] = repo[:md5] row[:module] = canonical_name(row[:module], row[:source]) stringify(row) end end
parse_args(name, args)
click to toggle source
# File lib/mvp/puppetfile_parser.rb, line 89 def parse_args(name, args) data = {:module => name} if args.include? :git data[:type] = :git data[:source] = args[:git] data[:version] = args[:ref] || args[:tag] || args[:commit] || args[:branch] || :latest elsif args.include? :svn data[:type] = :svn data[:source] = args[:svn] data[:version] = args[:rev] || args[:revision] || :latest elsif args.include? :boxen data[:type] = :boxen data[:source] = args[:repo] data[:version] = args[:version] || :latest else $logger.warn "#{@repo[:repo_name]}/Puppetfile: Unknown args format: mod('#{name}', #{args.inspect})" return nil end data end
sources=(modules)
click to toggle source
# File lib/mvp/puppetfile_parser.rb, line 13 def sources=(modules) modules.each do |row| next unless row[:source] next if row[:source] == 'UNKNOWN' @sources[canonical_git_repo(row[:source])] = row[:slug] end end
stringify(row)
click to toggle source
# File lib/mvp/puppetfile_parser.rb, line 44 def stringify(row) row.each do |key, value| if value.is_a? RubyVM::AbstractSyntaxTree::Node row[key] = :'#<programmatically generated via ruby code>' end end end
suitable?()
click to toggle source
# File lib/mvp/puppetfile_parser.rb, line 9 def suitable? defined?(RubyVM::AbstractSyntaxTree) end
test()
click to toggle source
# File lib/mvp/puppetfile_parser.rb, line 166 def test() require 'pry' binding.pry end
traverse(node)
click to toggle source
# File lib/mvp/puppetfile_parser.rb, line 112 def traverse(node) begin if node.type == :FCALL name = node.children.first args = node.children.last.children.map do |item| next if item.nil? case item.type when :HASH Hash[*item.children.first.children.compact.map {|n| n.children.first }] else item.children.first end end.compact case name when :mod add_module(args.shift, args.shift) when :forge # noop when :moduledir # noop when :github # oh boxen, you so silly. # The order of the unpacking below *is* important. modname = args.shift version = args.shift data = args.shift || {} # this is gross but I'm not sure I actually care right now. if (modname.is_a? String and [String, NilClass].include? version.class and data.is_a? Hash) data[:boxen] = :boxen data[:version] = version add_module(modname, data) else $logger.warn "#{@repo[:repo_name]}/Puppetfile: malformed boxen" end else # Should we record unexpected Ruby code or just log it to stdout? args = args.map {|a| a.is_a?(String) ? "'#{a}'" : a}.join(', ') $logger.warn "#{@repo[:repo_name]}/Puppetfile: Unexpected invocation of #{name}(#{args})" end end node.children.each do |n| next unless n.is_a? RubyVM::AbstractSyntaxTree::Node traverse(n) end rescue => e puts e.message end end