Bring some more sanity into quickstart validators.

This commit is contained in:
Georg Brandl 2009-04-29 12:26:38 +02:00
parent ab07eba895
commit ba0039cc4d
2 changed files with 37 additions and 29 deletions

View File

@ -464,30 +464,39 @@ def mkdir_p(dir):
os.makedirs(dir) os.makedirs(dir)
class ValidationError(Exception):
"""Raised for validation errors."""
def is_path(x): def is_path(x):
"""Please enter a valid path name.""" if path.exists(x) and not path.isdir(x):
return path.isdir(x) or not path.exists(x) raise ValidationError("Please enter a valid path name.")
return x
def nonempty(x): def nonempty(x):
"""Please enter some text.""" if not x:
return len(x) raise ValidationError("Please enter some text.")
return x
def choice(*l): def choice(*l):
def val(x): def val(x):
return x in l if x not in l:
val.__doc__ = 'Please enter one of %s.' % ', '.join(l) raise ValidationError('Please enter one of %s.' % ', '.join(l))
return x
return val return val
def boolean(x): def boolean(x):
"""Please enter either 'y' or 'n'.""" if x.upper() not in ('Y', 'YES', 'N', 'NO'):
return x.upper() in ('Y', 'YES', 'N', 'NO') raise ValidationError("Please enter either 'y' or 'n'.")
return x.upper() in ('Y', 'YES')
def suffix(x): def suffix(x):
"""Please enter a file suffix, e.g. '.rst' or '.txt'.""" if not (x[0:1] == '.' and len(x) > 1):
return x[0:1] == '.' and len(x) > 1 raise ValidationError("Please enter a file suffix, "
"e.g. '.rst' or '.txt'.")
return x
def ok(x): def ok(x):
return True return x
def do_prompt(d, key, text, default=None, validator=nonempty): def do_prompt(d, key, text, default=None, validator=nonempty):
@ -510,8 +519,10 @@ def do_prompt(d, key, text, default=None, validator=nonempty):
x = x.decode('utf-8') x = x.decode('utf-8')
except UnicodeDecodeError: except UnicodeDecodeError:
x = x.decode('latin1') x = x.decode('latin1')
if validator and not validator(x): try:
print red('* ' + validator.__doc__) x = validator(x)
except ValidationError, err:
print red('* ' + str(err))
continue continue
break break
d[key] = x d[key] = x
@ -617,7 +628,7 @@ directly.'''
repr('sphinx.ext.' + name) repr('sphinx.ext.' + name)
for name in ('autodoc', 'doctest', 'intersphinx', 'todo', 'coverage', for name in ('autodoc', 'doctest', 'intersphinx', 'todo', 'coverage',
'pngmath', 'jsmath', 'ifconfig') 'pngmath', 'jsmath', 'ifconfig')
if d['ext_' + name].upper() in ('Y', 'YES')) if d['ext_' + name])
d['copyright'] = time.strftime('%Y') + ', ' + d['author'] d['copyright'] = time.strftime('%Y') + ', ' + d['author']
d['author_texescaped'] = unicode(d['author']).\ d['author_texescaped'] = unicode(d['author']).\
translate(texescape.tex_escape_map) translate(texescape.tex_escape_map)
@ -634,11 +645,10 @@ directly.'''
if not path.isdir(d['path']): if not path.isdir(d['path']):
mkdir_p(d['path']) mkdir_p(d['path'])
separate = d['sep'].upper() in ('Y', 'YES') srcdir = d['sep'] and path.join(d['path'], 'source') or d['path']
srcdir = separate and path.join(d['path'], 'source') or d['path']
mkdir_p(srcdir) mkdir_p(srcdir)
if separate: if d['sep']:
builddir = path.join(d['path'], 'build') builddir = path.join(d['path'], 'build')
d['exclude_trees'] = '' d['exclude_trees'] = ''
else: else:
@ -649,7 +659,7 @@ directly.'''
mkdir_p(path.join(srcdir, d['dot'] + 'static')) mkdir_p(path.join(srcdir, d['dot'] + 'static'))
conf_text = QUICKSTART_CONF % d conf_text = QUICKSTART_CONF % d
if d['ext_intersphinx'].upper() in ('Y', 'YES'): if d['ext_intersphinx']:
conf_text += INTERSPHINX_CONFIG conf_text += INTERSPHINX_CONFIG
f = open(path.join(srcdir, 'conf.py'), 'w') f = open(path.join(srcdir, 'conf.py'), 'w')
@ -661,18 +671,16 @@ directly.'''
f.write((MASTER_FILE % d).encode('utf-8')) f.write((MASTER_FILE % d).encode('utf-8'))
f.close() f.close()
create_makefile = d['makefile'].upper() in ('Y', 'YES') if d['makefile']:
if create_makefile: d['rsrcdir'] = d['sep'] and 'source' or '.'
d['rsrcdir'] = separate and 'source' or '.' d['rbuilddir'] = d['sep'] and 'build' or d['dot'] + 'build'
d['rbuilddir'] = separate and 'build' or d['dot'] + 'build'
f = open(path.join(d['path'], 'Makefile'), 'w') f = open(path.join(d['path'], 'Makefile'), 'w')
f.write((MAKEFILE % d).encode('utf-8')) f.write((MAKEFILE % d).encode('utf-8'))
f.close() f.close()
create_batch = d['batchfile'].upper() in ('Y', 'YES') if d['batchfile']:
if create_batch: d['rsrcdir'] = d['sep'] and 'source' or '.'
d['rsrcdir'] = separate and 'source' or '.' d['rbuilddir'] = d['sep'] and 'build' or d['dot'] + 'build'
d['rbuilddir'] = separate and 'build' or d['dot'] + 'build'
f = open(path.join(d['path'], 'make.bat'), 'w') f = open(path.join(d['path'], 'make.bat'), 'w')
f.write((BATCHFILE % d).encode('utf-8')) f.write((BATCHFILE % d).encode('utf-8'))
f.close() f.close()
@ -681,7 +689,7 @@ directly.'''
print bold('Finished: An initial directory structure has been created.') print bold('Finished: An initial directory structure has been created.')
print ''' print '''
You should now populate your master file %s and create other documentation You should now populate your master file %s and create other documentation
source files. ''' % masterfile + ((create_makefile or create_batch) and '''\ source files. ''' % masterfile + ((d['makefile'] or d['batchfile']) and '''\
Use the Makefile to build the docs, like so: Use the Makefile to build the docs, like so:
make builder make builder
''' or '''\ ''' or '''\

View File

@ -65,9 +65,9 @@ def test_do_prompt():
qs.do_prompt(d, 'k2', 'Q2') qs.do_prompt(d, 'k2', 'Q2')
assert d['k2'] == 'v2' assert d['k2'] == 'v2'
qs.do_prompt(d, 'k4', 'Q4', validator=qs.boolean) qs.do_prompt(d, 'k4', 'Q4', validator=qs.boolean)
assert d['k4'] == 'yes' assert d['k4'] is True
qs.do_prompt(d, 'k5', 'Q5', validator=qs.boolean) qs.do_prompt(d, 'k5', 'Q5', validator=qs.boolean)
assert d['k5'] == 'no' assert d['k5'] is False
raises(AssertionError, qs.do_prompt, d, 'k6', 'Q6', validator=qs.boolean) raises(AssertionError, qs.do_prompt, d, 'k6', 'Q6', validator=qs.boolean)