1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
from docutils import nodes
from docutils.parsers.rst import Directive, directives
from sphinx import addnodes
from sphinx.domains.std import GenericObject
from sphinx.errors import SphinxError
from utils import build_table_from_list
def read_cabal_file(pkg_path):
import re
cabal_file = open(pkg_path, 'r').read()
pkg_name = re.search(r'^[nN]ame\s*:\s*([-a-zA-Z0-9]+)', cabal_file, re.MULTILINE)
if pkg_name is not None:
pkg_name = pkg_name.group(1)
else:
raise RuntimeError("Failed to parse `Name:` field from %s" % pkg_path)
pkg_version = re.search(r'^[vV]ersion\s*:\s*(\d+(\.\d+)*)', cabal_file, re.MULTILINE)
if pkg_version is not None:
pkg_version = pkg_version.group(1)
else:
raise RuntimeError("Failed to parse `Version:` field from %s" % pkg_path)
return (pkg_name, pkg_version)
class PackageListDirective(Directive):
has_content = True
def run(self):
self.assert_has_content()
packages = []
for line in self.content:
(pkg_path, _, reason) = line.partition(':')
if len(reason) == 0:
raise RuntimeError("Missing reason for inclusion of package %s"
% pkg_path)
# Parse reason
from docutils.statemachine import ViewList
reason_vl = ViewList(initlist=[reason.strip()])
reason_node = nodes.paragraph()
self.state.nested_parse(reason_vl, 0, reason_node)
packages.append((pkg_path, reason_node))
# Create column headers for table
header = [ nodes.inline(text=h)
for h in ["Package", "Version", "Reason for inclusion"] ]
package_list = [header]
for (pkg_path, reason) in sorted(packages):
(pkg_name, pkg_version) = read_cabal_file(pkg_path)
cells = [ nodes.paragraph(text=pkg_name),
nodes.inline(text=pkg_version),
reason ]
package_list.append(cells)
table = build_table_from_list(package_list, [20, 20, 40])
table['classes'].append('longtable')
return [table]
### Initialization
def setup(app):
app.add_directive('ghc-package-list', PackageListDirective)
return {'version': '1.0'}
|