]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - misc/build_helpers/gen-package-table.py
misc: gen-package-table: show only the highest-numbered package for each platform...
[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 FILENAME_RE  = re.compile(r'([a-zA-Z_0-9\.]*)-([0-9\.a-vx-z_]*)(-py[0-9\.]*)?(-.*)?')
12 FILENAME_RE2 = re.compile(r'([a-zA-Z_0-9\.]*)-([0-9\.a-vx-z_]*)(win32|win-amd64)?(-py[0-9\.]*)?')
13
14 matrix = {}
15 pkgs = set()
16 platform_dependent_pkgs = set()
17 python_versions = set()
18
19 depdir = '.'
20 if len(sys.argv) > 1:
21     depdir = sys.argv[1]
22
23 filenames = os.listdir(depdir)
24
25 def add(d, k, v):
26     if k in d:
27         d[k] += [v]
28     else:
29         d[k] = [v]
30
31 for fname in filenames:
32     for ext in extensions:
33         if fname.endswith(ext):
34             m = FILENAME_RE.match(fname[:-len(ext)])
35             try:
36                 pkg       = m.group(1)
37                 pythonver = (m.group(3) or '-py')[3:]
38                 platform  = (m.group(4) or '-')[1:]
39             except (IndexError, AttributeError, TypeError):
40                 continue
41
42             if not pythonver:
43                 m = FILENAME_RE2.match(fname[:-len(ext)])
44                 if m.group(3):
45                     try:
46                         platform  = m.group(3)
47                         pythonver = (m.group(4) or '-py')[3:]
48                     except (IndexError, AttributeError, TypeError):
49                         continue
50
51             for (alias, replacement) in platform_aliases:
52                 if platform.endswith(alias):
53                     platform = platform[:-len(alias)] + replacement
54                     break
55
56             pkgs.add(pkg)
57             if platform:
58                 platform_dependent_pkgs.add(pkg)
59             if pythonver not in matrix:
60                 python_versions.add(pythonver)
61                 matrix[pythonver] = {}
62             add(matrix[pythonver], platform, (pkg, fname))
63             break
64
65 platform_independent_pkgs = pkgs - platform_dependent_pkgs
66
67 width = 100 / (len(platform_independent_pkgs) + 1)
68
69 print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
70 print '<html>'
71 print '<head>'
72 print '  <meta http-equiv="Content-Type" content="text/html;charset=us-ascii">'
73 print '  <title>Software packages that Tahoe-LAFS depends on</title>'
74 print '</head>'
75 print '<body>'
76 print '<h2>Software packages that Tahoe-LAFS depends on</h2>'
77 print
78 for pyver in reversed(sorted(python_versions)):
79     if pyver:
80         print '<p>Packages for Python %s that have compiled C/C++ code:</p>' % (pyver,)
81         print '<table border="1">'
82         print '  <tr>'
83         print '    <th style="background-color: #FFFFD0" width="%d%%">&nbsp;Platform&nbsp;</th>' % (width,)
84         for pkg in sorted(platform_dependent_pkgs):
85             print '    <th style="background-color:#FFE8FF;" width="%d%%">&nbsp;%s&nbsp;</th>' % (width, pkg)
86         print '  </tr>'
87
88         first = True
89         for platform in sorted(matrix[pyver]):
90             row_files = sorted(matrix[pyver][platform])
91             style1 = first and 'border-top: 2px solid #000000; background-color: #FFFFF0' or 'background-color: #FFFFF0'
92             style2 = first and 'border-top: 2px solid #000000' or ''
93             print '  <tr>'
94             print '    <td style="%s">&nbsp;%s&nbsp;</td>' % (style1, platform,)
95             for pkg in sorted(platform_dependent_pkgs):
96                 files = [n for (p, n) in row_files if pkg == p]
97                 bestfile = files and max([(pkg_resources.parse_version(x), x) for x in files])[1] or None
98                 if pkg == 'pywin32' and not platform.startswith('windows'):
99                     print '    <td style="border: 0; text-align: center; %s"> n/a </td>' % (style2,)
100                 else:
101                     print '    <td style="%s">&nbsp;%s</td>' % (style2,
102                             bestfile and '<a href="%s">%s</a>' % (bestfile, bestfile) or '')
103             print '  </tr>'
104             first = False
105
106     print '</table>'
107     print
108
109 print '<p>Packages that are platform-independent or source-only:</p>'
110 print '<table border="1">'
111 print '  <tr>'
112 print '    <th style="background-color:#FFFFD0;">&nbsp;Package&nbsp;</th>'
113 print '    <th style="background-color:#FFE8FF;">&nbsp;All Python versions&nbsp;</th>'
114 print '  </tr>'
115
116 style1 = 'border-top: 2px solid #000000; background-color:#FFFFF0;'
117 style2 = 'border-top: 2px solid #000000;'
118 m = matrix['']['']
119 for pkg in sorted(platform_independent_pkgs):
120     print '  <tr>'
121     print '    <th style="%s">&nbsp;%s&nbsp;</th>' % (style1, pkg)
122     files = [n for (p, n) in m if pkg == p]
123     print '    <td style="%s">&nbsp;%s</td>' % (style2, '<br>&nbsp;'.join(['<a href="%s">%s</a>' % (f, f) for f in files]))
124     print '  </tr>'
125
126 print '</table>'
127
128 # The document does validate, but not when it is included at the bottom of a directory listing.
129 #print '<hr>'
130 #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>'
131 print '</body></html>'