diff --git a/management/editconf.py b/management/editconf.py new file mode 100644 index 00000000..bd279789 --- /dev/null +++ b/management/editconf.py @@ -0,0 +1,142 @@ +#!/usr/bin/python3 +# +# This is a helper tool for editing configuration files during the setup +# process. The tool is given new values for settings as command-line +# arguments. It comments-out existing setting values in the configuration +# file and adds new values either after their former location or at the +# end. +# +# The configuration file has settings that look like: +# +# NAME=VALUE +# +# If the -s option is given, then space becomes the delimiter, i.e.: +# +# NAME VALUE +# +# If the -c option is given, then the supplied character becomes the comment character +# +# If the -w option is given, then setting lines continue onto following +# lines while the lines start with whitespace, e.g.: +# +# NAME VAL +# UE + +# create the new config file in memory + +def edit_conf(filename, settings, folded_lines, testing): + found = set() + buf = "" + input_lines = list(open(filename)) + + while len(input_lines) > 0: + line = input_lines.pop(0) + + # If this configuration file uses folded lines, append any folded lines + # into our input buffer. + if folded_lines and line[0] not in (comment_char, " ", ""): + while len(input_lines) > 0 and input_lines[0][0] in " \t": + line += input_lines.pop(0) + + # See if this line is for any settings passed on the command line. + for i in range(len(settings)): + # Check that this line contain this setting from the command-line arguments. + name, val = settings[i].split("=", 1) + m = re.match( + "(\s*)" + + "(" + re.escape(comment_char) + "\s*)?" + + re.escape(name) + delimiter_re + "(.*?)\s*$", + line, re.S) + if not m: continue + indent, is_comment, existing_val = m.groups() + + # If this is already the setting, do nothing. + if is_comment is None and existing_val == val: + # It may be that we've already inserted this setting higher + # in the file so check for that first. + if i in found: break + buf += line + found.add(i) + break + + # comment-out the existing line (also comment any folded lines) + if is_comment is None: + buf += comment_char + line.rstrip().replace("\n", "\n" + comment_char) + "\n" + else: + # the line is already commented, pass it through + buf += line + + # if this option oddly appears more than once, don't add the setting again + if i in found: + break + + # add the new setting + buf += indent + name + delimiter + val + "\n" + + # note that we've applied this option + found.add(i) + + break + else: + # If did not match any setting names, pass this line through. + buf += line + + # Put any settings we didn't see at the end of the file. + for i in range(len(settings)): + if i not in found: + name, val = settings[i].split("=", 1) + buf += name + delimiter + val + "\n" + + if not testing: + # Write out the new file. + with open(filename, "w") as f: + f.write(buf) + else: + # Just print the new file to stdout. + print(buf) + +# Run standalone +if __name__ == "__main__": + import sys, re + + # sanity check + if len(sys.argv) < 3: + print("usage: python3 editconf.py /etc/file.conf [-s] [-w] [-c ] [-t] NAME=VAL [NAME=VAL ...]") + sys.exit(1) + + # parse command line arguments + filename = sys.argv[1] + settings = sys.argv[2:] + + delimiter = "=" + delimiter_re = r"\s*=\s*" + comment_char = "#" + folded_lines = False + testing = False + while settings[0][0] == "-" and settings[0] != "--": + opt = settings.pop(0) + if opt == "-s": + # Space is the delimiter + delimiter = " " + delimiter_re = r"\s+" + elif opt == "-w": + # Line folding is possible in this file. + folded_lines = True + elif opt == "-c": + # Specifies a different comment character. + comment_char = settings.pop(0) + elif opt == "-t": + testing = True + else: + print("Invalid option.") + sys.exit(1) + + # sanity check command line + for setting in settings: + try: + name, value = setting.split("=", 1) + except: + import subprocess + print("Invalid command line: ", subprocess.list2cmdline(sys.argv)) + + edit_conf(filename, settings, folded_lines, testing) diff --git a/tools/editconf.py b/tools/editconf.py old mode 100755 new mode 100644 index d665f861..c6727467 --- a/tools/editconf.py +++ b/tools/editconf.py @@ -1,137 +1,6 @@ #!/usr/bin/python3 -# -# This is a helper tool for editing configuration files during the setup -# process. The tool is given new values for settings as command-line -# arguments. It comments-out existing setting values in the configuration -# file and adds new values either after their former location or at the -# end. -# -# The configuration file has settings that look like: -# -# NAME=VALUE -# -# If the -s option is given, then space becomes the delimiter, i.e.: -# -# NAME VALUE -# -# If the -c option is given, then the supplied character becomes the comment character -# -# If the -w option is given, then setting lines continue onto following -# lines while the lines start with whitespace, e.g.: -# -# NAME VAL -# UE -import sys, re +from os import system, argv -# sanity check -if len(sys.argv) < 3: - print("usage: python3 editconf.py /etc/file.conf [-s] [-w] [-c ] [-t] NAME=VAL [NAME=VAL ...]") - sys.exit(1) - -# parse command line arguments -filename = sys.argv[1] -settings = sys.argv[2:] - -delimiter = "=" -delimiter_re = r"\s*=\s*" -comment_char = "#" -folded_lines = False -testing = False -while settings[0][0] == "-" and settings[0] != "--": - opt = settings.pop(0) - if opt == "-s": - # Space is the delimiter - delimiter = " " - delimiter_re = r"\s+" - elif opt == "-w": - # Line folding is possible in this file. - folded_lines = True - elif opt == "-c": - # Specifies a different comment character. - comment_char = settings.pop(0) - elif opt == "-t": - testing = True - else: - print("Invalid option.") - sys.exit(1) - -# sanity check command line -for setting in settings: - try: - name, value = setting.split("=", 1) - except: - import subprocess - print("Invalid command line: ", subprocess.list2cmdline(sys.argv)) - -# create the new config file in memory - -found = set() -buf = "" -input_lines = list(open(filename)) - -while len(input_lines) > 0: - line = input_lines.pop(0) - - # If this configuration file uses folded lines, append any folded lines - # into our input buffer. - if folded_lines and line[0] not in (comment_char, " ", ""): - while len(input_lines) > 0 and input_lines[0][0] in " \t": - line += input_lines.pop(0) - - # See if this line is for any settings passed on the command line. - for i in range(len(settings)): - # Check that this line contain this setting from the command-line arguments. - name, val = settings[i].split("=", 1) - m = re.match( - "(\s*)" - + "(" + re.escape(comment_char) + "\s*)?" - + re.escape(name) + delimiter_re + "(.*?)\s*$", - line, re.S) - if not m: continue - indent, is_comment, existing_val = m.groups() - - # If this is already the setting, do nothing. - if is_comment is None and existing_val == val: - # It may be that we've already inserted this setting higher - # in the file so check for that first. - if i in found: break - buf += line - found.add(i) - break - - # comment-out the existing line (also comment any folded lines) - if is_comment is None: - buf += comment_char + line.rstrip().replace("\n", "\n" + comment_char) + "\n" - else: - # the line is already commented, pass it through - buf += line - - # if this option oddly appears more than once, don't add the setting again - if i in found: - break - - # add the new setting - buf += indent + name + delimiter + val + "\n" - - # note that we've applied this option - found.add(i) - - break - else: - # If did not match any setting names, pass this line through. - buf += line - -# Put any settings we didn't see at the end of the file. -for i in range(len(settings)): - if i not in found: - name, val = settings[i].split("=", 1) - buf += name + delimiter + val + "\n" - -if not testing: - # Write out the new file. - with open(filename, "w") as f: - f.write(buf) -else: - # Just print the new file to stdout. - print(buf) +# Pass control to the actual script +system(f"management/editconf.py {argv[1:]}")