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('m', 'module', 'list2', 'modules',
28 _('modules from which to get the sources. This option can be'
29 ' passed several time to get the sources of several modules.'))
30 parser.add_option('', 'no_sample', 'boolean', 'no_sample',
31 _("do not get sources from sample modules."))
32 parser.add_option('f', 'force', 'boolean', 'force',
33 _("force to get the sources of the modules in development mode."))
35 def get_sources_for_dev(config, module_info, source_dir, force, logger, pad):
36 '''The method called if the module is in development mode
38 :param config Config: The global configuration
39 :param module_info Config: The configuration specific to
40 the module 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 module 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(module_info.source_dir) or force:
54 # Call the function corresponding to get the sources with True checkout
55 retcode = get_module_sources(config,
63 logger.write("\n", 3, False)
64 # +2 because module name is followed by ': '
65 logger.write(" " * (pad+2), 3, False)
67 logger.write('dev: %s ... ' %
68 src.printcolors.printcInfo(module_info.source_dir), 3, False)
73 def get_sources_from_git(module_info, source_dir, logger, pad, is_dev=False):
74 '''The method called if the module is to be get in git mode
76 :param module_info Config: The configuration specific to
77 the module 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 module is in development mode
83 :return: True if it succeed, else False
89 # Get the repository address. (from repo_dev key if the module is
91 if is_dev and 'repo_dev' in module_info.git_info:
92 coflag = src.printcolors.printcHighlight(coflag.upper())
93 repo_git = module_info.git_info.repo_dev
95 repo_git = module_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 module_info.git_info.tag),
105 logger.write(' %s. ' % ('.' * (10 - len(module_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 module_info.git_info.tag,
115 def get_sources_from_archive(module_info, source_dir, logger):
116 '''The method called if the module is to be get in archive mode
118 :param module_info Config: The configuration specific to
119 the module 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(module_info.archive_info.archive_name):
128 raise src.SatException(_("Archive not found: '%s'") %
129 module_info.archive_info.archive_name)
131 logger.write('arc:%s ... ' %
132 src.printcolors.printcInfo(module_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 module_info.archive_info.archive_name,
139 source_dir.dir(), logger)
141 # Rename the source directory if
142 # it does not match with module_info.source_dir
143 if (NameExtractedDirectory.replace('/', '') !=
144 os.path.basename(module_info.source_dir)):
145 shutil.move(os.path.join(os.path.dirname(module_info.source_dir),
146 NameExtractedDirectory),
147 module_info.source_dir)
151 def get_sources_from_cvs(user, module_info, source_dir, checkout, logger, pad):
152 '''The method called if the module is to be get in cvs mode
154 :param user str: The user to use in for the cvs command
155 :param module_info Config: The configuration specific to
156 the module 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 module_info.cvs_info:
167 protocol = module_info.cvs_info.protocol
171 # Construct the line to display
172 if "protocol" in module_info.cvs_info:
173 cvs_line = "%s:%s@%s:%s" % \
174 (protocol, user, module_info.cvs_info.server,
175 module_info.cvs_info.module_base)
177 cvs_line = "%s / %s" % (module_info.cvs_info.server,
178 module_info.cvs_info.module_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(module_info.cvs_info.source),
191 logger.write(' ' * (pad + 1 - len(module_info.cvs_info.source)), 3, False)
192 logger.write(' tag:%s' %
193 src.printcolors.printcInfo(module_info.cvs_info.tag),
196 # at least one '.' is visible
197 logger.write(' %s. ' % ('.' * (10 - len(module_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 module_info.cvs_info.server,
206 module_info.cvs_info.module_base,
207 module_info.cvs_info.tag,
208 module_info.cvs_info.source,
209 source_dir, logger, checkout)
212 def get_sources_from_svn(user, module_info, source_dir, checkout, logger):
213 '''The method called if the module is to be get in svn mode
215 :param user str: The user to use in for the svn command
216 :param module_info Config: The configuration specific to
217 the module 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 module_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 module_info.svn_info.repo,
238 module_info.svn_info.tag,
244 def get_module_sources(config,
252 '''Get the module sources.
254 :param config Config: The global configuration
255 :param module_info Config: The configuration specific to
256 the module to be prepared
257 :param is_dev boolean: True if the module 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_sources_for_dev(config,
275 if module_info.get_sources == "git":
276 return get_sources_from_git(module_info, source_dir, logger, pad,
279 if module_info.get_sources == "archive":
280 return get_sources_from_archive(module_info, source_dir, logger)
282 if module_info.get_sources == "cvs":
283 cvs_user = config.USER.cvs_user
284 return get_sources_from_cvs(cvs_user,
291 if module_info.get_sources == "svn":
292 svn_user = config.USER.svn_user
293 return get_sources_from_svn(svn_user, module_info, source_dir,
297 if module_info.get_sources == "native":
299 logger.write('%s ...' % _("native (ignored)"), 3, False)
302 if module_info.get_sources == "fixed":
304 logger.write('%s ...' % _("fixed (ignored)"), 3, False)
307 if len(module_info.get_sources) == 0:
309 logger.write('%s ...' % _("ignored"), 3, False)
312 # if the get_sources is not in [git, archive, cvs, svn, dir]
313 logger.write(_("Unknown get_mehtod %(get)s for module %(module)s") % \
314 { 'get': module_info.get_sources, 'module': module_info.name }, 3, False)
315 logger.write(" ... ", 3, False)
319 def get_all_module_sources(config, modules, force, logger):
320 '''Get all the module sources.
322 :param config Config: The global configuration
323 :param modules List: The list of tuples (module name, module 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 module_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_module_name_len = 1
337 max_module_name_len = max(map(lambda l: len(l), modules[0])) + 4
339 # The loop on all the modules from which to get the sources
340 for module_name, module_info in modules:
341 # get module name, module informations and the directory where to put
343 if not src.module.module_is_fixed(module_info):
344 source_dir = src.Path(module_info.source_dir)
346 source_dir = src.Path('')
349 logger.write('%s: ' % src.printcolors.printcLabel(module_name), 3)
350 logger.write(' ' * (max_module_name_len - len(module_name)), 3, False)
351 logger.write("\n", 4, False)
353 # Remove the existing source directory if
354 # the module is not in development mode
355 is_dev = ("dev_modules" in config.APPLICATION and
356 module_name in config.APPLICATION.dev_modules)
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 module
363 retcode = get_module_sources(config,
373 if 'no_rpath' in module_info.keys():
374 if module_info.no_rpath:
375 hack_no_rpath(config, module_info, logger)
379 results[module_name] = retcode
381 # The case where the module 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 modules "
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 modules in development mode\n\n")
430 logger.write(src.printcolors.printcWarning(msg))
432 # Get the modules list with modules informations reagrding the options
433 modules_infos = prepare.get_modules_list(options, runner.cfg, logger)
435 # Call to the function that gets all the sources
436 good_result, results = get_all_module_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(modules_infos):
447 res_count = "%d / %d" % (good_result, good_result)
449 status = src.KO_STATUS
450 res_count = "%d / %d" % (good_result, len(modules))
452 for module in results:
453 if results[module] == 0 or results[module] is None:
454 details.append(module)
456 result = len(modules_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)