Salome HOME
add options edit, list, and copy to config command
authorSerge Rehbinder <serge.rehbinder@cea.fr>
Thu, 28 Jan 2016 15:40:10 +0000 (16:40 +0100)
committerSerge Rehbinder <serge.rehbinder@cea.fr>
Thu, 28 Jan 2016 15:40:10 +0000 (16:40 +0100)
data/site.pyconf
src/common/__init__.py
src/common/fileSystem.py [new file with mode: 0644]
src/config.py
src/salomeTools.py

index 9a58fcdb66aded651ad4f6f6de800a0e2cd58071..97135df1a943afd3b615141ca3b5f7af3b1ada52 100644 (file)
@@ -6,6 +6,7 @@ SITE :
     config : 
     {
         configPath : ["/home/salome/SPN_PRIVATE/sat5dev_Applications"]
+       copy_prefix : "LOCAL_"
     }
 }
 
index 3eeca22030a11ec6bb3661d3ac41f5a414225e50..3a597b9b12ff808c336faaf9ae0949e7f79e722e 100644 (file)
@@ -22,10 +22,18 @@ from . import config_pyconf
 from . import architecture
 from . import printcolors
 from . import options
+from . import fileSystem
 
 class SatException(Exception):
     pass
 
 def ensure_path_exists(p):
     if not os.path.exists(p):
-        os.mkdir(p)
\ No newline at end of file
+        os.mkdir(p)
+        
+def check_config_has_application( config, details = None ):
+    if 'APPLICATION' not in config:
+        message = _("An APPLICATION is required. Use 'config --list' to get the list of available applications.\n")
+        if details :
+            details.append(message)
+        raise SatException( message )
\ No newline at end of file
diff --git a/src/common/fileSystem.py b/src/common/fileSystem.py
new file mode 100644 (file)
index 0000000..71c0046
--- /dev/null
@@ -0,0 +1,46 @@
+#!/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
+
+'''
+In this file : all functions that do a system call, like open a browser or an editor, or call a git command
+'''
+
+import sys
+import subprocess
+
+
+def show_in_editor(editor, filePath):
+    '''open filePath using editor.
+    :param editor str: The editor to use.
+    :param filePath str: The path to the file to open.
+    '''
+    # default editor is vi
+    if editor is None or len(editor) == 0:
+        editor = 'vi'
+    
+    if '%s' not in editor:
+        editor += ' %s'
+
+    try:
+        # launch cmd using subprocess.Popen
+        cmd = editor % filePath
+        p = subprocess.Popen(cmd, shell=True)
+        p.communicate()
+    except:
+        sys.stderr.write("Unable to edit file %s\n" % filePath)
+    
\ No newline at end of file
index d62cec1f4137ceb0d9774780c750cbf6894b4c81..32dda396b49fb0dfa23aa654a7a08c4bb9f119b6 100644 (file)
@@ -23,12 +23,23 @@ import datetime
 import glob
 import re
 import shutil
+import gettext
 
 import common
 
+# internationalization
+srcdir = os.path.dirname(os.path.realpath(__file__))
+gettext.install('salomeTools', os.path.join(srcdir, 'common', 'i18n'))
+
 # Define all possible option for config command :  sat config <options>
 parser = common.options.Options()
-parser.add_option('v', 'value', 'string', 'value', "print the value of CONFIG_VARIABLE.")
+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 MergeHandler:
@@ -206,7 +217,10 @@ class ConfigManager:
             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"
             raise common.SatException( e );
-
+        
+        # add user local path for configPath
+        site_cfg.SITE.config.configPath.append(os.path.join(cfg.VARS.personalDir, 'Applications'), "User applications path")
+        
         merger.merge(cfg, site_cfg)
 
         for rule in self.get_command_line_overrides(options, ["SITE"]):
@@ -261,18 +275,17 @@ class ConfigManager:
             if already_exisiting_pyconf_file:  
                 # copy
                 shutil.copyfile( already_exisiting_pyconf_file, self.user_config_file_path )
-                cfg = common.config_pyconf.Config(open(self.user_config_file_path))
             else: # create from scratch
                 self.createConfigFile(config)
     
-    def getAlreadyExistingUserPyconf(self, dir, sat_version ):
+    def getAlreadyExistingUserPyconf(self, userDir, sat_version ):
         '''Get a pyconf file younger than the given sat version in the given directory
         The file basename can be one of salometools-<younger version>.pyconf or salomeTools.pyconf
         Returns the file path or None if no file has been found.
         '''
         file_path = None  
         # Get a younger pyconf version   
-        pyconfFiles = glob.glob( os.path.join(dir, 'salomeTools-*.pyconf') )
+        pyconfFiles = glob.glob( os.path.join(userDir, 'salomeTools-*.pyconf') )
         sExpr = "^salomeTools-(.*)\.pyconf$"
         oExpr = re.compile(sExpr)
         younger_version = None
