diff options
Diffstat (limited to 'doc/gen_pkgdiff.py')
| -rw-r--r-- | doc/gen_pkgdiff.py | 234 |
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 | |||
| 37 | import os | ||
| 38 | import sys | ||
| 39 | import subprocess as sp | ||
| 40 | import xml.etree.ElementTree as ET | ||
| 41 | import re | ||
| 42 | |||
| 43 | repo_root = sp.check_output(["git", "rev-parse", "--show-toplevel"]).rstrip() | ||
| 44 | script_root = os.path.dirname(os.path.realpath(__file__)) | ||
| 45 | param_file = os.path.join(script_root, "docsrc_common/pardoc-distro.xml") | ||
| 46 | |||
| 47 | def 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 | |||
| 58 | def 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 (("”", """), ("”", """)): | ||
| 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 | |||
| 103 | if len(sys.argv) == 3: | ||
| 104 | new_file, prev_file = sys.argv[1:3] | ||
| 105 | |||
| 106 | elif 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 | |||
| 126 | else: | ||
| 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 | |||
| 139 | sys.stderr.write("New license file : %s\n" % new_file) | ||
| 140 | sys.stderr.write("Prev license file : %s\n" % prev_file) | ||
| 141 | |||
| 142 | old_pset, old_pdict = get_pkgs(prev_file) | ||
| 143 | new_pset, new_pdict = get_pkgs(new_file) | ||
| 144 | |||
| 145 | added = new_pset - old_pset # Set subtraction | ||
| 146 | removed = old_pset - new_pset # Set subtraction | ||
| 147 | common = old_pset & new_pset | ||
| 148 | changed = [ p for p in common if old_pdict[p] != new_pdict[p] ] | ||
| 149 | |||
| 150 | print '<?xml version="1.0" encoding="ISO-8859-1"?>' | ||
| 151 | print '<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"' | ||
| 152 | print '"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">' | ||
| 153 | print '<section id="relinfo-package-set-changes">' | ||
| 154 | print ' <title>Changes in the Set of Provided Package</title>' | ||
| 155 | print ' <para>' | ||
| 156 | print ' This section describes changes in the provided packages.' | ||
| 157 | print ' </para>' | ||
| 158 | print ' <section id="relinfo-added-packages">' | ||
| 159 | print ' <title>Added Packages</title>' | ||
| 160 | print ' <informaltable>' | ||
| 161 | print ' <tgroup cols="2">' | ||
| 162 | print ' <thead>' | ||
| 163 | print ' <row>' | ||
| 164 | print ' <entry>Package</entry>' | ||
| 165 | print ' <entry>Version(s)</entry>' | ||
| 166 | print ' </row>' | ||
| 167 | print ' </thead>' | ||
| 168 | print ' <tbody>' | ||
| 169 | |||
| 170 | for 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 | |||
| 176 | print ' </tbody>' | ||
| 177 | print ' </tgroup>' | ||
| 178 | print ' </informaltable>' | ||
| 179 | print ' </section>' | ||
| 180 | |||
| 181 | print ' <section id="relinfo-removed-packages">' | ||
| 182 | print ' <title>Removed Packages</title>' | ||
| 183 | print ' <informaltable>' | ||
| 184 | print ' <tgroup cols="2">' | ||
| 185 | print ' <thead>' | ||
| 186 | print ' <row>' | ||
| 187 | print ' <entry>Package</entry>' | ||
| 188 | print ' <entry>Version(s)</entry>' | ||
| 189 | print ' </row>' | ||
| 190 | print ' </thead>' | ||
| 191 | print ' <tbody>' | ||
| 192 | for 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>' | ||
| 197 | print ' </tbody>' | ||
| 198 | print ' </tgroup>' | ||
| 199 | print ' </informaltable>' | ||
| 200 | print ' </section>' | ||
| 201 | |||
| 202 | print ' <section id="relinfo-changed-packages">' | ||
| 203 | print ' <title>Changed Package Versions</title>' | ||
| 204 | print ' <informaltable>' | ||
| 205 | print ' <tgroup cols="3">' | ||
| 206 | print ' <thead>' | ||
| 207 | print ' <row>' | ||
| 208 | print ' <entry>Package</entry>' | ||
| 209 | print ' <entry>Previous Version(s)</entry>' | ||
| 210 | print ' <entry>New Version(s)</entry>' | ||
| 211 | print ' </row>' | ||
| 212 | print ' </thead>' | ||
| 213 | print ' <tbody>' | ||
| 214 | for 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 | |||
| 221 | print ' </tbody>' | ||
| 222 | print ' </tgroup>' | ||
| 223 | print ' </informaltable>' | ||
| 224 | print ' </section>' | ||
| 225 | print '</section>' | ||
| 226 | |||
| 227 | sys.stderr.write("Package Summary:\n") | ||
| 228 | sys.stderr.write(" Prev file : %3d\n" % len(old_pset)) | ||
| 229 | sys.stderr.write(" New file : %3d\n" % len(new_pset)) | ||
| 230 | sys.stderr.write(" Added : %3d\n" % len(added)) | ||
| 231 | sys.stderr.write(" Removed : %3d\n" % len(removed)) | ||
| 232 | sys.stderr.write(" Changed : %3d\n" % len(changed)) | ||
| 233 | sys.stderr.write(" Unchanged : %3d\n" % (len(common) - len(changed))) | ||
| 234 | sys.stderr.write("Done\n") | ||
