Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add file.comment ignore_missing #62045

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/61662.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix file.comment incorrectly reports changes in test mode
1 change: 1 addition & 0 deletions changelog/62044.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add ignore_missing parameter to file.comment state
22 changes: 18 additions & 4 deletions salt/states/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -6004,8 +6004,11 @@ def blockreplace(
return ret


def comment(name, regex, char="#", backup=".bak"):
def comment(name, regex, char="#", backup=".bak", ignore_missing=False):
"""
.. versionadded:: 0.9.5
.. versionchanged:: 3005

Comment out specified lines in a file.

name
Expand All @@ -6030,6 +6033,12 @@ def comment(name, regex, char="#", backup=".bak"):
after the first invocation.

Set to False/None to not keep a backup.
ignore_missing
Ignore a failure to find the regex in the file. This is useful for
scenarios where a line must only be commented if it is found in the
file.

.. versionadded:: 3005

Usage:

Expand All @@ -6039,7 +6048,6 @@ def comment(name, regex, char="#", backup=".bak"):
file.comment:
- regex: ^bind 127.0.0.1

.. versionadded:: 0.9.5
"""
name = os.path.expanduser(name)

Expand All @@ -6054,14 +6062,19 @@ def comment(name, regex, char="#", backup=".bak"):
# remove (?i)-like flags, ^ and $
unanchor_regex = re.sub(r"^(\(\?[iLmsux]\))?\^?(.*?)\$?$", r"\2", regex)

uncomment_regex = "^(?!.*{}).*".format(char) + unanchor_regex
comment_regex = char + unanchor_regex

# Make sure the pattern appears in the file before continuing
if not __salt__["file.search"](name, regex, multiline=True):
if not __salt__["file.search"](name, uncomment_regex, multiline=True):
if __salt__["file.search"](name, comment_regex, multiline=True):
ret["comment"] = "Pattern already commented"
ret["result"] = True
return ret
elif ignore_missing:
ret["comment"] = "Pattern not found and ignore_missing set to True"
ret["result"] = True
return ret
else:
return _error(ret, "{}: Pattern not found".format(unanchor_regex))

Expand All @@ -6070,6 +6083,7 @@ def comment(name, regex, char="#", backup=".bak"):
ret["comment"] = "File {} is set to be updated".format(name)
ret["result"] = None
return ret

with salt.utils.files.fopen(name, "rb") as fp_:
slines = fp_.read()
slines = slines.decode(__salt_system_encoding__)
Expand All @@ -6084,7 +6098,7 @@ def comment(name, regex, char="#", backup=".bak"):
nlines = nlines.splitlines(True)

# Check the result
ret["result"] = __salt__["file.search"](name, unanchor_regex, multiline=True)
ret["result"] = __salt__["file.search"](name, comment_regex, multiline=True)

if slines != nlines:
if not __utils__["files.is_text"](name):
Expand Down
19 changes: 17 additions & 2 deletions tests/pytests/unit/states/file/test_comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,30 @@ def test_comment():
with patch.object(os.path, "isabs", mock_t):
with patch.dict(
filestate.__salt__,
{"file.search": MagicMock(side_effect=[False, True, False, False])},
{
"file.search": MagicMock(
side_effect=[False, True, False, False, False, False]
)
},
):
comt = "Pattern already commented"
ret.update({"comment": comt, "result": True})
assert filestate.comment(name, regex) == ret

comt = "Pattern not found and ignore_missing set to True"
ret.update({"comment": comt, "result": True})
assert filestate.comment(name, regex, ignore_missing=True) == ret

comt = "{}: Pattern not found".format(regex)
ret.update({"comment": comt, "result": False})
assert filestate.comment(name, regex) == ret

with patch.dict(
filestate.__salt__,
{
"file.search": MagicMock(side_effect=[True, True, True]),
"file.search": MagicMock(
side_effect=[True, True, True, False, True]
),
"file.comment": mock_t,
"file.comment_line": mock_t,
},
Expand All @@ -98,6 +108,11 @@ def test_comment():
ret.update({"comment": comt, "result": True, "changes": {}})
assert filestate.comment(name, regex) == ret

with patch.dict(filestate.__opts__, {"test": True}):
comt = "Pattern already commented"
ret.update({"comment": comt, "result": True, "changes": {}})
assert filestate.comment(name, regex) == ret


# 'uncomment' function tests: 1
def test_uncomment():
Expand Down