From 082dc8fb7de8bbddd67ca3faddbc5f8e485e5af2 Mon Sep 17 00:00:00 2001 From: Serge Rehbinder Date: Mon, 22 Feb 2016 14:48:08 +0100 Subject: [PATCH] Add completion mechanism --- commands/config.py | 64 ++++++++++++++++++--- commands/log.py | 5 ++ complete_sat.sh | 139 +++++++++++++++++++++++++++++++++++++++++++++ src/pyconf.py | 2 +- 4 files changed, 202 insertions(+), 8 deletions(-) create mode 100755 complete_sat.sh diff --git a/commands/config.py b/commands/config.py index 3de5e95..52d4fb6 100644 --- a/commands/config.py +++ b/commands/config.py @@ -21,6 +21,7 @@ import platform import datetime import shutil import gettext +import sys import src @@ -31,15 +32,19 @@ 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.")) + _("print the value of CONFIG_VARIABLE.")) parser.add_option('e', 'edit', 'boolean', 'edit', - _("edit the product configuration file.")) + _("edit the product configuration file.")) parser.add_option('l', 'list', 'boolean', 'list', - _("list all available applications.")) + _("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.""")) +parser.add_option('n', 'no_label', 'boolean', 'no_label', + _("do not print labels, Works only with --value and --list.")) +parser.add_option('s', 'schema', 'boolean', 'schema', + _("Internal use.")) class ConfigOpener: '''Class that helps to find an application pyconf @@ -409,6 +414,10 @@ def print_value(config, path, show_label, logger, level=0, show_full_path=False) :param show_full_path : ''' + # Make sure that the path does not ends with a point + if path.endswith('.'): + path = path[:-1] + # display all the path or not if show_full_path: vname = path @@ -449,6 +458,40 @@ def print_value(config, path, show_label, logger, level=0, show_full_path=False) else: # case where val is just a str logger.write("%s\n" % val) +def get_config_children(config, args): + '''Gets the names of the children of the given parameter. + + :param config Config: The configuration where to read the values + :param args: The path in the config from which get the keys + ''' + vals = [] + rootkeys = config.keys() + + if len(args) == 0: + # no parameter returns list of root keys + vals = rootkeys + else: + parent = args[0] + pos = parent.rfind('.') + if pos < 0: + # Case where there is only on key as parameter. + # For example VARS + vals = [m for m in rootkeys if m.startswith(parent)] + else: + # Case where there is a part from a key + # for example VARS.us (for VARS.user) + head = parent[0:pos] + tail = parent[pos+1:] + try: + a = config.getByPath(head) + if dir(a).__contains__('keys'): + vals = map(lambda x: head + '.' + x, [m for m in a.keys() if m.startswith(tail)]) + except: + pass + + for v in sorted(vals): + sys.stdout.write("%s\n" % v) + def description(): '''method that is called when salomeTools is called with --help option. @@ -464,15 +507,20 @@ def run(args, runner, logger): ''' # Parse the options (options, args) = parser.parse_args(args) + + # Only useful for completion mechanism : print the keys of the config + if options.schema: + get_config_children(runner.cfg, args) + return # 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, logger) + print_value(runner.cfg, val, not options.no_label, logger) else: - print_value(runner.cfg, options.value, True, logger, + print_value(runner.cfg, options.value, not options.no_label, logger, level=0, show_full_path=False) # case : edit user pyconf file or application file @@ -542,7 +590,8 @@ def run(args, runner, logger): # search in all directories that can have pyconf applications for path in runner.cfg.SITE.config.config_path: # print a header - logger.write("------ %s\n" % src.printcolors.printcHeader(path)) + if not options.no_label: + logger.write("------ %s\n" % src.printcolors.printcHeader(path)) if not os.path.exists(path): logger.write(src.printcolors.printcError(_( @@ -556,7 +605,8 @@ def run(args, runner, logger): appliname = f[:-len('.pyconf')] if appliname not in lproduct: lproduct.append(appliname) - if path.startswith(runner.cfg.VARS.personalDir): + if path.startswith(runner.cfg.VARS.personalDir) \ + and not options.no_label: logger.write("%s*\n" % appliname) else: logger.write("%s\n" % appliname) diff --git a/commands/log.py b/commands/log.py index 2836734..6660e57 100644 --- a/commands/log.py +++ b/commands/log.py @@ -49,6 +49,11 @@ def get_last_log_file(logDir, notShownCommands): return os.path.join(logDir, last[0]) def remove_log_file(filePath, logger): + '''if it exists, print a warning and remove the input file + + :param filePath: the path of the file to delete + :param logger Logger: the logger instance to use for the print + ''' if os.path.exists(filePath): logger.write(src.printcolors.printcWarning("Removing ") + filePath + "\n", 5) diff --git a/complete_sat.sh b/complete_sat.sh new file mode 100755 index 0000000..fc03d4e --- /dev/null +++ b/complete_sat.sh @@ -0,0 +1,139 @@ +#!/bin/bash +# Copyright (C) 2010-2012 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 + +# Completion Function for salomeTools (sat) + +export SAT_PATH=$(cd `dirname "${BASH_SOURCE}"` && pwd) + +_show_applications() +{ + local opts2=$(for x in `$SAT_PATH/sat config -nl` + do + echo ${x} + done) + + # additional options for command working without products + case "${command}" in + config) + opts2=$(echo --list --value --edit --info $opts2) + ;; + log) + opts2=$(echo --clean --full --last --terminal $opts2) + ;; + esac + + COMPREPLY=( $(compgen -W "${opts2}" -- ${cur}) ) +} + +_salomeTools_complete() +{ + if [[ "${SAT_PATH}x" == "x" ]] + then + return 0 + fi + + local cur opts args command + COMPREPLY=() + argc="${COMP_CWORD}" + cur="${COMP_WORDS[COMP_CWORD]}" + + # second argument => show available APPLICATION + if [[ ${argc} > 1 ]] + then + command="${COMP_WORDS[1]}" + fi + + if [[ ${argc} > 1 ]] + then + if [[ ${command%%-*} == "" ]] + then + command="${COMP_WORDS[2]}" + argc="$((( argc - 1)))" + fi + fi + + # first argument => show available commands + if [[ ${argc} == 1 ]] + then + opts="config log testcommand --help" + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi + + if [[ ${argc} == 2 ]] + then + # get list of APPLICATIONS + _show_applications + return 0 + fi + + # option depending on command + local prev="${COMP_WORDS[COMP_CWORD-1]}" + + if [[ ${prev} == "--value" || ${prev} == "-v" ]] + then + if [[ ${argc} == 4 ]] + then + # with application + opts=$(for x in `$SAT_PATH/sat config ${COMP_WORDS[COMP_CWORD-2]} -s ${COMP_WORDS[COMP_CWORD]}` + do echo ${x} ; done) + COMPREPLY=( $(compgen -W "${opts}" -S "." -- ${cur}) ) + else + # without application + opts=$(for x in `$SAT_PATH/sat config -s ${COMP_WORDS[COMP_CWORD]}` + do echo ${x} ; done) + COMPREPLY=( $(compgen -W "${opts}" -S "." -- ${cur}) ) + fi + + return 0 + fi + + # show list of softwares + if [[ ${prev} == "--module" || ${prev} == "-m" ]] + then + prod="${COMP_WORDS[2]}" + if [[ ${command} != "test" ]] + then + opts=$(for x in `$SAT_PATH/sat config $prod -nv PRODUCT.softwares` + do echo ${x}; done) + + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi + fi + + # show argument for each command + case "${command}" in + config) + opts="--value --list --copy --edit --no_label" + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + ;; + log) + opts="--clean --last --terminal --last" + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + ;; + *) return 0 ;; + esac + +} + +# activation de l'auto-completion pour la commande sat +complete -F _salomeTools_complete sat +complete -F _salomeTools_complete ./sat + diff --git a/src/pyconf.py b/src/pyconf.py index 821f3d6..13fde67 100644 --- a/src/pyconf.py +++ b/src/pyconf.py @@ -864,7 +864,7 @@ class Sequence(Container): data = object.__getattribute__(self, 'data') comments = object.__getattribute__(self, 'comments') indstr = indent * ' ' - for i in xrange(0, len(data)): + for i in range(0, len(data)): value = data[i] comment = comments[i] if comment: -- 2.39.2