changeset 5771:613a3ddb9a71

moved core site functionality into mx.py
author Doug Simon <doug.simon@oracle.com>
date Thu, 05 Jul 2012 16:24:18 +0200
parents 25e37b01b92a
children 2f7a03583a32
files mx/commands.py mxtool/mx.py
diffstat 2 files changed, 186 insertions(+), 151 deletions(-) [+]
line wrap: on
line diff
--- a/mx/commands.py	Thu Jul 05 11:18:12 2012 +0200
+++ b/mx/commands.py	Thu Jul 05 16:24:18 2012 +0200
@@ -969,142 +969,13 @@
         mx.abort('jacocoreport takes only one argument : an output directory')
     mx.run_java(['-jar', jacocoreport.get_path(True), '-in', 'jacoco.exec', '-g', join(_graal_home, 'graal'), out])
 
-def _fix_overview_summary(path, topLink):
-    """
-    Processes an "overview-summary.html" generated by javadoc to put the complete
-    summary text above the Packages table.
-    """
-
-    # This uses scraping and so will break if the relevant content produced by javadoc changes in any way!
-    with open(path) as fp:
-        content = fp.read()
-
-    class Chunk:
-        def __init__(self, content, ldelim, rdelim):
-            lindex = content.find(ldelim)
-            rindex = content.find(rdelim)
-            self.ldelim = ldelim
-            self.rdelim = rdelim
-            if lindex != -1 and rindex != -1 and rindex > lindex:
-                self.text = content[lindex + len(ldelim):rindex]
-            else:
-                self.text = None
-
-        def replace(self, content, repl):
-            lindex = content.find(self.ldelim)
-            rindex = content.find(self.rdelim)
-            old = content[lindex:rindex + len(self.rdelim)]
-            return content.replace(old, repl)
-
-    chunk1 = Chunk(content, """<div class="header">
-<div class="subTitle">
-<div class="block">""", """</div>
-</div>
-<p>See: <a href="#overview_description">Description</a></p>
-</div>""")
-
-    chunk2 = Chunk(content, """<div class="footer"><a name="overview_description">
-<!--   -->
-</a>
-<div class="subTitle">
-<div class="block">""", """</div>
-</div>
-</div>
-<!-- ======= START OF BOTTOM NAVBAR ====== -->""")
-
-    assert chunk1.text, 'Could not find header section in ' + path
-    assert chunk2.text, 'Could not find footer section in ' + path
-
-    content = chunk1.replace(content, '<div class="header"><div class="subTitle"><div class="block">' + topLink + chunk2.text +'</div></div></div>')
-    content = chunk2.replace(content, '')
-
-    with open(path, 'w') as fp:
-        fp.write(content)
-
 def site(args):
     """creates a website containing javadoc and the project dependency graph"""
 
