[svn r38770] Removed option --apigen_relpath, added options --docpath and --apigenpath, both

of which are not only used for building the navigation, but also to actually
tell py.test where docs should be generated. Also cleaned up and fixed the
situation regarding relative links in the navigation menu and stylesheet/js
paths.

--HG--
branch : trunk
This commit is contained in:
guido 2007-02-14 00:56:57 +01:00
parent c9b5b1714a
commit 13c44faa38
11 changed files with 131 additions and 97 deletions

View File

@ -1,7 +1,4 @@
""" run 'py.test --apigen=<this script>' to get documentation exported
exports to /tmp/output by default, set the environment variable
'APIGEN_TARGET' to override
"""
import os
@ -11,6 +8,7 @@ from py.__.apigen import htmlgen
from py.__.apigen import linker
from py.__.apigen import project
from py.__.apigen.tracer.docstorage import pkg_to_dict
from py.__.doc.conftest import get_apigenpath
from layout import LayoutPage
@ -41,10 +39,8 @@ def build(pkgdir, dsa, capture):
proj = project.Project()
# output dir
if 'APIGEN_TARGET' in os.environ:
targetdir = py.path.local(os.environ['APIGEN_TARGET'])
else:
targetdir = pkgdir.dirpath().join('apigen')
from py.__.conftest import option
targetdir = get_apigenpath()
targetdir.ensure(dir=True)
# find out what to build

View File

