appy.bin: publish.py is now able to generate a Debian package for Appy, working with Python 2.6 and Python 2.7; new.py contains optimized code for generating a non-buildout Zope 2.13/Plone4 instance.

This commit is contained in:
Gaetan Delannay 2011-12-22 16:46:09 +01:00
parent 6ece750d9a
commit 29f92e401e
2 changed files with 119 additions and 8 deletions

View file

@ -44,6 +44,23 @@ export PYTHON
export PYTHONPATH export PYTHONPATH
exec "$PYTHON" "$ZOPE_RUN" -C "$CONFIG_FILE" "$@" exec "$PYTHON" "$ZOPE_RUN" -C "$CONFIG_FILE" "$@"
''' '''
pkgResourcesPatch = '''import os, os.path
productsFolder = os.path.join(os.environ["INSTANCE_HOME"], "Products")
for name in os.listdir(productsFolder):
if os.path.isdir(os.path.join(productsFolder, name)):
if name not in appyVersions:
appyVersions[name] = "1.0"
appyVersions['Products.%s' % name] = "1.0"
def getAppyVersion(req, location):
global appyVersions
if req.project_name not in appyVersions:
raise DistributionNotFound(req)
return Distribution(project_name=req.project_name,
version=appyVersions[req.project_name],
platform='linux2', location=location)
'''
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
class NewScript: class NewScript:
'''usage: %prog ploneVersion plonePath instancePath '''usage: %prog ploneVersion plonePath instancePath
@ -131,12 +148,10 @@ class NewScript:
sVersions = 'appyVersions = {' + ','.join(dVersions) + '}' sVersions = 'appyVersions = {' + ','.join(dVersions) + '}'
codeFile = "%s/pkg_resources.py" % self.libFolder codeFile = "%s/pkg_resources.py" % self.libFolder
f = file(codeFile) f = file(codeFile)
content = sVersions + '\n' + f.read() content = f.read().replace("raise DistributionNotFound(req)",
"dist = getAppyVersion(req, '%s')" % self.instancePath)
content = sVersions + '\n' + pkgResourcesPatch + '\n' + content
f.close() f.close()
content = content.replace("raise DistributionNotFound(req)",
"dist = Distribution(project_name=req.project_name, " \
"version=appyVersions[req.project_name], platform='linux2', " \
"location='%s')" % self.instancePath)
f = file(codeFile, 'w') f = file(codeFile, 'w')
f.write(content) f.write(content)
f.close() f.close()
@ -163,6 +178,8 @@ class NewScript:
if name == 'EGG-INFO': continue if name == 'EGG-INFO': continue
splittedName = name.split('-') splittedName = name.split('-')
res[splittedName[0]] = splittedName[1] res[splittedName[0]] = splittedName[1]
if splittedName[0].startswith('Products.'):
res[splittedName[0][9:]] = splittedName[1]
absName = j(eggsFolder, name) absName = j(eggsFolder, name)
# Copy every file or sub-folder into self.libFolder or # Copy every file or sub-folder into self.libFolder or
# self.productsFolder. # self.productsFolder.