-    parser = ArgumentParser(prog='site')
-    parser.add_argument('-d', '--base', action='store', help='directory for generated site', required=True, metavar='<dir>')
-
-    args = parser.parse_args(args)
-
-    args.base = os.path.abspath(args.base)
-    tmpbase = tempfile.mkdtemp(prefix=basename(args.base) + '.', dir=dirname(args.base))
-    unified = join(tmpbase, 'all')
-
-    try:
-        # Create javadoc for each project
-        mx.javadoc(['--base', tmpbase])
-
-        # Create unified javadoc for all projects
-        mx.javadoc(['--base', tmpbase,
-                    '--unified',
-                    '--arg', '@-windowtitle', '--arg', '@Graal OpenJDK Project Documentation',
-                    '--arg', '@-doctitle', '--arg', '@Graal OpenJDK Project Documentation',
-                    '--arg', '@-overview', '--arg', '@' + join(_graal_home, 'graal', 'overview.html')])
-        os.rename(join(tmpbase, 'javadoc'), unified)
-
-        # Generate dependency graph with Graphviz
-        _, tmp = tempfile.mkstemp()
-        try:
-            svg = join(tmpbase, 'all', 'modules.svg')
-            jpg = join(tmpbase, 'all', 'modules.jpg')
-            with open(tmp, 'w') as fp:
-                print >> fp, 'digraph projects {'
-                print >> fp, 'rankdir=BT;'
-                print >> fp, 'size = "13,13";'
-                print >> fp, 'node [shape=rect, fontcolor="blue"];'
-                #print >> fp, 'edge [color="green"];'
-                for p in mx.projects():
-                    print >> fp, '"' + p.name + '" [URL = "../' + p.name + '/javadoc/index.html", target = "_top"]'
-                    for dep in p.canonical_deps():
-                        if mx.project(dep, False):
-                            print >> fp, '"' + p.name + '" -> "' + dep + '"'
-                depths = dict()
-                for p in mx.projects():
-                    d = p.max_depth()
-                    depths.setdefault(d, list()).append(p.name)
-                for d, names in depths.iteritems():
-                    print >> fp, '{ rank = same; "' + '"; "'.join(names) + '"; }'
-                print >> fp, '}'
-
-            mx.run(['dot', '-Tsvg', '-o' + svg, '-Tjpg', '-o' + jpg, tmp])
-
-        finally:
-            os.remove(tmp)
-
-        # Post-process generated SVG to remove title elements which most browsers
-        # render as redundant (and annoying) tooltips.
-        with open(svg, 'r') as fp:
-            content = fp.read()
-        content = re.sub('<title>.*</title>', '', content)
-        content = re.sub('xlink:title="[^"]*"', '', content)
-        with open(svg, 'w') as fp:
-            fp.write(content)
-
-        # Post-process generated overview-summary.html files
-        top = join(tmpbase, 'all', 'overview-summary.html')
-        for root, _, files in os.walk(tmpbase):
-            for f in files:
-                if f == 'overview-summary.html':
-                    path = join(root, f)
-                    topLink = ''
-                    if top != path:
-                        link = os.path.relpath(join(tmpbase, 'all', 'index.html'), dirname(path))
-                        topLink = '<p><a href="' + link + '", target="_top"><b>[return to the overall Graal documentation]</b></a></p>'
-                    _fix_overview_summary(path, topLink)
-
-
-        if exists(args.base):
-            shutil.rmtree(args.base)
-        shutil.move(tmpbase, args.base)
-
-        print 'Created website - root is ' + join(args.base, 'all', 'index.html')
-
-    finally:
-        if exists(tmpbase):
-            shutil.rmtree(tmpbase)
+    return mx.site(['--name', 'Graal',
+                    '--overview', join(_graal_home, 'graal', 'overview.html'),
+                    '--title', 'Graal OpenJDK Project Documentation',
+                    '--dot-output-base', 'modules'] + args)
 
 def mx_init():
     _vmbuild = 'product'
--- a/mxtool/mx.py	Thu Jul 05 11:18:12 2012 +0200
+++ b/mxtool/mx.py	Thu Jul 05 16:24:18 2012 +0200
@@ -1993,6 +1993,7 @@
     parser.add_argument('--arg', action='append', dest='extra_args', help='extra Javadoc arguments (e.g. --arg @-use)', metavar='@<arg>', default=[])
     parser.add_argument('-m', '--memory', action='store', help='-Xmx value to pass to underlying JVM')
     parser.add_argument('--packages', action='store', help='comma separated packages to process (omit to process all packages)')
+    parser.add_argument('--exclude-packages', action='store', help='comma separated packages to exclude')
 
     args = parser.parse_args(args)
 
@@ -2006,6 +2007,10 @@
     if args.packages is not None:
         packages = [name for name in args.packages.split(',')]
 
+    exclude_packages = []
+    if args.exclude_packages is not None:
+        exclude_packages = [name for name in args.exclude_packages.split(',')]
+
     def outDir(p):
         if args.base is None:
             return join(p.dir, docDir)
@@ -2039,7 +2044,8 @@
                 if len([name for name in files if name.endswith('.java')]) != 0:
                     pkg = root[len(sourceDir) + 1:].replace(os.sep,'.')
                     if len(packages) == 0 or pkg in packages:
-                        pkgs.add(pkg)
+                        if len(exclude_packages) == 0 or not pkg in exclude_packages:
+                            pkgs.add(pkg)
         return pkgs
 
     extraArgs = [a.lstrip('@') for a in args.extra_args]
@@ -2066,26 +2072,33 @@
             cp = classpath(p.name, includeSelf=True)
             sp = os.pathsep.join(p.source_dirs())
             overviewFile = join(p.dir, 'overview.html')
-            overview = []
-            if exists(overviewFile):
-                overview = ['-overview', overviewFile]
+            delOverviewFile = False
+            if not exists(overviewFile):
+                with open(overviewFile, 'w') as fp:
+                    print >> fp, '<html><body>Documentation for the <code>' + p.name + '</code> project.</body></html>'
+                delOverviewFile = True
             nowarnAPI = []
             if not args.warnAPI:
                 nowarnAPI.append('-XDignore.symbol.file')
