]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - misc/build_helpers/gen-package-table.py
Update copy of gen-package-table.py in source tree.
[tahoe-lafs/tahoe-lafs.git] / misc / build_helpers / gen-package-table.py
1 #!/usr/bin/env python
2 # This script generates a table of dependencies in HTML format on stdout.
3 # It expects to be run in the tahoe-lafs-dep-eggs directory.
4
5 import re, os, sys
6 import pkg_resources
7
8 extensions = ('.egg', '.tar.bz2', '.tar.gz', '.exe')
9 platform_aliases = [('i686','x86'), ('i386','x86'), ('i86pc','x86'), ('win32','windows-x86'),
10                     ('win-amd64','windows-x86_64'), ('amd64','x86_64')]
11 min_supported_python = {'windows-x86': '2.7', 'windows-x86_64': '2.7'}
12 pkg_name_continuations = ('modules')
13
14 FILENAME_RE  = re.compile(r'([a-zA-Z_0-9\.]*)-([0-9\.a-vx-z_]*)(-py[0-9\.]*)?(-.*)?')
15 FILENAME_RE2 = re.compile(r'([a-zA-Z_0-9\.]*)-([0-9\.a-vx-z_]*)(win32|win-amd64)?(-py[0-9\.]*)?')
16
17 matrix = {}
18 pkgs = set()
19 platform_dependent_pkgs = set()
20 python_versions = set()
21
22 depdirs = ['.', '../tahoe-dep-sdists']
23 if len(sys.argv) > 1:
24     depdirs = sys.argv[1 :]
25
26 filenames = set()
27 for depdir in depdirs:
28     filenames = filenames.union(os.listdir(depdir))
29
30 def add(d, k, v):
31     if k in d:
32         d[k] += [v]
33     else:
34         d[k] = [v]
35
36 for fname in filenames:
37     for ext in extensions:
38         if fname.endswith(ext):
39             m = FILENAME_RE.match(fname[:-len(ext)])
40             try:
41                 pkg       = m.group(1)
42                 pkg2      = m.group(2)
43                 if pkg2 in pkg_name_continuations:
44                     pkg += '-' + pkg2
45                 else:
46                     pythonver = (m.group(3) or '-py')[3:]
47                     platform  = (m.group(4) or '-')[1:]
48             except (IndexError, AttributeError, TypeError):
49                 continue
50
51             if not pkg2 in pkg_name_continuations and not pythonver:
52                 m = FILENAME_RE2.match(fname[:-len(ext)])
53                 if m.group(3):
54                     try:
55                         platform  = m.group(3)
56                         pythonver = (m.group(4) or '-py')[3:]
57                     except (IndexError, AttributeError, TypeError):
58                         continue
59
60             for (alias, replacement) in platform_aliases:
61                 if platform.endswith(alias):
62                     platform = platform[:-len(alias)] + replacement
63                     break
64
65             pkgs.add(pkg)
66             if platform:
67                 platform_dependent_pkgs.add(pkg)
68             if pythonver not in matrix:
69                 python_versions.add(pythonver)
70                 matrix[pythonver] = {}
71             add(matrix[pythonver], platform, (pkg, fname))
72             break
73
74 platform_independent_pkgs = pkgs - platform_dependent_pkgs
75
76 width = 100 / (len(platform_dependent_pkgs) + 1)
77
78 def file_list(all_files, pkg):
79     files = sorted([(pkg_resources.parse_version(n), n) for (p, n) in all_files if pkg == p])
80     return '<br>&nbsp;'.join(['<a href="%s">%s</a>' % (f, f) for (v, f) in files])
81
82 greybgstyle = '; background-color: #E0E0E0'
83 nobgstyle = ''
84 unsupportedstyle = '; color: #C00000'
85
86 print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
87 print '<html>'
88 print '<head>'
89 print '  <meta http-equiv="Content-Type" content="text/html;charset=us-ascii">'
90 print '  <title>Software packages that Tahoe-LAFS depends on</title>'
91 print '</head>'
92 print '<body>'
93 print '<h2>What is this?</h2>'
94 print '<p>See <a href="https://tahoe-lafs.org/trac/tahoe-lafs/browser/docs/quickstart.rst">quickstart.rst</a>, <a href="https://tahoe-lafs.org/trac/tahoe-lafs/wiki/Installation">wiki:Installation</a>, and <a href="https://tahoe-lafs.org/trac/tahoe-lafs/wiki/CompileError">wiki:CompileError</a>.'
95 print '<h2>Software packages that Tahoe-LAFS depends on</h2>'
96 print
97 for pyver in reversed(sorted(python_versions)):
98     greybackground = False
99     if pyver:
100         print '<p>Packages for Python %s that have compiled C/C++ code:</p>' % (pyver,)
101         print '<table border="1">'
102         print '  <tr>'
103         print '    <th style="background-color: #FFFFD0" width="%d%%">&nbsp;Platform&nbsp;</th>' % (width,)
104         for pkg in sorted(platform_dependent_pkgs):
105             print '    <th style="background-color: #FFE8FF;" width="%d%%">&nbsp;%s&nbsp;</th>' % (width, pkg)
106         print '  </tr>'
107
108         first = True
109         for platform in sorted(matrix[pyver]):
110             unsupported_python = (platform in min_supported_python and
111                                   pyver.split('.') < min_supported_python[platform].split('.'))
112
113             if greybackground:
114                 bgstyle = greybgstyle
115             else:
116                 bgstyle = nobgstyle
117             greybackground = not greybackground
118             row_files = sorted(matrix[pyver][platform])
119             style1 = first and 'border-top: 2px solid #000000' or ''
120             style1 += bgstyle
121             style1 += unsupported_python and unsupportedstyle or ''
122             style2 = first and 'border-top: 2px solid #000000' or ''
123             style2 += bgstyle
124             annotated_platform = platform.replace('-', '&#x2011;') + (unsupported_python and '&nbsp;(unsupported)' or '')
125             print '  <tr>'
126             print '    <td style="%s">&nbsp;%s&nbsp;</td>' % (style1, annotated_platform)
127             for pkg in sorted(platform_dependent_pkgs):
128                 if pkg == 'pywin32' and not platform.startswith('windows'):
129                     print '    <td style="border: 0; text-align: center; %s"> n/a </td>' % (style2,)
130                 else:
131                     print '    <td style="%s">&nbsp;%s</td>' % (style2, file_list(row_files, pkg))
132             print '  </tr>'
133             first = False
134
135     print '</table>'
136     print
137
138 print '<p>Packages that are platform-independent or source-only:</p>'
139 print '<table border="1">'
140 print '  <tr>'
141 print '    <th style="background-color:#FFFFD0;">&nbsp;Package&nbsp;</th>'
142 print '    <th style="background-color:#FFE8FF;">&nbsp;All Python versions&nbsp;</th>'
143 print '  </tr>'
144
145 style1 = 'border-top: 2px solid #000000; background-color:#FFFFF0;'
146 style2 = 'border-top: 2px solid #000000;'
147 m = matrix['']['']
148 for pkg in sorted(platform_independent_pkgs):
149     print '  <tr>'
150     print '    <th style="%s">&nbsp;%s&nbsp;</th>' % (style1, pkg)
151     print '    <td style="%s">&nbsp;%s</td>' % (style2, file_list(m, pkg))
152     print '  </tr>'
153
154 print '</table>'
155
156 # The document does validate, but not when it is included at the bottom of a directory listing.
157 #print '<hr>'
158 #print '<a href="http://validator.w3.org/check?uri=referer" target="_blank"><img border="0" src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>'
159 print '</body></html>'