Salome HOME
#8577 extension du domaine des properties
[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 import pprint as PP
22
23 import src
24 import src.debug as DBG
25
26
27 # Define all possible option for prepare command :  sat prepare <options>
28 parser = src.options.Options()
29 parser.add_option('p', 'products', 'list2', 'products',
30     _('Optional: products to prepare. This option can be'
31     ' passed several time to prepare several products.'))
32 parser.add_option('f', 'force', 'boolean', 'force',
33     _("Optional: force to prepare the products in development mode."))
34 parser.add_option('', 'force_patch', 'boolean', 'force_patch', 
35     _("Optional: force to apply patch to the products in development mode."))
36
37
38 def find_products_already_getted(l_products):
39     '''function that returns the list of products that have an existing source 
40        directory.
41     
42     :param l_products List: The list of products to check
43     :return: The list of product configurations that have an existing source 
44              directory.
45     :rtype: List
46     '''
47     l_res = []
48     for p_name_p_cfg in l_products:
49         __, prod_cfg = p_name_p_cfg
50         if os.path.exists(prod_cfg.source_dir):
51             l_res.append(p_name_p_cfg)
52     return l_res
53
54 def find_products_with_patchs(l_products):
55     '''function that returns the list of products that have one or more patches.
56     
57     :param l_products List: The list of products to check
58     :return: The list of product configurations that have one or more patches.
59     :rtype: List
60     '''
61     l_res = []
62     for p_name_p_cfg in l_products:
63         __, prod_cfg = p_name_p_cfg
64         l_patchs = src.get_cfg_param(prod_cfg, "patches", [])
65         if len(l_patchs)>0:
66             l_res.append(p_name_p_cfg)
67     return l_res
68
69 def description():
70     '''method that is called when salomeTools is called with --help option.
71     
72     :return: The text to display for the prepare command description.
73     :rtype: str
74     '''
75     return _("The prepare command gets the sources of "
76              "the application products and apply the patches if there is any."
77              "\n\nexample:\nsat prepare SALOME-master --products KERNEL,GUI")
78   
79 def run(args, runner, logger):
80     '''method that is called when salomeTools is called with prepare parameter.
81     '''
82     
83     # Parse the options
84     (options, args) = parser.parse_args(args)
85
86     # check that the command has been called with an application
87     src.check_config_has_application( runner.cfg )
88
89     products_infos = src.product.get_products_list(options, runner.cfg, logger)
90
91     # Construct the arguments to pass to the clean, source and patch commands
92     args_appli = runner.cfg.VARS.application + " "  # useful whitespace
93     if options.products:
94         listProd = list(options.products)
95     else: # no product interpeted as all products
96         listProd = [name for name, tmp in products_infos]
97
98     DBG.write("prepare products", sorted(listProd))
99     args_product_opt = '--products ' + ",".join(listProd)
100     do_source = (len(listProd) > 0)
101
102
103     ldev_products = [p for p in products_infos if src.product.product_is_dev(p[1])]
104     newList = listProd # default
105     if not options.force and len(ldev_products) > 0:
106         l_products_not_getted = find_products_already_getted(ldev_products)
107         listNot = [i for i, tmp in l_products_not_getted]
108         newList, removedList = removeInList(listProd, listNot)
109         if len(removedList) > 0:
110             msg = _("""\
111 Do not get the source of the following products in development mode.
112 Use the --force option to overwrite it.
113 """)
114             msg += "\n%s\n" % ",".join(removedList)
115             logger.write(src.printcolors.printcWarning(msg), 1)
116
117     args_product_opt_clean = '--products ' + ",".join(newList)
118     do_clean = (len(newList) > 0)
119     
120     newList = listProd # default
121     if not options.force_patch and len(ldev_products) > 0:
122         l_products_with_patchs = find_products_with_patchs(ldev_products)
123         listNot = [i for i, tmp in l_products_with_patchs]
124         newList, removedList = removeInList(listProd, listNot)
125         if len(removedList) > 0:
126             msg = _("""\
127 Do not patch the following products in development mode.
128 Use the --force_patch option to overwrite it.
129 """)
130             msg += "\n%s\n" % ",".join(removedList)
131             logger.write(src.printcolors.printcWarning(msg), 1)
132                                                      
133     args_product_opt_patch = '--products ' + ",".join(newList)
134     do_patch = (len(newList) > 0)
135       
136     # Construct the final commands arguments
137     args_clean = args_appli + args_product_opt_clean + " --sources"
138     args_source = args_appli + args_product_opt  
139     args_patch = args_appli + args_product_opt_patch
140       
141     # Initialize the results to a failing status
142     res_clean = 1
143     res_source = 1
144     res_patch = 1
145     
146     # Call the commands using the API
147     if do_clean:
148         msg = _("Clean the source directories ...")
149         logger.write(msg, 3)
150         logger.flush()
151         res_clean = runner.clean(args_clean, batch=True, verbose = 0, logger_add_link = logger)
152         if res_clean == 0:
153             logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 3)
154         else:
155             logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 3)
156     if do_source:
157         msg = _("Get the sources of the products ...")
158         logger.write(msg, 5)
159         res_source = runner.source(args_source, logger_add_link = logger)
160         if res_source == 0:
161             logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 5)
162         else:
163             logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 5)
164     if do_patch:
165         msg = _("Patch the product sources (if any) ...")
166         logger.write(msg, 5)
167         res_patch = runner.patch(args_patch, logger_add_link = logger)
168         if res_patch == 0:
169             logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 5)
170         else:
171             logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 5)
172     
173     return res_clean + res_source + res_patch
174
175
176 def removeInList(aList, removeList):
177     """Removes elements of removeList list from aList
178     
179     :param aList: (list) The list from which to remove elements
180     :param removeList: (list) The list which contains elements to remove
181     :return: (list, list) (list with elements removed, list of elements removed) 
182     """
183     res1 = [i for i in aList if i not in removeList]
184     res2 = [i for i in aList if i in removeList]
185     return (res1, res2)
186
187