-            log('Generating {2} for {0} in {1}'.format(p.name, out, docDir))
-            run([java().javadoc, memory,
-                 '-windowtitle', p.name + ' javadoc',
-                 '-XDignore.symbol.file',
-                 '-classpath', cp,
-                 '-quiet',
-                 '-d', out,
-                 '-sourcepath', sp] +
-                 links +
-                 extraArgs +
-                 overview +
-                 nowarnAPI +
-                 list(pkgs))
-            log('Generated {2} for {0} in {1}'.format(p.name, out, docDir))
+            try:
+                log('Generating {2} for {0} in {1}'.format(p.name, out, docDir))
+                run([java().javadoc, memory,
+                     '-windowtitle', p.name + ' javadoc',
+                     '-XDignore.symbol.file',
+                     '-classpath', cp,
+                     '-quiet',
+                     '-d', out,
+                     '-overview', overviewFile,
+                     '-sourcepath', sp] +
+                     links +
+                     extraArgs +
+                     nowarnAPI +
+                     list(pkgs))
+                log('Generated {2} for {0} in {1}'.format(p.name, out, docDir))
+            finally:
+                if delOverviewFile:
+                    os.remove(overviewFile)
+                
     else:
         # The projects must be built to ensure javadoc can find class files for all referenced classes
         build(['--no-native'])
@@ -2119,6 +2132,156 @@
              list(pkgs))
         log('Generated {2} for {0} in {1}'.format(', '.join(names), out, docDir))
 
