From 25a6726a350fd4192b45a78b6312ab8345b02586 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal@redhat.com>
Date: Tue, 5 Dec 2017 13:43:04 +1100
Subject: [PATCH] installutils: refactor set_directive
To separate concerns and make it easier to test set_directive,
extract function ``set_directive_lines`` to do the line-wise
search/replace, leaving ``set_directive`` to deal with the file
handling.
Part of: https://pagure.io/freeipa/issue/7288
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipaserver/install/installutils.py | 56 +++++++++++++++++++++++----------------
1 file changed, 33 insertions(+), 23 deletions(-)
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 821609beb533fcc9064500a88ccd07b35142f1df..b56cf591496c679e5fcf3e94f458c286216eb1e4 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -444,34 +444,44 @@ def set_directive(filename, directive, value, quotes=True, separator=' '):
:param separator: character serving as separator between directive and
value. Correct value required even when dropping a directive.
"""
+ st = os.stat(filename)
+ with open(filename, 'r') as f:
+ lines = list(f) # read the whole file
+ new_lines = set_directive_lines(
+ quotes, separator, directive, value, lines)
+ with open(filename, 'w') as f:
+ # don't construct the whole string; write line-wise
+ for line in new_lines:
+ f.write(line)
+ os.chown(filename, st.st_uid, st.st_gid) # reset perms
- new_directive_value = ""
- if value is not None:
- value_to_set = quote_directive_value(value, '"') if quotes else value
- new_directive_value = "".join(
- [directive, separator, value_to_set, '\n'])
+def set_directive_lines(quotes, separator, k, v, lines):
+ """Set a name/value pair in a configuration (iterable of lines).
- valueset = False
- st = os.stat(filename)
- fd = open(filename)
- newfile = []
- for line in fd:
- if re.match(r'\s*{}'.format(re.escape(directive + separator)), line):
- valueset = True
- if value is not None:
- newfile.append(new_directive_value)
+ Replaces the value of the key if found, otherwise adds it at
+ end. If value is ``None``, remove the key if found.
+
+ Takes an iterable of lines (with trailing newline).
+ Yields lines (with trailing newline).
+
+ """
+ new_line = ""
+ if v is not None:
+ v_quoted = quote_directive_value(v, '"') if quotes else v
+ new_line = ''.join([k, separator, v_quoted, '\n'])
+
+ found = False
+ for line in lines:
+ if re.match(r'\s*{}'.format(re.escape(k + separator)), line):
+ found = True
+ if v is not None:
+ yield new_line
else:
- newfile.append(line)
- fd.close()
- if not valueset:
- if value is not None:
- newfile.append(new_directive_value)
+ yield line
- fd = open(filename, "w")
- fd.write("".join(newfile))
- fd.close()
- os.chown(filename, st.st_uid, st.st_gid) # reset perms
+ if not found and v is not None:
+ yield new_line
def get_directive(filename, directive, separator=' '):
--
2.13.6