mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Added additional lineinfile documentation.
A little more unit testing.
This commit is contained in:
parent
f9b70822d2
commit
ca581840ef
2 changed files with 67 additions and 16 deletions
|
@ -25,7 +25,8 @@ DOCUMENTATION = """
|
||||||
---
|
---
|
||||||
module: lineinfile
|
module: lineinfile
|
||||||
author: Daniel Hokka Zakrisson
|
author: Daniel Hokka Zakrisson
|
||||||
short_description: Ensure a particular line is in a file
|
short_description: Ensure a particular line is in a file, or replace an
|
||||||
|
existing line using a back-referenced regular expression.
|
||||||
description:
|
description:
|
||||||
- This module will search a file for a line, and ensure that it is present or absent.
|
- This module will search a file for a line, and ensure that it is present or absent.
|
||||||
- This is primarily useful when you want to change a single line in a
|
- This is primarily useful when you want to change a single line in a
|
||||||
|
@ -36,12 +37,13 @@ options:
|
||||||
required: true
|
required: true
|
||||||
aliases: [ name, destfile ]
|
aliases: [ name, destfile ]
|
||||||
description:
|
description:
|
||||||
- The file to modify
|
- The file to modify.
|
||||||
regexp:
|
regexp:
|
||||||
required: true
|
required: true
|
||||||
description:
|
description:
|
||||||
- The regular expression to look for in the file. For C(state=present),
|
- The regular expression to look for in every line of the file. For
|
||||||
the pattern to replace. For C(state=absent), the pattern of the line
|
C(state=present), the pattern to replace if found; only the last line
|
||||||
|
found will be replaced. For C(state=absent), the pattern of the line
|
||||||
to remove. Uses Python regular expressions; see
|
to remove. Uses Python regular expressions; see
|
||||||
U(http://docs.python.org/2/library/re.html).
|
U(http://docs.python.org/2/library/re.html).
|
||||||
state:
|
state:
|
||||||
|
@ -55,7 +57,22 @@ options:
|
||||||
required: false
|
required: false
|
||||||
description:
|
description:
|
||||||
- Required for C(state=present). The line to insert/replace into the
|
- Required for C(state=present). The line to insert/replace into the
|
||||||
file. May contain backreferences.
|
file. If backrefs is set, may contain backreferences that will get
|
||||||
|
expanded with the regexp capture groups if the regexp matches. The
|
||||||
|
backreferences should be double escaped (see examples).
|
||||||
|
backrefs:
|
||||||
|
required: false
|
||||||
|
default: "no"
|
||||||
|
choices: [ "yes", "no" ]
|
||||||
|
version_added: 1.1
|
||||||
|
description:
|
||||||
|
- Used with C(state=present). If set, line can contain backreferences
|
||||||
|
(both positional and named) that will get populated if the regexp
|
||||||
|
matches. This flag changes the operation of the module slightly;
|
||||||
|
insertbefore) and insertafter will be ignored, and if the regexp
|
||||||
|
doesn't match anywhere in the file, the file will be left unchanged.
|
||||||
|
If the regexp does match, the last matching line will be replaced by
|
||||||
|
the expanded line parameter.
|
||||||
insertafter:
|
insertafter:
|
||||||
required: false
|
required: false
|
||||||
default: EOF
|
default: EOF
|
||||||
|
@ -63,6 +80,7 @@ options:
|
||||||
- Used with C(state=present). If specified, the line will be inserted
|
- Used with C(state=present). If specified, the line will be inserted
|
||||||
after the specified regular expression. A special value is
|
after the specified regular expression. A special value is
|
||||||
available; C(EOF) for inserting the line at the end of the file.
|
available; C(EOF) for inserting the line at the end of the file.
|
||||||
|
May not be used with backrefs.
|
||||||
choices: [ 'EOF', '*regex*' ]
|
choices: [ 'EOF', '*regex*' ]
|
||||||
insertbefore:
|
insertbefore:
|
||||||
required: false
|
required: false
|
||||||
|
@ -70,8 +88,8 @@ options:
|
||||||
description:
|
description:
|
||||||
- Used with C(state=present). If specified, the line will be inserted
|
- Used with C(state=present). If specified, the line will be inserted
|
||||||
before the specified regular expression. A value is available;
|
before the specified regular expression. A value is available;
|
||||||
C(BOF) for inserting the line at the beginning of the
|
C(BOF) for inserting the line at the beginning of the file.
|
||||||
file.
|
May not be used with backrefs.
|
||||||
choices: [ 'BOF', '*regex*' ]
|
choices: [ 'BOF', '*regex*' ]
|
||||||
create:
|
create:
|
||||||
required: false
|
required: false
|
||||||
|
@ -94,7 +112,7 @@ options:
|
||||||
required: false
|
required: false
|
||||||
"""
|
"""
|
||||||
|
|
||||||
EXAMPLES = """
|
EXAMPLES = r"""
|
||||||
lineinfile: dest=/etc/selinux/config regexp=^SELINUX= line=SELINUX=disabled
|
lineinfile: dest=/etc/selinux/config regexp=^SELINUX= line=SELINUX=disabled
|
||||||
|
|
||||||
lineinfile: dest=/etc/sudoers state=absent regexp="^%wheel"
|
lineinfile: dest=/etc/sudoers state=absent regexp="^%wheel"
|
||||||
|
@ -105,9 +123,9 @@ EXAMPLES = """
|
||||||
|
|
||||||
lineinfile: dest=/etc/services regexp="^# port for http" insertbefore="^www.*80/tcp" line="# port for http by default"
|
lineinfile: dest=/etc/services regexp="^# port for http" insertbefore="^www.*80/tcp" line="# port for http by default"
|
||||||
|
|
||||||
lineinfile: \\\"dest=/etc/sudoers state=present regexp='^%wheel' line ='%wheel ALL=(ALL) NOPASSWD: ALL'\\\"
|
lineinfile: dest=/etc/sudoers state=present regexp='^%wheel' line ='%wheel ALL=(ALL) NOPASSWD: ALL'
|
||||||
|
|
||||||
lineinfile dest=/tmp/grub.conf state=present regexp='^(splashimage=.*)$' line="#\\1"
|
lineinfile: dest=/opt/jboss-as/bin/standalone.conf state=present regexp='^(.*)Xms(\d+)m(.*)$' line='\\1Xms${xms}m\\3'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -456,7 +456,7 @@ class TestRunner(unittest.TestCase):
|
||||||
# The order of the test cases is important
|
# The order of the test cases is important
|
||||||
|
|
||||||
# The regexp doesn't match, so the line will not be added anywhere.
|
# The regexp doesn't match, so the line will not be added anywhere.
|
||||||
testline = '\\1: Line added by default at the end of the file.'
|
testline = r'\\1: Line added by default at the end of the file.'
|
||||||
testcase = ('lineinfile', [
|
testcase = ('lineinfile', [
|
||||||
"dest=%s" % sample,
|
"dest=%s" % sample,
|
||||||
"regexp='^(First): '",
|
"regexp='^(First): '",
|
||||||
|
@ -471,7 +471,7 @@ class TestRunner(unittest.TestCase):
|
||||||
|
|
||||||
# insertafter with EOF
|
# insertafter with EOF
|
||||||
# The regexp doesn't match, so the line will not be added anywhere.
|
# The regexp doesn't match, so the line will not be added anywhere.
|
||||||
testline = '\\1: Line added with insertafter=EOF'
|
testline = r'\\1: Line added with insertafter=EOF'
|
||||||
testcase = ('lineinfile', [
|
testcase = ('lineinfile', [
|
||||||
"dest=%s" % sample,
|
"dest=%s" % sample,
|
||||||
"insertafter=EOF",
|
"insertafter=EOF",
|
||||||
|
@ -487,7 +487,7 @@ class TestRunner(unittest.TestCase):
|
||||||
|
|
||||||
# with invalid insertafter regex
|
# with invalid insertafter regex
|
||||||
# The regexp doesn't match, so do nothing.
|
# The regexp doesn't match, so do nothing.
|
||||||
testline = '\\1: Line added with an invalid insertafter regex'
|
testline = r'\\1: Line added with an invalid insertafter regex'
|
||||||
testcase = ('lineinfile', [
|
testcase = ('lineinfile', [
|
||||||
"dest=%s" % sample,
|
"dest=%s" % sample,
|
||||||
"insertafter='^abcdefgh'",
|
"insertafter='^abcdefgh'",
|
||||||
|
@ -501,7 +501,7 @@ class TestRunner(unittest.TestCase):
|
||||||
|
|
||||||
# with an insertafter regex
|
# with an insertafter regex
|
||||||
# The regexp doesn't match, so do nothing.
|
# The regexp doesn't match, so do nothing.
|
||||||
testline = '\\1: Line added with a valid insertafter regex'
|
testline = r'\\1: Line added with a valid insertafter regex'
|
||||||
testcase = ('lineinfile', [
|
testcase = ('lineinfile', [
|
||||||
"dest=%s" % sample,
|
"dest=%s" % sample,
|
||||||
"insertafter='^receive messages to '",
|
"insertafter='^receive messages to '",
|
||||||
|
@ -520,8 +520,8 @@ class TestRunner(unittest.TestCase):
|
||||||
target_line = 'combination of microphone, speaker, keyboard and display. It can send and'
|
target_line = 'combination of microphone, speaker, keyboard and display. It can send and'
|
||||||
idx = artifact.index(target_line)
|
idx = artifact.index(target_line)
|
||||||
|
|
||||||
testline = '\\\\1 of microphone'
|
testline = r'\\1 of megaphone'
|
||||||
testline_after = 'combination of microphone'
|
testline_after = 'combination of megaphone'
|
||||||
testcase = ('lineinfile', [
|
testcase = ('lineinfile', [
|
||||||
"dest=%s" % sample,
|
"dest=%s" % sample,
|
||||||
"regexp='(combination) of microphone'",
|
"regexp='(combination) of microphone'",
|
||||||
|
@ -536,6 +536,39 @@ class TestRunner(unittest.TestCase):
|
||||||
assert artifact.index(testline_after) == idx
|
assert artifact.index(testline_after) == idx
|
||||||
assert target_line not in artifact
|
assert target_line not in artifact
|
||||||
|
|
||||||
|
# Go again, should be unchanged now.
|
||||||
|
testline = r'\\1 of megaphone'
|
||||||
|
testline_after = 'combination of megaphone'
|
||||||
|
testcase = ('lineinfile', [
|
||||||
|
"dest=%s" % sample,
|
||||||
|
"regexp='(combination) of megaphone'",
|
||||||
|
"line='%s'" % testline,
|
||||||
|
"backrefs=yes",
|
||||||
|
])
|
||||||
|
result = self._run(*testcase)
|
||||||
|
assert not result['changed']
|
||||||
|
assert result['msg'] == ''
|
||||||
|
|
||||||
|
# Try a numeric, named capture group example.
|
||||||
|
f = open(sample, 'a+')
|
||||||
|
f.write("1 + 1 = 3" + os.linesep)
|
||||||
|
f.close()
|
||||||
|
testline = r"2 + \\g<num> = 3"
|
||||||
|
testline_after = "2 + 1 = 3"
|
||||||
|
testcase = ('lineinfile', [
|
||||||
|
"dest=%s" % sample,
|
||||||
|
r"regexp='1 \\+ (?P<num>\\d) = 3'",
|
||||||
|
"line='%s'" % testline,
|
||||||
|
"backrefs=yes",
|
||||||
|
])
|
||||||
|
result = self._run(*testcase)
|
||||||
|
artifact = [x.strip() for x in open(sample)]
|
||||||
|
assert result['changed']
|
||||||
|
assert result['msg'] == 'line replaced'
|
||||||
|
artifact = [x.strip() for x in open(sample)]
|
||||||
|
assert '1 + 1 = 3' not in artifact
|
||||||
|
assert testline_after == artifact[-1]
|
||||||
|
|
||||||
# with both insertafter and insertbefore (should fail)
|
# with both insertafter and insertbefore (should fail)
|
||||||
testline = 'Seventh: this line should not be there'
|
testline = 'Seventh: this line should not be there'
|
||||||
testcase = ('lineinfile', [
|
testcase = ('lineinfile', [
|
||||||
|
|
Loading…
Reference in a new issue