Index: twisted/python/_release.py
===================================================================
--- twisted/python/_release.py	(revision 33529)
+++ twisted/python/_release.py	(working copy)
@@ -424,8 +424,7 @@
     """
     Generate API documentation from source files using
     U{pydoctor<http://codespeak.net/~mwh/pydoctor/>}.  This requires
-    pydoctor to be installed and usable (which means you won't be able to
-    use it with Python 2.3).
+    pydoctor to be installed and usable.
     """
     def build(self, projectName, projectURL, sourceURL, packagePath,
               outputPath):
@@ -1367,3 +1366,66 @@
             sys.exit("Must specify two arguments: "
                      "Twisted checkout and destination path")
         self.buildAPIDocs(FilePath(args[0]), FilePath(args[1]))
+
+
+
+class BuildDocsScript(object):
+    """
+    A thing for building the main documentation. See L{main}.
+    """
+
+    def buildDocs(self, projectRoot, output, template):
+        """
+        Build the main documentation of Twisted, with our project policy.
+
+        @param projectRoot: A L{FilePath} representing the root of the Twisted
+            checkout.
+        @type projectRoot: L{FilePath}
+        @param output: A L{FilePath} pointing to the desired output directory.
+        @type output: L{FilePath}
+        @param template: A L{FilePath} pointing to the template file that is
+            used for the look and feel of the howto documentation.
+        @type template: L{FilePath}
+        """
+        version = Project(projectRoot.child("twisted")).getVersion()
+        versionString = version.base()
+        apiURL = "http://twistedmatrix.com/documents/%s/api/" % versionString
+        docRoot = projectRoot.child("doc")
+        howtoRoot = docRoot.descendant(["core", "howto"])
+
+        done = {}
+        for p in docRoot.walk():
+            if p.basename() == 'man':
+                done[p] = True
+                ManBuilder().build(p)
+
+        for p in docRoot.walk():
+            if p.basename().endswith('.xhtml'):
+                if p.parent() not in done:
+                    done[p.parent()] = True
+                    DocBuilder().build(
+                        versionString, howtoRoot, p.parent(),
+                        template,
+                        apiURL + "%s.html",
+                        False)
+
+        for p in done:
+            print '     ', p.path
+        BookBuilder().build(howtoRoot, done.keys(),
+                            howtoRoot.child('book.tex'),
+                            FilePath('book.pdf'))
+
+
+    def main(self, args):
+        """
+        Build the main documentation.
+
+        @type args: list of str
+        @param args: The command line arguments to process.  This must contain
+            three strings: the path to the root of the Twisted checkout, a path
+            to an output directory, and the path to the Twisted website template.
+        """
+        if len(args) != 3:
+            sys.exit("Must specify three arguments: "
+                     "Twisted checkout path, destination path, and template path.")
+        self.buildDocs(FilePath(args[0]), FilePath(args[1]), FilePath(args[2]))
Index: twisted/python/test/test_release.py
===================================================================
--- twisted/python/test/test_release.py	(revision 33529)
+++ twisted/python/test/test_release.py	(working copy)
@@ -35,7 +35,7 @@
 from twisted.python._release import NoDocumentsFound, filePathDelta
 from twisted.python._release import CommandFailed, BookBuilder
 from twisted.python._release import DistributionBuilder, APIBuilder
-from twisted.python._release import BuildAPIDocsScript
+from twisted.python._release import BuildAPIDocsScript, BuildDocsScript
 from twisted.python._release import buildAllTarballs, runCommand
 from twisted.python._release import UncleanWorkingDirectory, NotWorkingDirectory
 from twisted.python._release import ChangeVersionsScript, BuildTarballsScript
@@ -911,6 +911,31 @@
         self.assertEqual(linkrel, "../../howto/")
 
 
+    def test_docsBuilderScriptMainRequiresThreeArguments(self):
+        """
+        SystemExit is raised when the incorrect number of command line
+        arguments are passed to the main documentation building script.
+        """
+        script = BuildDocsScript()
+        self.assertRaises(SystemExit, script.main, [])
+        self.assertRaises(SystemExit, script.main, ["foo"])
+        self.assertRaises(SystemExit, script.main, ["foo", "bar"])
+        self.assertRaises(SystemExit, script.main, ["foo", "bar", "baz", "boo"])
+
+
+    def test_docsBuilderScriptMain(self):
+        """
+        The main documentation building script invokes the same code that
+        L{test_buildWithPolicy} tests.
+        """
+        script = BuildDocsScript()
+        calls = []
+        script.buildDocs = lambda a, b, c: calls.append((a, b, c))
+        script.main(["hello", "hi", "there"])
+        self.assertEqual(calls, [(FilePath("hello"), FilePath("hi"),
+            FilePath("there"))])
+
+
 
 class APIBuilderTestCase(TestCase):
     """
Index: bin/admin/build-docs
===================================================================
--- bin/admin/build-docs	(revision 0)
+++ bin/admin/build-docs	(revision 0)
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+
+# Copyright (c) Twisted Matrix Laboratories.
+# See LICENSE for details.
+
+# This script is not meant to be distributed to users of Twisted.
+# It is only for use in making upstream Twisted releases.
+
+import sys
+
+from twisted.python._release import BuildDocsScript
+
+BuildDocsScript().main(sys.argv[1:])

Property changes on: bin/admin/build-docs
___________________________________________________________________
Added: svn:executable
   + *

