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:
		
							parent
							
								
									a89d65afc6
								
							
						
					
					
						commit
						13443ea79e
					
				
					 5 changed files with 171 additions and 121 deletions
				
			
		|  | @ -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') | ||||
|  |  | |||
|  | @ -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.''' | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Gaetan Delannay
						Gaetan Delannay