Imported from SVN by Bitbucket
This commit is contained in:
278
PasteScript-1.7.4.2-py2.6.egg/paste/script/templates.py
Executable file
278
PasteScript-1.7.4.2-py2.6.egg/paste/script/templates.py
Executable file
@@ -0,0 +1,278 @@
|
||||
# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
|
||||
# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
|
||||
import sys
|
||||
import os
|
||||
import inspect
|
||||
import copydir
|
||||
import command
|
||||
|
||||
from paste.util.template import paste_script_template_renderer
|
||||
|
||||
class Template(object):
|
||||
|
||||
# Subclasses must define:
|
||||
# _template_dir (or template_dir())
|
||||
# summary
|
||||
|
||||
# Variables this template uses (mostly for documentation now)
|
||||
# a list of instances of var()
|
||||
vars = []
|
||||
|
||||
# Eggs that should be added as plugins:
|
||||
egg_plugins = []
|
||||
|
||||
# Templates that must be applied first:
|
||||
required_templates = []
|
||||
|
||||
# Use Cheetah for substituting templates:
|
||||
use_cheetah = False
|
||||
# If true, then read all the templates to find the variables:
|
||||
read_vars_from_templates = False
|
||||
|
||||
# You can also give this function/method to use something other
|
||||
# than Cheetah or string.Template. The function should be of the
|
||||
# signature template_renderer(content, vars, filename=filename).
|
||||
# Careful you don't turn this into a method by putting a function
|
||||
# here (without staticmethod)!
|
||||
template_renderer = None
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self._read_vars = None
|
||||
|
||||
def module_dir(self):
|
||||
"""Returns the module directory of this template."""
|
||||
mod = sys.modules[self.__class__.__module__]
|
||||
return os.path.dirname(mod.__file__)
|
||||
|
||||
def template_dir(self):
|
||||
assert self._template_dir is not None, (
|
||||
"Template %r didn't set _template_dir" % self)
|
||||
if isinstance( self._template_dir, tuple):
|
||||
return self._template_dir
|
||||
else:
|
||||
return os.path.join(self.module_dir(), self._template_dir)
|
||||
|
||||
def run(self, command, output_dir, vars):
|
||||
self.pre(command, output_dir, vars)
|
||||
self.write_files(command, output_dir, vars)
|
||||
self.post(command, output_dir, vars)
|
||||
|
||||
def check_vars(self, vars, cmd):
|
||||
expect_vars = self.read_vars(cmd)
|
||||
if not expect_vars:
|
||||
# Assume that variables aren't defined
|
||||
return vars
|
||||
converted_vars = {}
|
||||
unused_vars = vars.copy()
|
||||
errors = []
|
||||
for var in expect_vars:
|
||||
if var.name not in unused_vars:
|
||||
if cmd.interactive:
|
||||
prompt = 'Enter %s' % var.full_description()
|
||||
response = cmd.challenge(prompt, var.default, var.should_echo)
|
||||
converted_vars[var.name] = response
|
||||
elif var.default is command.NoDefault:
|
||||
errors.append('Required variable missing: %s'
|
||||
% var.full_description())
|
||||
else:
|
||||
converted_vars[var.name] = var.default
|
||||
else:
|
||||
converted_vars[var.name] = unused_vars.pop(var.name)
|
||||
if errors:
|
||||
raise command.BadCommand(
|
||||
'Errors in variables:\n%s' % '\n'.join(errors))
|
||||
converted_vars.update(unused_vars)
|
||||
vars.update(converted_vars)
|
||||
return converted_vars
|
||||
|
||||
def read_vars(self, command=None):
|
||||
if self._read_vars is not None:
|
||||
return self._read_vars
|
||||
assert (not self.read_vars_from_templates
|
||||
or self.use_cheetah), (
|
||||
"You can only read variables from templates if using Cheetah")
|
||||
if not self.read_vars_from_templates:
|
||||
self._read_vars = self.vars
|
||||
return self.vars
|
||||
|
||||
vars = self.vars[:]
|
||||
var_names = [var.name for var in self.vars]
|
||||
read_vars = find_args_in_dir(
|
||||
self.template_dir(),
|
||||
verbose=command and command.verbose > 1).items()
|
||||
read_vars.sort()
|
||||
for var_name, var in read_vars:
|
||||
if var_name not in var_names:
|
||||
vars.append(var)
|
||||
self._read_vars = vars
|
||||
return vars
|
||||
|
||||
def write_files(self, command, output_dir, vars):
|
||||
template_dir = self.template_dir()
|
||||
if not os.path.exists(output_dir):
|
||||
print "Creating directory %s" % output_dir
|
||||
if not command.simulate:
|
||||
# Don't let copydir create this top-level directory,
|
||||
# since copydir will svn add it sometimes:
|
||||
os.makedirs(output_dir)
|
||||
copydir.copy_dir(template_dir, output_dir,
|
||||
vars,
|
||||
verbosity=command.verbose,
|
||||
simulate=command.options.simulate,
|
||||
interactive=command.interactive,
|
||||
overwrite=command.options.overwrite,
|
||||
indent=1,
|
||||
use_cheetah=self.use_cheetah,
|
||||
template_renderer=self.template_renderer)
|
||||
|
||||
def print_vars(self, indent=0):
|
||||
vars = self.read_vars()
|
||||
var.print_vars(vars)
|
||||
|
||||
def pre(self, command, output_dir, vars):
|
||||
"""
|
||||
Called before template is applied.
|
||||
"""
|
||||
pass
|
||||
|
||||
def post(self, command, output_dir, vars):
|
||||
"""
|
||||
Called after template is applied.
|
||||
"""
|
||||
pass
|
||||
|
||||
NoDefault = command.NoDefault
|
||||
|
||||
class var(object):
|
||||
|
||||
def __init__(self, name, description,
|
||||
default='', should_echo=True):
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.default = default
|
||||
self.should_echo = should_echo
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s %s default=%r should_echo=%s>' % (
|
||||
self.__class__.__name__,
|
||||
self.name, self.default, self.should_echo)
|
||||
|
||||
def full_description(self):
|
||||
if self.description:
|
||||
return '%s (%s)' % (self.name, self.description)
|
||||
else:
|
||||
return self.name
|
||||
|
||||
def print_vars(cls, vars, indent=0):
|
||||
max_name = max([len(v.name) for v in vars])
|
||||
for var in vars:
|
||||
if var.description:
|
||||
print '%s%s%s %s' % (
|
||||
' '*indent,
|
||||
var.name,
|
||||
' '*(max_name-len(var.name)),
|
||||
var.description)
|
||||
else:
|
||||
print ' %s' % var.name
|
||||
if var.default is not command.NoDefault:
|
||||
print ' default: %r' % var.default
|
||||
if var.should_echo is True:
|
||||
print ' should_echo: %s' % var.should_echo
|
||||
print
|
||||
|
||||
print_vars = classmethod(print_vars)
|
||||
|
||||
class BasicPackage(Template):
|
||||
|
||||
_template_dir = 'paster-templates/basic_package'
|
||||
summary = "A basic setuptools-enabled package"
|
||||
vars = [
|
||||
var('version', 'Version (like 0.1)'),
|
||||
var('description', 'One-line description of the package'),
|
||||
var('long_description', 'Multi-line description (in reST)'),
|
||||
var('keywords', 'Space-separated keywords/tags'),
|
||||
var('author', 'Author name'),
|
||||
var('author_email', 'Author email'),
|
||||
var('url', 'URL of homepage'),
|
||||
var('license_name', 'License name'),
|
||||
var('zip_safe', 'True/False: if the package can be distributed as a .zip file', default=False),
|
||||
]
|
||||
|
||||
template_renderer = staticmethod(paste_script_template_renderer)
|
||||
|
||||
_skip_variables = ['VFN', 'currentTime', 'self', 'VFFSL', 'dummyTrans',
|
||||
'getmtime', 'trans']
|
||||
|
||||
def find_args_in_template(template):
|
||||
if isinstance(template, (str, unicode)):
|
||||
# Treat as filename:
|
||||
import Cheetah.Template
|
||||
template = Cheetah.Template.Template(file=template)
|
||||
if not hasattr(template, 'body'):
|
||||
# Don't know...
|
||||
return None
|
||||
method = template.body
|
||||
args, varargs, varkw, defaults = inspect.getargspec(method)
|
||||
defaults=list(defaults or [])
|
||||
vars = []
|
||||
while args:
|
||||
if len(args) == len(defaults):
|
||||
default = defaults.pop(0)
|
||||
else:
|
||||
default = command.NoDefault
|
||||
arg = args.pop(0)
|
||||
if arg in _skip_variables:
|
||||
continue
|
||||
# @@: No way to get description yet
|
||||
vars.append(
|
||||
var(arg, description=None,
|
||||
default=default))
|
||||
return vars
|
||||
|
||||
def find_args_in_dir(dir, verbose=False):
|
||||
all_vars = {}
|
||||
for fn in os.listdir(dir):
|
||||
if fn.startswith('.') or fn == 'CVS' or fn == '_darcs':
|
||||
continue
|
||||
full = os.path.join(dir, fn)
|
||||
if os.path.isdir(full):
|
||||
inner_vars = find_args_in_dir(full)
|
||||
elif full.endswith('_tmpl'):
|
||||
inner_vars = {}
|
||||
found = find_args_in_template(full)
|
||||
if found is None:
|
||||
# Couldn't read variables
|
||||
if verbose:
|
||||
print 'Template %s has no parseable variables' % full
|
||||
continue
|
||||
for var in found:
|
||||
inner_vars[var.name] = var
|
||||
else:
|
||||
# Not a template, don't read it
|
||||
continue
|
||||
if verbose:
|
||||
print 'Found variable(s) %s in Template %s' % (
|
||||
', '.join(inner_vars.keys()), full)
|
||||
for var_name, var in inner_vars.items():
|
||||
# Easy case:
|
||||
if var_name not in all_vars:
|
||||
all_vars[var_name] = var
|
||||
continue
|
||||
# Emit warnings if the variables don't match well:
|
||||
cur_var = all_vars[var_name]
|
||||
if not cur_var.description:
|
||||
cur_var.description = var.description
|
||||
elif (cur_var.description and var.description
|
||||
and var.description != cur_var.description):
|
||||
print >> sys.stderr, (
|
||||
"Variable descriptions do not match: %s: %s and %s"
|
||||
% (var_name, cur_var.description, var.description))
|
||||
if (cur_var.default is not command.NoDefault
|
||||
and var.default is not command.NoDefault
|
||||
and cur_var.default != var.default):
|
||||
print >> sys.stderr, (
|
||||
"Variable defaults do not match: %s: %r and %r"
|
||||
% (var_name, cur_var.default, var.default))
|
||||
return all_vars
|
||||
|
||||
Reference in New Issue
Block a user