summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorJason Pellerin <jpellerin@gmail.com>2007-10-13 21:45:45 +0000
committerJason Pellerin <jpellerin@gmail.com>2007-10-13 21:45:45 +0000
commit75c9c574e20b4ebe53c6a33753295ad65557d9bf (patch)
treef8bfb09eccdba87d5741fd83b0a37393b41ecdde /scripts
parent65b2975d6c4e6af7a64725987a5838d3e71245e5 (diff)
downloadnose-75c9c574e20b4ebe53c6a33753295ad65557d9bf.tar.gz
Merged 0.10.0-stable [308]:[378] into trunk
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/mkdocs.py430
-rwxr-xr-xscripts/mkrelease.py195
-rwxr-xr-xscripts/mkwiki.py60
3 files changed, 394 insertions, 291 deletions
diff --git a/scripts/mkdocs.py b/scripts/mkdocs.py
index 66da2a7..b027c46 100755
--- a/scripts/mkdocs.py
+++ b/scripts/mkdocs.py
@@ -5,22 +5,33 @@ import re
import time
from docutils.core import publish_string, publish_parts
from docutils.readers.standalone import Reader
+from docutils.writers.html4css1 import Writer, HTMLTranslator
from pudge.browser import Browser
-from epydoc.objdoc import _lookup_class_field
import inspect
import nose
import textwrap
from optparse import OptionParser
from nose.util import resolve_name, odict
from pygments import highlight
-from pygments.lexers import PythonLexer
+from pygments.lexers import PythonLexer, PythonConsoleLexer
from pygments.formatters import HtmlFormatter
remove_at = re.compile(r' at 0x[0-9a-f]+')
+root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+doc = os.path.join(root, 'doc')
+tpl = open(os.path.join(doc, 'doc.html.tpl'), 'r').read()
+api_tpl = open(os.path.join(doc, 'plugin_api.html.tpl'), 'r').read()
+plug_tpl = open(os.path.join(doc, 'plugin.html.tpl'), 'r').read()
+std_info = {
+ 'version': nose.__version__,
+ 'date': time.ctime()
+ }
+to_write = []
def defining_class(cls, attr):
+ from epydoc.objdoc import _lookup_class_field
val, container = _lookup_class_field(cls, attr)
return container.value()
@@ -41,12 +52,9 @@ def doc_word(node):
# handle links like package.module and module.Class
# as wellas 'foo bar'
- name = node.astext()
- print "Unknown ref %s" % name
+ orig = name = node.astext()
if '.' in name:
-
parts = name.split('.')
-
# if the first letter of a part is capitalized, assume it's
# a class name, and put all parts from that part on into
# the anchor part of the link
@@ -54,10 +62,15 @@ def doc_word(node):
addto = link
while parts:
part = parts.pop(0)
- if addto == link and part[0].upper() == part[0]:
- addto = anchor
+ if addto == link:
+ if part[0].upper() == part[0]:
+ addto = anchor
+ elif part.endswith('()'):
+ addto = anchor
+ part = part[:-2]
addto.append(part)
- if name.startswith('nose.plugins'):
+ if (name.startswith('nose.plugins')
+ and 'plugintest' not in name):
base = 'plugin_'
link = link[-1:]
else:
@@ -66,9 +79,12 @@ def doc_word(node):
if anchor:
node['refuri'] += '#' + '.'.join(anchor)
else:
- node['refuri'] = '_'.join(
- map(lambda s: s.lower(), name.split(' '))) + '.html'
+ # pad out wiki-words
+ name = name[0].lower() + name[1:]
+ name = re.sub(r'([A-Z])', r' \1', name).lower()
+ node['refuri'] = '_'.join(name.split(' ')) + '.html'
+ print "Unknown ref %s -> %s" % (orig, node['refuri'])
del node['refname']
node.resolved = True
return True
@@ -80,6 +96,26 @@ class DocReader(Reader):
unknown_reference_resolvers = (doc_word,)
+class PygHTMLTranslator(HTMLTranslator):
+ """HTML translator that uses pygments to highlight doctests.
+ """
+ def visit_doctest_block(self, node):
+ self.body.append(
+ highlight(node.rawsource, PythonConsoleLexer(), HtmlFormatter()))
+ # hacky way of capturing children -- we've processed the whole node
+ self._body = self.body
+ self.body = []
+
+ def depart_doctest_block(self, node):
+ # restore the real body, doctest node is done
+ self.body = self._body
+ del self._body
+
+class PygWriter(Writer):
+ def __init__(self):
+ Writer.__init__(self)
+ self.translator_class = PygHTMLTranslator
+
def formatargspec(func, exclude=()):
try:
args, varargs, varkw, defaults = inspect.getargspec(func)
@@ -105,9 +141,12 @@ def clean_default(val):
return val
+def to_html_parts(rst):
+ return publish_parts(rst, reader=DocReader(), writer=PygWriter())
+
+
def to_html(rst):
- parts = publish_parts(rst, reader=DocReader(), writer_name='html')
- return parts['body']
+ return to_html_parts(rst)['body']
def document_module(mod):
@@ -297,6 +336,7 @@ def format_attr(obj, attr):
val = remove_at.sub('', val)
return val
+
def link_to_class(cls):
mod = cls.__module__
name = cls.__name__
@@ -309,180 +349,200 @@ def link_to_class(cls):
return '<a href="module_%s.html#%s">%s</a>' % (mod, name, name)
-root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
-doc = os.path.join(root, 'doc')
-tpl = open(os.path.join(doc, 'doc.html.tpl'), 'r').read()
-api_tpl = open(os.path.join(doc, 'plugin_api.html.tpl'), 'r').read()
-plug_tpl = open(os.path.join(doc, 'plugin.html.tpl'), 'r').read()
-std_info = {
- 'version': nose.__version__,
- 'date': time.ctime()
- }
-to_write = []
+def plugin_example_tests():
+ dt_root = os.path.join(root, 'functional_tests', 'doc_tests')
+ for dirpath, dirnames, filenames in os.walk(dt_root):
+ for filename in filenames:
+ if filename.startswith('.'):
+ continue
+ base, ext = os.path.splitext(filename)
+ if ext == '.rst':
+ yield os.path.join(dirpath, filename)
+ if '.svn' in dirnames:
+ dirnames.remove('.svn')
+
+
+def document_rst_test(filename, section):
+ base, ext = os.path.splitext(os.path.basename(filename))
+ rst = open(filename, 'r').read()
+ parts = to_html_parts(rst)
+ parts.update(std_info)
+ to_write.append((section,
+ parts['title'],
+ os.path.join(doc, base + '.html'),
+ tpl,
+ parts))
+
+def main():
+ # plugins
+ from nose import plugins
+ from nose.plugins.base import IPluginInterface
+ from nose.plugins import errorclass
+
+ # writing plugins guide
+ writing_plugins = {'body': to_html(plugins.__doc__)}
+ writing_plugins.update(std_info)
+ writing_plugins['title'] = 'Writing Plugins'
+ to_write.append(
+ ('Plugins',
+ 'Writing Plugins',
+ os.path.join(doc, 'writing_plugins.html'), tpl, writing_plugins))
-# plugins
-from nose import plugins
-from nose.plugins.base import IPluginInterface
-from nose.plugins import errorclass
-
-# writing plugins guide
-writing_plugins = {'body': to_html(plugins.__doc__)}
-writing_plugins.update(std_info)
-writing_plugins['title'] = 'Writing Plugins'
-to_write.append(
- ('Plugins',
- 'Writing Plugins',
- os.path.join(doc, 'writing_plugins.html'), tpl, writing_plugins))
-
-
-# error class plugins
-ecp = {'body': to_html(errorclass.__doc__)}
-ecp.update(std_info)
-ecp['title'] = 'ErrorClass Plugins'
-to_write.append(
- ('Plugins',
- 'ErrorClass Plugins',
- os.path.join(doc, 'errorclassplugin.html'), tpl, ecp))
-
-# interface
-itf = {'body': to_html(textwrap.dedent(IPluginInterface.__doc__))}
-
-# methods
-attr = [(a, getattr(IPluginInterface, a)) for a in dir(IPluginInterface)]
-methods = [m for m in attr if inspect.ismethod(m[1])]
-methods.sort()
-# print "Documenting methods", [a[0] for a in methods]
-
-method_html = []
-method_tpl = """
-<div class="method %(extra_class)s">
-<a name="%(name)s">
-<span class="name">%(name)s</span><span class="arg">%(arg)s</span></a>
-<div class="doc">%(body)s</div>
-</div>
-"""
-
-menu_links = {}
-
-m_attrs = ('_new', 'changed', 'deprecated', 'generative', 'chainable')
-for m in methods:
- name, meth = m
- ec = []
- for att in m_attrs:
- if hasattr(meth, att):
- ec.append(att.replace('_', ''))
- menu_links.setdefault(att.replace('_', ''), []).append(name)
- # padding evens the lines
- print name
- mdoc = {'body': to_html(textwrap.dedent(' ' + meth.__doc__))}
- argspec = formatargspec(meth)
- mdoc.update({'name': name,
- 'extra_class': ' '.join(ec),
- 'arg': argspec})
- method_html.append(method_tpl % mdoc)
-
-itf['methods'] = ''.join(method_html)
-itf.update(std_info)
-itf['title'] = 'Plugin Interface'
-
-menu = []
-for section in ('new', 'changed', 'deprecated'):
- menu.append('<h2>%s methods</h2>' % section.title())
- menu.append('<ul><li>')
- menu.append('</li><li>'.join([
- '<a href="#%(name)s">%(name)s</a>' % {'name': n}
- for n in menu_links[section]]))
- menu.append('</li></ul>')
-itf['sub_menu'] = ''.join(menu)
-
-to_write.append(
- ('Plugins',
- 'Plugin Interface',
- os.path.join(doc, 'plugin_interface.html'), api_tpl, itf))
-
-
-# individual plugin usage docs
-from nose.plugins.builtin import builtins
-
-pmeths = [m[0] for m in methods[:]
- if not 'options' in m[0].lower()]
-pmeths.append('options')
-pmeths.sort()
-
-for modulename, clsname in builtins:
- _, _, modname = modulename.split('.')
- mod = resolve_name(modulename)
- cls = getattr(mod, clsname)
- filename = os.path.join(doc, 'plugin_%s.html' % modname)
- print modname, filename
- if not mod.__doc__:
- print "No docs"
- continue
- pdoc = {'body': to_html(mod.__doc__)}
- pdoc.update(std_info)
- pdoc['title'] = 'builtin plugin: %s' % modname
-
- # options
- parser = OptionParser(add_help_option=False)
- plug = cls()
- plug.addOptions(parser)
- options = parser.format_option_help()
- pdoc['options'] = options
-
- # hooks used
- hooks = []
- for m in pmeths:
- if getattr(cls, m, None):
- hooks.append('<li><a href="plugin_interface.html#%(name)s">'
- '%(name)s</a></li>' % {'name': m})
- pdoc['hooks'] = ''.join(hooks)
-
- source = inspect.getsource(mod)
- pdoc['source'] = highlight(source, PythonLexer(), HtmlFormatter())
+ # error class plugins
+ ecp = {'body': to_html(errorclass.__doc__)}
+ ecp.update(std_info)
+ ecp['title'] = 'ErrorClass Plugins'
to_write.append(
('Plugins',
- 'Builtin Plugin: %s' % modname,
- os.path.join(doc, filename), plug_tpl, pdoc))
-
-
-# individual module docs
-b = Browser(['nose','nose.plugins.manager'],
- exclude_modules=['nose.plugins', 'nose.ext'])
-for mod in b.modules(recursive=1):
- if mod.name == 'nose':
- # no need to regenerate, this is the source of the doc index page
- continue
- print mod.qualified_name()
- document_module(mod)
-
-
-# finally build the menu and write all pages
-menu = []
-sections = odict()
-for page in to_write:
- section, _, _, _, _ = page
- sections.setdefault(section, []).append(page)
-
-for section, pages in sections.items():
- menu.append('<h2>%s</h2>' % section)
- menu.append('<ul>')
- pages.sort()
- menu.extend([
- '<li><a href="%s">%s</a></li>' % (os.path.basename(filename), title)
- for _, title, filename, _, _ in pages ])
- menu.append('</ul>')
-
-menu = ''.join(menu)
-for section, title, filename, template, ctx in to_write:
- ctx['menu'] = menu
- write(filename, template, ctx)
-
-# doc section index page
-idx_tpl = open(os.path.join(doc, 'index.html.tpl'), 'r').read()
-idx = {
- 'title': 'API documentation',
- 'menu': menu}
-idx.update(std_info)
-write(os.path.join(doc, 'index.html'), idx_tpl, idx)
+ 'ErrorClass Plugins',
+ os.path.join(doc, 'error_class_plugin.html'), tpl, ecp))
+
+ # interface
+ itf = {'body': to_html(textwrap.dedent(IPluginInterface.__doc__))}
+
+ # methods
+ attr = [(a, getattr(IPluginInterface, a)) for a in dir(IPluginInterface)]
+ methods = [m for m in attr if inspect.ismethod(m[1])]
+ methods.sort()
+ # print "Documenting methods", [a[0] for a in methods]
+
+ method_html = []
+ method_tpl = """
+ <div class="method %(extra_class)s">
+ <a name="%(name)s">
+ <span class="name">%(name)s</span><span class="arg">%(arg)s</span></a>
+ <div class="doc">%(body)s</div>
+ </div>
+ """
+
+ menu_links = {}
+
+ m_attrs = ('_new', 'changed', 'deprecated', 'generative', 'chainable')
+ for m in methods:
+ name, meth = m
+ ec = []
+ for att in m_attrs:
+ if hasattr(meth, att):
+ ec.append(att.replace('_', ''))
+ menu_links.setdefault(att.replace('_', ''), []).append(name)
+ # padding evens the lines
+ print name
+ mdoc = {'body': to_html(textwrap.dedent(' ' + meth.__doc__))}
+ argspec = formatargspec(meth)
+ mdoc.update({'name': name,
+ 'extra_class': ' '.join(ec),
+ 'arg': argspec})
+ method_html.append(method_tpl % mdoc)
+
+ itf['methods'] = ''.join(method_html)
+ itf.update(std_info)
+ itf['title'] = 'Plugin Interface'
+
+ menu = []
+ for section in ('new', 'changed', 'deprecated'):
+ menu.append('<h2>%s methods</h2>' % section.title())
+ menu.append('<ul><li>')
+ menu.append('</li><li>'.join([
+ '<a href="#%(name)s">%(name)s</a>' % {'name': n}
+ for n in menu_links[section]]))
+ menu.append('</li></ul>')
+ itf['sub_menu'] = ''.join(menu)
+ to_write.append(
+ ('Plugins',
+ 'Plugin Interface',
+ os.path.join(doc, 'plugin_interface.html'), api_tpl, itf))
+
+
+ # individual plugin usage docs
+ from nose.plugins.builtin import builtins
+
+ pmeths = [m[0] for m in methods[:]
+ if not 'options' in m[0].lower()]
+ pmeths.append('options')
+ pmeths.sort()
+
+ for modulename, clsname in builtins:
+ _, _, modname = modulename.split('.')
+ mod = resolve_name(modulename)
+ cls = getattr(mod, clsname)
+ filename = os.path.join(doc, 'plugin_%s.html' % modname)
+ print modname, filename
+ if not mod.__doc__:
+ print "No docs"
+ continue
+ pdoc = {'body': to_html(mod.__doc__)}
+ pdoc.update(std_info)
+ pdoc['title'] = 'builtin plugin: %s' % modname
+
+ # options
+ parser = OptionParser(add_help_option=False)
+ plug = cls()
+ plug.addOptions(parser)
+ options = parser.format_option_help()
+ pdoc['options'] = options
+
+ # hooks used
+ hooks = []
+ for m in pmeths:
+ if getattr(cls, m, None):
+ hooks.append('<li><a href="plugin_interface.html#%(name)s">'
+ '%(name)s</a></li>' % {'name': m})
+ pdoc['hooks'] = ''.join(hooks)
+
+ source = inspect.getsource(mod)
+ pdoc['source'] = highlight(source, PythonLexer(), HtmlFormatter())
+ to_write.append(
+ ('Plugins',
+ 'Builtin Plugin: %s' % modname,
+ os.path.join(doc, filename), plug_tpl, pdoc))
+
+
+ # individual module docs
+ b = Browser(['nose','nose.plugins.manager', 'nose.plugins.plugintest'],
+ exclude_modules=['nose.plugins', 'nose.ext'])
+ for mod in b.modules(recursive=1):
+ if mod.name == 'nose':
+ # no need to regenerate, this is the source of the doc index page
+ continue
+ print mod.qualified_name()
+ document_module(mod)
+
+
+ # plugin examples doctests
+ for testfile in plugin_example_tests():
+ document_rst_test(testfile, "Plugin Examples")
+
+
+ # finally build the menu and write all pages
+ menu = []
+ sections = odict()
+ for page in to_write:
+ section, _, _, _, _ = page
+ sections.setdefault(section, []).append(page)
+
+ for section, pages in sections.items():
+ menu.append('<h2>%s</h2>' % section)
+ menu.append('<ul>')
+ pages.sort()
+ menu.extend([
+ '<li><a href="%s">%s</a></li>' % (os.path.basename(filename), title)
+ for _, title, filename, _, _ in pages ])
+ menu.append('</ul>')
+
+ menu = ''.join(menu)
+ for section, title, filename, template, ctx in to_write:
+ ctx['menu'] = menu
+ write(filename, template, ctx)
+
+ # doc section index page
+ idx_tpl = open(os.path.join(doc, 'index.html.tpl'), 'r').read()
+ idx = {
+ 'title': 'API documentation',
+ 'menu': menu}
+ idx.update(std_info)
+ write(os.path.join(doc, 'index.html'), idx_tpl, idx)
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/mkrelease.py b/scripts/mkrelease.py
index eb57bb8..14e21c4 100755
--- a/scripts/mkrelease.py
+++ b/scripts/mkrelease.py
@@ -10,102 +10,121 @@ from commands import getstatusoutput
success = 0
current = os.getcwd()
-
+version = nose.__version__
here = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
parts = here.split('/')
-svn = parts.index('svn')
-svnroot = os.path.join('/', *parts[:svn+1])
+branchindex = parts.index('branches')
+svnroot = os.path.join('/', *parts[:branchindex])
branchroot = os.path.join(svnroot, 'branches')
tagroot = os.path.join(svnroot, 'tags')
svntrunk = os.path.join(svnroot, 'trunk')
svn_trunk_url = 'https://python-nose.googlecode.com/svn/trunk'
+SIMULATE = 'exec' not in sys.argv
+if SIMULATE:
+ print("# simulated run: run as scripts/mkrelease.py exec "
+ "to execute commands")
+
+
def runcmd(cmd):
print cmd
- (status,output) = getstatusoutput(cmd)
- if status != success:
- raise Exception(output)
+ if not SIMULATE:
+ (status,output) = getstatusoutput(cmd)
+ if status != success:
+ raise Exception(output)
+
+
+def cd(dir):
+ print "cd %s" % dir
+ if not SIMULATE:
+ os.chdir(dir)
-version = nose.__version__
-versioninfo = nose.__versioninfo__
-
-os.chdir(svnroot)
-print "cd %s" % svnroot
-
-# FIXME tail of version is hardcoded
-branch = 'branches/%s.%s.0-stable' % (versioninfo[0], versioninfo[1])
-tag = 'tags/%s-release' % version
-
-if os.path.isdir(tag):
- raise Exception("Tag path %s already exists. Can't release same version "
- "twice!")
-
-# make branch, if needed
-if not os.path.isdir(branch):
- # update trunk
- os.chdir(svntrunk)
- print "cd %s" % svntrunk
- runcmd('svn up')
- os.chdir(svnroot)
- print "cd %s" % svnroot
- runcmd('svn copy %s %s' % (svn_trunk_url, branch))
-
- # clean up setup.cfg and check in branch
- os.chdir(branch)
- print "cd %s" % branch
-
- # remove dev tag from setup
- runcmd('cp setup.cfg.release setup.cfg')
- runcmd('svn rm setup.cfg.release --force')
-
- os.chdir(branchroot)
- print "cd %s" % branchroot
- runcmd("svn ci -m 'Release branch for %s'" % version)
-
-else:
- # re-releasing branch
- os.chdir(branch)
- print "cd %s" % branch
- runcmd('svn up')
- os.chdir(svnroot)
- print "cd %s"% svnroot
-
-# make tag from branch
-print "cd %s" % svnroot
-os.chdir(svnroot)
-runcmd('svn copy %s %s' % (branch, tag))
-
-# check in tag
-os.chdir(tagroot)
-print "cd %s" % tagroot
-runcmd("svn ci -m 'Release tag for %s'" % version)
-
-# make docs
-os.chdir(svnroot)
-os.chdir(tag)
-print "cd %s" % tag
-
-runcmd('scripts/mkindex.py')
-runcmd('scripts/mkdocs.py')
-# runcmd('scripts/mkwiki.py')
-
-# setup sdist
-runcmd('python setup.py sdist')
-
-# upload docs and distribution
-if 'NOSE_UPLOAD' in os.environ:
- cv = {'version':version,
- 'upload': os.environ['NOSE_UPLOAD'],
- 'upload_docs': "%s/%s" % (os.environ['NOSE_UPLOAD'], version) }
- cmd = 'scp -C dist/nose-%(version)s.tar.gz %(upload)s' % cv
- runcmd(cmd)
-
- cmd = 'mkdir -p %(upload_docs)s/doc' % cv
-
- cmd = 'scp -C index.html %(upload_docs)s' % cv
- runcmd(cmd)
-
- cmd = 'scp -C doc/*.html doc/*.css doc/*.png %(upload_docs)s/doc' % cv
- runcmd(cmd)
-os.chdir(current)
+def main():
+ cd(svnroot)
+ branch = 'branches/%s-stable' % version
+ tag = 'tags/%s-release' % version
+
+ if os.path.isdir(tag):
+ raise Exception(
+ "Tag path %s already exists. Can't release same version twice!"
+ % tag)
+
+ # make branch, if needed
+ if not os.path.isdir(os.path.join(svnroot, branch)):
+ # update trunk
+ cd(svntrunk)
+ runcmd('svn up')
+ cd(svnroot)
+ runcmd('svn copy %s %s' % (svn_trunk_url, branch))
+
+ # clean up setup.cfg and check in branch
+ cd(branch)
+
+ # remove dev tag from setup
+ runcmd('cp setup.cfg.release setup.cfg')
+ runcmd('svn rm setup.cfg.release --force')
+
+ cd(branchroot)
+ runcmd("svn ci -m 'Release branch for %s'" % version)
+
+ else:
+ # re-releasing branch
+ cd(branch)
+ runcmd('svn up')
+
+ # make tag from branch
+ cd(svnroot)
+ runcmd('svn copy %s %s' % (branch, tag))
+
+ # check in tag
+ cd(tagroot)
+ runcmd("svn ci -m 'Release tag for %s'" % version)
+
+ # make docs
+ cd(svnroot)
+ cd(tag)
+
+ runcmd('scripts/mkindex.py')
+ runcmd('scripts/mkdocs.py')
+ runcmd('scripts/mkwiki.py')
+
+ # FIXME need to do this from an *export* to limit files included
+ # (setuptools includes too many files when run under a checkout)
+ # setup sdist
+ runcmd('python setup.py sdist')
+
+ # upload docs and distribution
+ if 'NOSE_UPLOAD' in os.environ:
+ up = os.environ['NOSE_UPLOAD']
+ cv = {
+ 'host': up[:up.index(':')],
+ 'path': up[up.index(':')+1:],
+ 'version':version,
+ 'upload': up,
+ 'upload_docs': "%s/%s" % (up, version) }
+ cv['versionpath'] = "%(path)s/%(version)s" % cv
+ cv['docpath'] = "%(versionpath)s/doc" % cv
+
+ cmd = 'scp -C dist/nose-%(version)s.tar.gz %(upload)s' % cv
+ runcmd(cmd)
+
+ cmd = 'ssh %(host)s "mkdir -p %(docpath)s"' % cv
+ runcmd(cmd)
+
+ cmd = 'scp -C index.html %(upload_docs)s' % cv
+ runcmd(cmd)
+
+ cmd = ('scp -C doc/*.html doc/*.css doc/*.png '
+ '%(upload_docs)s/doc' % cv)
+ runcmd(cmd)
+
+ cmd = ('ssh %(host)s '
+ '"ln -nfs %(versionpath)s/index.html %(path)s/index.html; '
+ 'ln -nfs %(docpath)s %(path)s/doc"' % cv)
+ runcmd(cmd)
+
+ cd(current)
+
+if __name__ == '__main__':
+ main()
diff --git a/scripts/mkwiki.py b/scripts/mkwiki.py
index 4a0a354..eed9e59 100755
--- a/scripts/mkwiki.py
+++ b/scripts/mkwiki.py
@@ -6,7 +6,9 @@ from docutils.nodes import SparseNodeVisitor
from docutils.readers.standalone import Reader
from docutils.writers import Writer
from nose.config import Config
+import nose.plugins
from nose.plugins.manager import BuiltinPluginManager
+from nose.plugins import errorclass
import nose
import os
import pudge.browser
@@ -15,6 +17,8 @@ import sys
import textwrap
import time
+sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
+from mkdocs import formatargspec
# constants
success = 0
@@ -25,28 +29,37 @@ generated and edits above this line will be discarded.*
= Comments =
"""
+wiki_word_re = re.compile(r'^[A-Z][a-z]+(?:[A-Z][a-z]+)+')
def ucfirst(s):
return s[0].upper() + s[1:].lower()
def words(s):
return s.split(' ')
+
+
+def is_wiki_word(text):
+ return wiki_word_re.match(text)
+
def wiki_word(node):
- text = node.astext()
- print "Unknown ref %s" % text
+ orig = text = node.astext()
# handle module/plugin links -- link to code
- if '.' in text:
- parts = text.split('.')
- link = 'http://python-nose.googlecode.com/svn/trunk'
- for p in parts:
- # stop at class names
- if p[0].upper() == p[0]:
- break
- link += '/' + p
- node['refuri'] = link
- return True
- node['refuri'] = ''.join(map(ucfirst, words(text)))
+ if is_wiki_word(text):
+ node['refuri'] = text
+ else:
+ if '.' in text:
+ parts = text.split('.')
+ link = 'http://python-nose.googlecode.com/svn/trunk'
+ for p in parts:
+ # stop at class names
+ if p[0].upper() == p[0]:
+ break
+ link += '/' + p
+ node['refuri'] = link
+ return True
+ node['refuri'] = ''.join(map(ucfirst, words(text)))
+ print "Unknown ref %s -> %s" % (orig, node['refuri'])
del node['refname']
node.resolved = True
return True
@@ -208,7 +221,7 @@ def plugin_interface():
mdoc = []
for m in methods:
# FIXME fix the arg list so literal os.environ is not in there
- mdoc.append('*%s%s*\n\n' % (m.name, m.formatargs()))
+ mdoc.append('*%s%s*\n\n' % (m.name, formatargspec(m.obj)))
# FIXME this is resulting in poorly formatted doc sections
mdoc.append(' ' + m.doc().replace('\n', '\n '))
mdoc.append('\n\n')
@@ -261,6 +274,7 @@ def mkwiki(path):
'NoseFeatures': wikirst(section(nose.__doc__, 'Features')),
'WritingPlugins': wikirst(nose.plugins.__doc__),
'PluginInterface': plugin_interface(),
+ 'ErrorClassPlugin': wikirst(errorclass.__doc__),
'TestingTools': tools(),
'FindingAndRunningTests': wikirst(
section(nose.__doc__, 'Finding and running tests')),
@@ -313,7 +327,7 @@ class Wiki(object):
return (headers, ''.join(content))
except IOError:
self.newpages.append(page)
- return ''
+ return ('', '')
def set_docs(self, page, headers, page_src, docs):
wikified = docs + div
@@ -344,10 +358,20 @@ class Wiki(object):
if page in self.newpages:
runcmd('svn add %s' % self.filename(page))
-
+
+def findwiki(root):
+ if not root or root is '/': # not likely to work on windows
+ raise ValueError("wiki path not found")
+ if not os.path.isdir(root):
+ return findwiki(os.path.dirname(root))
+ entries = os.listdir(root)
+ if 'wiki' in entries:
+ return os.path.join(root, 'wiki')
+ return findwiki(os.path.dirname(root))
+
+
def main():
- path = os.path.abspath(
- os.path.join(os.path.dirname(__file__), '..', '..', '..', 'wiki'))
+ path = findwiki(os.path.abspath(__file__))
mkwiki(path)