Skip to content

Commit

Permalink
Merge pull request #212 from rodjek/fix-181
Browse files Browse the repository at this point in the history
Handle variables with array & hash references
  • Loading branch information
timtim123456 committed Aug 3, 2013
2 parents c9f2b6d + 6caa032 commit ec984f5
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 64 deletions.
1 change: 1 addition & 0 deletions lib/puppet-lint.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'set'
require 'puppet-lint/version'
require 'puppet-lint/lexer'
require 'puppet-lint/configuration'
Expand Down
20 changes: 9 additions & 11 deletions lib/puppet-lint/lexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -352,17 +352,15 @@ def interpolate_string(string, line, column)
end
else
contents = ss.scan_until(/\}/)[0..-2]
if contents.match(/\A(::)?([\w-]+::)*[\w-]+\Z/)
token_column = column + (ss.pos - contents.size - 1)
tokens << new_token(:VARIABLE, contents, :line => line, :column => token_column)
else
lexer = PuppetLint::Lexer.new
lexer.tokenise(contents)
lexer.tokens.each do |token|
tok_col = column + token.column + (ss.pos - contents.size - 1)
tok_line = token.line + line - 1
tokens << new_token(token.type, token.value, :line => tok_line, :column => tok_col)
end
if contents.match(/\A(::)?([\w-]+::)*[\w-]+/)
contents = "$#{contents}"
end
lexer = PuppetLint::Lexer.new
lexer.tokenise(contents)
lexer.tokens.each do |token|
tok_col = column + token.column + (ss.pos - contents.size - 1)
tok_line = token.line + line - 1
tokens << new_token(token.type, token.value, :line => tok_line, :column => tok_col)
end
end
end
Expand Down
72 changes: 41 additions & 31 deletions lib/puppet-lint/plugins/check_strings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,44 +32,54 @@ class PuppetLint::Plugins::CheckStrings < PuppetLint::CheckPlugin
#
# Returns nothing.
check 'only_variable_string' do
variable_tokens = Set.new [:VARIABLE, :UNENC_VARIABLE]

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

if token.type == :DQPRE and token.value == ''
if {:VARIABLE => true, :UNENC_VARIABLE => true}.include? tokens[token_idx + 1].type
if tokens[token_idx + 2].type == :DQPOST
if tokens[token_idx + 2].value == ''
if PuppetLint.configuration.fix
prev_token = token.prev_token
prev_code_token = token.prev_code_token
next_token = token.next_token.next_token.next_token
next_code_token = token.next_token.next_token.next_code_token
var_token = token.next_token
var_token = token.next_token
if variable_tokens.include? var_token.type
eos_offset = 2
loop do
eos_token = tokens[token_idx + eos_offset]
case eos_token.type
when :LBRACK
eos_offset += 3
when :DQPOST
if eos_token.value == ''
if PuppetLint.configuration.fix
prev_token = token.prev_token
prev_code_token = token.prev_code_token
next_token = eos_token.next_token
next_code_token = eos_token.next_code_token

tokens.delete_at(token_idx + 2)
tokens.delete_at(token_idx)
tokens.delete_at(token_idx + eos_offset)
tokens.delete_at(token_idx)

prev_token.next_token = var_token unless prev_token.nil?
prev_code_token.next_code_token = var_token unless prev_code_token.nil?
next_code_token.prev_code_token = var_token unless next_code_token.nil?
next_token.prev_token = var_token unless next_token.nil?
var_token.type = :VARIABLE
var_token.next_token = next_token
var_token.next_code_token = next_code_token
var_token.prev_code_token = prev_code_token
var_token.prev_token = prev_token
notify_type = :fixed
notify_token = var_token
else
notify_type = :warning
notify_token = tokens[token_idx + 1]
end
prev_token.next_token = var_token unless prev_token.nil?
prev_code_token.next_code_token = var_token unless prev_code_token.nil?
next_code_token.prev_code_token = var_token unless next_code_token.nil?
next_token.prev_token = var_token unless next_token.nil?
var_token.type = :VARIABLE
var_token.next_token = next_token
var_token.next_code_token = next_code_token
var_token.prev_code_token = prev_code_token
var_token.prev_token = prev_token
notify_type = :fixed
else
notify_type = :warning
end

notify notify_type, {
:message => 'string containing only a variable',
:linenumber => notify_token.line,
:column => notify_token.column,
}
notify notify_type, {
:message => 'string containing only a variable',
:linenumber => var_token.line,
:column => var_token.column,
}
end
break
else
break
end
end
end
Expand Down
104 changes: 82 additions & 22 deletions spec/puppet-lint/plugins/check_strings/only_variable_string_spec.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,48 @@
require 'spec_helper'

describe 'only_variable_string' do
describe 'string containing only a variable' do
let(:code) { '"${foo}"' }

its(:problems) {
should only_have_problem({
:kind => :warning,
:message => 'string containing only a variable',
:linenumber => 1,
:column => 3,
})
}
context 'with fix disabled' do
describe 'string containing only a variable' do
let(:code) { '"${foo}"' }

its(:problems) {
should only_have_problem({
:kind => :warning,
:message => 'string containing only a variable',
:linenumber => 1,
:column => 3,
})
}
end

describe 'string containing only a variable w/ ref' do
let(:code) { '"${foo[0]}"' }

its(:problems) {
should only_have_problem({
:kind => :warning,
:message => 'string containing only a variable',
:linenumber => 1,
:column => 3,
})
}
end

describe 'string containing only a variable w/ lots of refs' do
let(:code) { '"${foo[0][aoeuaoeu][bar][999]}"' }

its(:problems) {
should only_have_problem({
:kind => :warning,
:message => 'string containing only a variable',
:linenumber => 1,
:column => 3,
})
}
end
end

describe 'string containing only a variable w/fix' do
context 'with fix enabled' do
before do
PuppetLint.configuration.fix = true
end
Expand All @@ -23,17 +51,49 @@
PuppetLint.configuration.fix = false
end

let(:code) { '"${foo}"' }
describe 'string containing only a variable' do
let(:code) { '"${foo}"' }

its(:problems) {
should only_have_problem({
:kind => :fixed,
:message => 'string containing only a variable',
:linenumber => 1,
:column => 3,
})
}
its(:problems) {
should only_have_problem({
:kind => :fixed,
:message => 'string containing only a variable',
:linenumber => 1,
:column => 3,
})
}

its(:manifest) { should == "$foo" }
its(:manifest) { should == "$foo" }
end

describe 'string contaiting only a variable w/ ref' do
let(:code) { '"${foo[0]}"' }

its(:problems) {
should only_have_problem({
:kind => :fixed,
:message => 'string containing only a variable',
:linenumber => 1,
:column => 3,
})
}

its(:manifest) { should == "$foo[0]" }
end

describe 'string containing only a variable w/ lots of refs' do
let(:code) { '"${foo[0][aoeuaoeu][bar][999]}"' }

its(:problems) {
should only_have_problem({
:kind => :fixed,
:message => 'string containing only a variable',
:linenumber => 1,
:column => 3,
})
}

its(:manifest) { should == "$foo[0][aoeuaoeu][bar][999]" }
end
end
end

0 comments on commit ec984f5

Please sign in to comment.