diff options
author | Jason Pellerin <jpellerin@gmail.com> | 2007-10-13 21:45:45 +0000 |
---|---|---|
committer | Jason Pellerin <jpellerin@gmail.com> | 2007-10-13 21:45:45 +0000 |
commit | 75c9c574e20b4ebe53c6a33753295ad65557d9bf (patch) | |
tree | f8bfb09eccdba87d5741fd83b0a37393b41ecdde /scripts | |
parent | 65b2975d6c4e6af7a64725987a5838d3e71245e5 (diff) | |
download | nose-75c9c574e20b4ebe53c6a33753295ad65557d9bf.tar.gz |
Merged 0.10.0-stable [308]:[378] into trunk
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/mkdocs.py | 430 | ||||
-rwxr-xr-x | scripts/mkrelease.py | 195 | ||||
-rwxr-xr-x | scripts/mkwiki.py | 60 |
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) |