Skip to content

Commit

Permalink
Merge branch 'lexer-monkey-patch'
Browse files Browse the repository at this point in the history
  • Loading branch information
rodjek committed Sep 9, 2011
2 parents 26f6350 + 111dd5d commit 3183bad
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 27 deletions.
75 changes: 48 additions & 27 deletions lib/puppet-lint/plugins/check_strings.rb
@@ -1,40 +1,61 @@
require 'puppet'

class PuppetLint::Plugins::CheckStrings < PuppetLint::CheckPlugin
class ::Puppet::Parser::Lexer
class TokenList
def del_token(token)
@tokens.delete(token)
end
end

TOKENS.add_tokens("<single quotes string>" => :SSTRING)
TOKENS.del_token(:SQUOTE)

TOKENS.add_token :SQUOTE, "'" do |lexer, value|
[TOKENS[:SSTRING], lexer.slurpstring(value,["'"],:ignore_invalid_escapes).first ]
end
end

def test(data)
line_no = 0
data.each_line do |line|
line_no += 1
line.match(/"([^\\"]|\\\\|\\")*"/).to_a.each do |s|
if s.is_a? String and s.start_with? '"'
variable_found = false
s.scan(/.\$./) do |w|
if w.start_with? '\\'
next
elsif w.end_with? '{'
variable_found = true
else
warn "variable not enclosed in {} on line #{line_no}"
end
end
unless variable_found
warn "double quoted string containing no variables on line #{line_no}"
end
if s =~ /^"\$\{[\w\:]+\}"$/
warn "string containing only a variable on line #{line_no}"
end
l = Puppet::Parser::Lexer.new
l.string = data
tokens = l.fullscan

tokens.each_index do |token_idx|
token = tokens[token_idx]

if token.first == :STRING
warn "double quoted string containing no variables on line #{token.last[:line]}"
end

line = line[line.index('"', line.index('"')+1)..-1]
if token.first == :DQPRE and token.last[:value] == ""
if tokens[token_idx + 1].first == :VARIABLE
if tokens[token_idx + 2].first == :DQPOST and tokens[token_idx + 2].last[:value] == ""
warn "string containing only a variable on line #{tokens[token_idx + 1].last[:line]}"
end
end
end

line.match(/'.+?'/).to_a.each do |s|
if s.start_with? "'"
s.scan(/\$./) do |w|
if w.end_with? '{'
error "single quoted string containing a variable found on line #{line_no}"
if token.first == :DQPRE
end_of_string_idx = tokens[token_idx..-1].index { |r| r.first == :DQPOST }
tokens[token_idx..end_of_string_idx].each do |t|
if t.first == :VARIABLE
line = data.split("\n")[t.last[:line] - 1]
if line.is_a? String and line.include? "$#{t.last[:value]}"
warn "variable not enclosed in {} on line #{t.last[:line]}"
end
end
end
end

if token.first == :SSTRING
contents = token.last[:value]
line_no = token.last[:line]

if contents.include? '${'
error "single quoted string containing a variable found on line #{token.last[:line]}"
end
end
end
end
end
21 changes: 21 additions & 0 deletions spec/puppet-lint/check_strings_spec.rb
Expand Up @@ -27,4 +27,25 @@
its(:warnings) { should include "string containing only a variable on line 1" }
its(:errors) { should be_empty }
end

describe 'variable not enclosed in {}' do
let(:code) { '" $gronk"' }

its(:warnings) { should include "variable not enclosed in {} on line 1" }
its(:errors) { should be_empty }
end

describe 'double quoted string nested in a single quoted string' do
let(:code) { "'grep \"status=sent\" /var/log/mail.log'" }

its(:warnings) { should be_empty }
its(:errors) { should be_empty }
end

describe 'double quoted string after a comment' do
let(:code) { "service { 'foo': } # \"bar\"" }

its(:warnings) { should be_empty }
its(:errors) { should be_empty }
end
end

0 comments on commit 3183bad

Please sign in to comment.