summaryrefslogtreecommitdiffstats
path: root/doc/gen_pkgdiff.py
diff options
context:
space:
mode:
Diffstat (limited to 'doc/gen_pkgdiff.py')
-rw-r--r--doc/gen_pkgdiff.py234
1 files changed, 234 insertions, 0 deletions
diff --git a/doc/gen_pkgdiff.py b/doc/gen_pkgdiff.py
new file mode 100644
index 0000000..11b3809
--- /dev/null
+++ b/doc/gen_pkgdiff.py
@@ -0,0 +1,234 @@
1#!/bin/python
2###############################################################################
3#
4# Diff two licenses.xml files. There are two cases:
5# * Two arguments
6# In this case, the two arguments are the two files to compare
7#
8# * No arguments
9# In this casem the license files are specified by the following
10# parameters in pardoc-distro.xml:
11# - prev_baseline
12# - prev_lic_file
13# - new_lic_file
14#
15# The result is presented as three sets:
16# 1) Removed
17# Packages present in the previous file, but not in the new.
18#
19# 2) Added
20# Packages present in the new file, but not in the previous.
21#
22# 3) Changed
23# Packages present in both files, but with different versions. If more than
24# one version of a package is included, then all difference in the version
25# set causes the package to be listed as changed.
26# E.g.
27# (v1) -> (v2)
28# (v1, v2) -> (v2, v3)
29#
30# Note that packages with the unchanged version is not listed.
31#
32# The output is presented as XML code printed to stdout. A summary is printed
33# to STDERR at the end.
34#
35###############################################################################
36
37import os
38import sys
39import subprocess as sp
40import xml.etree.ElementTree as ET
41import re
42
43repo_root = sp.check_output(["git", "rev-parse", "--show-toplevel"]).rstrip()
44script_root = os.path.dirname(os.path.realpath(__file__))
45param_file = os.path.join(script_root, "docsrc_common/pardoc-distro.xml")
46
47def get_param(param_name):
48 pat = re.compile("%s.*>([^<>]+)</" % param_name)
49
50 with open(param_file) as f:
51 for line in f:
52 m = pat.search(line)
53 if m:
54 return m.group(1)
55
56 return None
57
58def get_pkgs(file_spec):
59 if file_spec.find(":") >= 0:
60 s = sp.check_output(("git", "show", file_spec))
61 else:
62 f = open(file_spec)
63 s = f.read()
64 f.close()
65 del f
66
67 # ET can't handle some special quotes
68 for old, new in (("&rdquor;", "&quot;"), ("&rdquo;", "&quot;")):
69 s = s.replace(old, new)
70
71 root = ET.fromstring(s)
72
73 for node in root.iter("section"):
74 if "id" in node.attrib:
75 if node.attrib["id"] == "licenses_packages":
76 break
77
78 else:
79 return None
80
81 for node in node:
82 if node.tag == "informaltable":
83 break
84 else:
85 return None
86
87 tab = node[0][-1]
88
89 plist = dict()
90 for row in tab:
91 pname = row[0].text
92 pver = row[1].text
93 if not pname in plist:
94 plist[pname] = set()
95
96 plist[pname].add(pver)
97
98 return set(plist), plist
99
100#----------------------------------------
101
102
103if len(sys.argv) == 3:
104 new_file, prev_file = sys.argv[1:3]
105
106elif len(sys.argv) == 1:
107 prev_baseline = get_param("prev_baseline")
108 prev_lic_file = get_param("prev_lic_file")
109 new_lic_file = get_param("new_lic_file")
110
111 if not (prev_baseline and prev_lic_file and new_lic_file):
112 print '<?xml version="1.0" encoding="ISO-8859-1"?>'
113 print '<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"'
114 print '"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">'
115 print '<section id="relinfo-package-set-changes">'
116 print ' <title>Changes in the Set of Provided Package</title>'
117 print ' <para>'
118 print ' N/A. No previous baseline defined.'
119 print ' </para>'
120 print '</section>'
121 exit(0)
122
123 new_file = os.path.relpath(os.path.join(repo_root, new_lic_file))
124 prev_file = "%s:%s" % (prev_baseline, prev_lic_file)
125
126else:
127 sys.stderr.write("Usage:\n")
128 sys.stderr.write(" 1) %s\n" % sys.argv[0])
129 sys.stderr.write(" 2) %s " % sys.argv[0])
130 sys.stderr.write("<new license file> <old license file>\n")
131 sys.stderr.write("\n")
132 sys.stderr.write("In case 1, the files are specified using the following\n")
133 sys.stderr.write("parameters in pardoc-distro.xml:\n")
134 sys.stderr.write(" - prev_baseline\n")
135 sys.stderr.write(" - prev_lic_file\n")
136 sys.stderr.write(" - new_lic_file\n")
137 exit()
138
139sys.stderr.write("New license file : %s\n" % new_file)
140sys.stderr.write("Prev license file : %s\n" % prev_file)
141
142old_pset, old_pdict = get_pkgs(prev_file)
143new_pset, new_pdict = get_pkgs(new_file)
144
145added = new_pset - old_pset # Set subtraction
146removed = old_pset - new_pset # Set subtraction
147common = old_pset & new_pset
148changed = [ p for p in common if old_pdict[p] != new_pdict[p] ]
149
150print '<?xml version="1.0" encoding="ISO-8859-1"?>'
151print '<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"'
152print '"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">'
153print '<section id="relinfo-package-set-changes">'
154print ' <title>Changes in the Set of Provided Package</title>'
155print ' <para>'
156print ' This section describes changes in the provided packages.'
157print ' </para>'
158print ' <section id="relinfo-added-packages">'
159print ' <title>Added Packages</title>'
160print ' <informaltable>'
161print ' <tgroup cols="2">'
162print ' <thead>'
163print ' <row>'
164print ' <entry>Package</entry>'
165print ' <entry>Version(s)</entry>'
166print ' </row>'
167print ' </thead>'
168print ' <tbody>'
169
170for p in sorted(list(added)):
171 print ' <row>'
172 print ' <entry>%s</entry>' % p
173 print ' <entry>%s</entry>' % ", ".join(sorted(new_pdict[p]))
174 print ' </row>'
175
176print ' </tbody>'
177print ' </tgroup>'
178print ' </informaltable>'
179print ' </section>'
180
181print ' <section id="relinfo-removed-packages">'
182print ' <title>Removed Packages</title>'
183print ' <informaltable>'
184print ' <tgroup cols="2">'
185print ' <thead>'
186print ' <row>'
187print ' <entry>Package</entry>'
188print ' <entry>Version(s)</entry>'
189print ' </row>'
190print ' </thead>'
191print ' <tbody>'
192for p in sorted(list(removed)):
193 print ' <row>'
194 print ' <entry>%s</entry>' % p
195 print ' <entry>%s</entry>' % ", ".join(sorted(old_pdict[p]))
196 print ' </row>'
197print ' </tbody>'
198print ' </tgroup>'
199print ' </informaltable>'
200print ' </section>'
201
202print ' <section id="relinfo-changed-packages">'
203print ' <title>Changed Package Versions</title>'
204print ' <informaltable>'
205print ' <tgroup cols="3">'
206print ' <thead>'
207print ' <row>'
208print ' <entry>Package</entry>'
209print ' <entry>Previous Version(s)</entry>'
210print ' <entry>New Version(s)</entry>'
211print ' </row>'
212print ' </thead>'
213print ' <tbody>'
214for p in sorted(list(changed)):
215 print ' <row>'
216 print ' <entry>%s</entry>' % p
217 print ' <entry>%s</entry>' % ", ".join(sorted(old_pdict[p]))
218 print ' <entry>%s</entry>' % ", ".join(sorted(new_pdict[p]))
219 print ' </row>'
220
221print ' </tbody>'
222print ' </tgroup>'
223print ' </informaltable>'
224print ' </section>'
225print '</section>'
226
227sys.stderr.write("Package Summary:\n")
228sys.stderr.write(" Prev file : %3d\n" % len(old_pset))
229sys.stderr.write(" New file : %3d\n" % len(new_pset))
230sys.stderr.write(" Added : %3d\n" % len(added))
231sys.stderr.write(" Removed : %3d\n" % len(removed))
232sys.stderr.write(" Changed : %3d\n" % len(changed))
233sys.stderr.write(" Unchanged : %3d\n" % (len(common) - len(changed)))
234sys.stderr.write("Done\n")