appypod-rattail/bin/generate.py
2011-12-05 15:11:29 +01:00

94 lines
4.6 KiB
Python

'''This script allows to generate a 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
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, ' \
'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.'
class GeneratorScript:
'''usage: %prog [options] app outputFolder
"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.
"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.
'''
def manageArgs(self, parser, options, args):
# Check number of args
if len(args) != 2:
print WRONG_NG_OF_ARGS
parser.print_help()
sys.exit(ERROR_CODE)
# Check existence of application
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])
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)
(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()
# Give the user some statistics about its code
LinesCounter(args[0]).run()
except GeneratorError, ge:
sys.stderr.write(str(ge))
sys.stderr.write('\n')
optParser.print_help()
sys.exit(ERROR_CODE)
# ------------------------------------------------------------------------------
if __name__ == '__main__':
GeneratorScript().run()
# ------------------------------------------------------------------------------