[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