[shell] #715938: support of script parameters (using standard '--' as arguments separator)
authorJulien Jehannet <julien.jehannet@logilab.fr>
Wed, 28 Apr 2010 16:13:56 +0200
changeset 5430 ed8f71e244f8
parent 5427 f0ea91195ef6
child 5435 cc7d00a1b36e
[shell] #715938: support of script parameters (using standard '--' as arguments separator) Arguments after bare "--" string will not be processed by the shell command You can use it to pass extra arguments to your script and expect for them in 'scriptargs' afterwards.
__pkginfo__.py
cwctl.py
debian/control
migration.py
test/data/scripts/script1.py
test/data/scripts/script2.py
test/data/scripts/script3.py
test/unittest_cwctl.py
--- a/__pkginfo__.py	Wed Apr 28 12:25:11 2010 +0200
+++ b/__pkginfo__.py	Wed Apr 28 16:13:56 2010 +0200
@@ -40,7 +40,7 @@
 ]
 
 __depends__ = {
-    'logilab-common': '>= 0.50.0',
+    'logilab-common': '>= 0.50.1',
     'logilab-mtconverter': '>= 0.6.0',
     'rql': '>= 0.26.0',
     'yams': '>= 0.28.1',
--- a/cwctl.py	Wed Apr 28 12:25:11 2010 +0200
+++ b/cwctl.py	Wed Apr 28 16:13:56 2010 +0200
@@ -781,11 +781,15 @@
     repository internals (session, etc...) so most migration commands won't be
     available.
 
+    Arguments after bare "--" string will not be processed by the shell command
+    You can use it to pass extra arguments to your script and expect for
+    them in 'scriptargs' afterwards.
+
     <instance>
       the identifier of the instance to connect.
     """
     name = 'shell'
-    arguments = '<instance> [batch command file]'
+    arguments = '<instance> [batch command file(s)] [-- <script arguments>]'
     options = (
         ('system-only',
          {'short': 'S', 'action' : 'store_true',
@@ -861,8 +865,11 @@
             mih = config.migration_handler()
         try:
             if args:
-                for arg in args:
-                    mih.cmd_process_script(arg)
+                # use cmdline parser to access left/right attributes only
+                # remember that usage requires instance appid as first argument
+                scripts, args = self.cmdline_parser.largs[1:], self.cmdline_parser.rargs
+                for script in scripts:
+                    mih.cmd_process_script(script, args=args)
             else:
                 mih.interactive_shell()
         finally:
--- a/debian/control	Wed Apr 28 12:25:11 2010 +0200
+++ b/debian/control	Wed Apr 28 16:13:56 2010 +0200
@@ -97,7 +97,7 @@
 Package: cubicweb-common
 Architecture: all
 XB-Python-Version: ${python:Versions}
-Depends: ${python:Depends}, graphviz, gettext, python-logilab-mtconverter (>= 0.6.0), python-logilab-common (>= 0.50.0), python-yams (>= 0.29.0), python-rql (>= 0.26.0), python-lxml
+Depends: ${python:Depends}, graphviz, gettext, python-logilab-mtconverter (>= 0.6.0), python-logilab-common (>= 0.50.1), python-yams (>= 0.29.0), python-rql (>= 0.26.0), python-lxml
 Recommends: python-simpletal (>= 4.0), python-crypto
 Conflicts: cubicweb-core
 Replaces: cubicweb-core
--- a/migration.py	Wed Apr 28 12:25:11 2010 +0200
+++ b/migration.py	Wed Apr 28 16:13:56 2010 +0200
@@ -281,14 +281,25 @@
         return context
 
     def cmd_process_script(self, migrscript, funcname=None, *args, **kwargs):
-        """execute a migration script
-        in interactive mode,  display the migration script path, ask for
-        confirmation and execute it if confirmed
+        """execute a migration script in interactive mode
+
+        Display the migration script path, ask for confirmation and execute it
+        if confirmed
+
+        Context environment can have these variables defined:
+        - __name__   : will be determine by funcname parameter
+        - __file__   : is the name of the script if it exists
+        - scriptargs : script arguments coming from command-line
+
+        :param migrscript: name of the script
+        :param funcname: defines __name__ internally (or use __main__)
+        :params args: arguments of the script
+        :keyword args: extra arguments of the script given by command-line
         """
         migrscript = os.path.normpath(migrscript)
         if migrscript.endswith('.py'):
             script_mode = 'python'
-        elif migrscript.endswith('.txt') or migrscript.endswith('.rst'):
+        elif migrscript.endswith(('.txt', '.rst')):
             script_mode = 'doctest'
         else:
             raise Exception('This is not a valid cubicweb shell input')
@@ -300,7 +311,8 @@
                 pyname = '__main__'
             else:
                 pyname = splitext(basename(migrscript))[0]
-            scriptlocals.update({'__file__': migrscript, '__name__': pyname})
+            scriptlocals.update({'__file__': migrscript, '__name__': pyname,
+                                 'scriptargs': kwargs.pop("args", [])})
             execfile(migrscript, scriptlocals)
             if funcname is not None:
                 try:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/scripts/script1.py	Wed Apr 28 16:13:56 2010 +0200
@@ -0,0 +1,3 @@
+assert 'data/scripts/script1.py' == __file__
+assert '__main__' == __name__
+assert [] == scriptargs, scriptargs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/scripts/script2.py	Wed Apr 28 16:13:56 2010 +0200
@@ -0,0 +1,3 @@
+assert 'data/scripts/script2.py' == __file__
+assert '__main__' == __name__
+assert ['-v'] == scriptargs, scriptargs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/scripts/script3.py	Wed Apr 28 16:13:56 2010 +0200
@@ -0,0 +1,3 @@
+assert 'data/scripts/script3.py' == __file__
+assert '__main__' == __name__
+assert ['-vd', '-f', 'FILE.TXT'] == scriptargs, scriptargs
--- a/test/unittest_cwctl.py	Wed Apr 28 12:25:11 2010 +0200
+++ b/test/unittest_cwctl.py	Wed Apr 28 16:13:56 2010 +0200
@@ -24,8 +24,12 @@
 from logilab.common.testlib import TestCase, unittest_main
 
 from cubicweb.cwconfig import CubicWebConfiguration
+from cubicweb.devtools.testlib import CubicWebTC
+from cubicweb.server.migractions import ServerMigrationHelper
+
 CubicWebConfiguration.load_cwctl_plugins() # XXX necessary?
 
+
 class CubicWebCtlTC(TestCase):
     def setUp(self):
         self.stream = StringIO()
@@ -37,5 +41,25 @@
         from cubicweb.cwctl import ListCommand
         ListCommand().run([])
 
+
+class CubicWebShellTC(CubicWebTC):
+
+    def test_process_script_args_context(self):
+        repo = self.cnx._repo
+        mih = ServerMigrationHelper(None, repo=repo, cnx=self.cnx,
+                                    interactive=False,
+                                    # hack so it don't try to load fs schema
+                                    schema=1)
+        scripts = {'script1.py': list(),
+                   'script2.py': ['-v'],
+                   'script3.py': ['-vd', '-f', 'FILE.TXT'],
+                  }
+        mih.cmd_process_script('data/scripts/script1.py', funcname=None)
+        for script, args in scripts.items():
+            scriptname = os.path.join('data/scripts/', script)
+            self.assert_(os.path.exists(scriptname))
+            mih.cmd_process_script(scriptname, None, args=args)
+
+
 if __name__ == '__main__':
     unittest_main()