Salome HOME
Porting: sip 5
[tools/configuration.git] / config / scfgcmp
1 #!/usr/bin/env python
2 #  -*- coding: iso-8859-1 -*-
3
4 # Copyright (C) 2016-2020  OPEN CASCADE
5 #
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
10 #
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # Lesser General Public License for more details.
15 #
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 #
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #
22
23 ###
24 # Command line tool to compare two SALOME configurations.
25 # Usage: type "scfgcmp help" to learn how to use tool.
26 ###
27
28 import sys
29 import os
30 from sconfig.salome_config import *
31 import getopt
32
33 def get_tool_name():
34     return os.path.basename(sys.argv[0])
35
36 def error_exit(msg):
37     print("%s: %s" % (get_tool_name(), msg))
38     print("Try '%s --help' for more information." % get_tool_name())
39     sys.exit(2)
40     pass
41
42 def usage():
43     print("Command line tool to compare two SALOME configurations.")
44     print()
45     print("Usage: %s [options] CFGFILE1 [CFGFILE2]" % get_tool_name())
46     print()
47     print("  CFGFILE1       First configuration file to compare.")
48     print("  CFGFILE2       Second configuration file to compare; if not specified,")
49     print("                 default one is used: %s." % defaultConfFile())
50     print()
51     print("Options:")
52     print("  --help (-h)    Prints this help information.")
53     print("  --force (-f)   Perform full comparation, including optional parameters.")
54     print("  --verbose (-v) Print results of comparison to the screen.")
55     print()
56
57 def main():
58     # parse command line
59
60     try:
61         opts, args = getopt.getopt(sys.argv[1:], "hfv", ["help", "force", "verbose"])
62     except getopt.GetoptError as err:
63         error_exit(str(err))
64         pass
65     opt_keys = [i[0] for i in opts]
66     isusage   = "-h" in opt_keys or "--help" in opt_keys
67     isverbose = "-v" in opt_keys or "--verbose" in opt_keys
68     isforce   = "-f" in opt_keys or "--force" in opt_keys
69
70     if isusage:
71         usage()
72         pass
73
74     cfgfile1 = args[0] if len(args) > 0 else defaultConfFile()
75     cfgfile2 = args[1] if len(args) > 1 else defaultConfFile()
76
77     if not cfgfile1:
78         error_exit("missing configuration file")
79         pass
80
81     if cfgfile1 and not os.path.isfile(cfgfile1):
82         error_exit("configuration file %s is not found" % cfgfile1)
83         pass
84
85     if cfgfile2 and not os.path.isfile(cfgfile2):
86         error_exit("configuration file %s is not found" % cfgfile2)
87         pass
88
89     if cfgfile1 and cfgfile2 and os.path.samefile(cfgfile1, cfgfile2):
90         error_exit("cannot compare the file with itself")
91         pass
92
93     # create config tools
94
95     try:
96         tool1 = CfgTool(cfgfile1)
97         tool2 = CfgTool(cfgfile2)
98     except Exception as e:
99         error_exit(str(e))
100         pass
101     
102     # diff config files
103
104     errors = []
105
106     def _cmpAttrs(_what, _where):
107         _attrs = tagAttributes(_what)
108         for _attr in _attrs:
109             try:
110                 _v1 = tool1.get(_where, _attr)
111             except:
112                 _v1 = None
113                 pass
114             try:
115                 _v2 = tool2.get(_where, _attr)
116             except:
117                 _v2 = None
118                 pass
119             if (isforce or _attrs[_attr]) and _v1 != _v2:
120                 errors.append("attribute '%s' of '%s' differs: '%s' in %s vs '%s' in %s" % (_attr, _where, str(_v1), tool1.cfgFile, str(_v2), tool2.cfgFile))
121                 pass
122             pass
123         pass
124     
125     # - compare parameters of configuration
126     _cmpAttrs(configTag(), configTag())
127
128     # - compare products
129
130     products1 = tool1.get(configTag(), softwareAlias())
131     products2 = tool2.get(configTag(), softwareAlias())
132     all_products = list(set(products1+products2))
133
134     for product in all_products:
135         if product in products1 and product not in products2:
136             errors.append("%s '%s' is only in '%s'" % (softwareTag(), product, tool1.cfgFile))
137             pass
138         elif product in products2 and product not in products1:
139             errors.append("%s '%s' is only in '%s'" % (softwareTag(), product, tool2.cfgFile))
140             pass
141         else:
142             # -- compare parameters of products
143             _cmpAttrs(softwareTag(), product)
144             # -- compare patches
145             patches1 = tool1.get(product, patchesAlias())
146             patches2 = tool2.get(product, patchesAlias())
147             all_patches = list(set(patches1+patches2))
148             for patch in all_patches:
149                 if patch in patches1 and patch not in patches2:
150                     errors.append("%s '%s' for '%s' is only in '%s'" % (patchTag(), patch, product, tool1.cfgFile))
151                     pass
152                 if patch in patches2 and patch not in patches1:
153                     errors.append("%s '%s' for '%s' is only in '%s'" % (patchTag(), patch, product, tool2.cfgFile))
154                     pass
155                 else:
156                     # -- compare parameters of products
157                     _cmpAttrs(patchTag(), "%s.%s.%s" % (product, patchesTag(), patch))
158                     pass
159                 pass
160             pass
161         pass
162     
163     # print results
164
165     if errors:
166         if isverbose:
167             print("Files %s and %s differ:" % (tool1.cfgFile, tool2.cfgFile))
168             print("\n".join(["  " + i for i in errors]))
169             pass
170         return 1
171
172     return 0
173
174 # -----------------------------------------------------------------------------
175
176 if __name__ == '__main__':
177     sys.exit(main())