lineinfile - properly insert line when line exists and backrefs are enabled (#63763)
Use a separate variable for the boolean test rather than having the same variable sometimes be a boolean and sometimes be a regular expression match object Add integration tests to cover this scenario
This commit is contained in:
parent
f6c85b7380
commit
29d4d318a5
3 changed files with 34 additions and 21 deletions
|
@ -0,0 +1,2 @@
|
||||||
|
bugfixes:
|
||||||
|
- lineinfile - properly handle inserting a line when backrefs are enabled and the line already exists in the file (https://github.com/ansible/ansible/issues/63756)
|
|
@ -286,7 +286,8 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
|
||||||
# index[0] is the line num where regexp has been found
|
# index[0] is the line num where regexp has been found
|
||||||
# index[1] is the line num where insertafter/insertbefore has been found
|
# index[1] is the line num where insertafter/insertbefore has been found
|
||||||
index = [-1, -1]
|
index = [-1, -1]
|
||||||
m = None
|
match = None
|
||||||
|
exact_line_match = False
|
||||||
b_line = to_bytes(line, errors='surrogate_or_strict')
|
b_line = to_bytes(line, errors='surrogate_or_strict')
|
||||||
|
|
||||||
# The module's doc says
|
# The module's doc says
|
||||||
|
@ -303,18 +304,17 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
|
||||||
match_found = bre_m.search(b_cur_line)
|
match_found = bre_m.search(b_cur_line)
|
||||||
if match_found:
|
if match_found:
|
||||||
index[0] = lineno
|
index[0] = lineno
|
||||||
m = match_found
|
match = match_found
|
||||||
if firstmatch:
|
if firstmatch:
|
||||||
break
|
break
|
||||||
|
|
||||||
# 2. When no match found on the previous step,
|
# 2. When no match found on the previous step,
|
||||||
# parse for searching insertafter/insertbefore:
|
# parse for searching insertafter/insertbefore:
|
||||||
if not m:
|
if not match:
|
||||||
for lineno, b_cur_line in enumerate(b_lines):
|
for lineno, b_cur_line in enumerate(b_lines):
|
||||||
match_found = b_line == b_cur_line.rstrip(b'\r\n')
|
if b_line == b_cur_line.rstrip(b'\r\n'):
|
||||||
if match_found:
|
|
||||||
index[0] = lineno
|
index[0] = lineno
|
||||||
m = match_found
|
exact_line_match = True
|
||||||
|
|
||||||
elif bre_ins is not None and bre_ins.search(b_cur_line):
|
elif bre_ins is not None and bre_ins.search(b_cur_line):
|
||||||
if insertafter:
|
if insertafter:
|
||||||
|
@ -334,8 +334,8 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
|
||||||
b_linesep = to_bytes(os.linesep, errors='surrogate_or_strict')
|
b_linesep = to_bytes(os.linesep, errors='surrogate_or_strict')
|
||||||
# Exact line or Regexp matched a line in the file
|
# Exact line or Regexp matched a line in the file
|
||||||
if index[0] != -1:
|
if index[0] != -1:
|
||||||
if backrefs:
|
if backrefs and match:
|
||||||
b_new_line = m.expand(b_line)
|
b_new_line = match.expand(b_line)
|
||||||
else:
|
else:
|
||||||
# Don't do backref expansion if not asked.
|
# Don't do backref expansion if not asked.
|
||||||
b_new_line = b_line
|
b_new_line = b_line
|
||||||
|
@ -345,7 +345,7 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create,
|
||||||
|
|
||||||
# If no regexp was given and no line match is found anywhere in the file,
|
# If no regexp was given and no line match is found anywhere in the file,
|
||||||
# insert the line appropriately if using insertbefore or insertafter
|
# insert the line appropriately if using insertbefore or insertafter
|
||||||
if regexp is None and m is None:
|
if regexp is None and match is None and not exact_line_match:
|
||||||
|
|
||||||
# Insert lines
|
# Insert lines
|
||||||
if insertafter and insertafter != 'EOF':
|
if insertafter and insertafter != 'EOF':
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: "{{ output_dir }}/test.txt"
|
dest: "{{ output_dir }}/test.txt"
|
||||||
state: present
|
state: present
|
||||||
line: "New line after line 5"
|
line: "New line before line 5"
|
||||||
insertbefore: "^This is line 5$"
|
insertbefore: "^This is line 5$"
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
|
@ -144,22 +144,33 @@
|
||||||
- name: assert test checksum matches after the insert before the last line
|
- name: assert test checksum matches after the insert before the last line
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "result.stat.checksum == 'e1cae425403507feea4b55bb30a74decfdd4a23e'"
|
- "result.stat.checksum == '2e9e460ff68929e4453eb765761fd99814f6e286'"
|
||||||
|
|
||||||
- name: replace a line with backrefs
|
- name: Replace a line with backrefs
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: "{{ output_dir }}/test.txt"
|
dest: "{{ output_dir }}/test.txt"
|
||||||
state: present
|
state: present
|
||||||
line: "This is line 3"
|
line: "This is line 3"
|
||||||
backrefs: yes
|
backrefs: yes
|
||||||
regexp: "^(REF) .* \\1$"
|
regexp: "^(REF) .* \\1$"
|
||||||
register: result
|
register: backrefs_result1
|
||||||
|
|
||||||
|
- name: Replace a line with backrefs again
|
||||||
|
lineinfile:
|
||||||
|
dest: "{{ output_dir }}/test.txt"
|
||||||
|
state: present
|
||||||
|
line: "This is line 3"
|
||||||
|
backrefs: yes
|
||||||
|
regexp: "^(REF) .* \\1$"
|
||||||
|
register: backrefs_result2
|
||||||
|
- command: cat {{ output_dir }}/test.txt
|
||||||
|
|
||||||
- name: assert that the line with backrefs was changed
|
- name: assert that the line with backrefs was changed
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result is changed
|
- backrefs_result1 is changed
|
||||||
- "result.msg == 'line replaced'"
|
- backrefs_result2 is not changed
|
||||||
|
- "backrefs_result1.msg == 'line replaced'"
|
||||||
|
|
||||||
- name: stat the test after the backref line was replaced
|
- name: stat the test after the backref line was replaced
|
||||||
stat:
|
stat:
|
||||||
|
@ -169,7 +180,7 @@
|
||||||
- name: assert test checksum matches after backref line was replaced
|
- name: assert test checksum matches after backref line was replaced
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "result.stat.checksum == '2ccdf45d20298f9eaece73b713648e5489a52444'"
|
- "result.stat.checksum == '72f60239a735ae06e769d823f5c2b4232c634d9c'"
|
||||||
|
|
||||||
- name: remove the middle line
|
- name: remove the middle line
|
||||||
lineinfile:
|
lineinfile:
|
||||||
|
@ -192,7 +203,7 @@
|
||||||
- name: assert test checksum matches after the middle line was removed
|
- name: assert test checksum matches after the middle line was removed
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "result.stat.checksum == 'a6ba6865547c19d4c203c38a35e728d6d1942c75'"
|
- "result.stat.checksum == 'd4eeb07bdebab2d1cdb3ec4a3635afa2618ad4ea'"
|
||||||
|
|
||||||
- name: run a validation script that succeeds
|
- name: run a validation script that succeeds
|
||||||
lineinfile:
|
lineinfile:
|
||||||
|
@ -216,7 +227,7 @@
|
||||||
- name: assert test checksum matches after the validation succeeded
|
- name: assert test checksum matches after the validation succeeded
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "result.stat.checksum == '76955a4516a00a38aad8427afc9ee3e361024ba5'"
|
- "result.stat.checksum == 'ab56c210ea82839a54487464800fed4878cb2608'"
|
||||||
|
|
||||||
- name: run a validation script that fails
|
- name: run a validation script that fails
|
||||||
lineinfile:
|
lineinfile:
|
||||||
|
@ -240,7 +251,7 @@
|
||||||
- name: assert test checksum matches the previous after the validation failed
|
- name: assert test checksum matches the previous after the validation failed
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "result.stat.checksum == '76955a4516a00a38aad8427afc9ee3e361024ba5'"
|
- "result.stat.checksum == 'ab56c210ea82839a54487464800fed4878cb2608'"
|
||||||
|
|
||||||
- name: use create=yes
|
- name: use create=yes
|
||||||
lineinfile:
|
lineinfile:
|
||||||
|
@ -351,7 +362,7 @@
|
||||||
- name: assert test checksum matches after inserting multiple lines
|
- name: assert test checksum matches after inserting multiple lines
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "result.stat.checksum == 'bf5b711f8f0509355aaeb9d0d61e3e82337c1365'"
|
- "result.stat.checksum == 'fde683229429a4f05d670e6c10afc875e1d5c489'"
|
||||||
|
|
||||||
- name: replace a line with backrefs included in the line
|
- name: replace a line with backrefs included in the line
|
||||||
lineinfile:
|
lineinfile:
|
||||||
|
@ -376,7 +387,7 @@
|
||||||
- name: assert test checksum matches after backref line was replaced
|
- name: assert test checksum matches after backref line was replaced
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- "result.stat.checksum == '04b7a54d0fb233a4e26c9e625325bb4874841b3c'"
|
- "result.stat.checksum == '981ad35c4b30b03bc3a1beedce0d1e72c491898e'"
|
||||||
|
|
||||||
###################################################################
|
###################################################################
|
||||||
# issue 8535
|
# issue 8535
|
||||||
|
|
Loading…
Reference in a new issue