From: Serge Rehbinder Date: Tue, 13 Dec 2016 13:43:29 +0000 (+0100) Subject: Add the profile command X-Git-Tag: 5.0.0a1~38^2~43 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=91ec70410b35d3c5539c308c2303599f2f79797b;p=tools%2Fsat.git Add the profile command --- diff --git a/commands/profile.py b/commands/profile.py new file mode 100644 index 0000000..cffb951 --- /dev/null +++ b/commands/profile.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +# Copyright (C) 2010-2013 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 + +import os +import shutil +import subprocess + +import src + +parser = src.options.Options() + +parser.add_option( 'p', 'prefix', 'string', 'prefix', _("Where the profile's " + "sources will be " + "generated.") ) +parser.add_option( 'n', 'name', 'string', 'name', _("Name of the profile's " + "sources. [Default: " + "${config.PRODUCT.name}" + "_PROFILE]") ) +parser.add_option( 'f', 'force', 'boolean', 'force', _("Overwrites " + "existing sources.") ) +parser.add_option( 'u', 'no_update', 'boolean', 'no_update', _("Does not update" + " pyconf file.")) +parser.add_option( 'v', 'version', 'string', 'version', _("Version of the " + "application. [Defa" + "ult: 1.0]"), '1.0' ) +parser.add_option( 's', 'slogan', 'string', 'slogan', _("Slogan of the " + "application.") ) + +################################################## + +## +# Class that overrides common.Reference +# in order to manipulate fields starting with '@' +class profileReference( src.pyconf.Reference ) : + def __str__(self): + s = self.elements[0] + for tt, tv in self.elements[1:]: + if tt == src.pyconf.DOT: + s += '.%s' % tv + else: + s += '[%r]' % tv + if self.type == src.pyconf.BACKTICK: + return src.pyconf.BACKTICK + s + src.pyconf.BACKTICK + elif self.type == src.pyconf.AT: + return src.pyconf.AT + s + else: + return src.pyconf.DOLLAR + s + +## +# Class that overrides how fields starting with '@' are read. +class profileConfigReader( src.pyconf.ConfigReader ) : + def parseMapping(self, parent, suffix): + if self.token[0] == src.pyconf.LCURLY: + self.match(src.pyconf.LCURLY) + rv = src.pyconf.Mapping(parent) + rv.setPath( + src.pyconf.makePath(object.__getattribute__(parent, 'path'), + suffix)) + self.parseMappingBody(rv) + self.match(src.pyconf.RCURLY) + else: + self.match(src.pyconf.AT) + __, fn = self.match('"') + rv = profileReference(self, src.pyconf.AT, fn) + return rv + +################################################## + +## +# Describes the command +def description(): + return _("The profile command creates default profile.\nusage: sat profile " + "[PRODUCT] [-p|--prefix (string)] [-n|--name (string)] [-f|--force" + "] [-v|--version (string)] [-s|--slogan (string)]") + +## +# Gets the profile name +def get_profile_name ( options, config ): + if options.name : + res = options.name + else : + res = config.APPLICATION.name + "_PROFILE" + return res + +## +# Generates the sources of the profile +def generate_profile_sources( config, options, logger ): + #Check script app-quickstart.py exists + kernel_cfg = src.product.get_product_config(config, "KERNEL") + kernel_root_dir = kernel_cfg.install_dir + if not src.product.check_installation(kernel_cfg): + raise src.SatException(_("KERNEL is not installed")) + script = os.path.join(kernel_root_dir,"bin","salome","app-quickstart.py") + if not os.path.exists( script ): + raise src.SatException(_("KERNEL's install has not the script " + "app-quickstart.py")) + + # Check that GUI is installed + gui_cfg = src.product.get_product_config(config, "GUI") + gui_root_dir = gui_cfg.install_dir + if not src.product.check_installation(gui_cfg): + raise src.SatException(_("GUI is not installed")) + + #Set prefix option passed to app-quickstart.py + name = get_profile_name ( options, config ) + prefix = os.path.join( options.prefix, name ) + if os.path.exists( prefix ) : + if not options.force : + raise src.SatException( _("The path %s already exists, use option" + " --force to remove it." %prefix ) ) + else : + shutil.rmtree( prefix ) + + #Set name option passed to app-quickstart.py + if name.upper().endswith("_PROFILE"): + name = name[:-8] + + #Write command line that calls app-quickstart.py + command = "python %s --prefix=%s --name=%s --modules=_NO_ --version=%s" % ( + script, prefix, name, options.version ) + if options.force : + command += " --force" + if options.slogan : + command += " --slogan=%s" % options.slogan + logger.write("\n>" + command + "\n", 5, False) + + #Run command + os.environ["KERNEL_ROOT_DIR"] = kernel_root_dir + os.environ["GUI_ROOT_DIR"] = gui_root_dir + res = subprocess.call(command, + shell=True, + env=os.environ, + stdout=logger.logTxtFile, + stderr=subprocess.STDOUT) + #Check result of command + if res != 0: + raise src.SatException(_("Cannot create application, code = %d\n")%res) + else: + logger.write(_("Profile sources were generated in directory %s."%prefix), + 3) + return res + +## +# Updates the pyconf +def update_pyconf( config, options, logger ): + + #Save previous version + pyconf = config.VARS.product + '.pyconf' + pyconfBackup = config.VARS.product + '-backup.pyconf' + logger.write(_("Updating %(new)s (previous version saved " + "as %(old)s).") % { "new": pyconf, "old": pyconfBackup }, 3) + path = config.getPath( pyconf ) + shutil.copyfile( os.path.join( path, pyconf ), + os.path.join( path, pyconfBackup ) ) + + #Load config + cfg = src.pyconf.Config( ) + object.__setattr__( cfg, 'reader', profileConfigReader( cfg ) ) + cfg.load( src.pyconf.defaultStreamOpener( os.path.join( path, pyconf ) ) ) + + #Check if profile is in APPLICATION.products + profile = get_profile_name ( options, config ) + if not profile in cfg.APPLICATION.products: + cfg.APPLICATION.products.append( profile, None ) + + #Check if profile is in APPLICATION + if not 'profile' in cfg.APPLICATION: + cfg.APPLICATION.addMapping( 'profile', src.pyconf.Mapping(), None ) + cfg.APPLICATION.profile.addMapping( 'module', profile, None ) + cfg.APPLICATION.profile.addMapping( 'launcher_name', + config.VARS.product.lower(), None ) + + #Check if profile info is in PRODUCTS + if not 'PRODUCTS' in cfg: + cfg.addMapping( 'PRODUCTS', src.pyconf.Mapping(), None ) + + if not profile in cfg.PRODUCTS: + cfg.PRODUCTS.addMapping( profile, src.pyconf.Mapping(), None ) + cfg.PRODUCTS[profile].addMapping( 'default', src.pyconf.Mapping(), + None ) + prf = cfg.TOOLS.common.module_info[profile].default + prf.addMapping( 'name', profile, None ) + prf.addMapping( 'get_source', 'archive', None ) + prf.addMapping( 'build_source', 'cmake', None ) + prf.addMapping( 'archive_info', src.pyconf.Mapping(), None ) + prf.archive_info.addMapping( 'name', + os.path.join(os.path.abspath(options.prefix), + profile ), None ) + prf.addMapping( 'source_dir', src.pyconf.Reference(cfg, + src.pyconf.DOLLAR, + 'APPLICATION.workdir' + ' + $VARS.sep + "SOU' + 'RCES" + $VARS.sep +' + ' $name' ), None ) + prf.addMapping( 'build_dir', src.pyconf.Reference(cfg, + src.pyconf.DOLLAR, + 'APPLICATION.workdir ' + '+ $VARS.sep + "BUILD' + '" + $VARS.sep + $nam' + 'e' ), None ) + prf.addMapping( 'depend', src.pyconf.Sequence(), None ) + prf.depend.append( 'KERNEL', None ) + prf.depend.append( 'GUI', None ) + prf.depend.append( 'Python', None ) + prf.depend.append( 'Sphinx', None ) + prf.depend.append( 'qt', None ) + prf.addMapping( 'opt_depend', src.pyconf.Sequence(), None ) + + #Save config + f = file( os.path.join( path, pyconf ) , 'w') + cfg.__save__(f) + + +## +# Runs the command. +def run(args, runner, logger): + '''method that is called when salomeTools is called with profile parameter. + ''' + (options, args) = parser.parse_args(args) + + src.check_config_has_application(runner.cfg) + + if options.prefix is None: + msg = _("The --%s argument is required\n") % "prefix" + logger.write(src.printcolors.printcWarning(msg), 1) + return 1 + + retcode = generate_profile_sources( runner.cfg, options, logger ) + + if not options.no_update : + update_pyconf( runner.cfg, options ) + + return retcode diff --git a/complete_sat.sh b/complete_sat.sh index 1da0897..a95ac24 100755 --- a/complete_sat.sh +++ b/complete_sat.sh @@ -104,7 +104,7 @@ _salomeTools_complete() # first argument => show available commands if [[ ${argc} == 1 ]] then - opts="config log testcommand source patch prepare environ clean configure make makeinstall compile launcher run jobs job shell test package generate find_duplicates application template base --help" + opts="config log testcommand source patch prepare environ clean configure make makeinstall compile launcher run jobs job shell test package generate find_duplicates application template base profile --help" COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi @@ -263,6 +263,11 @@ _salomeTools_complete() COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 ;; + profile) + opts="--prefix --name --force --no_update --version --slogan" + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + ;; *) return 0 ;; esac