Class: RubyParser

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet-check/ruby_parser.rb

Overview

executes diagnostics on ruby files

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.librarian(files, style, rc_args) ⇒ Object

checks librarian puppet (Puppetfile/Modulefile) and misc ruby (Rakefile/Gemfile)



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
# File 'lib/puppet-check/ruby_parser.rb', line 67

def self.librarian(files, style, rc_args)
  # efficient var assignment prior to iterator
  if style
    require 'rubocop'

    # RuboCop is grumpy about non-snake_case filenames so disable the FileName check
    rc_args.include?('--except') ? rc_args[rc_args.index('--except') + 1] = "#{rc_args[rc_args.index('--except') + 1]},Naming/FileName" : rc_args.concat(['--except', 'Naming/FileName'])
  end

  files.each do |file|
    # check librarian puppet syntax
    begin
      # prevents ruby code from actually executing
      catch(:good) { instance_eval("BEGIN {throw :good}; #{File.read(file)}", file) }
    rescue SyntaxError, LoadError, ArgumentError => err
      PuppetCheck.settings[:error_files].push("#{file}:\n#{err}")
    # check librarian puppet style
    else
      if style
        # check Rubocop
        warnings = Utils.capture_stdout { RuboCop::CLI.new.run(rc_args + ['--require', 'rubocop-performance', '--format', 'emacs', file]) }

        # collect style warnings
        next PuppetCheck.settings[:warning_files].push("#{file}:\n#{warnings.split("#{File.absolute_path(file)}:").join('')}") unless warnings.empty?
      end
      PuppetCheck.settings[:clean_files].push(file.to_s)
    end
  end
end

.ruby(files, style, rc_args) ⇒ Object

checks ruby (.rb)



7
8
9
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
# File 'lib/puppet-check/ruby_parser.rb', line 7

def self.ruby(files, style, rc_args)
  files.each do |file|
    # check ruby syntax
    begin
      # prevents ruby code from actually executing
      catch(:good) { instance_eval("BEGIN {throw :good}; #{File.read(file)}", file) }
    rescue ScriptError, StandardError => err
      PuppetCheck.settings[:error_files].push("#{file}:\n#{err}")
    else
      # check ruby style
      if style
        require 'rubocop'

        # check RuboCop and collect warnings
        rubocop_warnings = Utils.capture_stdout { RuboCop::CLI.new.run(rc_args + ['--require', 'rubocop-performance', '--format', 'emacs', file]) }
        warnings = rubocop_warnings == '' ? '' : rubocop_warnings.split("#{File.absolute_path(file)}:").join('')

        # check Reek and collect warnings
        require 'reek'
        require 'reek/cli/application'
        reek_warnings = Utils.capture_stdout { Reek::CLI::Application.new([file]).execute }
        warnings << reek_warnings.split("\n")[1..-1].map(&:strip).join("\n") unless reek_warnings == ''

        # return warnings
        next PuppetCheck.settings[:warning_files].push("#{file}:\n#{warnings.strip}") unless warnings == ''
      end
      PuppetCheck.settings[:clean_files].push(file.to_s)
    end
  end
end

.template(files) ⇒ Object

checks ruby template (.erb)



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/puppet-check/ruby_parser.rb', line 39

def self.template(files)
  require 'erb'

  files.each do |file|
    # check ruby template syntax
    begin
      # need to eventually have this associated with a different binding during each iteration
      # older usage throws extra warning and mixes with valid warnings confusingly
      warnings = if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6')
                   Utils.capture_stderr { ERB.new(File.read(file), trim_mode: '-').result }
                   # ERB.new(File.read(file), trim_mode: '-').result(RubyParser.new.bind)
                 # and for extra fun it is incompatible with non-new ruby
                 else
                   Utils.capture_stderr { ERB.new(File.read(file), nil, '-').result }
                 end
    rescue NameError, TypeError
      # empty out warnings since it would contain an error if this pass triggers
      warnings = ''
    rescue ScriptError => err
      next PuppetCheck.settings[:error_files].push("#{file}:\n#{err}")
    end
    # return warnings from the check if there were any
    next PuppetCheck.settings[:warning_files].push("#{file}:\n#{warnings.gsub('warning: ', '').split('(erb):').join('').strip}") unless warnings == ''
    PuppetCheck.settings[:clean_files].push(file.to_s)
  end
end

Instance Method Details

#bindObject

potentially for unique erb bindings



98
99
100
# File 'lib/puppet-check/ruby_parser.rb', line 98

def bind
  binding
end