Salome HOME
Improve help of each command
[tools/sat.git] / commands / makeinstall.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2012  CEA/DEN
4 #
5 #  This library is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU Lesser General Public
7 #  License as published by the Free Software Foundation; either
8 #  version 2.1 of the License.
9 #
10 #  This library is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #  Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public
16 #  License along with this library; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18
19 import os
20
21 import src
22
23 # Define all possible option for the makeinstall command : sat makeinstall <options>
24 parser = src.options.Options()
25 parser.add_option('p', 'products', 'list2', 'products',
26     _('Optional: products to install. This option can be'
27     ' passed several time to install several products.'))
28
29 def get_products_list(options, cfg, logger):
30     '''method that gives the product list with their informations from 
31        configuration regarding the passed options.
32     
33     :param options Options: The Options instance that stores the commands 
34                             arguments
35     :param cfg Config: The global configuration
36     :param logger Logger: The logger instance to use for the display and logging
37     :return: The list of (product name, product_informations).
38     :rtype: List
39     '''
40     # Get the products to be prepared, regarding the options
41     if options.products is None:
42         # No options, get all products sources
43         products = cfg.APPLICATION.products
44     else:
45         # if option --products, check that all products of the command line
46         # are present in the application.
47         products = options.products
48         for p in products:
49             if p not in cfg.APPLICATION.products:
50                 raise src.SatException(_("Product %(product)s "
51                             "not defined in application %(application)s") %
52                         { 'product': p, 'application': cfg.VARS.application} )
53     
54     # Construct the list of tuple containing 
55     # the products name and their definition
56     products_infos = src.product.get_products_infos(products, cfg)
57     
58     products_infos = [pi for pi in products_infos if not(src.product.product_is_native(pi[1]) or src.product.product_is_fixed(pi[1]))]
59     
60     return products_infos
61
62 def log_step(logger, header, step):
63     logger.write("\r%s%s" % (header, " " * 20), 3)
64     logger.write("\r%s%s" % (header, step), 3)
65     logger.write("\n==== %s \n" % src.printcolors.printcInfo(step), 4)
66     logger.flush()
67
68 def log_res_step(logger, res):
69     if res == 0:
70         logger.write("%s \n" % src.printcolors.printcSuccess("OK"), 4)
71         logger.flush()
72     else:
73         logger.write("%s \n" % src.printcolors.printcError("KO"), 4)
74         logger.flush()
75
76 def makeinstall_all_products(config, products_infos, logger):
77     '''Execute the proper configuration commands 
78        in each product build directory.
79
80     :param config Config: The global configuration
81     :param products_info list: List of 
82                                  (str, Config) => (product_name, product_info)
83     :param logger Logger: The logger instance to use for the display and logging
84     :return: the number of failing commands.
85     :rtype: int
86     '''
87     res = 0
88     for p_name_info in products_infos:
89         res_prod = makeinstall_product(p_name_info, config, logger)
90         if res_prod != 0:
91             res += 1 
92     return res
93
94 def makeinstall_product(p_name_info, config, logger):
95     '''Execute the proper configuration command(s) 
96        in the product build directory.
97     
98     :param p_name_info tuple: (str, Config) => (product_name, product_info)
99     :param config Config: The global configuration
100     :param logger Logger: The logger instance to use for the display 
101                           and logging
102     :return: 1 if it fails, else 0.
103     :rtype: int
104     '''
105     
106     p_name, p_info = p_name_info
107     
108     # Logging
109     logger.write("\n", 4, False)
110     logger.write("################ ", 4)
111     header = _("Make install of %s") % src.printcolors.printcLabel(p_name)
112     header += " %s " % ("." * (20 - len(p_name)))
113     logger.write(header, 3)
114     logger.write("\n", 4, False)
115     logger.flush()
116
117     # Do nothing if he product is not compilable
118     if ("properties" in p_info and "compilation" in p_info.properties and 
119                                         p_info.properties.compilation == "no"):
120         log_step(logger, header, "ignored")
121         logger.write("\n", 3, False)
122         return 0
123
124     # Instantiate the class that manages all the construction commands
125     # like cmake, make, make install, make test, environment management, etc...
126     builder = src.compilation.Builder(config, logger, p_info)
127     
128     # Prepare the environment
129     log_step(logger, header, "PREPARE ENV")
130     res_prepare = builder.prepare()
131     log_res_step(logger, res_prepare)
132     
133     # Execute buildconfigure, configure if the product is autotools
134     # Execute cmake if the product is cmake
135     res = 0
136     if not src.product.product_has_script(p_info):
137         log_step(logger, header, "MAKE INSTALL")
138         res_m = builder.install()
139         log_res_step(logger, res_m)
140         res += res_m
141     
142     # Log the result
143     if res > 0:
144         logger.write("\r%s%s" % (header, " " * 20), 3)
145         logger.write("\r" + header + src.printcolors.printcError("KO"))
146         logger.write("==== %(KO)s in make install of %(name)s \n" %
147             { "name" : p_name , "KO" : src.printcolors.printcInfo("ERROR")}, 4)
148         logger.flush()
149     else:
150         logger.write("\r%s%s" % (header, " " * 20), 3)
151         logger.write("\r" + header + src.printcolors.printcSuccess("OK"))
152         logger.write("==== %s \n" % src.printcolors.printcInfo("OK"), 4)
153         logger.write("==== Make install of %(name)s %(OK)s \n" %
154             { "name" : p_name , "OK" : src.printcolors.printcInfo("OK")}, 4)
155         logger.flush()
156     logger.write("\n", 3, False)
157
158     return res
159
160 def description():
161     '''method that is called when salomeTools is called with --help option.
162     
163     :return: The text to display for the makeinstall command description.
164     :rtype: str
165     '''
166     return _("The makeinstall command executes the \"make install\" command in"
167              " the build directory.\nIn case of  product that is constructed "
168              "using a script (build_source :  \"script\"), then the "
169              "makeinstall command do nothing.\n\nexample:\nsat makeinstall "
170              "SALOME-master --products KERNEL,GUI")
171   
172 def run(args, runner, logger):
173     '''method that is called when salomeTools is called with makeinstall parameter.
174     '''
175     
176     # Parse the options
177     (options, args) = parser.parse_args(args)
178
179     # check that the command has been called with an application
180     src.check_config_has_application( runner.cfg )
181
182     # Get the list of products to treat
183     products_infos = get_products_list(options, runner.cfg, logger)
184
185     # Print some informations
186     logger.write(_('Executing the make install command in the build directories of the application %s\n') % 
187                 src.printcolors.printcLabel(runner.cfg.VARS.application), 1)
188     
189     info = [(_("BUILD directory"),
190              os.path.join(runner.cfg.APPLICATION.workdir, 'BUILD'))]
191     src.print_info(logger, info)
192     
193     # Call the function that will loop over all the products and execute
194     # the right command(s)
195     res = makeinstall_all_products(runner.cfg, products_infos, logger)
196     
197     # Print the final state
198     nb_products = len(products_infos)
199     if res == 0:
200         final_status = "OK"
201     else:
202         final_status = "KO"
203    
204     logger.write(_("\nMake install: %(status)s (%(valid_result)d/%(nb_products)d)\n") % \
205         { 'status': src.printcolors.printc(final_status), 
206           'valid_result': nb_products - res,
207           'nb_products': nb_products }, 1)    
208     
209     return res