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
25 # Define all possible option for log command : sat log <options>
26 parser = src.options.Options()
27 parser.add_option('p', 'product', 'list2', 'products',
28 _('products from which to get the sources. This option can be'
29 ' passed several time to get the sources of several products.'))
30 parser.add_option('', 'no_sample', 'boolean', 'no_sample',
31 _("do not get sources from sample products."))
32 parser.add_option('f', 'force', 'boolean', 'force',
33 _("force to get the sources of the products in development mode."))
35 def get_source_for_dev(config, product_info, source_dir, force, logger, pad):
36 '''The method called if the product is in development mode
38 :param config Config: The global configuration
39 :param product_info Config: The configuration specific to
40 the product to be prepared
41 :param source_dir Path: The Path instance corresponding to the
42 directory where to put the sources
43 :param force boolean: True if the --force option was invoked
44 :param logger Logger: The logger instance to use for the display and logging
45 :param pad int: The gap to apply for the terminal display
46 :return: True if it succeed, else False
50 # if the product source directory does not exist,
51 # get it in checkout mode, else, do not do anything
52 # unless the force option is invoked
53 if not os.path.exists(product_info.source_dir) or force:
54 # Call the function corresponding to get the sources with True checkout
55 retcode = get_product_sources(config,
63 logger.write("\n", 3, False)
64 # +2 because product name is followed by ': '
65 logger.write(" " * (pad+2), 3, False)
67 logger.write('dev: %s ... ' %
68 src.printcolors.printcInfo(product_info.source_dir), 3, False)
73 def get_source_from_git(product_info, source_dir, logger, pad, is_dev=False):
74 '''The method called if the product is to be get in git mode
76 :param product_info Config: The configuration specific to
77 the product to be prepared
78 :param source_dir Path: The Path instance corresponding to the
79 directory where to put the sources
80 :param logger Logger: The logger instance to use for the display and logging
81 :param pad int: The gap to apply for the terminal display
82 :param is_dev boolean: True if the product is in development mode
83 :return: True if it succeed, else False
89 # Get the repository address. (from repo_dev key if the product is
91 if is_dev and 'repo_dev' in product_info.git_info:
92 coflag = src.printcolors.printcHighlight(coflag.upper())
93 repo_git = product_info.git_info.repo_dev
95 repo_git = product_info.git_info.repo
97 # Display informations
98 logger.write('%s:%s' % (coflag, src.printcolors.printcInfo(repo_git)), 3,
100 logger.write(' ' * (pad + 50 - len(repo_git)), 3, False)
101 logger.write(' tag:%s' % src.printcolors.printcInfo(
102 product_info.git_info.tag),
105 logger.write(' %s. ' % ('.' * (10 - len(product_info.git_info.tag))), 3,
108 logger.write('\n', 5, False)
109 # Call the system function that do the extraction in git mode
110 retcode = src.system.git_extract(repo_git,
111 product_info.git_info.tag,
115 def get_source_from_archive(product_info, source_dir, logger):
116 '''The method called if the product is to be get in archive mode
118 :param product_info Config: The configuration specific to
119 the product to be prepared
120 :param source_dir Path: The Path instance corresponding to the
121 directory where to put the sources
122 :param logger Logger: The logger instance to use for the display and logging
123 :return: True if it succeed, else False
126 # check archive exists
127 if not os.path.exists(product_info.archive_info.archive_name):
128 raise src.SatException(_("Archive not found: '%s'") %
129 product_info.archive_info.archive_name)
131 logger.write('arc:%s ... ' %
132 src.printcolors.printcInfo(product_info.archive_info.archive_name),
136 # Call the system function that do the extraction in archive mode
137 retcode, NameExtractedDirectory = src.system.archive_extract(
138 product_info.archive_info.archive_name,
139 source_dir.dir(), logger)
141 # Rename the source directory if
142 # it does not match with product_info.source_dir
143 if (NameExtractedDirectory.replace('/', '') !=
144 os.path.basename(product_info.source_dir)):
145 shutil.move(os.path.join(os.path.dirname(product_info.source_dir),
146 NameExtractedDirectory),
147 product_info.source_dir)
151 def get_source_from_cvs(user, product_info, source_dir, checkout, logger, pad):
152 '''The method called if the product is to be get in cvs mode
154 :param user str: The user to use in for the cvs command
155 :param product_info Config: The configuration specific to
156 the product to be prepared
157 :param source_dir Path: The Path instance corresponding to the
158 directory where to put the sources
159 :param checkout boolean: If True, get the source in checkout mode
160 :param logger Logger: The logger instance to use for the display and logging
161 :param pad int: The gap to apply for the terminal display
162 :return: True if it succeed, else False
165 # Get the protocol to use in the command
166 if "protocol" in product_info.cvs_info:
167 protocol = product_info.cvs_info.protocol
171 # Construct the line to display
172 if "protocol" in product_info.cvs_info:
173 cvs_line = "%s:%s@%s:%s" % \
174 (protocol, user, product_info.cvs_info.server,
175 product_info.cvs_info.product_base)
177 cvs_line = "%s / %s" % (product_info.cvs_info.server,
178 product_info.cvs_info.product_base)
181 if checkout: coflag = src.printcolors.printcHighlight(coflag.upper())
183 logger.write('%s:%s' % (coflag, src.printcolors.printcInfo(cvs_line)),
186 logger.write(' ' * (pad + 50 - len(cvs_line)), 3, False)
187 logger.write(' src:%s' %
188 src.printcolors.printcInfo(product_info.cvs_info.source),
191 logger.write(' ' * (pad + 1 - len(product_info.cvs_info.source)), 3, False)
192 logger.write(' tag:%s' %
193 src.printcolors.printcInfo(product_info.cvs_info.tag),
196 # at least one '.' is visible
197 logger.write(' %s. ' % ('.' * (10 - len(product_info.cvs_info.tag))),
201 logger.write('\n', 5, False)
203 # Call the system function that do the extraction in cvs mode
204 retcode = src.system.cvs_extract(protocol, user,
205 product_info.cvs_info.server,
206 product_info.cvs_info.product_base,
207 product_info.cvs_info.tag,
208 product_info.cvs_info.source,
209 source_dir, logger, checkout)
212 def get_source_from_svn(user, product_info, source_dir, checkout, logger):
213 '''The method called if the product is to be get in svn mode
215 :param user str: The user to use in for the svn command
216 :param product_info Config: The configuration specific to
217 the product to be prepared
218 :param source_dir Path: The Path instance corresponding to the
219 directory where to put the sources
220 :param checkout boolean: If True, get the source in checkout mode
221 :param logger Logger: The logger instance to use for the display and logging
222 :return: True if it succeed, else False
226 if checkout: coflag = src.printcolors.printcHighlight(coflag.upper())
228 logger.write('%s:%s ... ' % (coflag,
229 src.printcolors.printcInfo(
230 product_info.svn_info.repo)),
234 logger.write('\n', 5, False)
235 # Call the system function that do the extraction in svn mode
236 retcode = src.system.svn_extract(user,
237 product_info.svn_info.repo,
238 product_info.svn_info.tag,
244 def get_product_sources(config,
252 '''Get the product sources.
254 :param config Config: The global configuration
255 :param product_info Config: The configuration specific to
256 the product to be prepared
257 :param is_dev boolean: True if the product is in development mode
258 :param source_dir Path: The Path instance corresponding to the
259 directory where to put the sources
260 :param force boolean: True if the --force option was invoked
261 :param logger Logger: The logger instance to use for the display and logging
262 :param pad int: The gap to apply for the terminal display
263 :param checkout boolean: If True, get the source in checkout mode
264 :return: True if it succeed, else False
267 if not checkout and is_dev:
268 return get_source_for_dev(config,
275 if product_info.get_source == "git":
276 return get_source_from_git(product_info, source_dir, logger, pad,
279 if product_info.get_source == "archive":
280 return get_source_from_archive(product_info, source_dir, logger)
282 if product_info.get_source == "cvs":
283 cvs_user = config.USER.cvs_user
284 return get_source_from_cvs(cvs_user,
291 if product_info.get_source == "svn":
292 svn_user = config.USER.svn_user
293 return get_source_from_svn(svn_user, product_info, source_dir,
297 if product_info.get_source == "native":
299 logger.write('%s ...' % _("native (ignored)"), 3, False)
302 if product_info.get_source == "fixed":
304 logger.write('%s ...' % _("fixed (ignored)"), 3, False)
307 if len(product_info.get_source) == 0:
309 logger.write('%s ...' % _("ignored"), 3, False)
312 # if the get_source is not in [git, archive, cvs, svn, dir]
313 logger.write(_("Unknown get_mehtod %(get)s for product %(product)s") % \
314 { 'get': product_info.get_source, 'product': product_info.name }, 3, False)
315 logger.write(" ... ", 3, False)
319 def get_all_product_sources(config, products, force, logger):
320 '''Get all the product sources.
322 :param config Config: The global configuration
323 :param products List: The list of tuples (product name, product informations)
324 :param force boolean: True if the --force option was invoked
325 :param logger Logger: The logger instance to be used for the logging
326 :return: the tuple (number of success, dictionary product_name/success_fail)
330 # Initialize the variables that will count the fails and success
334 # Get the maximum name length in order to format the terminal display
335 max_product_name_len = 1
336 if len(products) > 0:
337 max_product_name_len = max(map(lambda l: len(l), products[0])) + 4
339 # The loop on all the products from which to get the sources
340 for product_name, product_info in products:
341 # get product name, product informations and the directory where to put
343 if not src.product.product_is_fixed(product_info):
344 source_dir = src.Path(product_info.source_dir)
346 source_dir = src.Path('')
349 logger.write('%s: ' % src.printcolors.printcLabel(product_name), 3)
350 logger.write(' ' * (max_product_name_len - len(product_name)), 3, False)
351 logger.write("\n", 4, False)
353 # Remove the existing source directory if
354 # the product is not in development mode
355 is_dev = ("dev_products" in config.APPLICATION and
356 product_name in config.APPLICATION.dev_products)
357 if source_dir.exists() and not is_dev:
358 logger.write(" " + _('remove %s') % source_dir, 4)
359 logger.write("\n ", 4, False)
362 # Call to the function that get the sources for one product
363 retcode = get_product_sources(config,
369 max_product_name_len,
373 if 'no_rpath' in product_info.keys():
374 if product_info.no_rpath:
375 hack_no_rpath(config, product_info, logger)
379 results[product_name] = retcode
381 # The case where the product was not prepared because it is
382 # in development mode
383 res =(src.printcolors.printc(src.OK_STATUS) +
384 src.printcolors.printcWarning(_(
385 ' source directory already exists')))
386 good_result = good_result + 1
388 # The case where it succeed
390 good_result = good_result + 1
392 # The case where it failed
396 logger.write('%s\n' % src.printcolors.printc(res), 3, False)
398 return good_result, results
401 '''method that is called when salomeTools is called with --help option.
403 :return: The text to display for the source command description.
406 return _("The source command gets the sources of the application products "
407 "from cvs, git, an archive or a directory..")
409 def run(args, runner, logger):
410 '''method that is called when salomeTools is called with source parameter.
413 (options, args) = parser.parse_args(args)
415 # check that the command has been called with an application
416 src.check_config_has_application( runner.cfg )
418 # Print some informations
419 logger.write(_('Getting sources of the application %s\n') %
420 src.printcolors.printcLabel(runner.cfg.VARS.application), 1)
421 src.printcolors.print_value(logger, 'out_dir',
422 runner.cfg.APPLICATION.out_dir, 2)
423 logger.write("\n", 2, False)
425 # Get the force option if it was passed
426 force = options.force
428 msg = _("Warning: the --force option has effect only "
429 "on products in development mode\n\n")
430 logger.write(src.printcolors.printcWarning(msg))
432 # Get the products list with products informations regarding the options
433 products_infos = prepare.get_products_list(options, runner.cfg, logger)
435 # Call to the function that gets all the sources
436 good_result, results = get_all_product_sources(runner.cfg,
441 # Display the results (how much passed, how much failed, etc...)
442 status = src.OK_STATUS
445 logger.write("\n", 2, False)
446 if good_result == len(products_infos):
447 res_count = "%d / %d" % (good_result, good_result)
449 status = src.KO_STATUS
450 res_count = "%d / %d" % (good_result, len(products_infos))
452 for product in results:
453 if results[product] == 0 or results[product] is None:
454 details.append(product)
456 result = len(products_infos) - good_result
459 logger.write(_("Getting sources of the application:"), 1)
460 logger.write(" " + src.printcolors.printc(status), 1, False)
461 logger.write(" (%s)\n" % res_count, 1, False)
464 logger.write(_("Following sources haven't been get:\n"), 2)
465 logger.write(" ".join(details), 2)
466 logger.write("\n", 2, False)