[Checkins] SVN: Sandbox/J1m/sbo/ initial port from zc repo

Jim Fulton jim at zope.com
Mon Mar 7 06:07:46 EST 2011


Log message for revision 120785:
  initial port from zc repo

Changed:
  U   Sandbox/J1m/sbo/buildout.cfg
  U   Sandbox/J1m/sbo/setup.py
  A   Sandbox/J1m/sbo/src/zc/sbo/
  A   Sandbox/J1m/sbo/src/zc/sbo/__init__.py
  A   Sandbox/J1m/sbo/src/zc/sbo/sbo.test
  A   Sandbox/J1m/sbo/src/zc/sbo/tests.py

-=-
Modified: Sandbox/J1m/sbo/buildout.cfg
===================================================================
--- Sandbox/J1m/sbo/buildout.cfg	2011-03-07 10:57:37 UTC (rev 120784)
+++ Sandbox/J1m/sbo/buildout.cfg	2011-03-07 11:07:46 UTC (rev 120785)
@@ -4,7 +4,7 @@
 
 [test]
 recipe = zc.recipe.testrunner
-eggs = 
+eggs = zc.sbo [test]
 
 [py]
 recipe = zc.recipe.egg

Modified: Sandbox/J1m/sbo/setup.py
===================================================================
--- Sandbox/J1m/sbo/setup.py	2011-03-07 10:57:37 UTC (rev 120784)
+++ Sandbox/J1m/sbo/setup.py	2011-03-07 11:07:46 UTC (rev 120785)
@@ -11,12 +11,14 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-name, version = 'zc.', '0'
+name, version = 'zc.sbo', '0'
 
 install_requires = ['setuptools']
 extras_require = dict(test=['zope.testing'])
 
 entry_points = """
+[console_scripts]
+sbo = sbo:main
 """
 
 from setuptools import setup

