From: Serge Rehbinder Date: Wed, 17 Feb 2016 15:27:01 +0000 (+0100) Subject: max lenght of lines is now 80 X-Git-Tag: sprint-02bis~2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=97d979ec2efd691cb0c1f4bc4e2da829eb461338;p=tools%2Fsat.git max lenght of lines is now 80 --- diff --git a/commands/config.py b/commands/config.py index c5439ad..a3bc109 100644 --- a/commands/config.py +++ b/commands/config.py @@ -30,16 +30,20 @@ gettext.install('salomeTools', os.path.join(satdir, 'src', 'i18n')) # Define all possible option for config command : sat config parser = src.options.Options() -parser.add_option('v', 'value', 'string', 'value', _("print the value of CONFIG_VARIABLE.")) -parser.add_option('e', 'edit', 'boolean', 'edit', _("edit the product configuration file.")) -parser.add_option('l', 'list', 'boolean', 'list',_("list all available applications.")) +parser.add_option('v', 'value', 'string', 'value', + _("print the value of CONFIG_VARIABLE.")) +parser.add_option('e', 'edit', 'boolean', 'edit', + _("edit the product configuration file.")) +parser.add_option('l', 'list', 'boolean', 'list', + _("list all available applications.")) parser.add_option('c', 'copy', 'boolean', 'copy', _("""copy a config file to the personnal config files directory. \tWARNING the included files are not copied. \tIf a name is given the new config file takes the given name.""")) class ConfigOpener: - ''' Class that helps to find an application pyconf in all the possible directories (pathList) + '''Class that helps to find an application pyconf + in all the possible directories (pathList) ''' def __init__(self, pathList): '''Initialization @@ -52,7 +56,8 @@ class ConfigOpener: if os.path.isabs(name): return src.pyconf.ConfigInputStream(open(name, 'rb')) else: - return src.pyconf.ConfigInputStream( open(os.path.join( self.get_path(name), name ), 'rb') ) + return src.pyconf.ConfigInputStream( + open(os.path.join( self.get_path(name), name ), 'rb') ) raise IOError(_("Configuration file '%s' not found") % name) def get_path( self, name ): @@ -71,17 +76,20 @@ class ConfigManager: pass def _create_vars(self, application=None, command=None, dataDir=None): - '''Create a dictionary that stores all information about machine, user, date, repositories, etc... + '''Create a dictionary that stores all information about machine, + user, date, repositories, etc... :param application str: The application for which salomeTools is called. :param command str: The command that is called. - :param dataDir str: The repository that contain external data for salomeTools. + :param dataDir str: The repository that contain external data + for salomeTools. :return: The dictionary that stores all information. :rtype: dict ''' var = {} var['user'] = src.architecture.get_user() - var['salometoolsway'] = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + var['salometoolsway'] = os.path.dirname( + os.path.dirname(os.path.abspath(__file__))) var['srcDir'] = os.path.join(var['salometoolsway'], 'src') var['sep']= os.path.sep @@ -90,14 +98,19 @@ class ConfigManager: if dataDir is not None: var['dataDir'] = dataDir - var['personalDir'] = os.path.join(os.path.expanduser('~'), '.salomeTools') + var['personalDir'] = os.path.join(os.path.expanduser('~'), + '.salomeTools') # read linux distributions dictionary - distrib_cfg = src.pyconf.Config(os.path.join(var['srcDir'], 'internal_config', 'distrib.pyconf')) + distrib_cfg = src.pyconf.Config(os.path.join(var['srcDir'], + 'internal_config', + 'distrib.pyconf')) # set platform parameters - dist_name = src.architecture.get_distribution(codes=distrib_cfg.DISTRIBUTIONS) - dist_version = src.architecture.get_distrib_version(dist_name, codes=distrib_cfg.VERSIONS) + dist_name = src.architecture.get_distribution( + codes=distrib_cfg.DISTRIBUTIONS) + dist_version = src.architecture.get_distrib_version(dist_name, + codes=distrib_cfg.VERSIONS) dist = dist_name + dist_version var['dist_name'] = dist_name @@ -130,28 +143,34 @@ class ConfigManager: def get_command_line_overrides(self, options, sections): '''get all the overwrites that are in the command line - :param options: the options from salomeTools class initialization (like -l5 or --overwrite) + :param options: the options from salomeTools class + initialization (like -l5 or --overwrite) :param sections str: The config section to overwrite. :return: The list of all the overwrites to apply. :rtype: list ''' - # when there are no options or not the overwrite option, return an empty list + # when there are no options or not the overwrite option, + # return an empty list if options is None or options.overwrite is None: return [] over = [] for section in sections: # only overwrite the sections that correspond to the option - over.extend(filter(lambda l: l.startswith(section + "."), options.overwrite)) + over.extend(filter(lambda l: l.startswith(section + "."), + options.overwrite)) return over - def get_config(self, application=None, options=None, command=None, dataDir=None): + def get_config(self, application=None, options=None, command=None, + dataDir=None): '''get the config from all the configuration files. :param application str: The application for which salomeTools is called. - :param options calss Options: The general salomeToosl options (--overwrite or -l5, for example) + :param options class Options: The general salomeToos + options (--overwrite or -l5, for example) :param command str: The command that is called. - :param dataDir str: The repository that contain external data for salomeTools. + :param dataDir str: The repository that contain + external data for salomeTools. :return: The final config. :rtype: class 'src.pyconf.Config' ''' @@ -162,9 +181,10 @@ class ConfigManager: # create the configuration instance cfg = src.pyconf.Config() - # ======================================================================================= + # ===================================================================== # create VARS section - var = self._create_vars(application=application, command=command, dataDir=dataDir) + var = self._create_vars(application=application, command=command, + dataDir=dataDir) # add VARS to config cfg.VARS = src.pyconf.Mapping(cfg) for variable in var: @@ -174,15 +194,18 @@ class ConfigManager: for rule in self.get_command_line_overrides(options, ["VARS"]): exec('cfg.' + rule) # this cannot be factorized because of the exec - # ======================================================================================= + # ===================================================================== # Load INTERNAL config # read src/internal_config/salomeTools.pyconf - src.pyconf.streamOpener = ConfigOpener([os.path.join(cfg.VARS.srcDir, 'internal_config')]) + src.pyconf.streamOpener = ConfigOpener([ + os.path.join(cfg.VARS.srcDir, 'internal_config')]) try: - internal_cfg = src.pyconf.Config(open(os.path.join(cfg.VARS.srcDir, 'internal_config', 'salomeTools.pyconf'))) + internal_cfg = src.pyconf.Config(open(os.path.join(cfg.VARS.srcDir, + 'internal_config', 'salomeTools.pyconf'))) except src.pyconf.ConfigError as e: - raise src.SatException(_("Error in configuration file: salomeTools.pyconf\n %(error)s") % \ - {'error': str(e) }) + raise src.SatException(_("Error in configuration file:" + " salomeTools.pyconf\n %(error)s") % \ + {'error': str(e) }) merger.merge(cfg, internal_cfg) @@ -190,23 +213,31 @@ class ConfigManager: for rule in self.get_command_line_overrides(options, ["INTERNAL"]): exec('cfg.' + rule) # this cannot be factorized because of the exec - # ======================================================================================= + # ===================================================================== # Load SITE config file # search only in the data directory src.pyconf.streamOpener = ConfigOpener([cfg.VARS.dataDir]) try: - site_cfg = src.pyconf.Config(open(os.path.join(cfg.VARS.dataDir, 'site.pyconf'))) + site_cfg = src.pyconf.Config(open(os.path.join(cfg.VARS.dataDir, + 'site.pyconf'))) except src.pyconf.ConfigError as e: - raise src.SatException(_("Error in configuration file: site.pyconf\n %(error)s") % \ + raise src.SatException(_("Error in configuration file: " + "site.pyconf\n %(error)s") % \ {'error': str(e) }) except IOError as error: e = str(error) if "site.pyconf" in e : - e += "\nYou can copy data" + cfg.VARS.sep + "site.template.pyconf to data" + cfg.VARS.sep + "site.pyconf and edit the file" + e += ("\nYou can copy data" + + cfg.VARS.sep + + "site.template.pyconf to data" + + cfg.VARS.sep + + "site.pyconf and edit the file") raise src.SatException( e ); # add user local path for configPath - site_cfg.SITE.config.configPath.append(os.path.join(cfg.VARS.personalDir, 'Applications'), "User applications path") + site_cfg.SITE.config.configPath.append( + os.path.join(cfg.VARS.personalDir, 'Applications'), + "User applications path") merger.merge(cfg, site_cfg) @@ -215,7 +246,7 @@ class ConfigManager: exec('cfg.' + rule) # this cannot be factorized because of the exec - # ======================================================================================= + # ===================================================================== # Load APPLICATION config file if application is not None: # search APPLICATION file in all directories in configPath @@ -224,31 +255,38 @@ class ConfigManager: try: application_cfg = src.pyconf.Config(application + '.pyconf') except IOError as e: - raise src.SatException(_("%s, use 'config --list' to get the list of available applications.") %e) + raise src.SatException(_("%s, use 'config --list' to get the" + " list of available applications.") %e) except src.pyconf.ConfigError as e: - raise src.SatException(_("Error in configuration file: %(application)s.pyconf\n %(error)s") % \ + raise src.SatException(_("Error in configuration file:" + " %(application)s.pyconf\n %(error)s") % \ { 'application': application, 'error': str(e) } ) merger.merge(cfg, application_cfg) # apply overwrite from command line if needed - for rule in self.get_command_line_overrides(options, ["APPLICATION"]): - exec('cfg.' + rule) # this cannot be factorized because of the exec + for rule in self.get_command_line_overrides(options, + ["APPLICATION"]): + # this cannot be factorized because of the exec + exec('cfg.' + rule) - # ======================================================================================= + # ===================================================================== # Load softwares config files in SOFTWARE section # The directory containing the softwares definition softsDir = os.path.join(cfg.VARS.dataDir, 'softwares') - # Loop on all files that are in softsDir directory and read their config + # Loop on all files that are in softsDir directory + # and read their config for fName in os.listdir(softsDir): if fName.endswith(".pyconf"): src.pyconf.streamOpener = ConfigOpener([softsDir]) try: - soft_cfg = src.pyconf.Config(open(os.path.join(softsDir, fName))) + soft_cfg = src.pyconf.Config(open( + os.path.join(softsDir, fName))) except src.pyconf.ConfigError as e: - raise src.SatException(_("Error in configuration file: %(soft)s\n %(error)s") % \ + raise src.SatException(_( + "Error in configuration file: %(soft)s\n %(error)s") % \ {'soft' : fName, 'error': str(e) }) except IOError as error: e = str(error) @@ -261,7 +299,7 @@ class ConfigManager: exec('cfg.' + rule) # this cannot be factorized because of the exec - # ======================================================================================= + # ===================================================================== # load USER config self.set_user_config_file(cfg) user_cfg_file = self.get_user_config_file() @@ -278,18 +316,21 @@ class ConfigManager: '''Set the user config file name and path. If necessary, build it from another one or create it from scratch. - :param config class 'src.pyconf.Config': The global config (containing all pyconf). + :param config class 'src.pyconf.Config': The global config + (containing all pyconf). ''' # get the expected name and path of the file self.config_file_name = 'salomeTools.pyconf' - self.user_config_file_path = os.path.join(config.VARS.personalDir, self.config_file_name) + self.user_config_file_path = os.path.join(config.VARS.personalDir, + self.config_file_name) # if pyconf does not exist, create it from scratch if not os.path.isfile(self.user_config_file_path): self.create_config_file(config) def create_config_file(self, config): - '''This method is called when there are no user config file. It build it from scratch. + '''This method is called when there are no user config file. + It build it from scratch. :param config class 'src.pyconf.Config': The global config. :return: the config corresponding to the file created. @@ -304,25 +345,42 @@ class ConfigManager: # user_cfg.USER.addMapping('workDir', os.path.expanduser('~'), - "This is where salomeTools will work. You may (and probably do) change it.\n") + "This is where salomeTools will work. " + "You may (and probably do) change it.\n") user_cfg.USER.addMapping('cvs_user', config.VARS.user, "This is the user name used to access salome cvs base.\n") user_cfg.USER.addMapping('svn_user', config.VARS.user, "This is the user name used to access salome svn base.\n") user_cfg.USER.addMapping('output_level', 3, - "This is the default output_level you want. 0=>no output, 5=>debug.\n") - user_cfg.USER.addMapping('publish_dir', os.path.join(os.path.expanduser('~'), 'websupport', 'satreport'), "") - user_cfg.USER.addMapping('editor', 'vi', "This is the editor used to modify configuration files\n") - user_cfg.USER.addMapping('browser', 'firefox', "This is the browser used to read html documentation\n") - user_cfg.USER.addMapping('pdf_viewer', 'evince', "This is the pdf_viewer used to read pdf documentation\n") + "This is the default output_level you want." + " 0=>no output, 5=>debug.\n") + user_cfg.USER.addMapping('publish_dir', + os.path.join(os.path.expanduser('~'), + 'websupport', + 'satreport'), + "") + user_cfg.USER.addMapping('editor', + 'vi', + "This is the editor used to " + "modify configuration files\n") + user_cfg.USER.addMapping('browser', + 'firefox', + "This is the browser used to " + "read html documentation\n") + user_cfg.USER.addMapping('pdf_viewer', + 'evince', + "This is the pdf_viewer used " + "to read pdf documentation\n") # src.ensure_path_exists(config.VARS.personalDir) - src.ensure_path_exists(os.path.join(config.VARS.personalDir, 'Applications')) + src.ensure_path_exists(os.path.join(config.VARS.personalDir, + 'Applications')) f = open(cfg_name, 'w') user_cfg.__save__(f) f.close() - print(_("You can edit it to configure salomeTools (use: sat config --edit).\n")) + print(_("You can edit it to configure salomeTools " + "(use: sat config --edit).\n")) return user_cfg @@ -332,16 +390,20 @@ class ConfigManager: :rtype: str ''' if not self.user_config_file_path: - raise src.SatException(_("Error in get_user_config_file: missing user config file path")) + raise src.SatException(_("Error in get_user_config_file: " + "missing user config file path")) return self.user_config_file_path def print_value(config, path, show_label, logger, level=0, show_full_path=False): - '''Prints a value from the configuration. Prints recursively the values under the initial path. + '''Prints a value from the configuration. Prints recursively the values + under the initial path. - :param config class 'src.pyconf.Config': The configuration from which the value is displayed. + :param config class 'src.pyconf.Config': The configuration + from which the value is displayed. :param path str : the path in the configuration of the value to print. - :param show_label boolean: if True, do a basic display. (useful for bash completion) + :param show_label boolean: if True, do a basic display. + (useful for bash completion) :param logger Logger: the logger instance :param level int: The number of spaces to add before display. :param show_full_path : @@ -361,7 +423,8 @@ def print_value(config, path, show_label, logger, level=0, show_full_path=False) val = config.getByPath(path) except Exception as e: logger.write(tab_level) - logger.write("%s: ERROR %s\n" % (src.printcolors.printcLabel(vname), src.printcolors.printcError(str(e)))) + logger.write("%s: ERROR %s\n" % (src.printcolors.printcLabel(vname), + src.printcolors.printcError(str(e)))) return # in this case, display only the value @@ -369,16 +432,19 @@ def print_value(config, path, show_label, logger, level=0, show_full_path=False) logger.write(tab_level) logger.write("%s: " % src.printcolors.printcLabel(vname)) - # The case where the value has under values, do a recursive call to the function + # The case where the value has under values, + # do a recursive call to the function if dir(val).__contains__('keys'): if show_label: logger.write("\n") for v in sorted(val.keys()): print_value(config, path + '.' + v, show_label, logger, level + 1) - elif val.__class__ == src.pyconf.Sequence or isinstance(val, list): # in this case, value is a list (or a Sequence) + elif val.__class__ == src.pyconf.Sequence or isinstance(val, list): + # in this case, value is a list (or a Sequence) if show_label: logger.write("\n") index = 0 for v in val: - print_value(config, path + "[" + str(index) + "]", show_label, logger, level + 1) + print_value(config, path + "[" + str(index) + "]", + show_label, logger, level + 1) index = index + 1 else: # case where val is just a str logger.write("%s\n" % val) @@ -389,7 +455,8 @@ def description(): :return: The text to display for the config command description. :rtype: str ''' - return _("The config command allows manipulation and operation on config files.") + return _("The config command allows manipulation " + "and operation on config files.") def run(args, runner, logger): @@ -405,23 +472,27 @@ def run(args, runner, logger): for val in sorted(runner.cfg.keys()): print_value(runner.cfg, val, True, logger) else: - print_value(runner.cfg, options.value, True, logger, level=0, show_full_path=False) + print_value(runner.cfg, options.value, True, logger, + level=0, show_full_path=False) # case : edit user pyconf file or application file elif options.edit: editor = runner.cfg.USER.editor if 'APPLICATION' not in runner.cfg: # edit user pyconf - usercfg = os.path.join(runner.cfg.VARS.personalDir, 'salomeTools.pyconf') + usercfg = os.path.join(runner.cfg.VARS.personalDir, + 'salomeTools.pyconf') src.system.show_in_editor(editor, usercfg, logger) else: # search for file .pyconf and open it for path in runner.cfg.SITE.config.configPath: - pyconf_path = os.path.join(path, runner.cfg.VARS.application + ".pyconf") + pyconf_path = os.path.join(path, + runner.cfg.VARS.application + ".pyconf") if os.path.exists(pyconf_path): src.system.show_in_editor(editor, pyconf_path, logger) break - # case : copy an existing .pyconf to ~/.salomeTools/Applications/LOCAL_.pyconf + # case : copy an existing .pyconf + # to ~/.salomeTools/Applications/LOCAL_.pyconf elif options.copy: # product is required src.check_config_has_application( runner.cfg ) @@ -440,22 +511,26 @@ def run(args, runner, logger): break if len(source_full_path) == 0: - raise src.SatException(_("Config file for product %s not found\n") % source) + raise src.SatException(_( + "Config file for product %s not found\n") % source) else: if len(args) > 0: # a name is given as parameter, use it dest = args[0] elif 'copy_prefix' in runner.cfg.SITE.config: # use prefix - dest = runner.cfg.SITE.config.copy_prefix + runner.cfg.VARS.application + dest = (runner.cfg.SITE.config.copy_prefix + + runner.cfg.VARS.application) else: # use same name as source dest = runner.cfg.VARS.application # the full path - dest_file = os.path.join(runner.cfg.VARS.personalDir, 'Applications', dest + '.pyconf') + dest_file = os.path.join(runner.cfg.VARS.personalDir, + 'Applications', dest + '.pyconf') if os.path.exists(dest_file): - raise src.SatException(_("A personal application '%s' already exists") % dest) + raise src.SatException(_("A personal application" + " '%s' already exists") % dest) # perform the copy shutil.copyfile(source_full_path, dest_file) @@ -470,7 +545,8 @@ def run(args, runner, logger): logger.write("------ %s\n" % src.printcolors.printcHeader(path)) if not os.path.exists(path): - logger.write(src.printcolors.printcError(_("Directory not found")) + "\n") + logger.write(src.printcolors.printcError(_( + "Directory not found")) + "\n") else: for f in sorted(os.listdir(path)): # ignore file that does not ends with .pyconf diff --git a/commands/log.py b/commands/log.py index ba593ce..1ceb3dc 100644 --- a/commands/log.py +++ b/commands/log.py @@ -17,9 +17,12 @@ import src # Define all possible option for log command : sat log parser = src.options.Options() parser.add_option('t', 'terminal', 'boolean', 'terminal', "Terminal log.") -parser.add_option('l', 'last', 'boolean', 'last', "Show the log of the last launched command.") -parser.add_option('f', 'full', 'boolean', 'full', "Show the logs of ALL launched commands.") -parser.add_option('c', 'clean', 'int', 'clean', "Erase the n most ancient log files.") +parser.add_option('l', 'last', 'boolean', 'last', "Show the log of the last " + "launched command.") +parser.add_option('f', 'full', 'boolean', 'full', "Show the logs of ALL " + "launched commands.") +parser.add_option('c', 'clean', 'int', 'clean', "Erase the n most ancient " + "log files.") def get_last_log_file(logDir, notShownCommands): '''Used in case of last option. Get the last log command file path. @@ -48,7 +51,8 @@ def get_last_log_file(logDir, notShownCommands): def print_log_command_in_terminal(filePath, logger): '''Print the contain of filePath. It contains a command log in xml format. - :param filePath: The command xml file from which extract the commands context and traces + :param filePath: The command xml file from which extract the commands + context and traces :param logger Logger: the logging instance to use in order to print. ''' logger.write(_("Reading ") + src.printcolors.printcHeader(filePath) + "\n", 5) @@ -66,7 +70,8 @@ def print_log_command_in_terminal(filePath, logger): command_traces = xmlRead.get_node_text('Log') # Print it if there is any if command_traces: - logger.write(src.printcolors.printcHeader(_("Here are the command traces :\n")), 1) + logger.write(src.printcolors.printcHeader( + _("Here are the command traces :\n")), 1) logger.write(command_traces, 1) logger.write("\n", 1) @@ -106,14 +111,18 @@ def run(args, runner, logger): # Parse the options (options, args) = parser.parse_args(args) - # get the log directory. If there is an application, it is in cfg.APPLICATION.out_dir, else in user directory + # get the log directory. + # If there is an application, it is in cfg.APPLICATION.out_dir, + # else in user directory logDir = runner.cfg.SITE.log.logDir - # If the clean options is invoked, do nothing but deleting the concerned files. + # If the clean options is invoked, + # do nothing but deleting the concerned files. if options.clean: nbClean = options.clean # get the list of files to remove - lLogs = src.logger.list_log_file(logDir, src.logger.logCommandFileExpression) + lLogs = src.logger.list_log_file(logDir, + src.logger.logCommandFileExpression) nbLogFiles = len(lLogs) # Delete all if the invoked number is bigger than the number of log files if nbClean > nbLogFiles: @@ -121,7 +130,8 @@ def run(args, runner, logger): # Get the list to delete and do the removing lLogsToDelete = sorted(lLogs)[:nbClean] for filePath, _, _, _, _, _ in lLogsToDelete: - logger.write(src.printcolors.printcWarning("Removing ") + filePath + "\n", 5) + logger.write(src.printcolors.printcWarning("Removing ") + + filePath + "\n", 5) os.remove(filePath) logger.write(src.printcolors.printcSuccess("OK\n")) @@ -135,11 +145,14 @@ def run(args, runner, logger): # If the user asks for a terminal display if options.terminal: - # Parse the log directory in order to find all the files corresponding to the commands - lLogs = src.logger.list_log_file(logDir, src.logger.logCommandFileExpression) + # Parse the log directory in order to find + # all the files corresponding to the commands + lLogs = src.logger.list_log_file(logDir, + src.logger.logCommandFileExpression) lLogsFiltered = [] for filePath, _, date, _, hour, cmd in lLogs: - showLog, cmdAppli = src.logger.show_command_log(filePath, cmd, runner.cfg.VARS.application, notShownCommands) + showLog, cmdAppli = src.logger.show_command_log(filePath, cmd, + runner.cfg.VARS.application, notShownCommands) if showLog: lLogsFiltered.append((filePath, date, hour, cmd, cmdAppli)) @@ -149,7 +162,8 @@ def run(args, runner, logger): # loop on all files and print it with date, time and command name for _, date, hour, cmd, cmdAppli in lLogsFiltered: num = src.printcolors.printcLabel("%2d" % (nb_logs - index)) - logger.write("%s: %13s %s %s %s\n" % (num, cmd, date, hour, cmdAppli), 1, False) + logger.write("%s: %13s %s %s %s\n" % + (num, cmd, date, hour, cmdAppli), 1, False) index += 1 # ask the user what for what command he wants to be displayed @@ -180,12 +194,15 @@ def run(args, runner, logger): if options.last: lastLogFilePath = get_last_log_file(logDir, notShownCommands) # open the log xml file in the user editor - src.system.show_in_editor(runner.cfg.USER.browser, lastLogFilePath, logger) + src.system.show_in_editor(runner.cfg.USER.browser, + lastLogFilePath, logger) return 0 # Create or update the hat xml that gives access to all the commands log files xmlHatFilePath = os.path.join(logDir, 'hat.xml') - src.logger.update_hat_xml(runner.cfg.SITE.log.logDir, application = runner.cfg.VARS.application, notShownCommands = notShownCommands) + src.logger.update_hat_xml(runner.cfg.SITE.log.logDir, + application = runner.cfg.VARS.application, + notShownCommands = notShownCommands) # open the hat xml in the user editor src.system.show_in_editor(runner.cfg.USER.browser, xmlHatFilePath, logger) diff --git a/src/__init__.py b/src/__init__.py index 6d20dbf..52f3ab8 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -45,7 +45,8 @@ def check_config_has_application( config, details = None ): :param config class 'common.pyconf.Config': The config. ''' if 'APPLICATION' not in config: - message = _("An APPLICATION is required. Use 'config --list' to get the list of available applications.\n") + message = _("An APPLICATION is required. Use 'config --list' to get" + " the list of available applications.\n") if details : details.append(message) raise SatException( message ) diff --git a/src/architecture.py b/src/architecture.py index d10b06c..75af0e4 100644 --- a/src/architecture.py +++ b/src/architecture.py @@ -17,7 +17,8 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ''' -In this file : all the stuff that can change with the architecture on which SAT is running +In this file : all the stuff that can change with the architecture +on which SAT is running ''' import os, sys, platform, pwd @@ -56,21 +57,24 @@ def _lsb_release(args): path = lsb_path + ":" + path from subprocess import Popen, PIPE - res = Popen(['lsb_release', args], env={'PATH': path}, stdout=PIPE).communicate()[0][:-1] + res = Popen(['lsb_release', args], env={'PATH': path}, + stdout=PIPE).communicate()[0][:-1] # in case of python3, convert byte to str if isinstance(res, bytes): res = res.decode() return res except OSError: sys.stderr.write(_(u"lsb_release not installed\n")) - sys.stderr.write(_(u"You can define $LSB_PATH to give the path to lsb_release\n")) + sys.stderr.write(_(u"You can define $LSB_PATH to give" + " the path to lsb_release\n")) sys.exit(-1) def get_distribution(codes): '''Gets the code for the distribution :param codes L{Mapping}: The map containing distribution correlation table. - :return: The distribution on which salomeTools is running, regarding the distribution correlation table contained in codes variable. + :return: The distribution on which salomeTools is running, regarding the + distribution correlation table contained in codes variable. :rtype: str ''' if is_windows(): @@ -82,7 +86,8 @@ def get_distribution(codes): distrib = codes[distrib] else: sys.stderr.write(_(u"Unknown distribution: '%s'\n") % distrib) - sys.stderr.write(_(u"Please add your distribution to data/distrib.pyconf\n")) + sys.stderr.write(_(u"Please add your distribution to" + " data/distrib.pyconf\n")) sys.exit(-1) return distrib @@ -93,7 +98,9 @@ def get_distrib_version(distrib, codes): :param distrib str: The distribution on which the version will be found. :param codes L{Mapping}: The map containing distribution correlation table. - :return: The version of the distribution on which salomeTools is running, regarding the distribution correlation table contained in codes variable. + :return: The version of the distribution on which salomeTools is running, + regarding the distribution correlation table contained in codes + variable. :rtype: str ''' @@ -119,7 +126,8 @@ def get_python_version(): return platform.python_version() def get_nb_proc(): - '''Gets the number of processors of the machine on which salomeTools is running. + '''Gets the number of processors of the machine + on which salomeTools is running. :return: the number of processors. :rtype: str diff --git a/src/logger.py b/src/logger.py index 5a19ab2..e2d2d1e 100644 --- a/src/logger.py +++ b/src/logger.py @@ -34,7 +34,8 @@ class Logger(object): '''Initialization :param config pyconf.Config: The global configuration. - :param silent_sysstd boolean: if True, do not write anything in terminal. + :param silent_sysstd boolean: if True, do not write anything + in terminal. ''' self.config = config self.default_level = 3 @@ -43,7 +44,8 @@ class Logger(object): # Construct xml log file location for sat prints. logFileName = config.VARS.datehour + "_" + config.VARS.command + ".xml" logFilePath = os.path.join(config.SITE.log.logDir, logFileName) - # Construct txt file location in order to log the external commands calls (cmake, make, git clone, etc...) + # Construct txt file location in order to log + # the external commands calls (cmake, make, git clone, etc...) txtFileName = config.VARS.datehour + "_" + config.VARS.command + ".txt" txtFilePath = os.path.join(config.SITE.log.logDir, "OUT", txtFileName) @@ -54,46 +56,60 @@ class Logger(object): self.logFilePath = logFilePath self.txtFileName = txtFileName self.txtFilePath = txtFilePath - # Initialize xml instance and put first fields like beginTime, user, command, etc... - self.xmlFile = xmlManager.XmlLogFile(logFilePath, "SATcommand", attrib = {"application" : config.VARS.application}) + # Initialize xml instance and put first fields + # like beginTime, user, command, etc... + self.xmlFile = xmlManager.XmlLogFile(logFilePath, "SATcommand", + attrib = {"application" : config.VARS.application}) self.put_initial_xml_fields() # Initialize the txt file for reading self.logTxtFile = open(str(self.txtFilePath), 'w') def put_initial_xml_fields(self): - '''Method called at class initialization : Put all fields corresponding to the command context (user, time, ...) + '''Method called at class initialization : Put all fields + corresponding to the command context (user, time, ...) ''' # command name - self.xmlFile.add_simple_node("Site", attrib={"command" : self.config.VARS.command}) + self.xmlFile.add_simple_node("Site", attrib={"command" : + self.config.VARS.command}) # version of salomeTools - self.xmlFile.append_node_attrib("Site", attrib={"satversion" : self.config.INTERNAL.sat_version}) + self.xmlFile.append_node_attrib("Site", attrib={"satversion" : + self.config.INTERNAL.sat_version}) # machine name on which the command has been launched - self.xmlFile.append_node_attrib("Site", attrib={"hostname" : self.config.VARS.hostname}) + self.xmlFile.append_node_attrib("Site", attrib={"hostname" : + self.config.VARS.hostname}) # Distribution of the machine - self.xmlFile.append_node_attrib("Site", attrib={"OS" : self.config.VARS.dist}) + self.xmlFile.append_node_attrib("Site", attrib={"OS" : + self.config.VARS.dist}) # The user that have launched the command - self.xmlFile.append_node_attrib("Site", attrib={"user" : self.config.VARS.user}) + self.xmlFile.append_node_attrib("Site", attrib={"user" : + self.config.VARS.user}) # The time when command was launched Y, m, dd, H, M, S = date_to_datetime(self.config.VARS.datehour) date_hour = "%2s/%2s/%4s %2sh%2sm%2ss" % (dd, m, Y, H, M, S) - self.xmlFile.append_node_attrib("Site", attrib={"beginTime" : date_hour}) + self.xmlFile.append_node_attrib("Site", attrib={"beginTime" : + date_hour}) # The application if any if "APPLICATION" in self.config: - self.xmlFile.append_node_attrib("Site", attrib={"application" : self.config.VARS.application}) + self.xmlFile.append_node_attrib("Site", + attrib={"application" : self.config.VARS.application}) # The initialization of the trace node self.xmlFile.add_simple_node("Log",text="") - self.xmlFile.add_simple_node("OutLog",text=os.path.join("OUT", self.txtFileName)) + self.xmlFile.add_simple_node("OutLog", + text=os.path.join("OUT", self.txtFileName)) def write(self, message, level=None, screenOnly=False): - '''the function used in the commands that will print in the terminal and the log file. + '''the function used in the commands + that will print in the terminal and the log file. :param message str: The message to print. - :param level int: The output level corresponding to the message 0 < level < 6. + :param level int: The output level corresponding + to the message 0 < level < 6. :param screenOnly boolean: if True, do not write in log file. ''' # do not write message starting with \r to log file if not message.startswith("\r") and not screenOnly: - self.xmlFile.append_node_text("Log", printcolors.cleancolor(message)) + self.xmlFile.append_node_text("Log", + printcolors.cleancolor(message)) # get user or option output level current_output_level = self.config.USER.output_level @@ -118,7 +134,8 @@ class Logger(object): # Print in the log file self.xmlFile.append_node_text("traces", _('ERROR:') + message) - # Print in the terminal and clean colors if the terminal is redirected by user + # Print in the terminal and clean colors if the terminal + # is redirected by user if not ('isatty' in dir(sys.stderr) and sys.stderr.isatty()): sys.stderr.write(printcolors.printcError(_('ERROR:') + message)) else: @@ -130,9 +147,10 @@ class Logger(object): sys.stdout.flush() def end_write(self, attribute): - '''Method called just after command end : Put all fields corresponding to the command end context (time). - Write the log xml file on the hard drive. - And display the command to launch to get the log + '''Method called just after command end : Put all fields + corresponding to the command end context (time). + Write the log xml file on the hard drive. + And display the command to launch to get the log :param attribute dict: the attribute to add to the node "Site". ''' @@ -146,10 +164,12 @@ class Logger(object): hours = int(total_time / 3600) minutes = int((total_time - hours*3600) / 60) seconds = total_time - hours*3600 - minutes*60 - # Add the fields corresponding to the end time and the total time of command + # Add the fields corresponding to the end time + # and the total time of command endtime = dt.strftime('%d/%Y/%m %Hh%Mm%Ss') self.xmlFile.append_node_attrib("Site", attrib={"endTime" : endtime}) - self.xmlFile.append_node_attrib("Site", attrib={"TotalTime" : "%ih%im%is" % (hours, minutes, seconds)}) + self.xmlFile.append_node_attrib("Site", + attrib={"TotalTime" : "%ih%im%is" % (hours, minutes, seconds)}) # Add the attribute passed to the method self.xmlFile.append_node_attrib("Site", attrib=attribute) @@ -159,7 +179,8 @@ class Logger(object): def date_to_datetime(date): - '''Little method that gets year, mon, day, hour , minutes and seconds from a str in format YYYYMMDD_HHMMSS + '''Little method that gets year, mon, day, hour , + minutes and seconds from a str in format YYYYMMDD_HHMMSS :param date str: The date in format YYYYMMDD_HHMMSS :return: the same date and time in separate variables. @@ -174,7 +195,8 @@ def date_to_datetime(date): return Y, m, dd, H, M, S def timedelta_total_seconds(timedelta): - '''Little method to replace total_seconds from datetime module in order to be compatible with old python versions + '''Little method to replace total_seconds from + datetime module in order to be compatible with old python versions :param timedelta datetime.timedelta: The delta between two dates :return: The number of seconds corresponding to timedelta. @@ -185,17 +207,22 @@ def timedelta_total_seconds(timedelta): (timedelta.seconds + timedelta.days * 24 * 3600) * 10 ** 6) / 10 ** 6 def show_command_log(logFilePath, cmd, application, notShownCommands): - '''Used in updateHatXml. Determine if the log xml file logFilePath has to be shown or not in the hat log. + '''Used in updateHatXml. Determine if the log xml file logFilePath + has to be shown or not in the hat log. :param logFilePath str: the path to the command xml log file :param cmd str: the command of the log file - :param application str: the application passed as parameter to the salomeTools command - :param notShownCommands list: the list of commands that are not shown by default + :param application str: the application passed as parameter + to the salomeTools command + :param notShownCommands list: the list of commands + that are not shown by default - :return: True if cmd is not in notShownCommands and the application in the log file corresponds to application + :return: True if cmd is not in notShownCommands and the application + in the log file corresponds to application :rtype: boolean ''' - # When the command is not in notShownCommands, no need to go further. Do not show + # When the command is not in notShownCommands, no need to go further : + # Do not show if cmd in notShownCommands: return False, None @@ -233,30 +260,42 @@ def list_log_file(dirPath, expression): # get date and hour and format it date_hour_cmd = fileName.split('_') date_not_formated = date_hour_cmd[0] - date = "%s/%s/%s" % (date_not_formated[6:8], date_not_formated[4:6], date_not_formated[0:4] ) + date = "%s/%s/%s" % (date_not_formated[6:8], + date_not_formated[4:6], date_not_formated[0:4] ) hour_not_formated = date_hour_cmd[1] - hour = "%s:%s:%s" % (hour_not_formated[0:2], hour_not_formated[2:4], hour_not_formated[4:6]) + hour = "%s:%s:%s" % (hour_not_formated[0:2], + hour_not_formated[2:4], hour_not_formated[4:6]) cmd = date_hour_cmd[2][:-len('.xml')] - lRes.append((os.path.join(dirPath, fileName), date_not_formated, date, hour_not_formated, hour, cmd)) + lRes.append((os.path.join(dirPath, fileName), + date_not_formated, date, hour_not_formated, hour, cmd)) return lRes def update_hat_xml(logDir, application=None, notShownCommands = []): - '''Create the xml file in logDir that contain all the xml file and have a name like YYYYMMDD_HHMMSS_namecmd.xml + '''Create the xml file in logDir that contain all the xml file + and have a name like YYYYMMDD_HHMMSS_namecmd.xml :param logDir str: the directory to parse :param application str: the name of the application if there is any ''' # Create an instance of XmlLogFile class to create hat.xml file xmlHatFilePath = os.path.join(logDir, 'hat.xml') - xmlHat = src.xmlManager.XmlLogFile(xmlHatFilePath, "LOGlist", {"application" : application}) - # parse the log directory to find all the command logs, then add it to the xml file + xmlHat = src.xmlManager.XmlLogFile(xmlHatFilePath, + "LOGlist", {"application" : application}) + # parse the log directory to find all the command logs, + # then add it to the xml file lLogFile = list_log_file(logDir, logCommandFileExpression) for filePath, _, date, _, hour, cmd in lLogFile: - showLog, cmdAppli = show_command_log(filePath, cmd, application, notShownCommands) + showLog, cmdAppli = show_command_log(filePath, cmd, + application, notShownCommands) #if cmd not in notShownCommands: if showLog: # add a node to the hat.xml file - xmlHat.add_simple_node("LogCommand", text=os.path.basename(filePath), attrib = {"date" : date, "hour" : hour, "cmd" : cmd, "application" : cmdAppli}) + xmlHat.add_simple_node("LogCommand", + text=os.path.basename(filePath), + attrib = {"date" : date, + "hour" : hour, + "cmd" : cmd, + "application" : cmdAppli}) # Write the file on the hard drive xmlHat.write_tree('hat.xsl') \ No newline at end of file diff --git a/src/options.py b/src/options.py index b54b190..a6bca2a 100644 --- a/src/options.py +++ b/src/options.py @@ -15,18 +15,21 @@ # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -'''The Options class that manages the access to all options passed as parameters in salomeTools command lines +'''The Options class that manages the access to all options passed as + parameters in salomeTools command lines ''' import getopt import sys from . import printcolors class OptResult(object): - '''An instance of this class will be the object manipulated in code of all salomeTools commands - The aim of this class is to have an elegant syntax to manipulate the options. - ex: - print(options.level) - 5 + '''An instance of this class will be the object manipulated + in code of all salomeTools commands + The aim of this class is to have an elegant syntax + to manipulate the options. + ex: + print(options.level) + 5 ''' def __init__(self): '''Initialization @@ -34,7 +37,8 @@ class OptResult(object): self.__dict__ = dict() def __getattr__(self, name): - '''Overwrite of the __getattr__ function to customize it for option usage + '''Overwrite of the __getattr__ function + to customize it for option usage :param name str: The attribute to get the value. :return: the value corresponding to the attribute. @@ -46,7 +50,8 @@ class OptResult(object): raise AttributeError(name + _(u" is not a valid option")) def __setattr__(self, name, value): - '''Overwrite of the __setattr__ function to customize it for option usage + '''Overwrite of the __setattr__ function + to customize it for option usage :param name str: The attribute to set. :param value str: The value corresponding to the attribute. @@ -61,19 +66,26 @@ class Options: def __init__(self): '''Initialization ''' - # The options field stocks all options of a command in a list that contains dicts + # The options field stocks all options of a command + # in a list that contains dicts self.options = [] # The list of available option type - self.availableOptions = ["boolean", "string", "int", "float", "long", "list", "list2"] + self.availableOptions = ["boolean", "string", "int", "float", + "long", "list", "list2"] - def add_option(self, shortName, longName, optionType, destName, helpString=""): - '''Method to add an option to a command. It gets all attributes of an option and append it in the options field + def add_option(self, shortName, longName, + optionType, destName, helpString=""): + '''Method to add an option to a command. It gets all attributes + of an option and append it in the options field - :param shortName str: The short name of the option (ex "l" for level option). - :param longName str: The long name of the option (ex "level" for level option). + :param shortName str: The short name of the option + (ex "l" for level option). + :param longName str: The long name of the option + (ex "level" for level option). :param optionType str: The type of the option (ex "int"). :param destName str: The name that will be used in the code. - :param helpString str: The text to display when user ask for help on a command. + :param helpString str: The text to display + when user ask for help on a command. :return: Nothing. :rtype: N\A ''' @@ -101,25 +113,32 @@ class Options: if len(self.options) == 0: return - # for all options, print its values. "shortname" is an optional field of the options + # for all options, print its values. + # "shortname" is an optional field of the options print(printcolors.printcHeader(_("Available options are:"))) for option in self.options: if 'shortName' in option and len(option['shortName']) > 0: - print(" -%(shortName)1s, --%(longName)s (%(optionType)s)\n\t%(helpString)s\n" % option) + print(" -%(shortName)1s, --%(longName)s" + " (%(optionType)s)\n\t%(helpString)s\n" % option) else: - print(" --%(longName)s (%(optionType)s)\n\t%(helpString)s\n" % option) + print(" --%(longName)s (%(optionType)s)\n\t%(helpString)s\n" + % option) def parse_args(self, argList=None): - '''Method that instantiates the class OptResult that gives access to all options in the code + '''Method that instantiates the class OptResult + that gives access to all options in the code :param argList list: the raw list of arguments that were passed - :return: optResult, args : optResult is the option instance to manipulate in the code. args is the full raw list of passed options + :return: optResult, args : optResult is the option instance + to manipulate in the code. args + is the full raw list of passed options :rtype: (class 'common.options.OptResult',list) ''' if argList is None: argList = sys.argv[1:] - # format shortNameOption and longNameOption to make right arguments to getopt.getopt function + # format shortNameOption and longNameOption + # to make right arguments to getopt.getopt function shortNameOption = "" longNameOption = [] for option in self.options: @@ -133,7 +152,8 @@ class Options: else: longNameOption.append(option['longName']) - # call to getopt.getopt function to get the option passed in the command regarding the available options + # call to getopt.getopt function to get the option + # passed in the command regarding the available options optlist, args = getopt.getopt(argList, shortNameOption, longNameOption) # instantiate and completing the optResult that will be returned @@ -168,7 +188,8 @@ class Options: option['result'].extend(elts) optResult.__setattr__(option['destName'], option['result']) - # free the option in order to be able to make a new free call of options (API case) + # free the option in order to be able to make + # a new free call of options (API case) option['result'] = None return optResult, args diff --git a/src/printcolors.py b/src/printcolors.py index da76a47..68e0a8b 100644 --- a/src/printcolors.py +++ b/src/printcolors.py @@ -39,7 +39,8 @@ __colormap__ = { } # list of available codes -__code_range__ = [1, 4] + list(range(30, 38)) + list(range(40, 48)) + list(range(90, 98)) + list(range(100, 108)) +__code_range__ = ([1, 4] + list(range(30, 38)) + list(range(40, 48)) + + list(range(90, 98)) + list(range(100, 108))) def printc(txt, code=''): '''print a text with colors @@ -152,7 +153,8 @@ def print_value(logger, label, value, level=1, suffix=""): if logger is None: print(" %s = %s %s" % (label, printcInfo(str(value)), suffix)) else: - logger.write(" %s = %s %s\n" % (label, printcInfo(str(value)), suffix), level) + logger.write(" %s = %s %s\n" % (label, printcInfo(str(value)), + suffix), level) def print_color_range(start, end): '''print possible range values for colors diff --git a/src/system.py b/src/system.py index c595a43..0107cdb 100644 --- a/src/system.py +++ b/src/system.py @@ -17,7 +17,8 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ''' -In this file : all functions that do a system call, like open a browser or an editor, or call a git command +In this file : all functions that do a system call, +like open a browser or an editor, or call a git command ''' import subprocess @@ -44,5 +45,6 @@ def show_in_editor(editor, filePath, logger): p = subprocess.Popen(cmd, shell=True) p.communicate() except: - logger.write(printcolors.printcError(_("Unable to edit file %s\n") % filePath), 1) + logger.write(printcolors.printcError(_("Unable to edit file %s\n") + % filePath), 1) \ No newline at end of file diff --git a/src/xmlManager.py b/src/xmlManager.py index 76ad6e0..9780778 100644 --- a/src/xmlManager.py +++ b/src/xmlManager.py @@ -29,9 +29,11 @@ class XmlLogFile(object): :param filePath str: The path to the file where to write the log file :param rootname str: The name of the root node of the xml file - :param attrib dict: the dictionary that contains the attributes and value of the root node + :param attrib dict: the dictionary that contains the attributes + and value of the root node ''' - # Initialize the filePath and ensure that the directory that contain the file exists (make it if necessary) + # Initialize the filePath and ensure that the directory + # that contain the file exists (make it if necessary) self.logFile = filePath src.ensure_path_exists(os.path.dirname(filePath)) # Initialize the field that contain the xml in memory @@ -45,7 +47,8 @@ class XmlLogFile(object): f = open(self.logFile, 'w') f.write("\n") if stylesheet: - f.write("\n" % stylesheet) + f.write("\n" % + stylesheet) f.write(etree.tostring(self.xmlroot, encoding='utf-8')) f.close() @@ -54,7 +57,8 @@ class XmlLogFile(object): :param node_name str: the name of the node to add :param text str: the text of the node - :param attrib dict: the dictionary containing the attribute of the new node + :param attrib dict: the dictionary containing the + attribute of the new node ''' n = etree.Element(node_name, attrib=attrib) n.text = text @@ -124,11 +128,12 @@ class readXmlFile(object): return fixedAttrib def get_node_text(self, node): - '''Get the text of the first node that has name that corresponds to the parameter node + '''Get the text of the first node that has name + that corresponds to the parameter node :param node str: the name of the node from which get the text - :return: the text of the first node that has name that corresponds to the parameter node + :return: the text of the first node that has name + that corresponds to the parameter node :rtype: str ''' return self.xmlroot.find(node).text -