[cylc] 18/23: Add fixed version of cylc driver cmd

Alastair McKinstry mckinstry at moszumanska.debian.org
Sun Mar 26 12:04:07 UTC 2017


This is an automated email from the git hooks/post-receive script.

mckinstry pushed a commit to branch debian/master
in repository cylc.

commit 250245c8514b4908bbccbad5b1117a27d08e9b02
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Tue Nov 15 00:37:59 2016 +0000

    Add fixed version of cylc driver cmd
---
 debian/cylc.install |   1 -
 debian/cylc.py      | 691 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 debian/rules        |   2 +
 3 files changed, 693 insertions(+), 1 deletion(-)

diff --git a/debian/cylc.install b/debian/cylc.install
index 8222baa..2ce1d17 100644
--- a/debian/cylc.install
+++ b/debian/cylc.install
@@ -1,5 +1,4 @@
 bin/cylc-* /usr/share/cylc/bin
-bin/cylc   /usr/share/cylc/bin
 conf/5to6 /usr/share/cylc/bin
 conf/cylc.vim	/usr/share/vim/addons/plugin
 conf/cylc.lang /usr/share/gtksourceview-3.0/language-specs
diff --git a/debian/cylc.py b/debian/cylc.py
new file mode 100755
index 0000000..1277a4c
--- /dev/null
+++ b/debian/cylc.py
@@ -0,0 +1,691 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2008-2016 NIWA
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This version of the cylc driver is identical to shipped in 6.11.2,
+# except sys.argv[0] is overriden with /usr/share/cycl/bin/cylc
+# - amck, 2016-11-15
+
+import os
+import re
+import sys
+
+
+def prelude():
+    """Ensure cylc library is at the front of "sys.path"."""
+    lib = os.path.join(
+        os.path.dirname(os.path.realpath(__file__)), '..', 'lib')
+    if lib in sys.path:
+        sys.path.remove(lib)
+    sys.path.insert(0, lib)
+
+
+prelude()
+
+
+try:
+    os.getcwd()
+except OSError as exc:
+    # The current working directory has been deleted (or filesystem
+    # problems of some kind...). This results in Pyro not being found,
+    # immediately below. We cannot just chdir to $HOME as gcylc does
+    # because that would break relative directory path command arguments
+    # (cylc reg SUITE PATH).
+    sys.exit(str(exc))
+
+# Import cylc to initialise CYLC_DIR and the path for python (__init__.py).
+import cylc
+from parsec.OrderedDict import OrderedDict
+
+
+class CommandError(Exception):
+
+    def __init__(self, msg):
+        self.msg = msg
+
+    def __str__(self):
+        return repr(self.msg)
+
+
+class CommandNotFoundError(CommandError):
+    pass
+
+
+class CommandNotUniqueError(CommandError):
+    pass
+
+
+def is_help(str):
+    if (str == '-h' or str == '--help' or str == '--hlep' or str == 'help' or
+            str == 'hlep' or str == '?'):
+        return True
+    else:
+        return False
+
+
+def match_dict(abbrev, categories, title):
+    # allow any unique abbreviation to cylc categories
+    matches = []
+    for cat in categories.keys():
+        for alias in categories[cat]:
+            if re.match('^' + abbrev + '.*', alias):
+                if cat not in matches:
+                    matches.append(cat)
+    if len(matches) == 0:
+        raise CommandNotFoundError(title + ' not found: ' + abbrev)
+    elif len(matches) > 1:
+        # multiple matches
+        res = ''
+        for cat in matches:
+            res += ' ' + '|'.join(categories[cat])
+        raise CommandNotUniqueError(
+            title + ' "' + abbrev + '" not unique:' + res)
+    else:
+        return matches[0]
+
+
+def match_command(abbrev):
+    # allow any unique abbreviation to commands when no category is specified
+    matches = []
+    finished_matching = False
+    for dct in [admin_commands,
+                license_commands,
+                database_commands,
+                preparation_commands,
+                information_commands,
+                discovery_commands,
+                control_commands,
+                utility_commands,
+                hook_commands,
+                task_commands]:
+        for com in dct.keys():
+            if com == abbrev:
+                matches = [com]
+                finished_matching = True
+                break
+            for alias in dct[com]:
+                if re.match('^' + abbrev + '.*', alias):
+                    if com not in matches:
+                        matches.append(com)
+            if finished_matching:
+                break
+    if len(matches) == 0:
+        raise CommandNotFoundError('COMMAND not found: ' + abbrev)
+    elif len(matches) > 1:
+        # multiple matches
+        res = ''
+        for com in matches:
+            res += ' ' + '|'.join(all_commands[com])
+        raise CommandNotUniqueError(
+            'COMMAND "' + abbrev + '" not unique:' + res)
+    else:
+        return matches[0]
+
+
+def pretty_print(incom, choose_dict, indent=True, numbered=False, sort=False):
+    # pretty print commands or topics from a dict:
+    # (com[item] = description)
+
+    if indent:
+        spacer = ' '
+    else:
+        spacer = ''
+
+    label = {}
+    choose = []
+    longest = 0
+    for item in choose_dict:
+        choose.append(item)
+        lbl = '|'.join(choose_dict[item])
+        label[item] = lbl
+        if len(lbl) > longest:
+            longest = len(lbl)
+
+    count = 0
+    pad = False
+    if len(choose) > 9:
+        pad = True
+
+    if sort:
+        choose.sort()
+    for item in choose:
+        if item not in incom:
+            raise SystemExit("ERROR: summary for '" + item + "' not found")
+
+        print spacer,
+        if numbered:
+            count += 1
+            if pad and count < 10:
+                digit = ' ' + str(count)
+            else:
+                digit = str(count)
+            print digit + '/',
+        print "%s %s %s" % (
+            label[item],
+            '.' * (longest - len(label[item])) + '...',
+            incom[item])
+
+# BEGIN MAIN
+
+# categories[category] = [aliases]
+categories = OrderedDict()
+categories['all'] = ['all']
+categories['database'] = ['db', 'database']
+categories['preparation'] = ['preparation']
+categories['information'] = ['information']
+categories['discovery'] = ['discovery']
+categories['control'] = ['control']
+categories['utility'] = ['utility']
+categories['task'] = ['task']
+categories['hook'] = ['hook']
+categories['admin'] = ['admin']
+categories['license'] = ['license', 'GPL']
+
+information_commands = OrderedDict()
+
+information_commands['gscan'] = ['gscan', 'gsummary']
+information_commands['gpanel'] = ['gpanel']
+information_commands['gui'] = ['gui', 'gcylc']
+information_commands['list'] = ['list', 'ls']
+information_commands['dump'] = ['dump']
+information_commands['cat-state'] = ['cat-state']
+information_commands['show'] = ['show']
+information_commands['cat-log'] = ['cat-log', 'log']
+information_commands['get-suite-version'] = [
+    'get-suite-version', 'get-cylc-version']
+information_commands['version'] = ['version']
+
+information_commands['documentation'] = ['documentation', 'browse']
+information_commands['monitor'] = ['monitor']
+information_commands['get-suite-config'] = ['get-suite-config', 'get-config']
+information_commands['get-site-config'] = [
+    'get-site-config', 'get-global-config']
+information_commands['get-gui-config'] = ['get-gui-config']
+
+control_commands = OrderedDict()
+control_commands['gui'] = ['gui']
+# NOTE: don't change 'run' to 'start' or the category [control]
+# becomes compulsory to disambiguate from 'cylc [task] started'.
+# Keeping 'start' as an alias however: 'cylc con start'.
+control_commands['run'] = ['run', 'start']
+control_commands['stop'] = ['stop', 'shutdown']
+control_commands['restart'] = ['restart']
+control_commands['trigger'] = ['trigger']
+control_commands['insert'] = ['insert']
+control_commands['remove'] = ['remove']
+control_commands['poll'] = ['poll']
+control_commands['kill'] = ['kill']
+control_commands['hold'] = ['hold']
+control_commands['release'] = ['release', 'unhold']
+control_commands['reset'] = ['reset']
+control_commands['spawn'] = ['spawn']
+control_commands['nudge'] = ['nudge']
+control_commands['reload'] = ['reload']
+control_commands['set-runahead'] = ['set-runahead']
+control_commands['set-verbosity'] = ['set-verbosity']
+control_commands['broadcast'] = ['broadcast', 'bcast']
+control_commands['ext-trigger'] = ['ext-trigger', 'external-trigger']
+
+utility_commands = OrderedDict()
+utility_commands['cycle-point'] = [
+    'cycle-point', 'cyclepoint', 'datetime', 'cycletime']
+utility_commands['random'] = ['random', 'rnd']
+utility_commands['scp-transfer'] = ['scp-transfer']
+utility_commands['suite-state'] = ['suite-state']
+utility_commands['ls-checkpoints'] = ['ls-checkpoints']
+
+hook_commands = OrderedDict()
+hook_commands['email-suite'] = ['email-suite']
+hook_commands['email-task'] = ['email-task']
+hook_commands['job-logs-retrieve'] = ['job-logs-retrieve']
+hook_commands['check-triggering'] = ['check-triggering']
+
+admin_commands = OrderedDict()
+admin_commands['test-db'] = ['test-db']
+admin_commands['test-battery'] = ['test-battery']
+admin_commands['import-examples'] = ['import-examples']
+admin_commands['upgrade-db'] = ['upgrade-db']
+admin_commands['upgrade-run-dir'] = ['upgrade-run-dir']
+admin_commands['check-software'] = ['check-software']
+
+license_commands = OrderedDict()
+license_commands['warranty'] = ['warranty']
+license_commands['conditions'] = ['conditions']
+
+database_commands = OrderedDict()
+database_commands['register'] = ['register']
+database_commands['reregister'] = ['reregister', 'rename']
+database_commands['unregister'] = ['unregister']
+database_commands['copy'] = ['copy', 'cp']
+database_commands['print'] = ['print']
+database_commands['get-directory'] = ['get-directory']
+database_commands['refresh'] = ['refresh']
+
+preparation_commands = OrderedDict()
+preparation_commands['edit'] = ['edit']
+preparation_commands['view'] = ['view']
+preparation_commands['validate'] = ['validate']
+preparation_commands['5to6'] = ['5to6']
+preparation_commands['list'] = ['list', 'ls']
+preparation_commands['search'] = ['search', 'grep']
+preparation_commands['graph'] = ['graph']
+preparation_commands['graph-diff'] = ['graph-diff']
+preparation_commands['diff'] = ['diff', 'compare']
+preparation_commands['jobscript'] = ['jobscript']
+
+discovery_commands = OrderedDict()
+discovery_commands['ping'] = ['ping']
+discovery_commands['scan'] = ['scan']
+discovery_commands['check-versions'] = ['check-versions']
+
+task_commands = OrderedDict()
+task_commands['submit'] = ['submit', 'single']
+task_commands['message'] = ['message', 'task-message']
+task_commands['jobs-kill'] = ['jobs-kill']
+task_commands['jobs-poll'] = ['jobs-poll']
+task_commands['jobs-submit'] = ['jobs-submit']
+task_commands['job-submit'] = ['job-submit']
+
+all_commands = OrderedDict()
+for dct in [
+        database_commands,
+        preparation_commands,
+        information_commands,
+        discovery_commands,
+        control_commands,
+        utility_commands,
+        task_commands,
+        admin_commands,
+        hook_commands,
+        license_commands]:
+    for com in dct.keys():
+        all_commands[com] = dct[com]
+
+general_usage = """
+Cylc ("silk") is a suite engine and metascheduler that specializes in
+cycling weather and climate forecasting suites and related processing
+(but it can also be used for one-off workflows of non-cycling tasks).
+For detailed documentation see the Cylc User Guide (cylc doc --help).
+
+Version __CYLC_VERSION__
+
+The graphical user interface for cylc is "gcylc" (a.k.a. "cylc gui").
+
+USAGE:
+  % cylc -v,--version                   # print cylc version
+  % cylc version                        # (ditto, by command)
+  % cylc help,--help,-h,?               # print this help page
+
+  % cylc help CATEGORY                  # print help by category
+  % cylc CATEGORY help                  # (ditto)
+
+  % cylc help [CATEGORY] COMMAND        # print command help
+  % cylc [CATEGORY] COMMAND help,--help # (ditto)
+
+  % cylc [CATEGORY] COMMAND [options] SUITE [arguments]
+  % cylc [CATEGORY] COMMAND [options] SUITE TASK [arguments]"""
+
+# topic summaries
+catsum = OrderedDict()
+catsum['all'] = "The complete command set."
+catsum['admin'] = "Cylc installation, testing, and example suites."
+catsum['license'] = "Software licensing information (GPL v3.0)."
+catsum['database'] = "Suite name registration, copying, deletion, etc."
+catsum['information'] = "Interrogate suite definitions and running suites."
+catsum['preparation'] = "Suite editing, validation, visualization, etc."
+catsum['discovery'] = "Detect running suites."
+catsum['control'] = "Suite start up, monitoring, and control."
+catsum['task'] = "The task messaging interface."
+catsum['hook'] = "Suite and task event hook scripts."
+catsum['utility'] = "Cycle arithmetic and templating, etc."
+
+usage = general_usage + """
+
+Commands and categories can both be abbreviated. Use of categories is
+optional, but they organize help and disambiguate abbreviated commands:
+  % cylc control trigger SUITE TASK     # trigger TASK in SUITE
+  % cylc trigger SUITE TASK             # ditto
+  % cylc con trig SUITE TASK            # ditto
+  % cylc c t SUITE TASK                 # ditto
+
+CYLC SUITE NAMES AND YOUR REGISTRATION DATABASE
+  Suites are addressed by hierarchical names such as suite1, nwp.oper,
+nwp.test.LAM2, etc. in a "name registration database" ($HOME/.cylc/REGDB)
+that simply associates names with the suite definition locations.  The
+'--db=' command option can be used to view and copy suites from other
+users, with access governed by normal filesystem permissions.
+
+TASK IDENTIFICATION IN CYLC SUITES
+  Tasks are identified by NAME.CYCLE_POINT where POINT is either a
+  date-time or an integer.
+  Date-time cycle points are in an ISO 8601 date-time format, typically
+  CCYYMMDDThhmm followed by a time zone - e.g. 20101225T0600Z.
+  Integer cycle points (including those for one-off suites) are integers
+  - just '1' for one-off suites.
+
+HOW TO DRILL DOWN TO COMMAND USAGE HELP:
+  % cylc help           # list all available categories (this page)
+  % cylc help prep      # list commands in category 'preparation'
+  % cylc help prep edit # command usage help for 'cylc [prep] edit'
+
+Command CATEGORIES:"""
+
+# Some commands and categories are aliased (db|database, cp|copy) and
+# some common typographical errors are corrected (e.g. cycl => cylc).
+
+# command summaries
+comsum = OrderedDict()
+# admin
+comsum['test-db'] = 'Run an automated suite name database test'
+comsum['test-battery'] = 'Run a battery of self-diagnosing test suites'
+comsum['import-examples'] = 'Import example suites your suite name database'
+comsum['upgrade-db'] = 'Upgrade a pre-cylc-5.4 suite name database'
+comsum['upgrade-run-dir'] = 'Upgrade a pre-cylc-6 suite run directory'
+comsum['check-software'] = 'Check required software is installed.'
+# license
+comsum['warranty'] = 'Print the GPLv3 disclaimer of warranty'
+comsum['conditions'] = 'Print the GNU General Public License v3.0'
+# database
+comsum['register'] = 'Register a suite for use'
+comsum['reregister'] = 'Change the name of a suite'
+comsum['unregister'] = 'Unregister and optionally delete suites'
+comsum['copy'] = 'Copy a suite or a group of suites'
+comsum['print'] = 'Print registered suites'
+comsum['get-directory'] = 'Retrieve suite definition directory paths'
+comsum['refresh'] = 'Report invalid registrations and update suite titles'
+# preparation
+comsum['edit'] = 'Edit suite definitions, optionally inlined'
+comsum['view'] = 'View suite definitions, inlined and Jinja2 processed'
+comsum['validate'] = 'Parse and validate suite definitions'
+comsum['5to6'] = 'Improve the cylc 6 compatibility of a cylc 5 suite file'
+comsum['search'] = 'Search in suite definitions'
+comsum['graph'] = 'Plot suite dependency graphs and runtime hierarchies'
+comsum['graph-diff'] = 'Compare two suite dependencies or runtime hierarchies'
+comsum['diff'] = 'Compare two suite definitions and print differences'
+# information
+comsum['list'] = 'List suite tasks and family namespaces'
+comsum['dump'] = 'Print the state of tasks in a running suite'
+comsum['cat-state'] = 'Print the state of tasks from the state dump'
+comsum['show'] = 'Print task state (prerequisites and outputs etc.)'
+comsum['cat-log'] = 'Print various suite and task log files'
+comsum['documentation'] = 'Display cylc documentation (User Guide etc.)'
+comsum['monitor'] = 'An in-terminal suite monitor (see also gcylc)'
+comsum['get-suite-config'] = 'Print suite configuration items'
+comsum['get-site-config'] = 'Print site/user configuration items'
+comsum['get-gui-config'] = 'Print gcylc configuration items'
+comsum['get-suite-version'] = 'Print the cylc version of a suite daemon'
+comsum['version'] = 'Print the cylc release version'
+comsum['gscan'] = 'Scan GUI for monitoring multiple suites'
+comsum['gpanel'] = 'Internal interface for GNOME 2 panel applet'
+# control
+comsum['gui'] = '(a.k.a. gcylc) cylc GUI for suite control etc.'
+comsum['run'] = 'Start a suite at a given cycle point'
+comsum['stop'] = 'Shut down running suites'
+comsum['restart'] = 'Restart a suite from a previous state'
+comsum['trigger'] = 'Manually trigger or re-trigger a task'
+comsum['insert'] = 'Insert tasks into a running suite'
+comsum['remove'] = 'Remove tasks from a running suite'
+comsum['poll'] = 'Poll submitted or running tasks'
+comsum['kill'] = 'Kill submitted or running tasks'
+comsum['hold'] = 'Hold (pause) suites or individual tasks'
+comsum['release'] = 'Release (unpause) suites or individual tasks'
+comsum['reset'] = 'Force one or more tasks to change state.'
+comsum['spawn'] = 'Force one or more tasks to spawn their successors.'
+comsum['nudge'] = 'Cause the cylc task processing loop to be invoked'
+comsum['reload'] = 'Reload the suite definition at run time'
+comsum['set-runahead'] = 'Change the runahead limit in a running suite.'
+comsum['set-verbosity'] = 'Change a running suite\'s logging verbosity'
+comsum['ext-trigger'] = 'Report an external trigger event to a suite'
+# discovery
+comsum['ping'] = 'Check that a suite is running'
+comsum['scan'] = 'Scan a host for running suites'
+comsum['check-versions'] = 'Compare cylc versions on task host accounts'
+# task
+comsum['submit'] = 'Run a single task just as its parent suite would'
+comsum['message'] = '(task messaging) Report task messages'
+comsum['broadcast'] = 'Change suite [runtime] settings on the fly'
+comsum['jobs-kill'] = '(Internal) Kill task jobs'
+comsum['jobs-poll'] = '(Internal) Retrieve status for task jobs'
+comsum['jobs-submit'] = '(Internal) Submit task jobs'
+comsum['job-submit'] = '(Internal) Submit a job'
+
+# utility
+comsum['cycle-point'] = 'Cycle point arithmetic and filename templating'
+comsum['random'] = 'Generate a random integer within a given range'
+comsum['jobscript'] = 'Generate a task job script and print it to stdout'
+comsum['scp-transfer'] = 'Scp-based file transfer for cylc suites'
+comsum['suite-state'] = 'Query the task states in a suite'
+comsum['ls-checkpoints'] = 'Display task pool etc at given events'
+
+# hook
+comsum['email-task'] = 'A task event hook script that sends email alerts'
+comsum['email-suite'] = 'A suite event hook script that sends email alerts'
+comsum['job-logs-retrieve'] = (
+    '(Internal) Retrieve logs from a remote host for a task job')
+comsum['check-triggering'] = 'A suite shutdown event hook for cylc testing'
+
+
+def typo(str):
+    corrected = str
+    if str == 'gcycl':
+        corrected = 'gcylc'
+    return corrected
+
+
+def category_help(category):
+    coms = eval(category + '_commands')
+    alts = '|'.join(categories[category])
+    print 'CATEGORY: ' + alts + ' - ' + catsum[category]
+    if category == 'database':
+        print "Suite name registrations are held under $HOME/.cylc/REGDB."
+    print
+    print 'HELP: cylc [' + alts + '] COMMAND help,--help'
+    print '  You can abbreviate ' + alts + ' and COMMAND.'
+    print '  The category ' + alts + ' may be omitted.'
+    print
+    print 'COMMANDS:'
+    pretty_print(comsum, coms, sort=True)
+
+
+def set_environment_vars(args):
+    """
+    Set --env=key=val arguments as environment variables & remove
+    from argument list
+    """
+    regex = re.compile('\A--env=(\S+)=(\S+)\Z')
+    for arg in args:
+        match = regex.match(arg)
+        if match is None:
+            continue
+        os.environ[match.group(1)] = match.group(2)
+    return filter(lambda i: not regex.search(i), args)
+
+# no arguments: print help and exit
+if len(sys.argv) == 1:
+    from cylc.version import CYLC_VERSION
+    print usage.replace("__CYLC_VERSION__", CYLC_VERSION)
+    pretty_print(catsum, categories)
+    sys.exit(1)
+
+args = sys.argv[1:]
+
+# Set environment variables from arguments like --env=key=val
+args = set_environment_vars(args)
+
+if len(args) == 1:
+    if args[0] == 'categories':
+        # secret argument for document processing
+        keys = catsum.keys()
+        keys.sort()
+        for key in keys:
+            print key
+        sys.exit(0)
+    if args[0] == 'commands':
+        # secret argument for document processing
+        keys = comsum.keys()
+        keys.sort()
+        for key in keys:
+            print key
+        sys.exit(0)
+    if args[0].startswith('category='):
+        # secret argument for gcylc
+        category = args[0][9:]
+        commands = eval(category + '_commands')
+        for command in commands:
+            print command
+        sys.exit(0)
+    if is_help(args[0]):
+        # cylc help
+        from cylc.version import CYLC_VERSION
+        print usage.replace("__CYLC_VERSION__", CYLC_VERSION)
+        pretty_print(catsum, categories)
+        sys.exit(0)
+    if (args[0] == '-v' or args[0] == '--version'):
+        from cylc.version import CYLC_VERSION
+        print CYLC_VERSION
+        sys.exit(0)
+
+    # cylc CATEGORY with no args => category help
+    try:
+        category = match_dict(args[0], categories, 'CATEGORY')
+    except CommandError, x:
+        # No matching category
+        # (no need to print this, the exception will recur below)
+        # Carry on in case of a no-argument command (e.g. 'cylc scan')
+        pass
+    else:
+        category_help(category)
+        sys.exit(0)
+
+command_args = []
+
+if len(args) == 2 and (is_help(args[0]) or is_help(args[1])):
+    # TWO ARGUMENTS, one help
+    # cylc help CATEGORY
+    # cylc CATEGORY help
+    # cylc help COMMAND
+    # cylc COMMAND help
+    if is_help(args[1]):
+        item = args[0]
+    else:
+        item = args[1]
+    try:
+        category = match_dict(item, categories, 'CATEGORY')
+    except CommandError, x:
+        # no matching category, try command
+        try:
+            command = match_command(typo(item))
+        except CommandError, y:
+            print >> sys.stderr, x
+            raise SystemExit(y)
+        else:
+            # cylc COMMAND --help
+            command_args = ['--help']
+    else:
+        # cylc help CATEGORY
+        category_help(category)
+        sys.exit(0)
+
+elif len(args) == 3 and (is_help(args[0]) or is_help(args[2])):
+    # cylc help CATEGORY COMMAND
+    # cylc CATEGORY COMMAND help
+    if is_help(args[2]):
+        category = args[0]
+        command = args[1]
+    else:
+        category = args[1]
+        command = args[2]
+    try:
+        category = match_dict(category, categories, 'CATEGORY')
+    except CommandError, x:
+        raise SystemExit(x)
+
+    coms = eval(category + '_commands')
+    try:
+        command = match_dict(command, coms, category + ' COMMAND')
+    except CommandNotUniqueError, y:
+        print y
+        sys.exit(1)
+    except CommandNotFoundError, y:
+        print y
+        print 'COMMANDS available in CATEGORY "' + category + '":'
+        print coms.keys()
+        sys.exit(1)
+
+    # cylc COMMAND --help
+    command_args = ['--help']
+
+else:
+    # two or more args, neither of first two are help
+    # cylc CATEGORY COMMAND [ARGS]
+    # cylc COMMAND [ARGS]
+    try:
+        category = args[0]
+        category = match_dict(category, categories, 'CATEGORY')
+    except CommandError, x:
+        # no matching category, try command
+        try:
+            command = args[0]
+            command = match_command(typo(command))
+        except CommandError, y:
+            print >> sys.stderr, x
+            raise SystemExit(y)
+        else:
+            # cylc COMMAND [ARGS]
+            command_args = args[1:]
+    else:
+        # cylc CATEGORY COMMAND [ARGS]
+        coms = eval(category + '_commands')
+        command = args[1]
+        try:
+            command = match_dict(command, coms, category + ' COMMAND')
+        except CommandNotUniqueError, y:
+            print y
+            sys.exit(1)
+        except CommandNotFoundError, y:
+            print y
+            print 'COMMANDS available in CATEGORY "' + category + '":'
+            print coms.keys()
+            sys.exit(1)
+
+        else:
+            # cylc COMMAND [ARGS]
+            if len(args) > 1:
+                command_args = args[2:]
+            else:
+                command_args = []
+
+args_new = []
+for item in command_args:
+    if is_help(item):
+        # transform all legal help options to '--help'
+        args_new.append('--help')
+    elif item.startswith('--owner'):
+        # deprecate '--owner' to '--user'
+        args_new.append(item.replace('--owner', '--user'))
+    else:
+        args_new.append(item)
+args = args_new
+
+cmd = '/usr/share/cylc/bin/cylc-' + command
+
+# Replace the current process with that of the sub-command.
+try:
+    os.execvp(cmd, [cmd] + args)
+except OSError, exc:
+    if exc.filename is None:
+        exc.filename = cmd
+    raise SystemExit(exc)
diff --git a/debian/rules b/debian/rules
index 7a3efde..6615dad 100755
--- a/debian/rules
+++ b/debian/rules
@@ -22,6 +22,8 @@ override_dh_auto_install:
 	install -d -m 0755 $(CURDIR)/debian/cylc-el/usr/share/emacs/site-lisp/cylc
 	install    -m 0644 conf/cylc-mode.el \
                            $(CURDIR)/debian/cylc-el/usr/share/emacs/site-lisp/cylc/cylc-mode.el
+	install  -m 0755 debian/cylc.py  \
+			$(CURDIR)/debian/cylc/usr/share/cylc/bin/cylc
 
 override_dh_fixperms:
 	# Delete after install. Use Pyro package instead.

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/cylc.git



More information about the debian-science-commits mailing list