URL
https://opencores.org/ocsvn/radiohdl/radiohdl/trunk
Subversion Repositories radiohdl
[/] [radiohdl/] [trunk/] [core/] [modify_configfiles] - Rev 4
Compare with Previous | Blame | View Log
#!/usr/bin/env python3
###############################################################################
#
# Copyright (C) 2014-2018
# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# $Id: configfile_modifier.py 18609 2018-07-18 08:06:30Z overeem $
#
###############################################################################
"""
Interactive program to modify all configfiles found in the hierarchical directory
structure under the given top directory.
"""
from argparse import ArgumentParser
from hdl_raw_access import RawConfigTree
# Define a simple menu system that is based on a dict that contains the menu actions:
# the keys are the valid strings the user may enter
# the values are lists: the first element is the menu tekst, the second the function to call and
# the remaining elememts (if any) are the arguments to ask the user
# All arguments are stored in a kwargs structure and passed to the functions that is called.
def get_menu_choice(menu, title):
"""
Iterate over the menu dict, show the menu choices and ask for input till valid input is received.
"""
print("\n", title)
print("-" * len(title))
input_ok = False
while not input_ok:
for key in sorted(menu.keys()):
print("{} {}".format(key, menu[key][0]))
choice = input("\n >>: ")
if choice not in list(menu.keys()):
print("ERROR: This input is not a valid menu choice. Try again.")
else:
input_ok = True
return menu[choice]
def execute_menu_line(line_spec, verbose):
"""
Given a menu line specification it asks the user for the specified arguments, stores the values in a
kwargs structure and finally call the specified function with this kwargs.
"""
print("\n--- {} ---".format(line_spec[0]))
nr_args = len(line_spec) - 2
if nr_args < 0:
raise SyntaxError("Invalid formatted menuline definition: {}.\nNeed at least two items in the list".format(line_spec))
if nr_args == 0:
return line_spec[1]()
# Iterate over the remaining items and get values for them
kwargs = {"verbose": verbose}
for spec_idx in range(2, len(line_spec)):
answer = input(line_spec[spec_idx].capitalize().replace("_", " ") + ": ")
kwargs[line_spec[spec_idx]] = answer
line_spec[1](**kwargs)
# ## Implementation of the menu commands
# Note: cleaner would to implement this with the Strategy pattern but we want to keep the code
# to be readable for everyone. ;-)
def change_value_of_key(**kwargs):
key = kwargs.pop("key")
new_value = kwargs.pop("new_value")
verbose = kwargs.pop("verbose")
global tree
for filename in sorted(tree.configfiles.keys()):
tree.configfiles[filename].change_value(key, new_value, verbose)
def append_key_value(**kwargs):
key = kwargs.pop("new_key")
new_value = kwargs.pop("new_value")
verbose = kwargs.pop("verbose")
global tree
for filename in sorted(tree.configfiles.keys()):
tree.configfiles[filename].append_key_value(key, new_value, verbose)
def insert_key_at_linenr(**kwargs):
new_key = kwargs.pop("new_key")
new_value = kwargs.pop("new_value")
linenumber = int(kwargs.pop("linenumber"))
verbose = kwargs.pop("verbose")
global tree
for filename in sorted(tree.configfiles.keys()):
tree.configfiles[filename].insert_key_at_linenr(new_key, new_value, linenumber, verbose)
def insert_key_value_before_key(**kwargs):
new_key = kwargs.pop("new_key")
new_value = kwargs.pop("new_value")
before_key = kwargs.pop("before_key")
verbose = kwargs.pop("verbose")
global tree
for filename in sorted(tree.configfiles.keys()):
tree.configfiles[filename].insert_key_value_before_key(new_key, new_value, before_key, verbose)
def rename_key(**kwargs):
old_key = kwargs.pop("old_key")
new_key = kwargs.pop("new_key")
verbose = kwargs.pop("verbose")
global tree
for filename in sorted(tree.configfiles.keys()):
tree.configfiles[filename].rename_key(old_key, new_key, verbose)
def remove_key(**kwargs):
key = kwargs.pop("key")
verbose = kwargs.pop("verbose")
global tree
for filename in sorted(tree.configfiles.keys()):
tree.configfiles[filename].remove_key(key, verbose)
def end_menu():
global running
running = False
if __name__ == '__main__':
# setup parser and parse the arguments.
argparser = ArgumentParser(description='Options and arguments for modifying collections of configfiles.')
argparser.add_argument('filename', help="Filename like 'hdl_buildset_<boardtype>.cfg'")
argparser.add_argument('rootdir', help="Top directory to start the search for configfiles.")
argparser.add_argument('-v', '--verbose', help="Show more information on what happens.", action="store_true")
args = argparser.parse_args()
tree = RawConfigTree(args.rootdir, args.filename)
print("Found {} configfiles in {}".format(len(tree.configfiles), args.rootdir))
if args.verbose:
for filename in sorted(tree.configfiles.keys()):
print(filename)
# define the menu including actions
# choice choice description function to call arguments to ask for
menu = {'1': ["Change value", change_value_of_key, "key", "new_value"],
'2': ["Append key", append_key_value, "new_key", "new_value"],
'3': ["Insert key at linenr", insert_key_at_linenr, "new_key", "new_value", "linenumber"],
'4': ["Insert key before other key", insert_key_value_before_key, "new_key", "new_value", "before_key"],
'5': ["Rename key", rename_key, "old_key", "new_key"],
'6': ["Remove key", remove_key, "key"],
'q': ["Exit", end_menu]
}
running = True
while running:
execute_menu_line(get_menu_choice(menu, "Menu for changing multiple configfiles"), args.verbose)