Salome HOME
Merge branch 'master' into ngr/python3_dev
[tools/configuration.git] / config / scfgcmp
1 #!/usr/bin/env python
2 #  -*- coding: iso-8859-1 -*-
3
4 ###
5 # Command line tool to compare two SALOME configurations.
6 # Usage: type "scfgcmp help" to learn how to use tool.
7 ###
8
9 import sys
10 import os
11 from sconfig.salome_config import *
12 import getopt
13
14 def get_tool_name():
15     return os.path.basename(sys.argv[0])
16
17 def error_exit(msg):
18     print("%s: %s" % (get_tool_name(), msg))
19     print("Try '%s --help' for more information." % get_tool_name())
20     sys.exit(2)
21     pass
22
23 def usage():
24     print("Command line tool to compare two SALOME configurations.")
25     print()
26     print("Usage: %s [options] CFGFILE1 [CFGFILE2]" % get_tool_name())
27     print()
28     print("  CFGFILE1       First configuration file to compare.")
29     print("  CFGFILE2       Second configuration file to compare; if not specified,")
30     print("                 default one is used: %s." % defaultConfFile())
31     print()
32     print("Options:")
33     print("  --help (-h)    Prints this help information.")
34     print("  --force (-f)   Perform full comparation, including optional parameters.")
35     print("  --verbose (-v) Print results of comparison to the screen.")
36     print()
37
38 def main():
39     # parse command line
40
41     try:
42         opts, args = getopt.getopt(sys.argv[1:], "hfv", ["help", "force", "verbose"])
43     except getopt.GetoptError as err:
44         error_exit(str(err))
45         pass
46     opt_keys = [i[0] for i in opts]
47     isusage   = "-h" in opt_keys or "--help" in opt_keys
48     isverbose = "-v" in opt_keys or "--verbose" in opt_keys
49     isforce   = "-f" in opt_keys or "--force" in opt_keys
50
51     if isusage:
52         usage()
53         pass
54
55     cfgfile1 = args[0] if len(args) > 0 else defaultConfFile()
56     cfgfile2 = args[1] if len(args) > 1 else defaultConfFile()
57
58     if not cfgfile1:
59         error_exit("missing configuration file")
60         pass
61
62     if cfgfile1 and not os.path.isfile(cfgfile1):
63         error_exit("configuration file %s is not found" % cfgfile1)
64         pass
65
66     if cfgfile2 and not os.path.isfile(cfgfile2):
67         error_exit("configuration file %s is not found" % cfgfile2)
68         pass
69
70     if cfgfile1 and cfgfile2 and os.path.samefile(cfgfile1, cfgfile2):
71         error_exit("cannot compare the file with itself")
72         pass
73
74     # create config tools
75
76     try:
77         tool1 = CfgTool(cfgfile1)
78         tool2 = CfgTool(cfgfile2)
79     except Exception as e:
80         error_exit(str(e))
81         pass
82     
83     # diff config files
84
85     errors = []
86
87     def _cmpAttrs(_what, _where):
88         _attrs = tagAttributes(_what)
89         for _attr in _attrs:
90             try:
91                 _v1 = tool1.get(_where, _attr)
92             except:
93                 _v1 = None
94                 pass
95             try:
96                 _v2 = tool2.get(_where, _attr)
97             except:
98                 _v2 = None
99                 pass
100             if (isforce or _attrs[_attr]) and _v1 != _v2:
101                 errors.append("attribute '%s' of '%s' differs: '%s' in %s vs '%s' in %s" % (_attr, _where, str(_v1), tool1.cfgFile, str(_v2), tool2.cfgFile))
102                 pass
103             pass
104         pass
105     
106     # - compare parameters of configuration
107     _cmpAttrs(configTag(), configTag())
108
109     # - compare products
110
111     products1 = tool1.get(configTag(), softwareAlias())
112     products2 = tool2.get(configTag(), softwareAlias())
113     all_products = list(set(products1+products2))
114
115     for product in all_products:
116         if product in products1 and product not in products2:
117             errors.append("%s '%s' is only in '%s'" % (softwareTag(), product, tool1.cfgFile))
118             pass
119         elif product in products2 and product not in products1:
120             errors.append("%s '%s' is only in '%s'" % (softwareTag(), product, tool2.cfgFile))
121             pass
122         else:
123             # -- compare parameters of products
124             _cmpAttrs(softwareTag(), product)
125             # -- compare patches
126             patches1 = tool1.get(product, patchesAlias())
127             patches2 = tool2.get(product, patchesAlias())
128             all_patches = list(set(patches1+patches2))
129             for patch in all_patches:
130                 if patch in patches1 and patch not in patches2:
131                     errors.append("%s '%s' for '%s' is only in '%s'" % (patchTag(), patch, product, tool1.cfgFile))
132                     pass
133                 if patch in patches2 and patch not in patches1:
134                     errors.append("%s '%s' for '%s' is only in '%s'" % (patchTag(), patch, product, tool2.cfgFile))
135                     pass
136                 else:
137                     # -- compare parameters of products
138                     _cmpAttrs(patchTag(), "%s.%s.%s" % (product, patchesTag(), patch))
139                     pass
140                 pass
141             pass
142         pass
143     
144     # print results
145
146     if errors:
147         if isverbose:
148             print("Files %s and %s differ:" % (tool1.cfgFile, tool2.cfgFile))
149             print("\n".join(["  " + i for i in errors]))
150             pass
151         return 1
152
153     return 0
154
155 # -----------------------------------------------------------------------------
156
157 if __name__ == '__main__':
158     sys.exit(main())