View file

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
# Imports ---------------------------------------------------------------------- # Imports ----------------------------------------------------------------------
import os, os.path, sys, shutil, re, zipfile, sys, ftplib, time import os, os.path, sys, shutil, re, zipfile, sys, ftplib, time, subprocess, md5
import appy import appy
from appy.shared import appyPath from appy.shared import appyPath
from appy.shared.utils import FolderDeleter, LinesCounter from appy.shared.utils import FolderDeleter, LinesCounter
@ -26,6 +26,33 @@ recursive-include appy/gen *
recursive-include appy/pod * recursive-include appy/pod *
recursive-include appy/shared * recursive-include appy/shared *
''' '''
debianInfo = '''Package: python-appy
Version: %s
Architecture: all
Maintainer: Gaetan Delannay <gaetan.delannay@geezteem.com>
Installed-Size: %d
Depends: python (>= 2.6), python (<< 3.0)
Section: python
Priority: optional
Homepage: http://appyframework.org
Description: Appy builds simple but complex web Python apps.
'''
debianPostInst = '''#!/bin/sh
set -e
if [ -e /usr/bin/python2.6 ]
then
/usr/bin/python2.6 -m compileall -q /usr/lib/python2.6/appy 2> /dev/null
fi
if [ -e /usr/bin/python2.7 ]
then
/usr/bin/python2.7 -m compileall -q /usr/lib/python2.7/appy 2> /dev/null
fi
'''
debianPreRm = '''#!/bin/sh
set -e
find /usr/lib/python2.6/appy -name "*.pyc" -delete
find /usr/lib/python2.7/appy -name "*.pyc" -delete
'''
def askLogin(): def askLogin():
print 'Login: ', print 'Login: ',
@ -274,6 +301,69 @@ class Publisher:
for prefix in self.distExcluded: for prefix in self.distExcluded:
if name.startswith(prefix): return True if name.startswith(prefix): return True
def createDebianRelease(self):
'''Creates a Debian package for Appy.'''
curdir = os.getcwd()
# Create a temp folder for creating the Debian files hierarchy.
srcFolder = os.path.join(self.genFolder, 'debian', 'usr', 'lib')
os.makedirs(os.path.join(srcFolder, 'python2.6'))
os.makedirs(os.path.join(srcFolder, 'python2.7'))
# Copy Appy sources in it
py26 = os.path.join(srcFolder, 'python2.6', 'appy')
os.rename(os.path.join(self.genFolder, 'appy'), py26)
shutil.copytree(py26, os.path.join(srcFolder, 'python2.7', 'appy'))
# Create data.tar.gz based on it.
debFolder = os.path.join(self.genFolder, 'debian')
os.chdir(debFolder)
os.system('tar czvf data.tar.gz ./usr')
# Get the size of Appy, in Kb.
cmd = subprocess.Popen(['du', '-b', '-s', 'usr'],stdout=subprocess.PIPE)
size = int(int(cmd.stdout.read().split()[0])/1024.0)
# Create control file
f = file('control', 'w')
f.write(debianInfo % (self.versionShort, size))
f.close()
# Create md5sum file
f = file('md5sums', 'w')
for dir, dirnames, filenames in os.walk('usr'):
for name in filenames:
m = md5.new()
pathName = os.path.join(dir, name)
currentFile = file(pathName, 'rb')
while True:
data = currentFile.read(8096)
if not data:
break
m.update(data)
currentFile.close()
# Add the md5 sum to the file
f.write('%s %s\n' % (m.hexdigest(), pathName))
f.close()
# Create postinst and prerm
f = file('postinst', 'w')
f.write(debianPostInst)
f.close()
f = file('prerm', 'w')
f.write(debianPreRm)
f.close()
# Create control.tar.gz
os.system('tar czvf control.tar.gz ./control ./md5sums ./postinst ' \
'./prerm')
# Create debian-binary
f = file('debian-binary', 'w')
f.write('2.0\n')
f.close()
# Create the .deb package
debName = 'python-appy-%s.deb' % self.versionShort
os.system('ar -r %s debian-binary control.tar.gz data.tar.gz' % \
debName)
os.chdir(curdir)
# Move it to folder "versions".
os.rename(os.path.join(debFolder, debName),
os.path.join(appyPath, 'versions', debName))
# Clean temp files
FolderDeleter.delete(debFolder)
def createDistRelease(self): def createDistRelease(self):
'''Create the distutils package.''' '''Create the distutils package.'''
curdir = os.getcwd() curdir = os.getcwd()
@ -299,12 +389,15 @@ class Publisher:
# Create the source distribution # Create the source distribution
os.chdir(distFolder) os.chdir(distFolder)
self.executeCommand('python setup.py sdist') self.executeCommand('python setup.py sdist')
# DistUtils has created the .tar.gz file. Copy it into folder "versions" # DistUtils has created the .tar.gz file. Move it to folder "versions"
name = 'appy-%s.tar.gz' % self.versionShort name = 'appy-%s.tar.gz' % self.versionShort
os.rename('%s/dist/%s' % (distFolder, name), os.rename('%s/dist/%s' % (distFolder, name),
'%s/versions/%s' % (appyPath, name)) '%s/versions/%s' % (appyPath, name))
# Clean temp files # Clean temp files
os.chdir(curdir) os.chdir(curdir)
# Keep the Appy source for building the Debian package afterwards
os.rename(os.path.join(self.genFolder, 'dist', 'appy'), \
os.path.join(self.genFolder, 'appy'))
FolderDeleter.delete(os.path.join(self.genFolder, 'dist')) FolderDeleter.delete(os.path.join(self.genFolder, 'dist'))
return name return name
@ -314,7 +407,7 @@ class Publisher:
def createZipRelease(self): def createZipRelease(self):
'''Creates a zip file with the appy sources.''' '''Creates a zip file with the appy sources.'''
newZipRelease = '%s/versions/appy%s.zip' % (appyPath, self.versionShort) newZipRelease = '%s/versions/appy-%s.zip' % (appyPath,self.versionShort)
if os.path.exists(newZipRelease): if os.path.exists(newZipRelease):
if not self.askQuestion('"%s" already exists. Replace it?' % \ if not self.askQuestion('"%s" already exists. Replace it?' % \
newZipRelease, default='yes'): newZipRelease, default='yes'):
@ -469,6 +562,7 @@ class Publisher:
self.applyTemplate() self.applyTemplate()
self.createZipRelease() self.createZipRelease()
tarball = self.createDistRelease() tarball = self.createDistRelease()
self.createDebianRelease()
if self.askQuestion('Upload %s on PyPI?' % tarball, default='no'): if self.askQuestion('Upload %s on PyPI?' % tarball, default='no'):
self.uploadOnPypi(tarball) self.uploadOnPypi(tarball)
if self.askQuestion('Publish on appyframework.org?', default='no'): if self.askQuestion('Publish on appyframework.org?', default='no'):