2012-01-18 07:27:24 -06:00
|
|
|
'''This script allows to generate a Zope product from a Appy application.'''
|
2009-12-01 13:36:59 -06:00
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
import sys, os.path
|
|
|
|
from optparse import OptionParser
|
2011-12-05 08:11:29 -06:00
|
|
|
from appy.gen.generator import GeneratorError, ZopeGenerator
|
2010-10-14 07:43:56 -05:00
|
|
|
from appy.shared.utils import LinesCounter
|
2012-02-14 05:52:36 -06:00
|
|
|
from appy.shared.packaging import Debianizer, Cortexer
|
2011-09-26 14:19:34 -05:00
|
|
|
import appy.version
|
2009-12-01 13:36:59 -06:00
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
ERROR_CODE = 1
|
|
|
|
APP_NOT_FOUND = 'Application not found at %s.'
|
|
|
|
WRONG_NG_OF_ARGS = 'Wrong number of arguments.'
|
|
|
|
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, ' \
|
|
|
|
'attributes, states, transitions, etc): in this case, the Appy ' \
|
|
|
|
'i18n label generation machinery produces lots of labels that ' \
|
|
|
|
'then become obsolete.'
|
|
|
|
S_OPTION = 'Sorts all i18n labels. If you use this option, among the ' \
|
|
|
|
'generated i18n files, you will find first all labels ' \
|
|
|
|
'that are automatically generated by appy.gen, in some logical ' \
|
|
|
|
'order (ie: field-related labels appear together, in the order ' \
|
|
|
|
'they are declared in the gen-class). Then, if you have added ' \
|
|
|
|
'labels manually, they will appear afterwards. Sorting labels ' \
|
|
|
|
'may not be desired under development. Indeed, when no sorting ' \
|
|
|
|
'occurs, every time you add or modify a field, class, state, etc, ' \
|
|
|
|
'newly generated labels will all appear together at the end of ' \
|
|
|
|
'the file; so it will be easy to translate them all. When sorting ' \
|
|
|
|
'occurs, those elements may be spread at different places in 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.'
|
2012-01-18 07:27:24 -06:00
|
|
|
D_OPTION = 'Generates a Debian package for this app. The Debian package will ' \
|
|
|
|
'be generated at the same level as the root application folder.'
|
2012-02-14 05:52:36 -06:00
|
|
|
X_OPTION = 'Generates a Cortex application definition for this app, in a ' \
|
|
|
|
'folder "cortex.admin" that will be generated at the same level ' \
|
|
|
|
'as the root application folder.'
|
2009-12-01 13:36:59 -06:00
|
|
|
|
|
|
|
class GeneratorScript:
|
2012-01-18 07:27:24 -06:00
|
|
|
'''usage: %prog [options] app
|
2009-12-01 13:36:59 -06:00
|
|
|
|
2011-12-05 03:52:18 -06:00
|
|
|
"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
|
2012-01-18 07:27:24 -06:00
|
|
|
in <yourZopeInstance>/lib/python.
|
2009-12-01 13:36:59 -06:00
|
|
|
|
2012-01-18 07:27:24 -06:00
|
|
|
This command generates a Zope product in <app>/zope, which must be
|
|
|
|
or symlinked in <yourZopeInstance>/Products.
|
2011-12-05 03:52:18 -06:00
|
|
|
'''
|
2009-12-01 13:36:59 -06:00
|
|
|
def manageArgs(self, parser, options, args):
|
|
|
|
# Check number of args
|
2012-01-18 07:27:24 -06:00
|
|
|
if len(args) != 1:
|
2013-05-29 17:46:11 -05:00
|
|
|
print(WRONG_NG_OF_ARGS)
|
2009-12-01 13:36:59 -06:00
|
|
|
parser.print_help()
|
|
|
|
sys.exit(ERROR_CODE)
|
|
|
|
# Check existence of application
|
|
|
|
if not os.path.exists(args[0]):
|
2013-05-29 17:46:11 -05:00
|
|
|
print(APP_NOT_FOUND % args[0])
|
2009-12-01 13:36:59 -06:00
|
|
|
sys.exit(ERROR_CODE)
|
2012-01-18 07:27:24 -06:00
|
|
|
# Convert app path to an absolute path
|
|
|
|
args[0] = os.path.abspath(args[0])
|
2011-12-05 08:11:29 -06:00
|
|
|
|
2009-12-01 13:36:59 -06:00
|
|
|
def run(self):
|
|
|
|
optParser = OptionParser(usage=GeneratorScript.__doc__)
|
|
|
|
optParser.add_option("-c", "--i18n-clean", action='store_true',
|
|
|
|
dest='i18nClean', default=False, help=C_OPTION)
|
|
|
|
optParser.add_option("-s", "--i18n-sort", action='store_true',
|
|
|
|
dest='i18nSort', default=False, help=S_OPTION)
|
2012-01-18 07:27:24 -06:00
|
|
|
optParser.add_option("-d", "--debian", action='store_true',
|
|
|
|
dest='debian', default=False, help=D_OPTION)
|
2012-02-14 05:52:36 -06:00
|
|
|
optParser.add_option("-x", "--cortex", action='store_true',
|
|
|
|
dest='cortex', default=False, help=X_OPTION)
|
2009-12-01 13:36:59 -06:00
|
|
|
(options, args) = optParser.parse_args()
|
|
|
|
try:
|
|
|
|
self.manageArgs(optParser, options, args)
|
2013-05-29 17:46:11 -05:00
|
|
|
print('Appy version: %s' % appy.version.verbose)
|
|
|
|
print('Generating Zope product in %s/zope...' % args[0])
|
2012-01-18 07:27:24 -06:00
|
|
|
ZopeGenerator(args[0], options).run()
|
2010-10-14 07:43:56 -05:00
|
|
|
# Give the user some statistics about its code
|
2012-01-18 07:27:24 -06:00
|
|
|
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)
|
2012-02-02 10:30:54 -06:00
|
|
|
appName = os.path.basename(app)
|
2012-01-18 07:27:24 -06:00
|
|
|
# Get the app version from zope/version.txt
|
2012-02-02 10:30:54 -06:00
|
|
|
f = file(os.path.join(app, 'zope', appName, 'version.txt'))
|
2012-01-18 07:27:24 -06:00
|
|
|
version = f.read()
|
|
|
|
f.close()
|
|
|
|
version = version[:version.find('build')-1]
|
|
|
|
Debianizer(app, appDir, appVersion=version).run()
|
2012-02-14 05:52:36 -06:00
|
|
|
# Generates a Cortex application definition if required
|
|
|
|
if options.cortex:
|
|
|
|
Cortexer(args[0]).run()
|
2009-12-01 13:36:59 -06:00
|
|
|
except GeneratorError, ge:
|
|
|
|
sys.stderr.write(str(ge))
|
|
|
|
sys.stderr.write('\n')
|
|
|
|
optParser.print_help()
|
|
|
|
sys.exit(ERROR_CODE)
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
if __name__ == '__main__':
|
|
|
|
GeneratorScript().run()
|
|
|
|
# ------------------------------------------------------------------------------
|