# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import os
-import subprocess as sP
+import pprint as PP
import src.debug as DBG
import src.returnCode as RCO
# Print some informations
logger.info("Patching sources of the application %s" % \
- UTS.blue(config.VARS.application))
+ UTS.label(config.VARS.application))
- logger.info(" workdir = %s" % UTS.blue(config.APPLICATION.workdir))
+ logger.info(" workdir = %s" % UTS.info(config.APPLICATION.workdir))
# Get the products list with products informations regarding the options
products_infos = self.get_products_list(options, config)
# The loop on all the products on which to apply the patches
good_result = 0
for tmp, product_info in products_infos:
- # Apply the patch
- rc = apply_patch(config, product_info, max_product_name_len, logger)
- logger.info(str(rc))
- if rc.isOk():
- good_result += 1
+ # Apply the patch
+ rc = apply_patch(config, product_info, max_product_name_len, logger)
+ if rc.isOk():
+ good_result += 1
# Display the results (how much passed, how much failed, etc...)
-
if good_result == len(products_infos):
- status = "OK"
+ status = "OK"
else:
- status = "KO"
+ status = "KO"
# write results
msg = ("Patching sources of the application: <%s> (%d/%d)") % \
- (status, good_result, len(products_infos))
- logger.info(msg)
-
+ (status, good_result, len(products_infos))
+ logger.info(msg)
return RCO.ReturnCode(status, msg)
def apply_patch(config, product_info, max_product_name_len, logger):
- """The method called to apply patches on a product
-
- :param config: (Config) The global configuration
- :param product_info: (Config)
- The configuration specific to the product to be patched
- :param logger: (Logger:
- The logger instance to use for the display and logging
- :return: (RCO.ReturnCode)
- """
-
- # if the product is native, do not apply patch
- if PROD.product_is_native(product_info):
- # display and log
- logger.info('%s: ' % UTS.label(product_info.name))
- logger.info(' ' * (max_product_name_len - len(product_info.name)))
- logger.info("\n")
- msg = _("The %s product is native. Do not apply any patch") % product_info.name
- logger.info(msg + "\n")
- return RCO.ReturnCode("OK", msg)
-
- if not "patches" in product_info or len(product_info.patches) == 0:
- # display and log
- logger.info('%s: ' % UTS.label(product_info.name))
- logger.info(' ' * (max_product_name_len - len(product_info.name)))
- logger.info("\n")
- msg = _("No patch for the %s product") % product_info.name
- logger.info(msg + "\n")
- return RCO.ReturnCode("OK", msg)
- else:
- # display and log
- logger.info('%s: ' % UTS.label(product_info.name))
- logger.info(' ' * (max_product_name_len - len(product_info.name)))
- logger.info("\n")
-
- if not os.path.exists(product_info.source_dir):
- msg = _("No sources found for the %s product") % product_info.name
- logger.error(UTS.red(msg))
- return RCO.ReturnCode("KO", msg)
-
- # At this point, there one or more patches and the source directory exists
- retcode = []
- res = []
- # Loop on all the patches of the product
- for patch in product_info.patches:
- details = []
-
- # Check the existence and apply the patch
- if os.path.isfile(patch):
- patch_cmd = "patch -p1 < %s" % patch
-
- # Write the command in the terminal if verbose level is at 5
- logger.info(" >%s\n" % patch_cmd)
-
- # Write the command in the log file (can be seen using 'sat log')
- logger.logTxtFile.write("\n >%s\n" % patch_cmd)
- logger.logTxtFile.flush()
-
- # Call the command
- res_cmd = SP.call(patch_cmd, shell=True, cwd=product_info.source_dir,
- stdout=logger.logTxtFile, stderr=SP.STDOUT )
-
- res_cmd = (res_cmd == 0)
- else:
- res_cmd = False
- details.append(" " + UTS.red(_("Not a valid patch: %s\n")) % patch)
-
- res.append(res_cmd)
-
- if res_cmd:
- message = _("Apply patch %s") % UTS.blue(patch)
- else:
- message = _("Failed to apply patch %s") % UTS.red(patch)
-
- if config.USER.output_verbose_level >= 3:
- retcode.append(" %s" % message)
- else:
- retcode.append("%s: %s" % (product_info.name, message))
-
- if len(details) > 0:
- retcode.extend(details)
-
- if False in res:
+ """The method called to apply patches on a product
+
+ :param config: (Config) The global configuration
+ :param product_info: (Config)
+ The configuration specific to the product to be patched
+ :param logger: (Logger:
+ The logger instance to use for the display and logging
+ :return: (RCO.ReturnCode)
+ """
+
+ # if the product is native, do not apply patch
+ msg = '%s: ' % UTS.label(product_info.name)
+ if PROD.product_is_native(product_info):
+ # display and log
+ msg += _("The product is native. Do not apply any patch")
+ logger.info(msg)
+ return RCO.ReturnCode("OK", msg)
+
+ if not "patches" in product_info or len(product_info.patches) == 0:
+ # display and log
+ msg += _("No patch for the product")
+ logger.info(msg)
+ return RCO.ReturnCode("OK", msg)
+ else:
+ # display and log after action
+ pass
+
+ if not os.path.exists(product_info.source_dir):
+ msg += _("No sources found for the product")
+ logger.error(UTS.red(msg))
+ return RCO.ReturnCode("KO", msg)
+
+ # At this point, there one or more patches and the source directory exists
+ retcodes = []
+ rc = "OK"
+ # Loop on all the patches of the product
+ for patch in product_info.patches:
+ details = []
+ # Check the existence and apply the patch
+ if not os.path.isfile(patch):
+ msg += _("Patch file %s not found") % UTS.info(patch)
+ logger.error(msg)
+ continue
+
+ cmd = """
+set -x
+patch -p1 < %s
+""" % patch
+ # Call the command
+ res = UTS.Popen(cmd, cwd=product_info.source_dir, logger=logger)
+ if not res.isOk():
rc = "KO"
+ resPatch = RCO.ReturnCode("KO", _("Failed to apply patch %s") % UTS.red(patch))
else:
- rc = "OK"
-
- return RCO.ReturnCode(rc, "\n".join(retcode))
+ resPatch = RCO.ReturnCode("OK", _("Apply patch %s") % UTS.info(patch))
+ retcodes.append(resPatch)
+
+ res = RCO.ReturnCodeFromList(retcodes)
+ if res.isOk():
+ logger.info(msg + "...<OK>")
+ logger.trace(msg + "...<OK> %s" % res.getWhy())
+ else:
+ logger.info(msg + "...<KO> %s" % res.getWhy())
+ return res
+
repo_git = product_info.git_info.repo
# Display informations
- msg = " %s:%s tag:%s ..." % (coflag, repo_git, product_info.git_info.tag)
+ msg = " %s:%s tag:%s ..." % (coflag, UTS.info(repo_git), product_info.git_info.tag)
logger.info(msg)
# Call the system function that do the extraction in git mode
:return: (bool) True if it succeed, else False
"""
# check archive exists
- if not os.path.exists(product_info.archive_info.archive_name):
- raise Exception(_("Archive not found: '%s'") % \
- product_info.archive_info.archive_name)
+ archName = product_info.archive_info.archive_name
+ if not os.path.exists(archName):
+ raise Exception(_("Archive not found: '%s'") % archName)
- logger.info('arc:%s ... ' % UTS.info(product_info.archive_info.archive_name))
+ logger.info(' arc:%s ...' % UTS.info(archName))
# Call the system function that do the extraction in archive mode
- retcode, NameExtractedDirectory = SYSS.archive_extract(
- product_info.archive_info.archive_name,
- source_dir.dir(), logger)
+ retcode = SYSS.archive_extract(archName, source_dir.dir(), logger)
+ nameDirectory = retcode.getValue() # where extracted
# Rename the source directory if
# it does not match with product_info.source_dir
- if (NameExtractedDirectory.replace('/', '') !=
- os.path.basename(product_info.source_dir)):
- shutil.move(os.path.join(os.path.dirname(product_info.source_dir),
- NameExtractedDirectory),
- product_info.source_dir)
-
+ baseDir = os.path.basename(product_info.source_dir)
+ if (nameDirectory.replace('/', '') != baseDir):
+ iniDir = os.path.join(os.path.dirname(product_info.source_dir), nameDirectory)
+ shutil.move(iniDir, product_info.source_dir)
return retcode
def get_source_from_dir(product_info, source_dir, logger):
logger.error(msg)
return False
- logger.info('DIR: %s ... ' % UTS.info(product_info.dir_info.dir))
+ logger.info(' DIR: %s ...' % UTS.info(product_info.dir_info.dir))
retcode = UTS.Path(product_info.dir_info.dir).copy(source_dir)
return retcode
coflag = 'cvs'
if checkout: coflag = coflag.upper()
- msg = '%s:%s' % (coflag, cvs_line)
- msg += " " * (pad + 50 - len(cvs_line))
+ msg = " %s:%s" % (coflag, cvs_line)
msg += " src:%s" % product_info.cvs_info.source
- msg += " " * (pad + 1 - len(product_info.cvs_info.source))
msg += " tag:%s" % product_info.cvs_info.tag
# at least one '.' is visible
- msg += " %s. " % ("." * (10 - len(product_info.cvs_info.tag)))
-
+ msg += " %s ..." % msg
logger.info(msg)
-
# Call the system function that do the extraction in cvs mode
retcode = SYSS.cvs_extract(protocol, user,
product_info.cvs_info.server,
coflag = 'svn'
if checkout: coflag = coflag.upper()
- logger.info('%s:%s ... ' % (coflag, product_info.svn_info.repo))
-
+ logger.info(' %s:%s ...' % (coflag, product_info.svn_info.repo))
# Call the system function that do the extraction in svn mode
retcode = SYSS.svn_extract(user,
product_info.svn_info.repo,
LOGI.STEP = _STEP # only for coherency,
LOGI.TRACE = _TRACE # only for coherency,
+_knownLevels = "CRITICAL ERROR WARNING INFO STEP TRACE DEBUG".upper().split()
#################################################################
# utilities methods
LOGI.addLevelName(_STEP, "STEP")
LOGI.addLevelName(_TRACE, "TRACE")
self.dateLogger = "NoDateLogger"
+ self.dateHour = None # datehour of main command
self.isClosed = False
self.idCommandHandlers = 0 # incremented, 0 for main command 1, 2, etc. for micro command
self.STEP = _STEP
log_dir_out = os.path.join(log_dir, "OUT") # files txt
UTS.ensure_path_exists(log_dir)
UTS.ensure_path_exists(log_dir_out)
- datehour = config.VARS.datehour
+ if self.idCommandHandlers == 0:
+ datehour = config.VARS.datehour
+ self.dateHour = datehour # save dateHour for micro commands
+ else:
+ datehour = self.dateHour # micro commands have same datehour for naming files
+
cmd = config.VARS.command
fullNameCmd = cmdInstance.getFullNameStr()
hostname = config.VARS.hostname
# in a list that contains dicts
self.options = []
# The list of available option type
- self.availableOptions = "boolean string int float long list list2 level".split()
+ self.availableOptions = "noboolean boolean string int float long list list2 level".split()
+ self.noArgOptions = "noboolean boolean".split()
self.default = None
self.results = {}
longNameOption = []
for option in self.options:
shortNameOption = shortNameOption + option['shortName']
- if option['shortName'] != "" and option['optionType'] != "boolean":
+ if option['shortName'] != "" and option['optionType'] not in self.noArgOptions:
shortNameOption = shortNameOption + ":"
if option['longName'] != "":
- if option['optionType'] != "boolean":
+ if option['optionType'] not in self.noArgOptions:
longNameOption.append(option['longName'] + "=")
else:
longNameOption.append(option['longName'])
try:
optlist, args = getopt.getopt(argList, shortNameOption, longNameOption)
except Exception as e:
- msg = str(e) + " on %s\n\n" % argList + self.get_help()
+ msg = str(e) + " on '%s'\n\n" % " ".join(argList) + self.get_help()
raise Exception(msg)
# instantiate and completing the optResult that will be returned
option['result'] = opt[1]
elif optionType == "boolean":
option['result'] = True
+ elif optionType == "noboolean":
+ option['result'] = False
elif optionType == "int":
option['result'] = int(opt[1])
elif optionType == "float":
option['result'] = list()
option['result'].append(opt[1])
elif optionType == "level": #logger logging levels
- option['result'] = opt[1]
- # TODO test in (lowercase) debug info warning error critical
+ option['result'] = self.filterLevel(opt[1])
elif optionType == "list2":
if option['result'] is None:
option['result'] = list()
- if opt[1].find(",") == -1:
- option['result'].append(opt[1])
- else:
- elts = filter(lambda l: len(l) > 0, opt[1].split(","))
- option['result'].extend(elts)
+ option['result'] = self.filterList2(opt[1])
optResult.__setattr__(option['destName'], option['result'])
# free the option in order to be able to make
self.results = {"optlist": optlist, "optResult": optResult, "args": args, "argList": argList}
DBG.write("results", self.results)
return optResult, args
+
+ def filterLevel(self, aLevel):
+ """filter level logging values"""
+ import src.loggingSat as LOG
+ aLev = aLevel.upper()
+ knownLevels = LOG._knownLevels
+ maxLen = max([len(i) for i in knownLevels])
+ for i in range(maxLen):
+ for lev in knownLevels:
+ if aLev == lev[:i]:
+ DBG.write("filterLevel", "%s -> %s" % (aLevel, lev), True)
+ return lev
+ msg = "Unknown level '%s', accepted are:\n%s" % (aLev, ",".join(knownLevels))
+ raise Exception(msg)
+
+ def filterList2(self, aStr):
+ """filter a list as 'KERNEL,YACS,etc.'"""
+ aList = aStr.strip().split(",")
+ return aList
+
def __repr__(self):
"""
return self
else:
raise Exception(self.getWhy())
+
+def ReturnCodeFromList(aListOfReturnCodes):
+ """
+ Create ReturnCode from list of ReturnCode
+
+ convenience over "+" operand
+ """
+ res = "OK"
+ whyes = []
+ for rc in aListOfReturnCodes:
+ if not rc.isOk():
+ res = "KO"
+ whyes.append(str(rc))
+ reswhy = "\n ".join(whyes)
+ return ReturnCode(res, "\n " + reswhy)
+
+
\ No newline at end of file
(internal use only)
"""
parser = Options()
+
parser.add_option('h', 'help', 'boolean', 'help',
_("shows global help or help on a specific command."))
+
parser.add_option('o', 'overwrite', 'list', "overwrite",
_("overwrites a configuration parameters."))
- parser.add_option('g', 'debug', 'boolean', 'debug_mode',
- _("run salomeTools in debug mode."))
- parser.add_option('v', 'verbose', 'int', "output_verbose_level",
- _("change output verbose level (default is 3)."))
+
+ parser.add_option('v', 'verbose', 'level', "output_verbose_level",
+ _("change console output verbose level (default is INFO)."))
+
+ parser.add_option('d', 'devel', 'noboolean', "development mode",
+ _("""\
+development mode (more verbose error/exception messages)
+(default is production mode)."""))
+
parser.add_option('b', 'batch', 'boolean', "batch",
_("batch mode (no question)."))
- parser.add_option('t', 'all_in_terminal', 'boolean', "all_in_terminal",
- _("all traces in the terminal (for example compilation logs)."))
+
+ parser.add_option('t', 'terminal_all_log', "noboolean", 'terminal_all_log',
+ _("all log traces in the terminal (for example compilation logs)."))
+
parser.add_option('l', 'logs_paths_in_file', 'string', "logs_paths_in_file",
_("put the command result and paths to log files."))
return parser
def parseArguments(self, arguments):
args = self.assumeAsList(arguments)
genericOptions, remaindersArgs = self.parser.parse_args(args)
- DBG.write("Sat generic options", genericOptions)
- DBG.write("Sat remainders arguments", remaindersArgs)
+ DBG.write("Sat generic options", genericOptions, True)
+ DBG.write("Sat remainders arguments", remaindersArgs, True)
return genericOptions, remaindersArgs