Added: Sandbox/J1m/sbo/src/zc/sbo/__init__.py
===================================================================
--- Sandbox/J1m/sbo/src/zc/sbo/__init__.py	                        (rev 0)
+++ Sandbox/J1m/sbo/src/zc/sbo/__init__.py	2011-03-07 11:07:46 UTC (rev 120785)
@@ -0,0 +1,152 @@
+import optparse
+import os
+import subprocess
+import sys
+import tempfile
+
+parser = optparse.OptionParser("""\
+Usage: %prog [options] application [configuration]
+
+Configure or unconfigure an application defined by a buildout
+configuration file.  By default, an application is configured.  If the
+-U option is provided, then the application is unconfigured.  An
+optional configuration name may be given.  If not given, the
+configuration name defaults to the application name.
+
+The buildout configuration path is computed as:
+
+   /etc/${application}/${configuration}.cfg
+
+During configuration, the file:
+
+   /etc/${application}/${configuration}.configured
+
+will be created, which records information about what was configured to
+support unconfiguring.
+
+To perform it's work, the script will run:
+
+   /opt/${application}/bin/buildout
+
+So the named application must be installed in /opt.
+""")
+
+parser.add_option(
+    '-a', '--all', action="store_true", dest="all",
+    help="Operate on all configurations.",
+    )
+
+parser.add_option(
+    '-l', '--list', action="store_true", dest="list",
+    help="""List available configurations.""",
+    )
+
+parser.add_option("-q", action="count", dest="quiet",
+                  help="Decrease the verbosity")
+
+parser.add_option('--test-root', dest="test_root",
+                  help="""\
+The location of an alternate root directory for testing.
+
+If this is used then the given directory will be used rather than / to
+find the opt and etc directories.
+""")
+
+parser.add_option(
+    '-u', '--unconfigure', action="store_true", dest="unconfigure",
+    help="""\
+Remove any configuration artifacts for the given configuration file.
+This option reads the associated installation database to discover what
+to unconfigure.""")
+
+parser.add_option("-v", action="count", dest="verbosity",
+                  help="Increase the verbosity")
+
+def error(message):
+    print 'Error:\n%s\n' % message
+    try:
+        parser.parse_args(['-h'])
+    except SystemExit:
+        pass
+    sys.exit(1)
+
+def assert_exists(label, path):
+    if not os.path.exists(path):
+        error("%s, %r, doesn't exist." % (label, path))
+
+def configs(config_dir):
+    return sorted(
+        name[:-4] for name in os.listdir(config_dir)
+        if name.endswith('.cfg')
+        )
+
+def main(args=None):
+    if args is None:
+        args = sys.argv[1:]
+    options, args = parser.parse_args(args)
+
+    root = options.test_root or '/'
+
+    if not args:
+        error("No application was specified.")
+    application = args.pop(0)
+
+    app_dir = os.path.join(root, 'opt', application)
+    assert_exists("The application directory", app_dir)
+
+    buildout = os.path.join(app_dir, 'bin', 'buildout')
+    assert_exists("The application buildout script", buildout)
+
+    config_dir = os.path.join(root, 'etc', application)
+    assert_exists("The application configuration directory", config_dir)
+
+    if options.list:
+        print '\n'.join(configs(config_dir))
+        sys.exit(0)
+
+    if options.all:
+        configurations = list(configs(config_dir))
+        if not configurations:
+            error("There aren't any configurations")
+    elif args:
+        configurations = [args.pop(0)]
+    else:
+        configurations = [application]
+
+    base_options = [
+        "buildout:directory=%s" % app_dir,
+        "-oU",
+        ]
+    verbosity = (options.verbosity or 0) - (options.quiet or 0)
+    if verbosity > 0:
+        base_options[-1] += 'v'*verbosity
+    elif verbosity < 0:
+        base_options[-1] += 'q'*(-verbosity)
+
+    base_options[-1] += 'c'
+
+    for configuration in configurations:
+        configured = os.path.join(config_dir, '%s.configured' % configuration)
+
+        sbooptions = ([buildout] + args + ["buildout:installed=%s" % configured]
+                      + base_options)
+        if options.unconfigure:
+            if not os.path.exists(configured):
+                print "%r doesn't exist.\nNothing to unconfigure." % configured
+                sys.exit(0)
+            fd, configfile = tempfile.mkstemp("buildout")
+            os.write(fd, "[buildout]\nparts=\n")
+            os.close(fd)
+            if verbosity >= 0:
+                print "Unconfiguring:", configuration
+            proc = subprocess.Popen(sbooptions + [configfile]
+                )
+            proc.wait()
+            os.remove(configfile)
+        else:
+            configfile = os.path.join(config_dir, "%s.cfg" % configuration)
+            assert_exists("The configuration file", configfile)
+            if verbosity >= 0:
+                print "Configuring:", configuration
+            proc = subprocess.Popen(sbooptions + [configfile])
+            proc.wait()