+def site(args):
+    """creates a website containing javadoc and the project dependency graph"""
+
+    parser = ArgumentParser(prog='site')
+    parser.add_argument('-d', '--base', action='store', help='directory for generated site', required=True, metavar='<dir>')
+    parser.add_argument('--name', action='store', help='name of overall documentation', required=True, metavar='<name>')
+    parser.add_argument('--overview', action='store', help='path to the overview content for overall documentation', required=True, metavar='<path>')
+    parser.add_argument('--projects', action='store', help='comma separated projects to process (omit to process all projects)')
+    parser.add_argument('--exclude-packages', action='store', help='comma separated packages to exclude', metavar='<pkgs>')
+    parser.add_argument('--dot-output-base', action='store', help='base file name (relative to <dir>/all) for project dependency graph .svg and .jpg files generated by dot (omit to disable dot generation)', metavar='<path>')
+    parser.add_argument('--title', action='store', help='value used for -windowtitle and -doctitle javadoc args for overall documentation (default: "<name>")', metavar='<title>')
+    args = parser.parse_args(args)
+
+    args.base = os.path.abspath(args.base)
+    tmpbase = tempfile.mkdtemp(prefix=basename(args.base) + '.', dir=dirname(args.base))
+    unified = join(tmpbase, 'all')
+
+    exclude_packages_arg = []
+    if args.exclude_packages is not None:
+        exclude_packages_arg = ['--exclude-packages', args.exclude_packages]
+
+    projects = sorted_deps()
+    projects_arg = []
+    if args.projects is not None:
+        projects_arg = ['--projects', args.projects]
+        projects = [project(name) for name in args.projects.split(',')]
+
+    try:
+        # Create javadoc for each project
+        javadoc(['--base', tmpbase] + exclude_packages_arg + projects_arg)
+
+        # Create unified javadoc for all projects
+        title = args.title if args.title is not None else args.name
+        javadoc(['--base', tmpbase,
+                 '--unified',
+                 '--arg', '@-windowtitle', '--arg', '@' + title,
+                 '--arg', '@-doctitle', '--arg', '@' + title,
+                 '--arg', '@-overview', '--arg', '@' + args.overview] + exclude_packages_arg + projects_arg)
+        os.rename(join(tmpbase, 'javadoc'), unified)
+
+        # Generate dependency graph with Graphviz
+        if args.dot_output_base is not None:
+            dot = join(tmpbase, 'all', str(args.dot_output_base) + '.dot')
+            svg = join(tmpbase, 'all', str(args.dot_output_base) + '.svg')
+            jpg = join(tmpbase, 'all', str(args.dot_output_base) + '.jpg')
+            with open(dot, 'w') as fp:
+                dim = len(projects)
+                print >> fp, 'digraph projects {'
+                print >> fp, 'rankdir=BT;'
+                print >> fp, 'size = "' + str(dim) + ',' + str(dim) + '";'
+                print >> fp, 'node [shape=rect, fontcolor="blue"];'
+                #print >> fp, 'edge [color="green"];'
+                for p in projects:
+                    print >> fp, '"' + p.name + '" [URL = "../' + p.name + '/javadoc/index.html", target = "_top"]'
+                    for dep in p.canonical_deps():
+                        if dep in [proj.name for proj in projects]:
+                            print >> fp, '"' + p.name + '" -> "' + dep + '"'
+                depths = dict()
+                for p in projects:
+                    d = p.max_depth()
+                    depths.setdefault(d, list()).append(p.name)
+                print >> fp, '}'
+
+            run(['dot', '-Tsvg', '-o' + svg, '-Tjpg', '-o' + jpg, dot])
+
+        # Post-process generated SVG to remove title elements which most browsers
+        # render as redundant (and annoying) tooltips.
+        with open(svg, 'r') as fp:
+            content = fp.read()
+        content = re.sub('<title>.*</title>', '', content)
+        content = re.sub('xlink:title="[^"]*"', '', content)
+        with open(svg, 'w') as fp:
+            fp.write(content)
+
+        # Post-process generated overview-summary.html files
+
+        def fix_overview_summary(path, topLink):
+            """
+            Processes an "overview-summary.html" generated by javadoc to put the complete
+            summary text above the Packages table.
+            """
+        
+            # This uses scraping and so will break if the relevant content produced by javadoc changes in any way!
+            with open(path) as fp:
+                content = fp.read()
+        
+            class Chunk:
+                def __init__(self, content, ldelim, rdelim):
+                    lindex = content.find(ldelim)
+                    rindex = content.find(rdelim)
+                    self.ldelim = ldelim
+                    self.rdelim = rdelim
+                    if lindex != -1 and rindex != -1 and rindex > lindex:
+                        self.text = content[lindex + len(ldelim):rindex]
+                    else:
+                        self.text = None
+        
+                def replace(self, content, repl):
+                    lindex = content.find(self.ldelim)
+                    rindex = content.find(self.rdelim)
+                    old = content[lindex:rindex + len(self.rdelim)]
+                    return content.replace(old, repl)
+        
+            chunk1 = Chunk(content, """<div class="header">
+<div class="subTitle">
+<div class="block">""", """</div>
+</div>
+<p>See: <a href="#overview_description">Description</a></p>
+</div>""")
+        
+            chunk2 = Chunk(content, """<div class="footer"><a name="overview_description">
+<!--   -->
+</a>
+<div class="subTitle">
+<div class="block">""", """</div>
+</div>
+</div>
+<!-- ======= START OF BOTTOM NAVBAR ====== -->""")
+        
+            assert chunk1.text, 'Could not find header section in ' + path
+            assert chunk2.text, 'Could not find footer section in ' + path
+        
+            content = chunk1.replace(content, '<div class="header"><div class="subTitle"><div class="block">' + topLink + chunk2.text +'</div></div></div>')
+            content = chunk2.replace(content, '')
+        
+            with open(path, 'w') as fp:
+                fp.write(content)
+        
+        top = join(tmpbase, 'all', 'overview-summary.html')
+        for root, _, files in os.walk(tmpbase):
+            for f in files:
+                if f == 'overview-summary.html':
+                    path = join(root, f)
+                    topLink = ''
+                    if top != path:
+                        link = os.path.relpath(join(tmpbase, 'all', 'index.html'), dirname(path))
+                        topLink = '<p><a href="' + link + '", target="_top"><b>[return to the overall ' + args.name + ' documentation]</b></a></p>'
+                    fix_overview_summary(path, topLink)
+
+
+        if exists(args.base):
+            shutil.rmtree(args.base)
+        shutil.move(tmpbase, args.base)
+
+        print 'Created website - root is ' + join(args.base, 'all', 'index.html')
+
+    finally:
+        if exists(tmpbase):
+            shutil.rmtree(tmpbase)
+
 def findclass(args):
     """find all classes matching a given substring"""
 
@@ -2181,6 +2344,7 @@
     'projectgraph': [projectgraph, ''],
     'javap': [javap, ''],
     'javadoc': [javadoc, '[options]'],
+    'site': [site, '[options]'],
     'netbeansinit': [netbeansinit, ''],
     'projects': [show_projects, ''],
 }