@@ -285,9 +298,9 @@ class ConfigManager:
 
         # Build the pyconf filepath
         if younger_version :   
-            file_path = os.path.join( dir, 'salomeTools-%s.pyconf'%younger_version )
-        elif os.path.isfile( os.path.join(dir, 'salomeTools.pyconf') ):
-            file_path = os.path.join( dir, 'salomeTools.pyconf' )
+            file_path = os.path.join( userDir, 'salomeTools-%s.pyconf'%younger_version )
+        elif os.path.isfile( os.path.join(userDir, 'salomeTools.pyconf') ):
+            file_path = os.path.join( userDir, 'salomeTools.pyconf' )
         
         return file_path 
     
@@ -384,6 +397,95 @@ def description():
 
 def run(args, runner):
     (options, args) = parser.parse_args(args)
+    
+    # case : print a value of the config
     if options.value:
+        if options.value == ".":
+            # if argument is ".", print all the config
+            for val in sorted(runner.cfg.keys()):
+                print_value(runner.cfg, val, True)
+            return
         print_value(runner.cfg, options.value, True, level=0, show_full_path=False)
+        return
+    
+    # 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-%s.pyconf'%runner.cfg.INTERNAL['sat_version'])
+            common.fileSystem.show_in_editor(editor, usercfg)
+        else:
+            # search for file <application>.pyconf and open it
+            for path in runner.cfg.SITE.config.configPath:
+                pyconf_path = os.path.join(path, runner.cfg.VARS.application + ".pyconf")
+                if os.path.exists(pyconf_path):
+                    common.fileSystem.show_in_editor(editor, pyconf_path)
+                    break
+    
+    # case : copy an existing <application>.pyconf to ~/.salomeTools/Applications/LOCAL_<application>.pyconf
+    elif options.copy:
+        # product is required
+        common.check_config_has_application( runner.cfg )
+
+        # get application file path 
+        source = runner.cfg.VARS.application + '.pyconf'
+        source_full_path = ""
+        for path in runner.cfg.SITE.config.configPath:
+            # ignore personal directory
+            if path == runner.cfg.VARS.personalDir:
+                continue
+            # loop on all directories that can have pyconf applications
+            zz = os.path.join(path, source)
+            if os.path.exists(zz):
+                source_full_path = zz
+                break
+
+        if len(source_full_path) == 0:
+            raise common.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
+            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')
+            if os.path.exists(dest_file):
+                raise common.SatException(_("A personal application '%s' already exists") % dest)
+            
+            # perform the copy
+            shutil.copyfile(source_full_path, dest_file)
+            print(_("%s has been created.") % dest_file)
+    
+    # case : display all the available pyconf applications
+    elif options.list:
+        lproduct = list()
+        # search in all directories that can have pyconf applications
+        for path in runner.cfg.SITE.config.configPath:
+            # print a header
+            sys.stdout.write("------ %s\n" % common.printcolors.printcHeader(path))
+
+            if not os.path.exists(path):
+                sys.stdout.write(common.printcolors.printcError(_("Directory not found")) + "\n")
+            else:
+                for f in sorted(os.listdir(path)):
+                    # ignore file that does not ends with .pyconf
+                    if not f.endswith('.pyconf'):
+                        continue
+
+                    appliname = f[:-len('.pyconf')]
+                    if appliname not in lproduct:
+                        lproduct.append(appliname)
+                        if path.startswith(runner.cfg.VARS.personalDir):
+                            sys.stdout.write("%s*\n" % appliname)
+                        else:
+                            sys.stdout.write("%s\n" % appliname)
+
+            sys.stdout.write("\n")
+    
     
\ No newline at end of file
index ccfa5ebef69d05e29533d601a181dee63e69de0c..78dc0afb6a902bf05567f1ec273d8385d56b8188 100755 (executable)
@@ -34,8 +34,9 @@ import config
 srcdir = os.path.dirname(os.path.realpath(__file__))
 
 # load resources for internationalization
-es = gettext.translation('salomeTools', os.path.join(srcdir, 'common', 'i18n'))
-es.install()
+#es = gettext.translation('salomeTools', os.path.join(srcdir, 'common', 'i18n'))
+#es.install()
+gettext.install('salomeTools', os.path.join(srcdir, 'common', 'i18n'))
 
 def find_command_list(dirPath):
     ''' Parse files in dirPath that end with .py : it gives commands list
@@ -238,6 +239,7 @@ if __name__ == "__main__":
     command = args[0]
     # get dynamically the command function to call
     fun_command = sat.__getattr__(command)
+    # call the command with two cases : mode debug or not
     if options.debug_mode:
         # call classically the command and if it fails, show exception and stack (usual python mode)
         code = fun_command(' '.join(args[1:]))