@ -119,10 +119,9 @@ def create_namespace_tree(dotted_names):
ret[ns].append(itempath)
return ret
def wrap_page(project, title, contentel, navel, relbase, basepath,
def wrap_page(project, title, targetpath, contentel, navel, basepath,
pageclass):
page = pageclass(project, title, nav=navel, encoding='UTF-8',
relpath=relbase)
page = pageclass(project, title, targetpath, nav=navel, encoding='UTF-8')
page.set_content(contentel)
page.setup_scripts_styles(basepath)
return page
@ -180,7 +179,7 @@ class AbstractPageBuilder(object):
targetpath = self.base.join(reltargetpath)
relbase= relpath('%s%s' % (targetpath.dirpath(), targetpath.sep),
self.base.strpath + '/')
page = wrap_page(self.project, title, tag, nav, relbase, self.base,
page = wrap_page(self.project, title, targetpath, tag, nav, self.base,
self.pageclass)
# we write the page with _temporary_ hrefs here, need to be replaced
# from the TempLinker later

View File

@ -6,6 +6,7 @@
import py
from py.__.doc import confrest
from py.__.apigen import linker
from py.__.doc.conftest import get_apigenpath, get_docpath
here = py.magic.autopath().dirpath()
@ -18,10 +19,14 @@ class LayoutPage(confrest.PyPage):
def __init__(self, *args, **kwargs):
self.nav = kwargs.pop('nav')
self.relpath = kwargs.pop('relpath')
super(LayoutPage, self).__init__(*args, **kwargs)
self.relpath = self.get_relpath()
self.project.logo.attr.id = 'logo'
def get_relpath(self):
return linker.relpath(self.targetpath.strpath,
get_apigenpath().strpath) + '/'
def set_content(self, contentel):
self.contentspace.append(contentel)
@ -29,23 +34,6 @@ class LayoutPage(confrest.PyPage):
super(LayoutPage, self).fill()
self.body.insert(0, self.nav)
def _getdocrelpath(self, default="../py/doc"):
docrel = py.std.os.environ.get("APIGEN_DOCRELPATH", default)
return docrel.rstrip("/") + "/"
def a_docref(self, name, relhtmlpath):
docrelpath = self._getdocrelpath()
relnew = self.relpath + docrelpath + relhtmlpath
return super(LayoutPage, self).a_docref(name, relnew)
def a_apigenref(self, name, relhtmlpath):
# XXX the path construction is probably rather too complicated
# but i reused the same logic that was there
# before.
docrelpath = self._getdocrelpath()
relnew = self.relpath + docrelpath + relhtmlpath
return super(LayoutPage, self).a_apigenref(name, relnew)
def setup_scripts_styles(self, copyto=None):
for path, name in self.stylesheets:
if copyto:

View File

@ -5,6 +5,7 @@ from py.__.apigen.linker import TempLinker
from py.__.apigen.htmlgen import *
from py.__.apigen.tracer.docstorage import DocStorage, DocStorageAccessor
from py.__.apigen.tracer.tracer import Tracer
from py.__.apigen.layout import LayoutPage
from py.__.apigen.project import Project
from py.__.test.web import webcheck
from py.__.apigen.conftest import option
@ -94,6 +95,10 @@ def _checkhtmlsnippet(htmlstring):
#"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n""" + unicode(h)
#_checkhtml(newstring)
class LayoutTestPage(LayoutPage):
def get_relpath(self):
return '../'
class AbstractBuilderTest(object):
def setup_class(cls):
temp = py.test.ensuretemp('apigen_example')
@ -121,6 +126,7 @@ class AbstractBuilderTest(object):
self.spb = SourcePageBuilder(base, linker,
self.fs_root.join(self.pkg_name),
self.project)
self.apb.pageclass = self.spb.pageclass = LayoutTestPage
class TestApiPageBuilder(AbstractBuilderTest):
def test_build_callable_view(self):
@ -396,7 +402,7 @@ class TestSourcePageBuilder(AbstractBuilderTest):
html = funcsource.read()
print html
run_string_sequence_test(html, [
'href="../../style.css"',
'href="../style.css"',
'<a href="index.html">pkg</a>',
'<a href="someclass.py.html">someclass.py</a>',
'<a href="somesubclass.py.html">somesubclass.py</a>',
@ -410,7 +416,7 @@ class TestSourcePageBuilder(AbstractBuilderTest):
html = pkgindex.read()
print html
run_string_sequence_test(html, [
'href="../../style.css"',
'href="../style.css"',
'<a href="index.html">pkg</a>',
'<a href="func.py.html">func.py</a>',
'<a href="someclass.py.html">someclass.py</a>',

View File

@ -125,10 +125,10 @@ def test_apigen_functional():
pydir = py.magic.autopath().dirpath().dirpath().dirpath()
pakdir = fs_root.join('pak')
if py.std.sys.platform == 'win32':
cmd = ('set APIGEN_TARGET=%s && set PYTHONPATH=%s && '
cmd = ('set APIGENPATH=%s && set PYTHONPATH=%s && '
'python "%s/bin/py.test"') % (tempdir, fs_root, pydir)
else:
cmd = ('APIGEN_TARGET="%s" PYTHONPATH="%s" '
cmd = ('APIGENPATH="%s" PYTHONPATH="%s" '
'python "%s/bin/py.test"') % (tempdir, fs_root, pydir)
try:
output = py.process.cmdexec('%s --apigen="%s/apigen.py" "%s"' % (

View File

@ -23,7 +23,7 @@ def build_apigen_docs(targetpath, testargs=''):
run_tests(pypath,
'APIGEN_TARGET="%s/apigen" APIGEN_DOCRELPATH="../"' % (
targetpath,),
testargs + ' --apigen="%s/apigen/apigen.py"' % (pypath,))
'%s --apigen="%s/apigen/apigen.py"' % (testargs, pypath))
def build_docs(targetpath, testargs):
docpath = pypath.join('doc')

View File

@ -22,32 +22,32 @@ def rsync(pkgpath, apidocspath, gateway, remotepath):
rs.add_target(gateway, remotepath, delete=True)
rs.send()
def run_tests(pkgpath, args='', captureouterr=False):
def run_tests(pkgpath, apigenpath, args='', captureouterr=False):
""" run the unit tests and build the docs """
pypath = py.__package__.getpath()
pytestpath = pypath.join('bin/py.test')
# XXX this would need a Windows specific version if we want to allow
# running this script on that platform, but currently --apigen doesn't
# work there anyway...
apigenpath = pkgpath.join('apigen/apigen.py') # XXX be more general here?
if not apigenpath.check(file=True):
apigenpath = pypath.join('apigen/apigen.py')
cmd = 'PYTHONPATH="%s:%s" python "%s" %s --apigen="%s" "%s"' % (
pypath.dirpath(),
pkgpath.dirpath(),
pytestpath,
args,
apigenpath,
pkgpath,
)
apigenscript = pkgpath.join('apigen/apigen.py') # XXX be more general here?
if not apigenscript.check(file=True):
apigenscript = pypath.join('apigen/apigen.py')
cmd = ('APIGENPATH="%s" PYTHONPATH="%s:%s" python '
'"%s" %s --apigen="%s" "%s"' % (apigenpath, pypath.dirpath(),
pkgpath.dirpath(), pytestpath,
args, apigenscript,
pkgpath))
if captureouterr:
cmd += ' > /dev/null 2>&1'
status = py.std.os.system(cmd)
return status
try:
output = py.process.cmdexec(cmd)
except py.error.Error, e:
return e.err or str(e)
return None
def main(pkgpath, apidocspath, rhost, rpath, args='', ignorefail=False):
print 'running tests'
errors = run_tests(pkgpath, args)
errors = run_tests(pkgpath, apidocspath, args)
if errors:
print >>sys.stderr, \
'Errors while running the unit tests: %s' % (errors,)

View File

@ -19,11 +19,22 @@ nomagic = False
import py
Option = py.test.config.Option
here = py.magic.autopath().dirpath()
option = py.test.config.addoptions("execnet options",
Option('-S', '',
action="store", dest="sshtarget", default=None,
help=("target to run tests requiring ssh, e.g. "
"user@codespeak.net")),
Option('', '--apigenpath',
action="store", dest="apigenpath",
default=here.join("../apigen").strpath,
type="string",
help="absolute path to where apigen docs are built"),
Option('', '--docpath',
action='store', dest='docpath',
default=here.join('doc').strpath, type='string',
help='absolute path to where the docs are built'),
)
dist_rsync_roots = ['.']

View File

@ -1,7 +1,8 @@
import py
from py.__.misc.rest import convert_rest_html, strip_html_header
from py.__.misc.difftime import worded_time
from py.__.doc.conftest import get_apigen_relpath
from py.__.doc.conftest import get_apigenpath, get_docpath
from py.__.apigen.linker import relpath
mydir = py.magic.autopath().dirpath()
html = py.xml.html
@ -10,9 +11,11 @@ class Page(object):
doctype = ('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n')
def __init__(self, project, title, stylesheeturl=None, type="text/html", encoding="ISO-8859-1"):
def __init__(self, project, title, targetpath, stylesheeturl=None,
type="text/html", encoding="ISO-8859-1"):
self.project = project
self.title = project.prefix_title + title
self.targetpath = targetpath
self.stylesheeturl = stylesheeturl
self.type = type
self.encoding = encoding
@ -23,22 +26,26 @@ class Page(object):
self.fill()
def a_docref(self, name, relhtmlpath):
return html.a(name, class_="menu", href=relhtmlpath)
docpath = get_docpath()
return html.a(name, class_="menu",
href=relpath(self.targetpath.strpath,
docpath.join(relhtmlpath).strpath))
def a_apigenref(self, name, relhtmlpath):
apigen_relpath = get_apigen_relpath()
path = apigen_relpath.rstrip("/") + "/" + relhtmlpath
return html.a(name, href=path, class_="menu")
apipath = get_apigenpath()
return html.a(name, class_="menu",
href=relpath(self.targetpath.strpath,
apipath.join(relhtmlpath).strpath))
def fill_menubar(self):
items = [
self.a_docref("index", "index.html"),
self.a_apigenref("api", "api/index.html"),
self.a_apigenref("source", "source/index.html"),
self.a_docref("contact", "contact.html"),
self.a_docref("download", "download.html"),
html.a("contact", href="contact.html", class_="menu"),
html.a("download", href="download.html", class_="menu"),
self.a_docref("index", "index.html"),
self.a_apigenref("api", "api/index.html"),
self.a_apigenref("source", "source/index.html"),
self.a_docref("contact", "contact.html"),
self.a_docref("download", "download.html"),
html.a("contact", href="contact.html", class_="menu"),
html.a("download", href="download.html", class_="menu"),
]
items2 = [items.pop(0)]
sep = " "
@ -47,26 +54,26 @@ class Page(object):
items2.append(item)
self.menubar = html.div(id="menubar", *items2)
def fill(self):
content_type = "%s;charset=%s" %(self.type, self.encoding)
self.head.append(html.title(self.title))
def fill(self):
content_type = "%s;charset=%s" %(self.type, self.encoding)
self.head.append(html.title(self.title))
self.head.append(html.meta(name="Content-Type", content=content_type))
if self.stylesheeturl:
if self.stylesheeturl:
self.head.append(
html.link(href=self.stylesheeturl,
media="screen", rel="stylesheet",
html.link(href=self.stylesheeturl,
media="screen", rel="stylesheet",
type="text/css"))
self.fill_menubar()
self.metaspace = html.div(
html.div(self.title, class_="project_title"),
html.div(self.title, class_="project_title"),
self.menubar,
id='metaspace')
self.body.append(self.project.logo)
self.body.append(self.metaspace)
self.body.append(self.project.logo)
self.body.append(self.metaspace)
self.contentspace = html.div(id="contentspace")
self.body.append(self.contentspace)
self.body.append(self.contentspace)
def unicode(self, doctype=True):
page = self._root.unicode()
@ -76,12 +83,14 @@ class Page(object):
return page
class PyPage(Page):
def fill(self):
super(PyPage, self).fill()
def get_menubar(self):
menubar = super(PyPage, self).get_menubar()
# base layout
self.menubar.append(
html.a("issue", href="https://codespeak.net/issue/py-dev/", class_="menu"),
)
menubar.append(
html.a("issue", href="https://codespeak.net/issue/py-dev/",
class_="menu"),
)
return menubar
def getrealname(username):
@ -99,8 +108,9 @@ def getrealname(username):
return username
class Project:
stylesheet = 'style.css'
class Project:
# string for url, path for local file
stylesheet = mydir.join('style.css')
title = "py lib"
prefix_title = "" # we have a logo already containing "py lib"
encoding = 'latin1'
@ -118,15 +128,23 @@ class Project:
def process(self, txtpath):
encoding = self.encoding
content = self.get_content(txtpath, encoding)
stylesheet = self.stylesheet
if not stylesheet.startswith('http') and \
not txtpath.dirpath(stylesheet).check():
stylesheet = None
docpath = get_docpath()
reloutputpath = txtpath.new(ext='.html').relto(mydir)
outputpath = docpath.join(reloutputpath)
content = convert_rest_html(content, txtpath, stylesheet=stylesheet, encoding=encoding)
stylesheet = self.stylesheet
if isinstance(self.stylesheet, py.path.local):
if not docpath.join(stylesheet.basename).check():
stylesheet.copy(docpath)
stylesheet = relpath(outputpath.strpath,
docpath.join(stylesheet.basename).strpath)
content = convert_rest_html(content, txtpath,
stylesheet=stylesheet, encoding=encoding)
content = strip_html_header(content, encoding=encoding)
page = self.Page(self, "[%s] " % txtpath.purebasename, stylesheeturl=stylesheet)
page = self.Page(self, "[%s] " % txtpath.purebasename,
outputpath, stylesheeturl=stylesheet)
try:
svninfo = txtpath.info()
@ -142,6 +160,5 @@ class Project:
id = 'docinfoline'))
page.contentspace.append(py.xml.raw(content))
htmlpath = txtpath.new(ext='.html')
htmlpath.write(page.unicode().encode(encoding))
outputpath.ensure().write(page.unicode().encode(encoding))

View File

@ -1,6 +1,10 @@
from __future__ import generators
import py
from py.__.misc import rest
from py.__.apigen.linker import relpath
import os
mypath = py.magic.autopath().dirpath()
Option = py.test.config.Option
option = py.test.config.addoptions("documentation check options",
@ -12,16 +16,24 @@ option = py.test.config.addoptions("documentation check options",
action="store_true", dest="forcegen", default=False,
help="force generation of html files even if they appear up-to-date"
),
Option('', '--apigenrelpath',
action="store", dest="apigen_relpath", default="../../apigen",
type="string",
help=("specify the relative path to apigen (used for link "
"generation)")
)
)
def get_apigenpath():
from py.__.conftest import option
path = os.environ.get('APIGENPATH')
if path is None:
path = option.apigenpath
return py.path.local(path)
def get_docpath():
from py.__.conftest import option
path = os.environ.get('DOCPATH')
if path is None:
path = option.docpath
return py.path.local(path)
def get_apigen_relpath():
return py.test.config.option.apigen_relpath.rstrip('\/') + "/"
return relpath(get_apigenpath().strpath, get_docpath().strpath)
def deindent(s, sep='\n'):
leastspaces = -1
@ -82,7 +94,7 @@ def restcheck(path):
def _checkskip(lpath):
if not option.forcegen:
if lpath.ext == '.txt':
htmlpath = lpath.new(ext='.html')
htmlpath = get_docpath().join(lpath.new(ext='.html').relto(mypath))
if htmlpath.check(file=1) and htmlpath.mtime() >= lpath.mtime():
py.test.skip("html file is up to date, use --forcegen to regenerate")
#return [] # no need to rebuild

View File

@ -52,7 +52,10 @@ def test_run_tests():
if py.std.sys.platform == "win32":
py.test.skip("update_website is not supposed to be run from win32")
pkgpath = setup_pkg('update_website_run_tests')
errors = update_website.run_tests(pkgpath, captureouterr=True)
errors = update_website.run_tests(pkgpath,
pkgpath.dirpath().join('apigen'),
captureouterr=True)
print errors
assert not errors
assert pkgpath.join('../apigen').check(dir=True)
assert pkgpath.join('../apigen/api/sub.foo.html').check(file=True)
@ -63,6 +66,8 @@ def test_run_tests_failure():
pkgpath = setup_pkg('update_website_run_tests_failure')
assert not pkgpath.join('../apigen').check(dir=True)
pkgpath.ensure('../apigen', file=True)
errors = update_website.run_tests(pkgpath, captureouterr=True)
errors = update_website.run_tests(pkgpath,
pkgpath.dirpath().join('apigen'),
captureouterr=True)
assert errors # some error message