3 # Copyright (C) 2010-2012 CEA/DEN
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.
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.
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
23 import src.debug as DBG
25 PROPERTY_EXPRESSION = "^.+:.+$"
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('', 'properties', 'string', 'properties',
33 _('Optional: Filter the products by their properties.\n\tSyntax: '
34 '--properties <property>:<value>'))
35 parser.add_option('f', 'force', 'boolean', 'force',
36 _("Optional: force to prepare the products in development mode."))
37 parser.add_option('', 'force_patch', 'boolean', 'force_patch',
38 _("Optional: force to apply patch to the products in development mode."))
40 def get_products_list(options, cfg, logger):
41 '''method that gives the product list with their informations from
42 configuration regarding the passed options.
44 :param options Options: The Options instance that stores the commands
46 :param config Config: The global configuration
47 :param logger Logger: The logger instance to use for the display and logging
48 :return: The list of (product name, product_informations).
51 # Get the products to be prepared, regarding the options
52 if options.products is None:
53 # No options, get all products sources
54 products = cfg.APPLICATION.products
56 # if option --products, check that all products of the command line
57 # are present in the application.
58 products = options.products
60 if p not in cfg.APPLICATION.products:
61 raise src.SatException(_("Product %(product)s "
62 "not defined in application %(application)s") %
63 { 'product': p, 'application': cfg.VARS.application} )
65 # Construct the list of tuple containing
66 # the products name and their definition
67 products_infos = src.product.get_products_infos(products, cfg)
69 # if the property option was passed, filter the list
70 if options.properties:
71 [prop, value] = options.properties.split(":")
72 products_infos = [(p_name, p_info) for
73 (p_name, p_info) in products_infos
74 if "properties" in p_info and
75 prop in p_info.properties and
76 p_info.properties[prop] == value]
80 def remove_products(arguments, l_products_info, logger):
81 '''function that removes the products in l_products_info from arguments list.
83 :param arguments str: The arguments from which to remove products
84 :param l_products_info list: List of
85 (str, Config) => (product_name, product_info)
86 :param logger Logger: The logger instance to use for the display and logging
87 :return: The updated arguments.
90 args = str(arguments) #copy of "--products ,XDATA,TESSCODE,cmake" for example
91 largs = args.split(',')
92 DBG.write("largs", largs)
93 toRemove = [name for name, xx in l_products_info]
94 DBG.write("remove_products", toRemove)
97 for name in largs[1:]: # skip largs[0] as "--products "
101 notRemoved.append(name)
102 # DBG.write(removed, removed, True)
103 logger.write(" %s\n" % ",".join(removed), 1)
104 DBG.write("notRemoved", notRemoved)
105 res = largs[0] + ",".join(notRemoved)
108 def find_products_already_getted(l_products):
109 '''function that returns the list of products that have an existing source
112 :param l_products List: The list of products to check
113 :return: The list of product configurations that have an existing source
118 for p_name_p_cfg in l_products:
119 __, prod_cfg = p_name_p_cfg
120 if os.path.exists(prod_cfg.source_dir):
121 l_res.append(p_name_p_cfg)
124 def find_products_with_patchs(l_products):
125 '''function that returns the list of products that have one or more patches.
127 :param l_products List: The list of products to check
128 :return: The list of product configurations that have one or more patches.
132 for p_name_p_cfg in l_products:
133 __, prod_cfg = p_name_p_cfg
134 l_patchs = src.get_cfg_param(prod_cfg, "patches", [])
136 l_res.append(p_name_p_cfg)
140 '''method that is called when salomeTools is called with --help option.
142 :return: The text to display for the prepare command description.
145 return _("The prepare command gets the sources of "
146 "the application products and apply the patches if there is any."
147 "\n\nexample:\nsat prepare SALOME-master --products KERNEL,GUI")
149 def run(args, runner, logger):
150 '''method that is called when salomeTools is called with prepare parameter.
154 (options, args) = parser.parse_args(args)
156 # check that the command has been called with an application
157 src.check_config_has_application( runner.cfg )
159 # Verify the --properties option
160 if options.properties:
161 oExpr = re.compile(PROPERTY_EXPRESSION)
162 if not oExpr.search(options.properties):
163 msg = _('WARNING: the "--properties" options must have the '
164 'following syntax:\n--properties <property>:<value>')
165 logger.write(src.printcolors.printcWarning(msg), 1)
166 logger.write("\n", 1)
167 options.properties = None
169 products_infos = get_products_list(options, runner.cfg, logger)
171 # Construct the arguments to pass to the clean, source and patch commands
172 args_appli = runner.cfg.VARS.application + ' '
173 args_product_opt = '--products '
175 for p_name in options.products:
176 args_product_opt += ',' + p_name
178 for p_name, __ in products_infos:
179 args_product_opt += ',' + p_name
181 ldev_products = [p for p in products_infos if src.product.product_is_dev(p[1])]
182 args_product_opt_clean = args_product_opt
183 if not options.force and len(ldev_products) > 0:
184 l_products_not_getted = find_products_already_getted(ldev_products)
185 if len(l_products_not_getted) > 0:
187 Do not get the source of the following products in development mode
188 Use the --force option to overwrite it.
190 logger.write(src.printcolors.printcWarning(msg), 1)
191 args_product_opt_clean = remove_products(args_product_opt_clean,
192 l_products_not_getted,
194 logger.write("\n", 1)
197 args_product_opt_patch = args_product_opt
198 if not options.force_patch and len(ldev_products) > 0:
199 l_products_with_patchs = find_products_with_patchs(ldev_products)
200 if len(l_products_with_patchs) > 0:
202 do not patch the following products in development mode
203 Use the --force_patch option to overwrite it.
205 logger.write(src.printcolors.printcWarning(msg), 1)
206 args_product_opt_patch = remove_products(args_product_opt_patch,
207 l_products_with_patchs,
209 logger.write("\n", 1)
211 # Construct the final commands arguments
212 args_clean = args_appli + args_product_opt_clean + " --sources"
213 args_source = args_appli + args_product_opt
214 args_patch = args_appli + args_product_opt_patch
216 # If there is no more any product in the command arguments,
217 # do not call the concerned command
218 oExpr = re.compile("^--products *$")
219 do_clean = not(oExpr.search(args_product_opt_clean))
220 do_source = not(oExpr.search(args_product_opt))
221 do_patch = not(oExpr.search(args_product_opt_patch))
224 # Initialize the results to a failing status
229 # Call the commands using the API
231 msg = _("Clean the source directories ...")
234 res_clean = runner.clean(args_clean, batch=True, verbose = 0,
235 logger_add_link = logger)
237 logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 3)
239 logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 3)
241 msg = _("Get the sources of the products ...")
243 res_source = runner.source(args_source,
244 logger_add_link = logger)
246 logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 5)
248 logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 5)
250 msg = _("Patch the product sources (if any) ...")
252 res_patch = runner.patch(args_patch,
253 logger_add_link = logger)
255 logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 5)
257 logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 5)
259 return res_clean + res_source + res_patch