[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pyamf-commits
Subject:    [pyamf-commits] r2915 - in pyamf/sandbox: . release release/release
From:       SVN commit logs for PyAMF <commits () pyamf ! org>
Date:       2009-10-04 15:18:51
Message-ID: 20091004151851.9529D7BC01D () mail ! collab ! com
[Download RAW message or body]

Author: thijs
Date: 2009-10-04 17:18:51 +0200 (Sun, 04 Oct 2009)
New Revision: 2915

Added:
   pyamf/sandbox/release/release/
   pyamf/sandbox/release/release/__init__.py
   pyamf/sandbox/release/release/builds/
   pyamf/sandbox/release/release/builds/__init__.py
   pyamf/sandbox/release/release/builds/util.py
   pyamf/sandbox/release/release/package.py
   pyamf/sandbox/release/setup.py
Removed:
   pyamf/sandbox/buildbot/
   pyamf/sandbox/release/package.py
Log:
Create release package


Deleted: pyamf/sandbox/release/package.py
===================================================================
--- pyamf/sandbox/release/package.py	2009-10-03 23:58:58 UTC (rev 2914)
+++ pyamf/sandbox/release/package.py	2009-10-04 15:18:51 UTC (rev 2915)
@@ -1,273 +0,0 @@
-#!/usr/local/bin/python
-
-# Copyright (c) 2007-2009 The PyAMF Project.
-# See LICENSE for details.
-
-"""
-A basic release builder.
-
-Example usage:
-  python package.py --version=0.3 --name=PyAMF \
                --baseurl=http://svn.pyamf.org/pyamf/tags --branch=release-0.3
-
-For more help try:
-  python package.py --help
-"""
-
-import os, os.path, sys, shutil
-import subprocess, tempfile
-import hashlib
-
-def export_svn(url, options):
-    print
-    print 'Checking out: %s\n' % url
-
-    args = ['svn', 'export']
-
-    args.append(url)
-
-    if options.username is not None:
-        args.append('--username %s' % options.username)
-
-    if options.password is not None:
-        args.append('--password %s' % options.password)
-
-    args.append('--force')
-    export_dir = tempfile.mkdtemp()
-    args.append(export_dir)
-
-    cmd = subprocess.Popen(args)
-    retcode = cmd.wait()
-
-    return retcode, cmd, export_dir
-
-def export_repo(options):
-    repo_url = '%s/%s' % (options.baseurl, options.branch)
-
-    if options.repository == 'svn':
-        retcode, cmd, export_dir = export_svn(repo_url, options)
-    else:
-        raise ValueError, "Unknown repository type %s" % options.repository
-
-    if retcode != 0:
-        raise RuntimeError, "Problem exporting repository"
-
-    return export_dir
-
-def build_ext(src_dir):
-    cwd = os.getcwd()
-    os.chdir(src_dir)
-
-    args = ["python", "setup.py", "develop"]
-
-    cmd = subprocess.Popen(args)
-    retcode = cmd.wait()
-
-    if retcode != 0:
-        raise RuntimeError, "Error building extension"
-
-    os.chdir(cwd)
-
-def build_api_docs(src_dir, doc_dir, options):
-    # create .so files for epydoc
-    build_ext(export_dir)
-
-    # generate html doc from rst file
-    args = ["rst2html.py", os.path.join(src_dir, "CHANGES.txt"),
-            os.path.join(doc_dir, "changes.html")]
-
-    cmd = subprocess.Popen(args)
-    retcode = cmd.wait()
-
-    # generate API documentation
-    args = ["epydoc", "--config=" +
-        os.path.join(src_dir, "setup.cfg"), "-v",
-        "--graph=umlclasstree", "--dotpath=" + options.dotpath,
-        "--help-file=" + os.path.join(doc_dir, "changes.html")]
-
-    cmd = subprocess.Popen(args)
-    retcode = cmd.wait()
-
-    if retcode != 0:
-        raise RuntimeError, "Error building API docs"
-
-    # the --output override for epydoc doesn't work
-    # so copy the files and get rid of the old default
-    # output destination folder
-    temp_doc = os.path.join(os.getcwd(), "docs")
-    shutil.copytree(temp_doc, os.path.join(doc_dir, "api"))
-    shutil.rmtree(temp_doc)
-
-
-def build_docs(options):
-    # create .so files for epydoc
-    doc_url = 'https://svn.pyamf.org/doc/tags/release-%s' % (options.version)
-    retcode, cmd, export_dir = export_svn(doc_url, options)
-
-    args = ["make", "html"]
-
-    if retcode != 0:
-        raise RuntimeError, "Problem exporting repository"
-
-    cmd = subprocess.Popen(args, cwd=export_dir)
-    retcode = cmd.wait()
-
-    if retcode != 0:
-        raise RuntimeError, "Error building docs"
-
-    doc_dir = tempfile.mkdtemp()
-    shutil.rmtree(doc_dir)
-    temp_doc = os.path.join(export_dir, "_build", 'html')
-    shutil.copytree(temp_doc, doc_dir)
-
-    return doc_dir
-
-def parse_args():
-    def parse_targets(option, opt, value, parser):
-        print value
-
-    from optparse import OptionParser
-
-    parser = OptionParser()
-
-    parser.add_option('--baseurl', dest='baseurl',
-                      help='Root URL of the source control system')
-    parser.add_option('--branch', dest='branch', default='trunk',
-                      help='Name of the target folder in the source control system \
                [default: %default]')
-    parser.add_option('--version', dest='version',
-                      help='The version number of the project')
-    parser.add_option('--name', dest='name', help='The name of the project')
-    parser.add_option('--username', dest='username', default=None,
-                                    help='Username to access the repository')
-    parser.add_option('--password', dest='password', default=None,
-                                    help='Password to access the repository')
-    parser.add_option('--repository', dest='repository', default='svn',
-                       help='Source control system type [default: %default]')
-    parser.add_option('--dotpath', dest='dotpath', default='/usr/bin/dot',
-                      help="Location of the Graphviz 'dot' executable [default: \
                %default]")
-
-    return parser.parse_args()
-
-def build_zip(build_dir, options):
-    cwd = os.getcwd()
-    nandv = '%s-%s' % (options.name, options.version)
-
-    os.chdir(build_dir)
-
-    args = ['zip', '-9r', '%s.zip' % nandv, nandv]
-    cmd = subprocess.Popen(args)
-    retcode = cmd.wait()
-
-    if retcode != 0:
-        raise RuntimeError, "Error creating zip"
-
-    os.chdir(cwd)
-
-    return os.path.join(build_dir, '%s.zip' % nandv)
-
-def build_tar_gz(build_dir, options):
-    cwd = os.getcwd()
-    nandv = '%s-%s' % (options.name, options.version)
-
-    os.chdir(build_dir)
-
-    args = ['tar', '-cvzf', '%s.tar.gz' % nandv, nandv]
-    cmd = subprocess.Popen(args)
-    retcode = cmd.wait()
-
-    if retcode != 0:
-        raise RuntimeError, "Error creating tar.gz"
-
-    os.chdir(cwd)
-
-    return os.path.join(build_dir, '%s.tar.gz' % nandv)
-
-def build_tar_bz2(build_dir, options):
-    cwd = os.getcwd()
-    nandv = '%s-%s' % (options.name, options.version)
-
-    os.chdir(build_dir)
-
-    args = ['tar', '-cvjf', '%s.tar.bz2' % nandv, nandv]
-    cmd = subprocess.Popen(args)
-    retcode = cmd.wait()
-
-    if retcode != 0:
-        raise RuntimeError, "Error creating tar.bz2"
-
-    os.chdir(cwd)
-
-    return os.path.join(build_dir, '%s.tar.bz2' % nandv)
-
-def clean_package_dir(package_dir):
-    for files in os.walk(package_dir):
-        for f in files[2]:
-            if f.endswith('.pyc') or f.endswith('.so'):
-                os.unlink(os.path.join(files[0], f))
-
-def package_project(src_dir, doc_dir, options):
-    """
-    Builds tar.gz, tar.bz2, zip from the src_dir's
-    """
-    build_dir = tempfile.mkdtemp()
-    package_dir = os.path.join(build_dir, '%s-%s' % (options.name, options.version))
-    shutil.rmtree(os.path.join(src_dir, 'build'))
-    shutil.rmtree(os.path.join(src_dir, '%s.egg-info' % options.name))
-    shutil.copytree(src_dir, package_dir)
-    shutil.copytree(doc_dir, os.path.join(package_dir, 'doc'))
-
-    clean_package_dir(package_dir)
-
-    return build_dir, build_zip(build_dir, options), \
-        build_tar_gz(build_dir, options), build_tar_bz2(build_dir, options)
-
-def md5(fileName, excludeLine="", includeLine=""):
-    """
-    Compute md5 hash of the specified file.
-    """
-    m = hashlib.md5()
-    try:
-        fd = open(fileName, "rb")
-    except IOError:
-        print "Unable to open the file:", filename
-        return
-    content = fd.readlines()
-    fd.close()
-    for eachLine in content:
-        if excludeLine and eachLine.startswith(excludeLine):
-            continue
-        m.update(eachLine)
-    m.update(includeLine)
-
-    return m.hexdigest()
-
-if __name__ == '__main__':
-    options, args = parse_args()
-
-    if options.baseurl is None:
-        raise ValueError, "baseurl is required"
-    if options.name is None:
-        raise ValueError, "project name is required"
-    if options.version is None:
-        raise ValueError, "version is required"
-
-    cwd = os.getcwd()
-    export_dir = export_repo(options)
-    sys.path.insert(0, export_dir)
-    doc_dir = build_docs(options)
-    build_api_docs(export_dir, doc_dir, options)
-
-    build_dir = package_project(export_dir, doc_dir, options)
-    archives = build_dir[1:]
-    build_dir = build_dir[0]
-
-    print '=' * 70
-    for archive in archives:
-        print '%s  ./%s' % (md5(archive), os.path.basename(archive))
-        shutil.copy(os.path.join(build_dir, archive), cwd)
-    print '=' * 70
-
-    shutil.rmtree(export_dir)
-    shutil.rmtree(build_dir)
-    shutil.rmtree(os.path.dirname(api_dir))
-
-    print '\n%s-%s ready.\n' % (options.name, options.version)


Property changes on: pyamf/sandbox/release/release
___________________________________________________________________
Added: svn:ignore
   + *.pyc


Added: pyamf/sandbox/release/release/__init__.py
===================================================================
--- pyamf/sandbox/release/release/__init__.py	                        (rev 0)
+++ pyamf/sandbox/release/release/__init__.py	2009-10-04 15:18:51 UTC (rev 2915)
@@ -0,0 +1,2 @@
+# Copyright (c) 2009 The PyAMF Project.
+# See LICENSE.txt for details.
\ No newline at end of file


Property changes on: pyamf/sandbox/release/release/builds
___________________________________________________________________
Added: svn:ignore
   + *.pyc


Copied: pyamf/sandbox/release/release/builds/__init__.py (from rev 2914, \
pyamf/sandbox/buildbot/pyamf.py) \
                ===================================================================
--- pyamf/sandbox/release/release/builds/__init__.py	                        (rev 0)
+++ pyamf/sandbox/release/release/builds/__init__.py	2009-10-04 15:18:51 UTC (rev \
2915) @@ -0,0 +1,163 @@
+# Copyright (c) 2007-2009 The PyAMF Project.
+# See LICENSE for details.
+
+"""
+Buildsteps for the PyAMF buildmaster.
+
+Requires installation of setuptools and buildbot >= 0.7.11.
+"""
+
+
+import os
+import glob
+
+from release.builds.util import Builder
+
+
+class AppBuilder(Builder):
+    """
+    Builder for PyAMF.
+    """
+
+    def __init__(self, name, slaveName, scm, destFolder, webFolder,
+                 saFolder, sa04='0.4.8', sa05='0.5.0', dumps='dumps.tar.gz',
+                 **kwargs):
+        """
+        @param name: Name of the builder.
+        @type name: C{str}
+        @param slaveName: Name of the buildslave.
+        @type slaveName: C{str}
+        @param scm: Source control buildstep.
+        @type scm: L{buildbot.steps.source.*}
+        @param os: String containing the operating system name.
+        @type os: C{str}
+        @param destFolder: Destination folder on buildmaster for .egg file.
+        @type destFolder: C{str}
+        @param webFolder: Destination folder on buildmaster for nightly file.
+        @type webFolder: C{str}
+        @param saFolder: Source folder on buildmaster with SQLAlchemy tarballs.
+        @type saFolder: C{str}
+        @param sa04: SQLAlchemy 0.4.x version number, ie. '0.4.8'.
+        @type sa04: C{str}
+        @param sa05: SQLAlchemy 0.5.x version number, ie. '0.5.0'.
+        @type sa05: C{str}
+        @param dumps: Name of AMF dumps gzipped tarball.
+        @type dumps: C{str}
+        """
+        self.name = name
+        self.slaveName = slaveName
+        self.scm = scm
+        self.destFolder = destFolder
+        self.webFolder = webFolder
+        self.saFolder = saFolder
+        self.sa04 = sa04
+        self.sa05 = sa05
+        self.dumps = dumps
+        
+        Builder.__init__(self, name, slaveName, scm, name, **kwargs)
+        
+
+    def start(self):
+        """
+        Run the builder.
+        """
+        # Name of gzipped tarball that contains the compiled egg that gets
+        # uploaded from the slave to the master
+        eggTarball = 'pyamf-egg-%s.tar.gz' % (self.name)
+
+        # Checkout source code
+        self.checkout()
+        
+        # Download source to slave for SQLAlchemy 0.4.x and 0.5.x
+        sa_tarball = 'sqlalchemy-%s.tar.gz'
+        sa_path = os.path.join(self.saFolder, sa_tarball)
+        
+        self.download(sa_path % self.sa04, sa_tarball % self.sa04)
+        self.download(sa_path % self.sa05, sa_tarball % self.sa05)
+        self.unpack_sqlalchemy(sa_tarball, self.sa04)
+        self.unpack_sqlalchemy(sa_tarball, self.sa05)
+        
+        # Setup build steps
+        self.compile()
+        self.test()
+        self.install('./install')
+        self.compile(True)
+        self.test(True)
+        self.install('./install', True)
+        self.dist('./build/dist')
+        self.pyflakes('pyamf')
+
+        # Download AMF dumps gzipped tarball to slaves
+        self.download('~/'+self.dumps, self.dumps)
+
+        # Run parser script on AMF dumps
+        self.unpack_dumps(self.dumps)
+        self.parse_dumps()
+
+        # Build .egg file for trunk and upload to the master
+        egg_path = os.path.join(self.destFolder, eggTarball)
+        self.compress_egg(eggTarball)
+        self.upload(eggTarball, egg_path)
+        self.master(['mv ' + egg_path + ' ' + self.webFolder])
+        
+        Builder.start(self)
+
+
+    def unpack_sqlalchemy(self, src, version, **buildstep_kwargs):
+        """
+        Put SQLAlchemy source files in place on the buildslave.
+
+        @param src: Location of the compressed dumps tarball.
+        @type src: C{src}
+        @param version: SQLAlchemy version number, ie. '0.4.8'.
+        @type version: C{str}
+        """
+        if version is None:
+            return
+
+        self.name = 'unpack-sqlalchemy-' + version
+        self.descriptionDone = 'Unpacked SQLAlchemy ' + version
+
+        src = src % version
+
+        return self.decompress(src, **buildstep_kwargs)
+
+
+    def compress_egg(self, src, **buildstep_kwargs):
+        """
+        Compresses the .egg file into a tarball for transfer to the buildmaster.
+        
+        @param src: Location of the tarball.
+        @type src: C{str}
+        """
+        self.name = 'Compress .egg file'
+        self.descriptionDone = 'Compressed .egg file'
+        self.command = ['./build/dist']
+
+        return self.compress(src, **buildstep_kwargs)
+
+
+    def unpack_dumps(self, src, **buildstep_kwargs):
+        """
+        Decompresses the tarball's .amf* dump files.
+        
+        @param src: Location of the dumps tarball.
+        @type src: C{str}
+        """
+        self.name = 'Decompress AMF dump files'
+        self.descriptionDone = 'Decompressed AMF dump files'
+
+        return self.decompress(src, **buildstep_kwargs)
+
+
+    def parse_dumps(self, **buildstep_kwargs):
+        """
+        Run the parse_dump script on the AMF dump files.
+        """
+        self.name = 'Parsing AMF dumps'
+        self.descriptionDone = 'Parsed AMF dumps'
+        script = './build/parse_dump.py'
+        args = ['./build/dumps/*']
+
+        return self.python(script, args, **buildstep_kwargs)
+

Added: pyamf/sandbox/release/release/builds/util.py
===================================================================
--- pyamf/sandbox/release/release/builds/util.py	                        (rev 0)
+++ pyamf/sandbox/release/release/builds/util.py	2009-10-04 15:18:51 UTC (rev 2915)
@@ -0,0 +1,404 @@
+# Copyright (c) 2007-2009 The PyAMF Project.
+# See LICENSE for details.
+
+"""
+Buildbot util.
+"""
+
+import re
+import os
+
+try:
+    from buildbot.process.factory import BuildFactory
+    from buildbot.process.properties import WithProperties
+    from buildbot.status.builder import SUCCESS, FAILURE
+    from buildbot.steps.shell import Compile, Test, ShellCommand
+    from buildbot.steps.master import MasterShellCommand
+    from buildbot.steps.transfer import FileDownload, FileUpload
+    from buildbot.steps.python import PyFlakes
+except ImportError:
+    raise ImportError('This script requires Buildbot 0.7.11 or newer')
+
+
+def getInterpreter(os='unix', version='2.5'):
+    """
+    Get Python or Jython interpreter string.
+    
+    @param os: Builder name containing the operating system name.
+    @type os: C{str}
+    @param version: Version number of interpreter, ie. '2.5'.
+    @type version: C{str}
+    """
+    # unix
+    interpreter = 'python' + version 
+        
+    if re.search('win', os) is not None:
+        # windows-only command
+        interpreter = 'C:\Python%s%s\Python.exe' % (version[0], version[2])
+
+    elif re.search('jython', os) is not None:
+        # Jython
+        interpreter = 'jython'
+
+    return [interpreter]
+
+
+class Builder(object):
+    """
+    """
+
+    def __init__(self, name, slaveName, scm_step, os):
+        """
+        @param name: Name of the builder.
+        @type name: C{str}
+        @param slaveName: Name of the buildslave.
+        @type slaveName: C{str}
+        @param scm_step: Source control buildstep.
+        @type scm_step: L{buildbot.steps.source.*}
+        @param os: String containing the operating system name.
+        @type os: C{str}
+        """
+        self.name = name
+        self.slaveName = slaveName
+        self.scm_step = scm_step
+        self.version = '%s.%s' % (name[-2], name[-1])
+        self.os = os
+        self.command = []
+        self.factory = BuildFactory()
+
+
+    def start(self):
+        """
+        Create and return builder.
+        """
+        b = {'name': self.name,
+             'slavename': self.slaveName,
+             'builddir': self.name,
+             'factory': self.factory,
+        }
+        
+        return b
+
+
+    def slave_step(self, **buildstep_kwargs):
+        """
+        Create slave buildstep.
+        
+        @return: The step.
+        """
+        step = self.type(name=self.name, descriptionDone=self.descriptionDone,
+                         command=self.command, **buildstep_kwargs)
+        
+        self.factory.addStep(step)
+
+
+    def master_step(self, **buildstep_kwargs):
+        """
+        Create master buildstep.
+        
+        @return: The step.
+        """
+        step = MasterShellCommand(name=self.name, command=self.command,
+				  **buildstep_kwargs)
+        
+        self.factory.addStep(step)
+
+
+    def setup_step(self, action, **buildstep_kwargs):
+        """
+        Create Python setuptools step.
+
+        @param action: One of: build, install, test
+        @type action: C{str}
+        """
+        self.name = 'python%s-%s' % (self.version, action)
+        self.descriptionDone = 'python%s %s' % (self.version, action)
+        self.command = getInterpreter(self.os, self.version) + ['./setup.py', \
action, self.command] +
+        if self.ext is not True:
+            self.command.append('--disable-ext')
+
+        return self.slave_step(**buildstep_kwargs)
+
+
+    def decompress(self, file, **buildstep_kwargs):
+        """
+        Decompress a tar file.
+
+        @param file: Name of the tarball file.
+        @type file: C{str}
+
+        @return: A slave step.
+        """
+        self.type = ShellCommand
+        self.name = 'Decompressing %s' % file
+        self.descriptionDone = 'Decompressed %s' % file
+        self.command = ['tar', 'xvf', file]
+        
+        return self.slave_step(**buildstep_kwargs)
+
+
+    def compress(self, file, **buildstep_kwargs):
+        """
+        Compress a tar file with gzip encoding.
+
+        @param file: Name of the output tarball.
+        @type file: C{str}
+
+        @return: A slave step.
+        """
+        self.type = ShellCommand
+        self.name = 'Compressing %s' % file
+        self.descriptionDone = 'Compressed %s' % file
+        self.command = ['tar', 'zcvf', file]
+        
+        return self.slave_step(**buildstep_kwargs)
+
+
+    def compile(self, ext=False, **buildstep_kwargs):
+        """
+        Build the code.
+        
+        @param ext: Enable C-extension build.
+        @type ext: C{bool}
+        """
+        self.type = Compile
+        self.ext = ext
+        self.name = 'Compiling code'
+        self.descriptionDone = 'Compiled code'
+
+        return self.setup_step('build', **buildstep_kwargs)
+
+
+    def test(self, ext=False, **buildstep_kwargs):
+        """
+        Test the code.
+        
+        @param ext: Enable C-extension build.
+        @type ext: C{bool}
+        """
+        self.type = Test
+        self.ext = ext
+        self.name = 'Running unit tests'
+        self.descriptionDone = 'Completed unit tests'
+        #step.evaluateCommand = evaluateCommand
+
+        return self.setup_step('test', **buildstep_kwargs)
+
+
+    def install(self, dest, ext=False, **buildstep_kwargs):
+        """
+        Install the code.
+
+        @param dest: Destination folder for installed files.
+        @type dest: C{str}
+        @param ext: Enable C-extension build.
+        @type ext: C{bool}
+        """
+        self.type = Compile
+        self.ext = ext
+        self.name = 'Installing code to %s' % dest
+        self.descriptionDone = 'Installed code to %s' % dest
+        self.command = ['--root=' + dest]
+        
+        return self.setup_step('install', **buildstep_kwargs)
+
+
+    def dist(self, dest, ext=True, **buildstep_kwargs):
+        """
+        Build platform-specific .egg file.
+
+        @param dest: Destination folder for compiled files.
+        @type dest: C{str}
+        @param ext: Enable C-extension build.
+        @type ext: C{bool}
+        """
+        self.type = ShellCommand
+        self.ext = ext
+        self.name = 'Building .egg in %s' % dest
+        self.descriptionDone = 'Created .egg in %s' % dest
+        self.command = ['--dist-dir=' + dest]
+        
+        return self.setup_step('bdist_egg', **buildstep_kwargs)
+
+
+    def master(self, command, **buildstep_kwargs):
+        """
+        Run a command on the buildmaster.
+
+        @param command: Command to run on the master.
+        @type command: L{}
+        """
+        self.name = 'Publish .egg to web'
+        self.descriptionDone = 'Published .egg to web'
+        self.command = command
+
+        return self.master_step(**buildstep_kwargs)
+
+
+    def python(self, script, args=[], **buildstep_kwargs):
+        """
+        Execute a Python script.
+        
+        @param script: Location of the Python script.
+        @type script: C{str}
+        @param args: Arguments passed to the Python script.
+        @type args: C{list}
+        """
+        self.type = ShellCommand
+        self.command = [getInterpreter(self.os, self.version),
+                        script] + args
+
+        return self.slave_step(**buildstep_kwargs)
+
+
+    def upload(self, src, dest, **buildstep_kwargs):
+        """
+        Transfer a file from the buildslave to the buildmaster.
+        
+        @param src: Location of the file
+        @type src: C{str}
+        @param dest: Target folder on the buildmaster.
+        @type dest: C{str}
+        """
+        self.factory.addStep(FileUpload(slavesrc=src, masterdest=dest, \
**buildstep_kwargs)) +
+
+    def download(self, src, dest, **buildstep_kwargs):
+        """
+        Download a file from the buildmaster to the buildslave.
+        
+        @param src: Location of the file on the master.
+        @type src: C{str}
+        @param dest: Target folder on the slave.
+        @type dest: C{str}
+        """
+        self.factory.addStep(FileDownload(mastersrc=src, slavedest=dest, \
**buildstep_kwargs)) +
+
+    def pyflakes(self, src, **buildstep_kwargs):
+        """
+        Run pyflakes on a Python package or module.
+        
+        @param src: Location of Python module to be checked.
+        @type src: C{str}
+        """
+        self.type = PyFlakes
+        self.name = 'PyFlakes'
+        self.descriptionDone = 'PyFlakes'
+        self.command = ['pyflakes', src]
+
+        return self.slave_step(**buildstep_kwargs)
+
+
+    def checkout(self, **buildstep_kwargs):
+        """
+        Checkout the code.
+        """
+        self.factory.addStep(self.scm)
+
+
+class GAECompile(ShellCommand):
+    """
+    Google App Engine buildstep.
+    """
+
+    def __init__(self, slaveScript=None, **kwargs):
+        """
+        @param slaveScript: Location of the buildslave script.
+        @type slaveScript: C{str}
+        """
+        self.name = 'google-app-engine'
+        self.descriptionDone = 'google-app-engine punit'
+        self.slaveScript = slaveScript
+
+        ShellCommand.__init__(self, **kwargs)
+
+        self.addFactoryArguments(slaveScript=slaveScript)
+
+    def start(self):
+        command = ['python2.5', self.slaveScript]
+
+        if self.getProperty('branch') is not None:
+            command.append(WithProperties('--branch=%(branch)s'))
+
+        self.setCommand(command)
+        ShellCommand.start(self)
+
+
+class GAEBuilder(object):
+    """
+    Google App Engine build factory.
+    """
+
+    def __init__(self, builder, slave, src):
+        """
+        @param builder: Builder name.
+        @type builder: C{str}
+        @param slave: Slave name.
+        @type slave: C{str}
+        @param src: Location of the buildslave script.
+        @type src: C{str}
+        """
+        self.builder = builder
+        self.slave = slave
+        self.script = src
+
+
+    def createBuilder(self):
+        """
+        Create and return the builder.
+        
+        @return: The Google App Engine builder.
+        @rtype: L{BuildFactory}
+        """
+        compile = GAECompile(slaveScript=self.script)
+
+        f = factory.BuildFactory()
+        f.addStep(compile)
+
+        b = {'name': self.builder,
+             'slavename': self.slave,
+             'builddir': self.builder,
+             'factory': f,
+        }
+
+        return b
+
+
+def evaluateCommand(cmd):
+    r = Test.evaluateCommand(self, cmd)
+
+    if r is FAILURE:
+        return r
+
+    lines = self.getLog('stdio').readlines()
+
+    re_test_result = re.compile("FAILED \((failures=(\d*), )?(errors=(\d*), \
)?successes=(\d*)\)") +
+    mos = map(lambda line: re_test_result.search(line), lines)
+    test_result_lines = [mo.groups() for mo in mos if mo]
+
+    if not test_result_lines:
+        return cmd.rc
+
+    results = test_result_lines[0]
+
+    failures = errors = passed = 0
+
+    if results[1] is not None:
+        failures = int(results[1])
+
+    if results[3] is not None:
+        errors = int(results[3])
+
+    passed = int(results[4])
+
+    if [failures, errors] == [0, 0]:
+        rc = SUCCESS
+    else:
+        rc = FAILURE
+
+    self.setTestResults(total=failures + errors + passed, failed=failures + errors, \
passed=passed) +
+    return rc

Copied: pyamf/sandbox/release/release/package.py (from rev 2913, \
pyamf/sandbox/release/package.py) \
                ===================================================================
--- pyamf/sandbox/release/release/package.py	                        (rev 0)
+++ pyamf/sandbox/release/release/package.py	2009-10-04 15:18:51 UTC (rev 2915)
@@ -0,0 +1,273 @@
+#!/usr/local/bin/python
+
+# Copyright (c) 2007-2009 The PyAMF Project.
+# See LICENSE for details.
+
+"""
+A basic release builder.
+
+Example usage:
+  python package.py --version=0.3 --name=PyAMF \
--baseurl=http://svn.pyamf.org/pyamf/tags --branch=release-0.3 +
+For more help try:
+  python package.py --help
+"""
+
+import os, os.path, sys, shutil
+import subprocess, tempfile
+import hashlib
+
+def export_svn(url, options):
+    print
+    print 'Checking out: %s\n' % url
+
+    args = ['svn', 'export']
+
+    args.append(url)
+
+    if options.username is not None:
+        args.append('--username %s' % options.username)
+
+    if options.password is not None:
+        args.append('--password %s' % options.password)
+
+    args.append('--force')
+    export_dir = tempfile.mkdtemp()
+    args.append(export_dir)
+
+    cmd = subprocess.Popen(args)
+    retcode = cmd.wait()
+
+    return retcode, cmd, export_dir
+
+def export_repo(options):
+    repo_url = '%s/%s' % (options.baseurl, options.branch)
+
+    if options.repository == 'svn':
+        retcode, cmd, export_dir = export_svn(repo_url, options)
+    else:
+        raise ValueError, "Unknown repository type %s" % options.repository
+
+    if retcode != 0:
+        raise RuntimeError, "Problem exporting repository"
+
+    return export_dir
+
+def build_ext(src_dir):
+    cwd = os.getcwd()
+    os.chdir(src_dir)
+
+    args = ["python", "setup.py", "develop"]
+
+    cmd = subprocess.Popen(args)
+    retcode = cmd.wait()
+
+    if retcode != 0:
+        raise RuntimeError, "Error building extension"
+
+    os.chdir(cwd)
+
+def build_api_docs(src_dir, doc_dir, options):
+    # create .so files for epydoc
+    build_ext(export_dir)
+
+    # generate html doc from rst file
+    args = ["rst2html.py", os.path.join(src_dir, "CHANGES.txt"),
+            os.path.join(doc_dir, "changes.html")]
+
+    cmd = subprocess.Popen(args)
+    retcode = cmd.wait()
+
+    # generate API documentation
+    args = ["epydoc", "--config=" +
+        os.path.join(src_dir, "setup.cfg"), "-v",
+        "--graph=umlclasstree", "--dotpath=" + options.dotpath,
+        "--help-file=" + os.path.join(doc_dir, "changes.html")]
+
+    cmd = subprocess.Popen(args)
+    retcode = cmd.wait()
+
+    if retcode != 0:
+        raise RuntimeError, "Error building API docs"
+
+    # the --output override for epydoc doesn't work
+    # so copy the files and get rid of the old default
+    # output destination folder
+    temp_doc = os.path.join(os.getcwd(), "docs")
+    shutil.copytree(temp_doc, os.path.join(doc_dir, "api"))
+    shutil.rmtree(temp_doc)
+
+
+def build_docs(options):
+    # create .so files for epydoc
+    doc_url = 'https://svn.pyamf.org/doc/tags/release-%s' % (options.version)
+    retcode, cmd, export_dir = export_svn(doc_url, options)
+
+    args = ["make", "html"]
+
+    if retcode != 0:
+        raise RuntimeError, "Problem exporting repository"
+
+    cmd = subprocess.Popen(args, cwd=export_dir)
+    retcode = cmd.wait()
+
+    if retcode != 0:
+        raise RuntimeError, "Error building docs"
+
+    doc_dir = tempfile.mkdtemp()
+    shutil.rmtree(doc_dir)
+    temp_doc = os.path.join(export_dir, "_build", 'html')
+    shutil.copytree(temp_doc, doc_dir)
+
+    return doc_dir
+
+def parse_args():
+    def parse_targets(option, opt, value, parser):
+        print value
+
+    from optparse import OptionParser
+
+    parser = OptionParser()
+
+    parser.add_option('--baseurl', dest='baseurl',
+                      help='Root URL of the source control system')
+    parser.add_option('--branch', dest='branch', default='trunk',
+                      help='Name of the target folder in the source control system \
[default: %default]') +    parser.add_option('--version', dest='version',
+                      help='The version number of the project')
+    parser.add_option('--name', dest='name', help='The name of the project')
+    parser.add_option('--username', dest='username', default=None,
+                                    help='Username to access the repository')
+    parser.add_option('--password', dest='password', default=None,
+                                    help='Password to access the repository')
+    parser.add_option('--repository', dest='repository', default='svn',
+                       help='Source control system type [default: %default]')
+    parser.add_option('--dotpath', dest='dotpath', default='/usr/bin/dot',
+                      help="Location of the Graphviz 'dot' executable [default: \
%default]") +
+    return parser.parse_args()
+
+def build_zip(build_dir, options):
+    cwd = os.getcwd()
+    nandv = '%s-%s' % (options.name, options.version)
+
+    os.chdir(build_dir)
+
+    args = ['zip', '-9r', '%s.zip' % nandv, nandv]
+    cmd = subprocess.Popen(args)
+    retcode = cmd.wait()
+
+    if retcode != 0:
+        raise RuntimeError, "Error creating zip"
+
+    os.chdir(cwd)
+
+    return os.path.join(build_dir, '%s.zip' % nandv)
+
+def build_tar_gz(build_dir, options):
+    cwd = os.getcwd()
+    nandv = '%s-%s' % (options.name, options.version)
+
+    os.chdir(build_dir)
+
+    args = ['tar', '-cvzf', '%s.tar.gz' % nandv, nandv]
+    cmd = subprocess.Popen(args)
+    retcode = cmd.wait()
+
+    if retcode != 0:
+        raise RuntimeError, "Error creating tar.gz"
+
+    os.chdir(cwd)
+
+    return os.path.join(build_dir, '%s.tar.gz' % nandv)
+
+def build_tar_bz2(build_dir, options):
+    cwd = os.getcwd()
+    nandv = '%s-%s' % (options.name, options.version)
+
+    os.chdir(build_dir)
+
+    args = ['tar', '-cvjf', '%s.tar.bz2' % nandv, nandv]
+    cmd = subprocess.Popen(args)
+    retcode = cmd.wait()
+
+    if retcode != 0:
+        raise RuntimeError, "Error creating tar.bz2"
+
+    os.chdir(cwd)
+
+    return os.path.join(build_dir, '%s.tar.bz2' % nandv)
+
+def clean_package_dir(package_dir):
+    for files in os.walk(package_dir):
+        for f in files[2]:
+            if f.endswith('.pyc') or f.endswith('.so'):
+                os.unlink(os.path.join(files[0], f))
+
+def package_project(src_dir, doc_dir, options):
+    """
+    Builds tar.gz, tar.bz2, zip from the src_dir's
+    """
+    build_dir = tempfile.mkdtemp()
+    package_dir = os.path.join(build_dir, '%s-%s' % (options.name, options.version))
+    shutil.rmtree(os.path.join(src_dir, 'build'))
+    shutil.rmtree(os.path.join(src_dir, '%s.egg-info' % options.name))
+    shutil.copytree(src_dir, package_dir)
+    shutil.copytree(doc_dir, os.path.join(package_dir, 'doc'))
+
+    clean_package_dir(package_dir)
+
+    return build_dir, build_zip(build_dir, options), \
+        build_tar_gz(build_dir, options), build_tar_bz2(build_dir, options)
+
+def md5(fileName, excludeLine="", includeLine=""):
+    """
+    Compute md5 hash of the specified file.
+    """
+    m = hashlib.md5()
+    try:
+        fd = open(fileName, "rb")
+    except IOError:
+        print "Unable to open the file:", filename
+        return
+    content = fd.readlines()
+    fd.close()
+    for eachLine in content:
+        if excludeLine and eachLine.startswith(excludeLine):
+            continue
+        m.update(eachLine)
+    m.update(includeLine)
+
+    return m.hexdigest()
+
+if __name__ == '__main__':
+    options, args = parse_args()
+
+    if options.baseurl is None:
+        raise ValueError, "baseurl is required"
+    if options.name is None:
+        raise ValueError, "project name is required"
+    if options.version is None:
+        raise ValueError, "version is required"
+
+    cwd = os.getcwd()
+    export_dir = export_repo(options)
+    sys.path.insert(0, export_dir)
+    doc_dir = build_docs(options)
+    build_api_docs(export_dir, doc_dir, options)
+
+    build_dir = package_project(export_dir, doc_dir, options)
+    archives = build_dir[1:]
+    build_dir = build_dir[0]
+
+    print '=' * 70
+    for archive in archives:
+        print '%s  ./%s' % (md5(archive), os.path.basename(archive))
+        shutil.copy(os.path.join(build_dir, archive), cwd)
+    print '=' * 70
+
+    shutil.rmtree(export_dir)
+    shutil.rmtree(build_dir)
+    shutil.rmtree(os.path.dirname(api_dir))
+
+    print '\n%s-%s ready.\n' % (options.name, options.version)

Added: pyamf/sandbox/release/setup.py
===================================================================
--- pyamf/sandbox/release/setup.py	                        (rev 0)
+++ pyamf/sandbox/release/setup.py	2009-10-04 15:18:51 UTC (rev 2915)
@@ -0,0 +1,33 @@
+# Copyright (c) 2009 The PyAMF Project.
+# See LICENSE.txt for details.
+
+from ez_setup import use_setuptools
+
+use_setuptools()
+
+import sys, os.path
+from setuptools import setup, find_packages
+
+
+def get_version():
+    """
+    Gets the version number. Pulls it from the source files rather than
+    duplicating it.
+    """
+    # we read the file instead of importing it as root sometimes does not
+    # have the cwd as part of the PYTHONPATH
+    from pyamf import __version__ as version
+
+    return '.'.join([str(x) for x in version])
+
+
+setup(name = "PyAMF Release Scripts",
+    version = get_version(),
+    description = "Tools and scripts for the PyAMF release process",
+    url = "http://pyamf.org",
+    author = "The PyAMF Project",
+    author_email = "users@pyamf.org",
+    packages = find_packages(exclude=["*.tests"]),
+    zip_safe = True,
+    license = "MIT License",
+    platforms = ["any"])

_______________________________________________
PyAMF commits mailing list - commits@pyamf.org
http://lists.pyamf.org/mailman/listinfo/commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic