appy.bin: generate.py: one less arg: outputFolder has been removed (the script now generates the Zope product in <appFolder>/zope); generate.py: new option '-d', for generating a Debian package from the Python (Appy) app.

This commit is contained in:
Gaetan Delannay 2012-01-18 14:27:24 +01:00
parent a89d65afc6
commit 13443ea79e
5 changed files with 171 additions and 121 deletions

View file

@ -1,17 +1,17 @@
'''This script allows to generate a product from a Appy application.'''
'''This script allows to generate a Zope product from a Appy application.'''
# ------------------------------------------------------------------------------
import sys, os.path
from optparse import OptionParser
from appy.gen.generator import GeneratorError, ZopeGenerator
from appy.shared.utils import LinesCounter
from appy.shared.packaging import Debianizer
import appy.version
# ------------------------------------------------------------------------------
ERROR_CODE = 1
APP_NOT_FOUND = 'Application not found at %s.'
WRONG_NG_OF_ARGS = 'Wrong number of arguments.'
WRONG_OUTPUT_FOLDER = 'Output folder not found. Please create it first.'
C_OPTION = 'Removes from i18n files all labels that are not automatically ' \
'generated from your gen-application. It can be useful during ' \
'development, when you do lots of name changes (classes, ' \
@ -32,26 +32,24 @@ S_OPTION = 'Sorts all i18n labels. If you use this option, among the ' \
'i18n file. When the development is finished, it may be a good ' \
'idea to sort the labels to get a clean and logically ordered ' \
'set of translation files.'
D_OPTION = 'Generates a Debian package for this app. The Debian package will ' \
'be generated at the same level as the root application folder.'
class GeneratorScript:
'''usage: %prog [options] app outputFolder
'''usage: %prog [options] app
"app" is the path to your Appy application, which must be a
Python package (= a folder containing a file named
__init__.py). Your app may reside anywhere, but needs to
be accessible by Zope. Typically, it may be or symlinked
in <yourZopeInstance>/lib/python, but not within the
generated product, stored or symlinked in
<yourZopeInstance>/Products.
in <yourZopeInstance>/lib/python.
"outputFolder" is the folder where the Zope product will be generated.
For example, if you develop your application in
/home/gdy/MyProject/MyProject, you typically specify
"/home/gdy/MyProject/zope" as outputFolder.
This command generates a Zope product in <app>/zope, which must be
or symlinked in <yourZopeInstance>/Products.
'''
def manageArgs(self, parser, options, args):
# Check number of args
if len(args) != 2:
if len(args) != 1:
print WRONG_NG_OF_ARGS
parser.print_help()
sys.exit(ERROR_CODE)
@ -59,13 +57,8 @@ class GeneratorScript:
if not os.path.exists(args[0]):
print APP_NOT_FOUND % args[0]
sys.exit(ERROR_CODE)
# Check existence of outputFolder
if not os.path.exists(args[1]):
print WRONG_OUTPUT_FOLDER
sys.exit(ERROR_CODE)
# Convert all paths in absolute paths
for i in (0,1):
args[i] = os.path.abspath(args[i])
# Convert app path to an absolute path
args[0] = os.path.abspath(args[0])
def run(self):
optParser = OptionParser(usage=GeneratorScript.__doc__)
@ -73,14 +66,26 @@ class GeneratorScript:
dest='i18nClean', default=False, help=C_OPTION)
optParser.add_option("-s", "--i18n-sort", action='store_true',
dest='i18nSort', default=False, help=S_OPTION)
optParser.add_option("-d", "--debian", action='store_true',
dest='debian', default=False, help=D_OPTION)
(options, args) = optParser.parse_args()
try:
self.manageArgs(optParser, options, args)
print 'Appy version:', appy.version.verbose
print 'Generating Zope product in %s...' % args[1]
ZopeGenerator(args[0], args[1], options).run()
print 'Generating Zope product in %s/zope...' % args[0]
ZopeGenerator(args[0], options).run()
# Give the user some statistics about its code
LinesCounter(args[0]).run()
LinesCounter(args[0], excludes=['%szope' % os.sep]).run()
# Generates a Debian package for this app if required
if options.debian:
app = args[0]
appDir = os.path.dirname(app)
# Get the app version from zope/version.txt
f = file(os.path.join(app, 'zope', 'version.txt'))
version = f.read()
f.close()
version = version[:version.find('build')-1]
Debianizer(app, appDir, appVersion=version).run()
except GeneratorError, ge:
sys.stderr.write(str(ge))
sys.stderr.write('\n')

View file

@ -1,9 +1,10 @@
#!/usr/bin/python
# Imports ----------------------------------------------------------------------
import os, os.path, sys, shutil, re, zipfile, sys, ftplib, time, subprocess, md5
import os, os.path, sys, shutil, re, zipfile, sys, ftplib, time
import appy
from appy.shared import appyPath
from appy.shared.utils import FolderDeleter, LinesCounter
from appy.shared.packaging import Debianizer
from appy.bin.clean import Cleaner
from appy.gen.utils import produceNiceMessage
@ -26,34 +27,6 @@ recursive-include appy/gen *
recursive-include appy/pod *
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():
print 'Login: ',
login = sys.stdin.readline().strip()
@ -242,9 +215,6 @@ class Text2Html:
class Publisher:
'''Publishes Appy on the web.'''
pageBody = re.compile('<body.*?>(.*)</body>', re.S)
eggVersion = re.compile('version\s*=\s*".*?"')
pythonTargets = ('2.4', '2.5')
svnServer = 'http://svn.communesplone.org/svn/communesplone/appy'
def __init__(self):
self.genFolder = '%s/temp' % appyPath
@ -303,66 +273,9 @@ class Publisher:
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)
j = os.path.join
Debianizer(j(self.genFolder, 'appy'), j(appyPath, 'versions'),
appVersion=self.versionShort).run()
def createDistRelease(self):
'''Create the distutils package.'''