Salome HOME
sat jobs: remove empty lines from the boards.
[tools/sat.git] / commands / prepare.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 re
20 import os
21
22 import src
23
24 # Define all possible option for prepare command :  sat prepare <options>
25 parser = src.options.Options()
26 parser.add_option('p', 'products', 'list2', 'products',
27     _('Optional: products to prepare. This option can be'
28     ' passed several time to prepare several products.'))
29 parser.add_option('f', 'force', 'boolean', 'force', 
30     _("Optional: force to prepare the products in development mode."))
31 parser.add_option('', 'force_patch', 'boolean', 'force_patch', 
32     _("Optional: force to apply patch to the products in development mode."))
33
34 def get_products_list(options, cfg, logger):
35     '''method that gives the product list with their informations from 
36        configuration regarding the passed options.
37     
38     :param options Options: The Options instance that stores the commands 
39                             arguments
40     :param config Config: The global configuration
41     :param logger Logger: The logger instance to use for the display and logging
42     :return: The list of (product name, product_informations).
43     :rtype: List
44     '''
45     # Get the products to be prepared, regarding the options
46     if options.products is None:
47         # No options, get all products sources
48         products = cfg.APPLICATION.products
49     else:
50         # if option --products, check that all products of the command line
51         # are present in the application.
52         products = options.products
53         for p in products:
54             if p not in cfg.APPLICATION.products:
55                 raise src.SatException(_("Product %(product)s "
56                             "not defined in application %(application)s") %
57                         { 'product': p, 'application': cfg.VARS.application} )
58     
59     # Construct the list of tuple containing 
60     # the products name and their definition
61     products_infos = src.product.get_products_infos(products, cfg)
62     
63     return products_infos
64
65 def remove_products(arguments, l_products_info, logger):
66     '''function that removes the products in l_products_info from arguments list.
67     
68     :param arguments str: The arguments from which to remove products
69     :param l_products_info list: List of 
70                                  (str, Config) => (product_name, product_info)
71     :param logger Logger: The logger instance to use for the display and logging
72     :return: The updated arguments.
73     :rtype: str
74     '''
75     args = arguments
76     for i, (product_name, __) in enumerate(l_products_info):
77         args = args.replace(',' + product_name, '')
78         end_text = ', '
79         if i+1 == len(l_products_info):
80             end_text = '\n'            
81         logger.write(product_name + end_text, 1)
82     return args
83
84 def find_products_already_getted(l_products):
85     '''function that returns the list of products that have an existing source 
86        directory.
87     
88     :param l_products List: The list of products to check
89     :return: The list of product configurations that have an existing source 
90              directory.
91     :rtype: List
92     '''
93     l_res = []
94     for p_name_p_cfg in l_products:
95         __, prod_cfg = p_name_p_cfg
96         if os.path.exists(prod_cfg.source_dir):
97             l_res.append(p_name_p_cfg)
98     return l_res
99
100 def find_products_with_patchs(l_products):
101     '''function that returns the list of products that have one or more patches.
102     
103     :param l_products List: The list of products to check
104     :return: The list of product configurations that have one or more patches.
105     :rtype: List
106     '''
107     l_res = []
108     for p_name_p_cfg in l_products:
109         __, prod_cfg = p_name_p_cfg
110         l_patchs = src.get_cfg_param(prod_cfg, "patches", [])
111         if len(l_patchs)>0:
112             l_res.append(p_name_p_cfg)
113     return l_res
114
115 def description():
116     '''method that is called when salomeTools is called with --help option.
117     
118     :return: The text to display for the prepare command description.
119     :rtype: str
120     '''
121     return _("The prepare command gets the sources of "
122              "the application products and apply the patches if there is any."
123              "\n\nexample:\nsat prepare SALOME-master --products KERNEL,GUI")
124   
125 def run(args, runner, logger):
126     '''method that is called when salomeTools is called with prepare parameter.
127     '''
128     
129     # Parse the options
130     (options, args) = parser.parse_args(args)
131
132     # check that the command has been called with an application
133     src.check_config_has_application( runner.cfg )
134
135     products_infos = get_products_list(options, runner.cfg, logger)
136
137     # Construct the arguments to pass to the clean, source and patch commands
138     args_appli = runner.cfg.VARS.application + ' '
139     args_product_opt = '--products '
140     if options.products:
141         for p_name in options.products:
142             args_product_opt += ',' + p_name
143     else:
144         for p_name, __ in products_infos:
145             args_product_opt += ',' + p_name
146
147     ldev_products = [p for p in products_infos if src.product.product_is_dev(p[1])]
148     args_product_opt_clean = args_product_opt
149     if not options.force and len(ldev_products) > 0:
150         l_products_not_getted = find_products_already_getted(ldev_products)
151         if len(l_products_not_getted) > 0:
152             msg = _("Do not get the source of the following products "
153                     "in development mode\nUse the --force option to"
154                     " overwrite it.\n")
155             logger.write(src.printcolors.printcWarning(msg), 1)
156             args_product_opt_clean = remove_products(args_product_opt_clean,
157                                                      l_products_not_getted,
158                                                      logger)
159             logger.write("\n", 1)
160
161     
162     args_product_opt_patch = args_product_opt
163     if not options.force_patch and len(ldev_products) > 0:
164         l_products_with_patchs = find_products_with_patchs(ldev_products)
165         if len(l_products_with_patchs) > 0:
166             msg = _("do not patch the following products "
167                     "in development mode\nUse the --force_patch option to"
168                     " overwrite it.\n")
169             logger.write(src.printcolors.printcWarning(msg), 1)
170             args_product_opt_patch = remove_products(args_product_opt_patch,
171                                                      l_products_with_patchs,
172                                                      logger)
173             logger.write("\n", 1)
174
175     # Construct the final commands arguments
176     args_clean = args_appli + args_product_opt_clean + " --sources"
177     args_source = args_appli + args_product_opt  
178     args_patch = args_appli + args_product_opt_patch
179
180     # If there is no more any product in the command arguments,
181     # do not call the concerned command 
182     oExpr = re.compile("^--products *$")
183     do_clean = not(oExpr.search(args_product_opt_clean))
184     do_source = not(oExpr.search(args_product_opt))
185     do_patch = not(oExpr.search(args_product_opt_patch))
186     
187     
188     # Initialize the results to a failing status
189     res_clean = 1
190     res_source = 1
191     res_patch = 1
192     
193     # Call the commands using the API
194     if do_clean:
195         msg = _("Clean the source directories ...")
196         logger.write(msg, 3)
197         logger.flush()
198         res_clean = runner.clean(args_clean, batch=True, verbose = 0,
199                                     logger_add_link = logger)
200         if res_clean == 0:
201             logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 3)
202         else:
203             logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 3)
204     if do_source:
205         msg = _("Get the sources of the products ...")
206         logger.write(msg, 5)
207         res_source = runner.source(args_source,
208                                     logger_add_link = logger)
209         if res_source == 0:
210             logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 5)
211         else:
212             logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 5)
213     if do_patch:
214         msg = _("Patch the product sources (if any) ...")
215         logger.write(msg, 5)
216         res_patch = runner.patch(args_patch,
217                                     logger_add_link = logger)
218         if res_patch == 0:
219             logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 5)
220         else:
221             logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 5)
222     
223     return res_clean + res_source + res_patch