#!/usr/bin/env python # -*- coding: utf-8 -*- ''' @author: Pierre Thibault (pierre.thibault1 -at- gmail.com) @license: MIT @since: 2011-06-17 Usage: dict_diff [OPTION]... dict1 dict2 Show the differences for two dictionaries. -h, --help Display this help message. dict1 and dict2 are two web2py dictionary files to compare. These are the files located in the "languages" directory of a web2py app. The tools show the differences between the two files. ''' __docformat__ = "epytext en" import getopt import os.path import sys def main(argv): """Parse the arguments and start the main process.""" try: opts, args = getopt.getopt(argv, "h", ["help"]) except getopt.GetoptError: exit_with_parsing_error() for opt, arg in opts: arg = arg # To avoid a warning from Pydev if opt in ("-h", "--help"): usage() sys.exit() if len(args) == 2: params = list(get_dicts(*args)) params.extend(get_dict_names(*args)) compare_dicts(*params) else: exit_with_parsing_error() def exit_with_parsing_error(): """Report invalid arguments and usage.""" print("Invalid argument(s).") usage() sys.exit(2) def usage(): """Display the documentation""" print(__doc__) def get_dicts(dict_path1, dict_path2): """ Parse the dictionaries. @param dict_path1: The path to the first dictionary. @param dict_path2: The path to the second dictionary. @return: The two dictionaries as a sequence. """ return eval(open(dict_path1).read()), eval(open(dict_path2).read()) def get_dict_names(dict1_path, dict2_path): """ Get the name of the dictionaries for the end user. Use the base name of the files. If the two base names are identical, returns "dict1" and "dict2." @param dict1_path: The path to the first dictionary. @param dict2_path: The path to the second dictionary. @return: The two dictionary names as a sequence. """ dict1_name = os.path.basename(dict1_path) dict2_name = os.path.basename(dict2_path) if dict1_name == dict2_name: dict1_name = "dict1" dict2_name = "dict2" return dict1_name, dict2_name def compare_dicts(dict1, dict2, dict1_name, dict2_name): """ Compare the two dictionaries. Print out the result. @param dict1: The first dictionary. @param dict1: The second dictionary. @param dict1_name: The name of the first dictionary. @param dict2_name: The name of the second dictionary. """ dict1_keyset = set(dict1.keys()) dict2_keyset = set(dict2.keys()) print_key_diff(dict1_keyset - dict2_keyset, dict1_name, dict2_name) print_key_diff(dict2_keyset - dict1_keyset, dict2_name, dict1_name) print "Value differences:" has_value_differences = False for key in dict1_keyset & dict2_keyset: if dict1[key] != dict2[key]: print " %s:" % (key,) print " %s: %s" % (dict1_name, dict1[key],) print " %s: %s" % (dict2_name, dict2[key],) print has_value_differences = True if not has_value_differences: print " None" def print_key_diff(key_diff, dict1_name, dict2_name): """ Prints the keys in the first dictionary and are in the second dictionary. @param key_diff: Keys in dictionary 1 not in dictionary 2. @param dict1_name: Name used for the first dictionary. @param dict2_name: Name used for the second dictionary. """ print "Keys in %s not in %s:" % (dict1_name, dict2_name) if len(key_diff): for key in key_diff: print " %s" % (key,) else: print " None" print if __name__ == "__main__": main(sys.argv[1:]) # Start the process (without the application name)