Property changes on: Sandbox/J1m/sbo/src/zc/sbo/__init__.py
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Added: Sandbox/J1m/sbo/src/zc/sbo/sbo.test
===================================================================
--- Sandbox/J1m/sbo/src/zc/sbo/sbo.test	                        (rev 0)
+++ Sandbox/J1m/sbo/src/zc/sbo/sbo.test	2011-03-07 11:07:46 UTC (rev 120785)
@@ -0,0 +1,233 @@
+System Buildout Script
+======================
+
+The system buildout script simply automates running an application
+buildout.
+
+    >>> from zc import sbo
+    >>> def test(*args):
+    ...     try:
+    ...         sbo.main(list(args))
+    ...     except SystemExit, v:
+    ...          print 'Exit status', v
+
+
+    >>> test('-h')
+    Usage: test [options] application [configuration]
+    <BLANKLINE>
+    Configure or unconfigure an application defined by a buildout
+    configuration file.  By default, an application is configured.  If the
+    -U option is provided, then the application is unconfigured.  An
+    optional configuration name may be given.  If not given, the
+    configuration name defaults to the application name.
+    <BLANKLINE>
+    The buildout configuration path is computed as:
+    <BLANKLINE>
+       /etc/${application}/${configuration}.cfg
+    <BLANKLINE>
+    During configuration, the file:
+    <BLANKLINE>
+       /etc/${application}/${configuration}.configured
+    <BLANKLINE>
+    will be created, which records information about what was configured to
+    support unconfiguring.
+    <BLANKLINE>
+    To perform it's work, the script will run:
+    <BLANKLINE>
+       /opt/${application}/bin/buildout
+    <BLANKLINE>
+    So the named application must be installed in /opt.
+    <BLANKLINE>
+    <BLANKLINE>
+    Options:
+      -h, --help            show this help message and exit
+      -a, --all             Operate on all configurations.
+      -l, --list            List available configurations.
+      -q                    Decrease the verbosity
+      --test-root=TEST_ROOT
+                            The location of an alternate root directory for
+                            testing.  If this is used then the given directory
+                            will be used rather than / to find the opt and etc
+                            directories.
+      -u, --unconfigure     Remove any configuration artifacts for the given
+                            configuration file. This option reads the associated
+                            installation database to discover what to unconfigure.
+      -v                    Increase the verbosity
+    Exit status 0
+
+We can supply a root directory for testing. Let's create one:
+
+    >>> import os
+    >>> os.mkdir('root')
+    >>> test('--test-root', 'root') # doctest: +ELLIPSIS
+    Error:
+    No application was specified.
+    <BLANKLINE>
+    Usage: test [options] application [configuration]
+    ...
+    Exit status 1
+
+    >>> test('--test-root', 'root', 'myapp') # doctest: +ELLIPSIS
+    Error:
+    The application directory, 'root/opt/myapp', doesn't exist.
+    <BLANKLINE>
+    Usage: test [options] application [configuration]
+    ...
+    Exit status 1
+
+    >>> os.makedirs(os.path.join('root', 'opt', 'myapp'))
+    >>> test('--test-root', 'root', 'myapp')
+    ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+    Error:
+    The application buildout script, 'root/opt/myapp/bin/buildout',
+    doesn't exist.
+    <BLANKLINE>
+    Usage: test [options] application [configuration]
+    ...
+    Exit status 1
+
+We create a fake buildout script, just for testing purposes:
+
+    >>> os.mkdir(os.path.join('root', 'opt', 'myapp', 'bin'))
+    >>> import sys
+    >>> open(os.path.join('root', 'opt', 'myapp', 'bin', 'buildout'),
+    ...      'w').write(
+    ... """#!%s
+    ... import sys
+    ... installed = [a[19:] for a in sys.argv
+    ...              if a.startswith('buildout:installed=')][0]
+    ... open(installed, 'w').write('\\n'.join(sys.argv[1:]))
+    ... """ % sys.executable)
+    >>> os.chmod(os.path.join('root', 'opt', 'myapp', 'bin', 'buildout'), 0755)
+
+    >>> test('--test-root', 'root', 'myapp') # doctest: +ELLIPSIS
+    Error:
+    The application configuration directory, 'root/etc/myapp', doesn't exist.
+    <BLANKLINE>
+    Usage: test [options] application [configuration]
+    ...
+    Exit status 1
+
+    >>> os.makedirs(os.path.join('root', 'etc', 'myapp'))
+    >>> test('--test-root', 'root', 'myapp') # doctest: +ELLIPSIS
+    Error:
+    The configuration file, 'root/etc/myapp/myapp.cfg', doesn't exist.
+    <BLANKLINE>
+    Usage: test [options] application [configuration]
+    ...
+    Exit status 1
+
+    >>> open(os.path.join('root', 'etc', 'myapp', 'myapp.cfg'), 'w').write("""
+    ... [buildout]
+    ... parts = foo
+    ... """)
+
+    >>> test('--test-root', 'root', 'myapp') # doctest: +ELLIPSIS
+    Configuring: myapp
+
+    >>> print open(os.path.join('root', 'etc', 'myapp', 'myapp.configured')
+    ... ).read()
+    buildout:installed=root/etc/myapp/myapp.configured
+    buildout:directory=root/opt/myapp
+    -oUc
+    root/etc/myapp/myapp.cfg
+
+We can specify a configuration name:
+
+    >>> test('--test-root', 'root', 'myapp', 'cust') # doctest: +ELLIPSIS
+    Error:
+    The configuration file, 'root/etc/myapp/cust.cfg', doesn't exist.
+    <BLANKLINE>
+    Usage: test [options] application [configuration]
+    ...
+    Exit status 1
+
+    >>> open(os.path.join('root', 'etc', 'myapp', 'cust.cfg'), 'w').write("""
+    ... [buildout]
+    ... parts = foo
+    ... """)
+
+    >>> test('--test-root', 'root', 'myapp', 'cust') # doctest: +ELLIPSIS
+    Configuring: cust
+    >>> print open(os.path.join('root', 'etc', 'myapp', 'cust.configured')
+    ... ).read()
+    buildout:installed=root/etc/myapp/cust.configured
+    buildout:directory=root/opt/myapp
+    -oUc
+    root/etc/myapp/cust.cfg
+
+The -l/--list option can be used to list available configurations:
+
+    >>> test('--test-root', 'root', 'myapp', '-l')
+    cust
+    myapp
+    Exit status 0
+
+The -a/--all option can be used to work with all configurations:
+
+    >>> test('--test-root', 'root', 'myapp', '-a')
+    Configuring: cust
+    Configuring: myapp
+
+If we use the -u option, we'll unconfigure:
+
+    >>> import tempfile
+    >>> os.mkdir('tmp')
+    >>> oldtempdir = tempfile.tempdir
+    >>> tempfile.tempdir = 'tmp'
+
+    >>> test('--test-root', 'root', '-u', 'myapp', 'cust') # doctest: +ELLIPSIS
+    Unconfiguring: cust
+
+    >>> print open(os.path.join('root', 'etc', 'myapp', 'cust.configured')
+    ... ).read() # doctest: +ELLIPSIS
+    buildout:installed=root/etc/myapp/cust.configured
+    buildout:directory=root/opt/myapp
+    -oUc
+    ...tmp/...buildout
+
+    >>> test('--test-root', 'root', '-u', 'myapp', 'cust2') # doctest: +ELLIPSIS
+    'root/etc/myapp/cust2.configured' doesn't exist.
+    Nothing to unconfigure.
+    Exit status 0
+
+The -a/--all option works when unconfiguring as well:
+
+    >>> test('--test-root', 'root', '-u', 'myapp', '-a')
+    Unconfiguring: cust
+    Unconfiguring: myapp
+
+If we pass -v or -q options, they are passed through to the buildout:
+
+    >>> test('--test-root', 'root', '-u', 'myapp', '-vv') # doctest: +ELLIPSIS
+    Unconfiguring: myapp
+
+    >>> print open(os.path.join('root', 'etc', 'myapp', 'myapp.configured')
+    ... ).read() # doctest: +ELLIPSIS
+    buildout:installed=root/etc/myapp/myapp.configured
+    buildout:directory=root/opt/myapp
+    -oUvvc
+    ...tmp/...buildout
+
+    >>> test('--test-root', 'root', '-u', 'myapp', '-q') # doctest: +ELLIPSIS
+    >>> print open(os.path.join('root', 'etc', 'myapp', 'myapp.configured')
+    ... ).read() # doctest: +ELLIPSIS
+    buildout:installed=root/etc/myapp/myapp.configured
+    buildout:directory=root/opt/myapp
+    -oUqc
+    ...tmp/...buildout
+
+    >>> test('--test-root', 'root', '-u', 'myapp', '-vvq') # doctest: +ELLIPSIS
+    Unconfiguring: myapp
+
+    >>> print open(os.path.join('root', 'etc', 'myapp', 'myapp.configured')
+    ... ).read() # doctest: +ELLIPSIS
+    buildout:installed=root/etc/myapp/myapp.configured
+    buildout:directory=root/opt/myapp
+    -oUvc
+    ...tmp/...buildout
+
+
+Cleanup
+
+    >>> tempfile.tempdir = oldtempdir


Property changes on: Sandbox/J1m/sbo/src/zc/sbo/sbo.test
___________________________________________________________________
Added: svn:eol-style
   + native

Added: Sandbox/J1m/sbo/src/zc/sbo/tests.py
===================================================================
--- Sandbox/J1m/sbo/src/zc/sbo/tests.py	                        (rev 0)
+++ Sandbox/J1m/sbo/src/zc/sbo/tests.py	2011-03-07 11:07:46 UTC (rev 120785)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import doctest
+import unittest
+from zope.testing import setupstack
+
+def test_suite():
+    return doctest.DocFileSuite(
+        'sbo.test',
+        setUp=setupstack.setUpDirectory, tearDown=setupstack.tearDown,
+        )
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')
+


Property changes on: Sandbox/J1m/sbo/src/zc/sbo/tests.py
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native



More information about the checkins mailing list