Skip to content

Commit

Permalink
Merge pull request #874 from rodjek/gh-826
Browse files Browse the repository at this point in the history
Include hash/array references when enclosing variables
  • Loading branch information
rodjek authored Sep 25, 2019
2 parents 25c9a1e + cb65768 commit b5999d6
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
55 changes: 55 additions & 0 deletions lib/puppet-lint/plugins/check_strings/variables_not_enclosed.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
require 'set'
require 'strscan'

# Public: Check the manifest tokens for any variables in a string that have
# not been enclosed by braces ({}) and record a warning for each instance
# found.
#
# https://puppet.com/docs/puppet/latest/style_guide.html#quoting
PuppetLint.new_check(:variables_not_enclosed) do
STRING_TOKEN_TYPES = Set[
:DQMID,
:DQPOST,
:HEREDOC_MID,
:HEREDOC_POST,
]

def check
tokens.select { |r|
r.type == :UNENC_VARIABLE
Expand All @@ -18,7 +28,52 @@ def check
end
end

def hash_or_array_ref?(token)
token.next_token &&
STRING_TOKEN_TYPES.include?(token.next_token.type) &&
token.next_token.value.start_with?('[')
end

def extract_hash_or_array_ref(token)
scanner = StringScanner.new(token.value)

brack_depth = 0
result = { :ref => '' }

until scanner.eos?
result[:ref] += scanner.getch

# Pass a length of 1 when slicing the last character from the string
# to prevent Ruby 1.8 returning a Fixnum instead of a String.
case result[:ref][-1, 1]
when '['
brack_depth += 1
when ']'
brack_depth -= 1
end

break if brack_depth.zero? && scanner.peek(1) != '['
end

result[:remainder] = scanner.rest
result
end

def fix(problem)
problem[:token].type = :VARIABLE

return unless hash_or_array_ref?(problem[:token])

string_token = problem[:token].next_token
tokens_index = tokens.index(string_token)

hash_or_array_ref = extract_hash_or_array_ref(string_token)

ref_tokens = PuppetLint::Lexer.new.tokenise(hash_or_array_ref[:ref])
ref_tokens.each_with_index do |token, i|
add_token(tokens_index + i, token)
end

string_token.value = hash_or_array_ref[:remainder]
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,21 @@
expect(manifest).to eq('"${foo}-${bar}"')
end
end

context 'variable with a hash or array reference not enclosed' do
let(:code) { %("$foo['bar'][2]something") }

it 'should only detect a single problem' do
expect(problems).to have(1).problem
end

it 'should fix the manifest' do
expect(problems).to contain_fixed(msg).on_line(1).in_column(2)
end

it 'should enclose the variable with the references' do
expect(manifest).to eq(%("${foo['bar'][2]}something"))
end
end
end
end

0 comments on commit b5999d6

Please sign in to comment.