parser.add_option('l', 'list', 'boolean', 'list',
_("Optional: list all available applications."))
parser.add_option('', 'show_patchs', 'boolean', 'show_patchs',
- _("Optional: synthetic view of all patches used in the application"))
+ _("Optional: synthetic list of all patches used in the application"))
+parser.add_option('', 'show_properties', 'boolean', 'show_properties',
+ _("Optional: synthetic list of all properties used in the application"))
parser.add_option('c', 'copy', 'boolean', 'copy',
_("""Optional: copy a config file to the personal config files directory.
\tWARNING the included files are not copied.
False)
zz.set_python_libdirs()
zz.set_a_product(name, logger)
-
+ logger.write("\n", 2)
+
+
def show_patchs(config, logger):
- '''Prints all the used patchs in the application.
-
- :param config Config: the global configuration.
- :param logger Logger: The logger instance to use for the display
- '''
- len_max = max([len(p) for p in config.APPLICATION.products]) + 2
- for product in config.APPLICATION.products:
- product_info = src.product.get_product_config(config, product)
- if src.product.product_has_patches(product_info):
- logger.write("%s: " % product, 1)
- logger.write(src.printcolors.printcInfo(
- " " * (len_max - len(product) -2) +
- "%s\n" % product_info.patches[0]),
- 1)
- if len(product_info.patches) > 1:
- for patch in product_info.patches[1:]:
- logger.write(src.printcolors.printcInfo(len_max*" " +
- "%s\n" % patch), 1)
- logger.write("\n", 1)
+ '''Prints all the used patchs in the application.
+
+ :param config Config: the global configuration.
+ :param logger Logger: The logger instance to use for the display
+ '''
+ oneOrMore = False
+ for product in sorted(config.APPLICATION.products):
+ product_info = src.product.get_product_config(config, product)
+ if src.product.product_has_patches(product_info):
+ oneOrMore = True
+ logger.write("%s:\n" % product, 1)
+ for i in product_info.patches:
+ logger.write(src.printcolors.printcInfo(" %s\n" % i), 1)
+ if oneOrMore:
+ logger.write("\n", 1)
+ else:
+ logger.write("No patchs found\n", 1)
+
+
+def show_properties(config, logger):
+ '''Prints all the used properties in the application.
+
+ :param config Config: the global configuration.
+ :param logger Logger: The logger instance to use for the display
+ '''
+ oneOrMore = False
+ for product in sorted(config.APPLICATION.products):
+ product_info = src.product.get_product_config(config, product)
+ done = False
+ try:
+ for i in product_info.properties:
+ if not done:
+ logger.write("%s:\n" % product, 1)
+ done = True
+ oneOrMore = True
+ logger.write(src.printcolors.printcInfo(" %s\n" % i), 1)
+ except:
+ # logger.write(src.printcolors.printcInfo(" %s\n" % "no properties"), 1)
+ pass
+ if oneOrMore:
+ logger.write("\n", 1)
+ else:
+ logger.write("No properties found\n", 1)
def print_value(config, path, show_label, logger, level=0, show_full_path=False):
'''Prints a value from the configuration. Prints recursively the values
if options.schema:
get_config_children(runner.cfg, args)
return
-
+
# case : print a value of the config
if options.value:
if options.value == ".":
# case : edit user pyconf file or application file
- elif options.edit:
+ if options.edit:
editor = runner.cfg.USER.editor
if ('APPLICATION' not in runner.cfg and
'open_application' not in runner.cfg): # edit user pyconf
break
# case : give information about the product in parameter
- elif options.info:
+ if options.info:
src.check_config_has_application(runner.cfg)
if options.info in runner.cfg.APPLICATION.products:
show_product_info(runner.cfg, options.info, logger)
- return
- raise src.SatException(_("%(product_name)s is not a product "
- "of %(application_name)s.") %
- {'product_name' : options.info,
- 'application_name' :
- runner.cfg.VARS.application})
+ # return
+ else:
+ msg = _("%s is not a product of %s.") % \
+ (options.info, runner.cfg.VARS.application)
+ raise Exception(msg)
# case : copy an existing <application>.pyconf
# to ~/.salomeTools/Applications/LOCAL_<application>.pyconf
- elif options.copy:
+ if options.copy:
# product is required
src.check_config_has_application( runner.cfg )
logger.write(_("%s has been created.\n") % dest_file)
# case : display all the available pyconf applications
- elif options.list:
+ if options.list:
lproduct = list()
# search in all directories that can have pyconf applications
for path in runner.cfg.PATHS.APPLICATIONPATH:
logger.write("%s\n" % appliname)
logger.write("\n")
+
+ # case: print all the products name of the application (internal use for completion)
+ if options.completion:
+ for product_name in runner.cfg.APPLICATION.products.keys():
+ logger.write("%s\n" % product_name)
+
# case : give a synthetic view of all patches used in the application
- elif options.show_patchs:
+ if options.show_patchs:
src.check_config_has_application(runner.cfg)
# Print some informations
- logger.write(_('Show the patchs of application %s\n') %
+ logger.write(_('Patchs of application %s\n') %
src.printcolors.printcLabel(runner.cfg.VARS.application), 3)
logger.write("\n", 2, False)
show_patchs(runner.cfg, logger)
-
- # case: print all the products name of the application (internal use for completion)
- elif options.completion:
- for product_name in runner.cfg.APPLICATION.products.keys():
- logger.write("%s\n" % product_name)
-
-
+
+ # case : give a synthetic view of all patches used in the application
+ if options.show_properties:
+ src.check_config_has_application(runner.cfg)
+ # Print some informations
+ logger.write(_('Properties of application %s\n') %
+ src.printcolors.printcLabel(runner.cfg.VARS.application), 3)
+ logger.write("\n", 2, False)
+ show_properties(runner.cfg, logger)
+
# Parse the options
(options, args) = parser.parse_args(args)
- # get the log directory.
+ # get the log directory.
logDir = src.get_log_path(runner.cfg)
-
+
# Print a header
nb_files_log_dir = len(glob.glob(os.path.join(logDir, "*")))
info = [("log directory", logDir),
# copy the stylesheets in the log directory
# OP We use copy instead of copy2 to update the creation date
# So we can clean the LOGS directories easily
- shutil.copy(xslCommand, logDir)
- shutil.copy(xslHat, logDir)
- src.ensure_path_exists(os.path.join(logDir, "TEST"))
- shutil.copy(xsltest, os.path.join(logDir, "TEST"))
- shutil.copy(imgLogo, logDir)
+ try:
+ src.ensure_path_exists(logDir)
+ shutil.copy(xslCommand, logDir)
+ shutil.copy(xslHat, logDir)
+ src.ensure_path_exists(os.path.join(logDir, "TEST"))
+ shutil.copy(xsltest, os.path.join(logDir, "TEST"))
+ shutil.copy(imgLogo, logDir)
+ except:
+ # we are here if an user make sat log in jenkins LOGS without write rights
+ # Make a warning and do nothing
+ logger.warning("problem for writing in directory '%s', may be not owner." % logDir)
# If the last option is invoked, just, show the last log file
if options.last_terminal:
src.check_config_has_application(runner.cfg)
- log_dirs = os.listdir(os.path.join(runner.cfg.APPLICATION.workdir,
- 'LOGS'))
+ log_dirs = os.listdir(os.path.join(runner.cfg.APPLICATION.workdir, 'LOGS'))
show_last_logs(logger, runner.cfg, log_dirs)
return 0
# If the last option is invoked, just, show the last log file
if options.last:
lastLogFilePath = get_last_log_file(logDir,
- notShownCommands + ["config"])
+ notShownCommands + ["config"])
if options.terminal:
# Show the log corresponding to the selected command call
print_log_command_in_terminal(lastLogFilePath, logger)
# Create or update the hat xml that gives access to all the commands log files
logger.write(_("Generating the hat log file (can be long) ... "), 3)
xmlHatFilePath = os.path.join(logDir, 'hat.xml')
- src.logger.update_hat_xml(logDir,
+ try:
+ src.logger.update_hat_xml(logDir,
application = runner.cfg.VARS.application,
notShownCommands = notShownCommands)
- logger.write(src.printcolors.printc("OK"), 3)
+
+ logger.write(src.printcolors.printc("OK"), 3)
+ except:
+ logger.write(src.printcolors.printc("KO"), 3)
+ logger.write(" problem update hat.xml", 3)
+
logger.write("\n", 3)
# open the hat xml in the user editor
if not options.no_browser:
- logger.write(_("\nOpening the log file\n"), 3)
+ logger.write(_("\nOpening the hat log file %s\n" % xmlHatFilePath), 3)
src.system.show_in_editor(runner.cfg.USER.browser, xmlHatFilePath, logger)
+ else:
+ logger.write("\nHat log File is %s\n" % xmlHatFilePath, 3)
return 0
# Append source folder to path in order to enable autodoc
currentPath = os.path.dirname(__file__)
-print "sphinx on file", __file__
+print("sphinx on file %s" % __file__=
dirAutodoc = os.path.realpath(os.path.join(currentPath, '..', '..'))
-print "autodoc on dir", dirAutodoc
+print("autodoc on dir %s" % dirAutodoc)
sys.path.append(dirAutodoc)
sys.path.append(dirAutodoc + "/commands")
return log_dir_path
def get_salome_version(config):
+ import versionMinorMajorPatch as VMMP
+
if hasattr(config.APPLICATION, 'version_salome'):
- Version = config.APPLICATION.version_salome
+ version = VMMP.MinorMajorPatch(config.APPLICATION.version_salome)
else:
- KERNEL_info = product.get_product_config(config, "KERNEL")
- VERSION = os.path.join(
- KERNEL_info.install_dir,
+ kernel_info = product.get_product_config(config, "KERNEL")
+ aFile = os.path.join(
+ kernel_info.install_dir,
"bin",
"salome",
"VERSION")
- if not os.path.isfile(VERSION):
+ if not os.path.isfile(aFile):
return None
-
- fVERSION = open(VERSION)
- Version = fVERSION.readline()
- fVERSION.close()
-
- VersionSalome = int(only_numbers(Version))
- return VersionSalome
+ with open(aFile) as f:
+ line = f.readline() # example: '[SALOME KERNEL] : 8.4.0'
+ version = VMMP.MinorMajorPatch(line.split(":")[1])
-def only_numbers(str_num):
- return ''.join([nb for nb in str_num if nb in '0123456789'] or '0')
+ res = version.strCompact()
+ # print("get_salome_version %s -> %s" % (version, res))
+ return res
def read_config_from_a_file(filePath):
try:
indstr = indent * ' ' # '':no indent, ' ':indent
strType = str(type(config))
- if debug: print "saveDbg Type", path, strType
+ if debug: print("saveDbg Type %s %s" % (path, strType))
if "Sequence" in strType:
for i in range(len(config)):
for key in sorted(data): #order): # data as sort alphabetical, order as initial order
value = data[key]
strType = str(type(value))
- if debug: print 'strType', path, key, strType
+ if debug: print('strType %s %s %s' % (path, key, strType))
if "Config" in strType:
_saveConfigRecursiveDbg(value, aStream, indentp, path+"."+key, nbp)
continue
import src.debug as DBG
import pprint as PP
+
class Environ:
"""\
Class to manage the environment context
def append_value(self, key, value, sep=os.pathsep):
"""\
- append value to key using sep
-
+ append value to key using sep,
+ if value contains ":" or ";" then raise error
+
:param key str: the environment variable to append
:param value str: the value to append to key
:param sep str: the separator string
"""
+ for c in [";", ":"]: # windows or linux path separators
+ if c in value:
+ raise Exception("Environ append key '%s' value '%s' contains forbidden character '%s'" % (key, value, c))
# check if the key is already in the environment
if key in self.environ:
value_list = self.environ[key].split(sep)
def prepend_value(self, key, value, sep=os.pathsep):
"""\
- prepend value to key using sep
+ prepend value to key using sep,
+ if value contains ":" or ";" then raise error
:param key str: the environment variable to prepend
:param value str: the value to prepend to key
:param sep str: the separator string
"""
+ for c in [";", ":"]: # windows or linux path separators
+ if c in value:
+ raise Exception("Environ prepend key '%s' value '%s' contains forbidden character '%s'" % (key, value, c))
+ # check if the key is already in the environment
if key in self.environ:
value_list = self.environ[key].split(sep)
if not value in value_list:
:param sep str: the separator string
"""
if isinstance(value, list):
- for v in value:
+ for v in reversed(value): # prepend list, first item at last to stay first
self.prepend_value(key, v, sep)
else:
self.prepend_value(key, value, sep)
def append_value(self, key, value, sep=os.pathsep):
"""\
- append value to key using sep
-
+ append value to key using sep,
+ if value contains ":" or ";" then raise error
+
:param key str: the environment variable to append
:param value str: the value to append to key
:param sep str: the separator string
"""
+ for c in [";", ":"]: # windows or linux path separators
+ if c in value:
+ raise Exception("FileEnviron append key '%s' value '%s' contains forbidden character '%s'" % (key, value, c))
self.set(key, self.get(key) + sep + value)
if (key, sep) not in self.toclean:
self.toclean.append((key, sep))
:param sep str: the separator string
"""
if isinstance(value, list):
- self.append_value(key, sep.join(value), sep)
+ for v in value:
+ self.append_value(key, v, sep)
else:
self.append_value(key, value, sep)
def prepend_value(self, key, value, sep=os.pathsep):
"""\
- prepend value to key using sep
+ prepend value to key using sep,
+ if value contains ":" or ";" then raise error
:param key str: the environment variable to prepend
:param value str: the value to prepend to key
:param sep str: the separator string
"""
+ for c in [";", ":"]: # windows or linux path separators
+ if c in value:
+ raise Exception("FileEnviron prepend key '%s' value '%s' contains forbidden character '%s'" % (key, value, c))
self.set(key, value + sep + self.get(key))
if (key, sep) not in self.toclean:
self.toclean.append((key, sep))
:param sep str: the separator string
"""
if isinstance(value, list):
- self.prepend_value(key, sep.join(value), sep)
+ for v in reversed(value): # prepend list, first item at last to stay first
+ self.prepend_value(key, v, sep)
else:
self.prepend_value(key, value, sep)
self.output.write('# "WARNING %s"\n' % warning)
def append_value(self, key, value, sep=":"):
- """append value to key using sep
+ """append value to key using sep,
+ if value contains ":" or ";" then raise error
:param key str: the environment variable to append
:param value str: the value to append to key
:param sep str: the separator string
"""
+ for c in [";", ":"]: # windows or linux path separators
+ if c in value:
+ raise Exception("LauncherFileEnviron append key '%s' value '%s' contains forbidden character '%s'" % (key, value, c))
if self.is_defined(key) :
self.add(key, value)
else :
:param sep str: the separator string
"""
if isinstance(value, list):
- self.append_value(key, sep.join(value), sep)
+ for v in value:
+ self.append_value(key, v, sep)
else:
self.append_value(key, value, sep)
def prepend_value(self, key, value, sep=":"):
- """prepend value to key using sep
+ """prepend value to key using sep,
+ if value contains ":" or ";" then raise error
:param key str: the environment variable to prepend
:param value str: the value to prepend to key
:param sep str: the separator string
"""
+ for c in [";", ":"]: # windows or linux path separators
+ if c in value:
+ raise Exception("LauncherFileEnviron prepend key '%s' value '%s' contains forbidden character '%s'" % (key, value, c))
if self.is_defined(key) :
self.add(key, value)
else :
:param sep str: the separator string
"""
if isinstance(value, list):
- self.prepend_value(key, sep.join(value), sep)
+ for v in value:
+ self.prepend_value(key, v, sep)
else:
self.prepend_value(key, value, sep)
try:
from salomeContextUtils import setOmniOrbUserPath
setOmniOrbUserPath()
- except Exception, e:
- print e
+ except Exception as e:
+ print(e)
sys.exit(1)
# End of preliminary work
import sys
import os
+import stat
import datetime
import re
import tempfile
# the external commands calls (cmake, make, git clone, etc...)
txtFileName = prefix + hour_command_host + ".txt"
txtFilePath = os.path.join(log_dir, "OUT", txtFileName)
-
- src.ensure_path_exists(os.path.dirname(logFilePath))
+
+ aDirLog = os.path.dirname(logFilePath)
+ if not os.path.exists(aDirLog):
+ print("create log dir %s" % aDirLog)
+ src.ensure_path_exists(aDirLog)
+ # sometimes other users make 'sat log' and create hat.xml file...
+ os.chmod(aDirLog,
+ stat.S_IRUSR |
+ stat.S_IRGRP |
+ stat.S_IROTH |
+ stat.S_IWUSR |
+ stat.S_IWGRP |
+ stat.S_IWOTH |
+ stat.S_IXUSR |
+ stat.S_IXGRP |
+ stat.S_IXOTH)
src.ensure_path_exists(os.path.dirname(txtFilePath))
# The path of the log files (one for sat traces, and the other for
"""
# 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})
+ 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, log_macro_command_file_expression)
# Write the file on the hard drive
xmlHat.write_tree('hat.xsl')
+ # Sometimes other users will make 'sat log' and update this file
+ os.chmod(xmlHatFilePath,
+ stat.S_IRUSR |
+ stat.S_IRGRP |
+ stat.S_IROTH |
+ stat.S_IWUSR |
+ stat.S_IWGRP |
+ stat.S_IWOTH )
+
# TODO for future
prod_info.section = section_range
prod_info.from_file = config.PRODUCTS[product_name].from_file
return prod_info
+
+
# Else, get the standard informations
if "default" in config.PRODUCTS[product_name]:
--- /dev/null
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+# Copyright (C) 2010-2018 CEA/DEN
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# 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
+
+
+"""\
+class and utilities to define a version as MAJOR.MINOR.PATCH
+
+| Given a version number MAJOR.MINOR.PATCH separator "_" or "."
+| increment the
+| MAJOR version when you make incompatible API changes,
+| MINOR version when you add functionality in a backwards-compatible manner,
+| PATCH version when you make backwards-compatible bug fixes.
+"""
+
+import os
+import sys
+
+verbose = False # True
+
+#############################################
+def only_numbers(aStr):
+ """
+ Remove non numericals characters from string,
+ returns None if no numbers
+ """
+ res = ''.join([nb for nb in aStr if nb in '0123456789'])
+ if res == "":
+ return None
+ else:
+ return res
+
+#############################################
+def toList_majorMinorPatch(aStr):
+ """
+ Returns list of integer as [major, minor, patch] from a string,
+ raise exception if problem
+ """
+ if verbose: print("toList_majorMinorPatch('%s')" % aStr)
+ res = aStr.replace(" ", "").replace(".", "_").split("_")
+ if len(res) > 3:
+ msg = "Not a major_minor_patch correct syntax: '%s'" % aStr
+ raise Exception(msg)
+ if len(res) == 0:
+ msg = "An empty string is not a major_minor_patch syntax"
+ raise Exception(msg)
+ # complete MINOR.PATCH if not existing
+ if len(res) == 1:
+ res.append("0")
+ if len(res) == 2:
+ res.append("0")
+
+ try:
+ ii = int(res[0])
+ except:
+ msg = "major in major_minor_patch is not integer: '%s'" % aStr
+ raise Exception(msg)
+ if ii < 0:
+ msg = "major in major_minor_patch is negative integer: '%s'" % aStr
+ raise Exception(msg)
+
+ try:
+ ii = int(res[1])
+ except:
+ msg = "minor in major_minor_patch is not integer: '%s'" % aStr
+ raise Exception(msg)
+ if ii < 0:
+ msg = "minor in major_minor_patch is negative integer: '%s'" % aStr
+ raise Exception(msg)
+
+ try:
+ ii = int(res[2])
+ except:
+ msg = "patch in major_minor_patch is not integer: '%s'" % aStr
+ raise Exception(msg)
+ if ii < 0:
+ msg = "patch in major_minor_patch is negative integer: '%s'" % aStr
+ raise Exception(msg)
+
+ return [int(i) for i in res]
+
+#############################################
+def toCompactStr_majorMinorPatch(version):
+ """
+ parameter version is list of integer as [major, minor, patch]
+
+ | returns "789" for [7, 8, 9]
+ | warning:
+ | minor, pach have to be integer less than 10
+ | raise exception for [7, 10, 11]
+ | (which returns "71011" as ambigous 710.1.1 for example)
+ """
+ if len(version) != 3:
+ msg = "version major_minor_patch is incorrect: '%s'" % version
+ raise Exception(msg)
+
+ aStr = '_'.join([str(i) for i in version])
+ toList_majorMinorPatch(aStr) # will raise error if problem (as too much or negative values)
+
+ res = "".join([str(i) for i in version])
+ if version[1] > 9 or version[2] > 9:
+ raise Exception("ambigous major_minor_patch compact representation '%s' from '%s'" % (res, version))
+
+ return res
+
+
+#############################################
+class MinorMajorPatch(object):
+ """\
+ class to define a version as MAJOR.MINOR.PATCH
+
+ | Given a version number MAJOR.MINOR.PATCH separator "_" or "."
+ | increment the
+ | MAJOR version when you make incompatible API changes,
+ | MINOR version when you add functionality in a backwards-compatible manner,
+ | PATCH version when you make backwards-compatible bug fixes.
+ """
+
+ def __init__(self, version):
+ if type(version) == list:
+ aStr = '_'.join([str(i) for i in version])
+ v = toList_majorMinorPatch(aStr)
+ else:
+ v = toList_majorMinorPatch(version)
+ self.major = v[0]
+ self.minor = v[1]
+ self.patch = v[2]
+
+ def __repr__(self, sep="_"):
+ """example is 'version_1_2_3' """
+ res = "version_%i%s%i%s%i" % (self.major, sep, self.minor, sep, self.patch)
+ return res
+
+ def __str__(self, sep="."):
+ """example is '1.2.3' """
+ res = "%i%s%i%s%i" % (self.major, sep, self.minor, sep, self.patch)
+ return res
+
+ def strSalome(self):
+ """example is '1_2_3' """
+ return self.__str__(sep="_")
+
+ def strClassic(self):
+ """example is '1.2.3' """
+ return self.__str__(sep=".")
+
+ def strCompact(self):
+ """example is '123' from '1.2.3' """
+ return toCompactStr_majorMinorPatch(self.toList())
+
+ def toList(self):
+ """example is list of integer [1, 2, 3] from '1.2.3' """
+ return [self.major, self.minor, self.patch]
+
+ def __lt__(self, other):
+ res = (self.toList() < other.toList())
+ return res
+
+ def __le__(self, other):
+ res = (self.toList() <= other.toList())
+ return res
+
+ def __gt__(self, other):
+ res = (self.toList() > other.toList())
+ return res
+
+ def __ge__(self, other):
+ res = (self.toList() >= other.toList())
+ return res
+
+ def __eq__(self, other):
+ res = (self.toList() == other.toList())
+ return res
+
+ def __ne__(self, other):
+ res = (self.toList() != other.toList())
+ return res
+
+#############################################
+import unittest
+import pprint as PP
+
+
+class TestCase(unittest.TestCase):
+ "Test the versionMajorMinorPatch.py"""
+
+ def test_010(self):
+ if verbose: print(PP.pformat(dir(self)))
+ self.assertTrue(only_numbers("") is None)
+ self.assertEqual(only_numbers("1.2.3"), "123")
+ self.assertEqual(only_numbers("\n11.12.13\n"), "111213")
+ self.assertEqual(only_numbers(" \n 11.\t\n\t..12.13-rc2\n"), "1112132")
+
+ def test_020(self):
+ res = [11, 222, 3333]
+ self.assertEqual(toList_majorMinorPatch("11.222.3333"), res)
+ self.assertEqual(toList_majorMinorPatch("11_222_3333"), res)
+ self.assertEqual(toList_majorMinorPatch("11.222_3333"), res)
+ self.assertEqual(toList_majorMinorPatch(" 11. 222 . 3333 "), res)
+ self.assertEqual(toList_majorMinorPatch("\n 11 . 222 . 3333 \n"), res)
+ self.assertEqual(toList_majorMinorPatch(" \n11.\t222.\r3333\n "), res) # could be tricky
+
+ self.assertEqual(toList_majorMinorPatch("11"), [11, 0, 0])
+ self.assertEqual(toList_majorMinorPatch("11.0"), [11, 0, 0])
+ self.assertEqual(toList_majorMinorPatch("11.2"), [11, 2, 0])
+ self.assertEqual(toList_majorMinorPatch("\n1 . 2 \n"), [1, 2, 0])
+
+ with self.assertRaises(Exception): toList_majorMinorPatch("")
+ with self.assertRaises(Exception): toList_majorMinorPatch("11.")
+ with self.assertRaises(Exception): toList_majorMinorPatch("11.2.")
+ with self.assertRaises(Exception): toList_majorMinorPatch("11.2.3.")
+ with self.assertRaises(Exception): toList_majorMinorPatch(".11")
+ with self.assertRaises(Exception): toList_majorMinorPatch("1_2_3_4")
+ with self.assertRaises(Exception): toList_majorMinorPatch("_1_2_3_")
+ with self.assertRaises(Exception): toList_majorMinorPatch(" \n 11...22.333-rc2\n")
+ with self.assertRaises(Exception): toList_majorMinorPatch(" \n 11...22.333-rc2\n")
+ with self.assertRaises(Exception): toList_majorMinorPatch(" \n 11...22.333-rc2\n")
+
+
+ def test_030(self):
+ self.assertEqual(toCompactStr_majorMinorPatch([1, 2, 3]), "123")
+ self.assertEqual(toCompactStr_majorMinorPatch([11, 2, 3]), "1123")
+ self.assertEqual(toCompactStr_majorMinorPatch([1, 9, 9]), "199")
+
+ with self.assertRaises(Exception): toCompactStr_majorMinorPatch([1, 2, 10])
+ with self.assertRaises(Exception): toCompactStr_majorMinorPatch([1, 10, 3])
+ with self.assertRaises(Exception): toCompactStr_majorMinorPatch([10, 10, 10])
+
+ def test_040(self):
+ MMP = MinorMajorPatch
+ v = [1, 2, 3]
+ self.assertEqual(MMP(v).__str__(), "1.2.3")
+ self.assertEqual(MMP(v).__str__(sep="_"), "1_2_3")
+ self.assertEqual(str(MMP(v)), "1.2.3")
+
+ self.assertEqual(MMP(v).__repr__(), "version_1_2_3")
+ self.assertEqual(MMP(v).__repr__(sep="."), "version_1.2.3")
+
+ self.assertEqual(MMP(v).strSalome(), "1_2_3")
+ self.assertEqual(MMP(v).strClassic(), "1.2.3")
+
+ self.assertEqual(MMP([' 123 \n', 2, 10]).strClassic(), "123.2.10")
+ self.assertEqual(MMP([' 123 \n', 2, 10]).strSalome(), "123_2_10")
+ self.assertEqual(MMP([' 123 \n', 2, 9]).strCompact(), "12329") # no ambigous
+
+ with self.assertRaises(Exception): MMP([-5, 2, 10])
+ with self.assertRaises(Exception): MMP([5, -2, 10])
+ with self.assertRaises(Exception): MMP([5, 2, -10])
+ with self.assertRaises(Exception): MMP(['-123', 2, 10])
+ with self.assertRaises(Exception): MMP([123, 2, 10].strCompact()) # ambigous
+
+ def test_040(self):
+ MMP = MinorMajorPatch
+ v000 = MMP("0.0.0")
+ v010 = MMP("0.1.0")
+ v100 = MMP("1.0.0")
+ v101 = MMP("1.0.1")
+
+ va = v000
+ vb = MMP("0.0.0")
+ self.assertTrue(va == vb)
+ self.assertTrue(va >= vb)
+ self.assertTrue(va <= vb)
+ self.assertFalse(va != vb)
+ self.assertFalse(va > vb)
+ self.assertFalse(va < vb)
+
+ va = v000
+ vb = v010
+ self.assertFalse(va == vb)
+ self.assertFalse(va >= vb)
+ self.assertTrue(va <= vb)
+ self.assertTrue(va != vb)
+ self.assertFalse(va > vb)
+ self.assertTrue(va < vb)
+
+
+if __name__ == '__main__':
+ unittest.main(exit=False)
+ pass
+