X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=dak%2Fexamine_package.py;h=182ed2d87ee19faf436db148917d43a7dd146970;hb=d9822f04453a1b62ca0aa66e2efeea35f654778f;hp=31549e11099c4a98aaa1cf6d81f3f940e25fcbdf;hpb=da6c203995ae67bf86d4424d94127798fe9e0b8b;p=dak.git diff --git a/dak/examine_package.py b/dak/examine_package.py old mode 100755 new mode 100644 index 31549e11..182ed2d8 --- a/dak/examine_package.py +++ b/dak/examine_package.py @@ -89,24 +89,24 @@ PACKAGE can be a .changes, .dsc, .deb or .udeb filename.""" # probably xml.sax.saxutils would work as well def html_escape(s): - return re_html_escaping.sub(lambda x: html_escaping.get(x.group(0)), s) + return re_html_escaping.sub(lambda x: html_escaping.get(x.group(0)), s) def escape_if_needed(s): - if use_html: - return re_html_escaping.sub(html_escaping.get, s) - else: - return s - + if use_html: + return re_html_escaping.sub(lambda x: html_escaping.get(x.group(0)), s) + else: + return s + def headline(s, level=2, bodyelement=None): - if use_html: - if bodyelement: - print """ - %(title)s - """%{"bodyelement":bodyelement,"title":html_escape(s)} + if use_html: + if bodyelement: + print """ + %(title)s + """%{"bodyelement":bodyelement,"title":html_escape(s)} + else: + print "%s" % (level, html_escape(s), level) else: - print "%s" % (level, html_escape(s), level) - else: - print "---- %s ----" % (s) + print "---- %s ----" % (s) # Colour definitions, 'end' isn't really for use @@ -128,22 +128,26 @@ html_colours = { 'maintainer': ('',"")} def colour_output(s, colour): - if use_html: - return ("%s%s%s" % (html_colours[colour][0], html_escape(s), html_colours[colour][1])) - else: - return ("%s%s%s" % (ansi_colours[colour], s, ansi_colours['end'])) - -def escaped_text(s): - if use_html: - return "
%s
" % (s) - else: - return s - -def formatted_text(s): - if use_html: - return "
%s
" % (html_escape(s)) - else: - return s + if use_html: + return ("%s%s%s" % (html_colours[colour][0], html_escape(s), html_colours[colour][1])) + else: + return ("%s%s%s" % (ansi_colours[colour], s, ansi_colours['end'])) + +def escaped_text(s, strip=False): + if use_html: + if strip: + s = s.strip() + return "
%s
" % (s) + else: + return s + +def formatted_text(s, strip=False): + if use_html: + if strip: + s = s.strip() + return "
%s
" % (html_escape(s)) + else: + return s def output_row(s): if use_html: @@ -151,7 +155,13 @@ def output_row(s): else: return s -def foldable_output(title, elementnameprefix, content): +def format_field(k,v): + if use_html: + return """%s:%s"""%(k,v) + else: + return "%s: %s"%(k,v) + +def foldable_output(title, elementnameprefix, content, norow=False): d = {'elementnameprefix':elementnameprefix} if use_html: print """
@@ -159,7 +169,10 @@ def foldable_output(title, elementnameprefix, content): headline(title, bodyelement="%(elementnameprefix)s-body"%d) if use_html: print """ """%d - print output_row(content) + if norow: + print content + else: + print output_row(content) if use_html: print """
""" @@ -168,9 +181,9 @@ def foldable_output(title, elementnameprefix, content): def get_depends_parts(depend) : v_match = re_version.match(depend) if v_match: - d_parts = { 'name' : v_match.group(1), 'version' : v_match.group(2) } + d_parts = { 'name' : v_match.group(1), 'version' : v_match.group(2) } else : - d_parts = { 'name' : depend , 'version' : '' } + d_parts = { 'name' : depend , 'version' : '' } return d_parts def get_or_list(depend) : @@ -190,19 +203,19 @@ def split_depends (d_str) : dep_list = get_comma_list(d_str) d = 0 while d < len(dep_list): - # put depends into their own list - depends_tree.append([dep_list[d]]) - d += 1 + # put depends into their own list + depends_tree.append([dep_list[d]]) + d += 1 d = 0 while d < len(depends_tree): - k = 0 - # split up Or'd depends into a multi-item list - depends_tree[d] = get_or_list(depends_tree[d][0]) - while k < len(depends_tree[d]): - # split depends into {package, version relation} - depends_tree[d][k] = get_depends_parts(depends_tree[d][k]) - k += 1 - d += 1 + k = 0 + # split up Or'd depends into a multi-item list + depends_tree[d] = get_or_list(depends_tree[d][0]) + while k < len(depends_tree[d]): + # split depends into {package, version relation} + depends_tree[d][k] = get_depends_parts(depends_tree[d][k]) + k += 1 + d += 1 return depends_tree def read_control (filename): @@ -214,81 +227,89 @@ def read_control (filename): deb_file = daklib.utils.open_file(filename) try: - extracts = apt_inst.debExtractControl(deb_file) - control = apt_pkg.ParseSection(extracts) + extracts = apt_inst.debExtractControl(deb_file) + control = apt_pkg.ParseSection(extracts) except: - print formatted_text("can't parse control info") - # TV-COMMENT: this will raise exceptions in two lines - control = '' + print formatted_text("can't parse control info") + deb_file.close() + raise deb_file.close() control_keys = control.keys() if control.has_key("Depends"): - depends_str = control.Find("Depends") - # create list of dependancy lists - depends = split_depends(depends_str) + depends_str = control.Find("Depends") + # create list of dependancy lists + depends = split_depends(depends_str) if control.has_key("Recommends"): - recommends_str = control.Find("Recommends") - recommends = split_depends(recommends_str) + recommends_str = control.Find("Recommends") + recommends = split_depends(recommends_str) if control.has_key("Section"): - section_str = control.Find("Section") - - c_match = re_contrib.search(section_str) - nf_match = re_nonfree.search(section_str) - if c_match : - # contrib colour - section = colour_output(section_str, 'contrib') - elif nf_match : - # non-free colour - section = colour_output(section_str, 'nonfree') - else : - # main - section = colour_output(section_str, 'main') + section_str = control.Find("Section") + + c_match = re_contrib.search(section_str) + nf_match = re_nonfree.search(section_str) + if c_match : + # contrib colour + section = colour_output(section_str, 'contrib') + elif nf_match : + # non-free colour + section = colour_output(section_str, 'nonfree') + else : + # main + section = colour_output(section_str, 'main') if control.has_key("Architecture"): - arch_str = control.Find("Architecture") - arch = colour_output(arch_str, 'arch') + arch_str = control.Find("Architecture") + arch = colour_output(arch_str, 'arch') if control.has_key("Maintainer"): - maintainer = control.Find("Maintainer") - localhost = re_localhost.search(maintainer) - if localhost: - #highlight bad email - maintainer = colour_output(maintainer, 'maintainer') - else: - maintainer = escape_if_needed(maintainer) + maintainer = control.Find("Maintainer") + localhost = re_localhost.search(maintainer) + if localhost: + #highlight bad email + maintainer = colour_output(maintainer, 'maintainer') + else: + maintainer = escape_if_needed(maintainer) return (control, control_keys, section, depends, recommends, arch, maintainer) -def read_dsc (dsc_filename): +def read_changes_or_dsc (filename): dsc = {} - dsc_file = daklib.utils.open_file(dsc_filename) + dsc_file = daklib.utils.open_file(filename) try: - dsc = daklib.utils.parse_changes(dsc_filename) + dsc = daklib.utils.parse_changes(filename) except: - return formatted_text("can't parse control info") + return formatted_text("can't parse .dsc control info") dsc_file.close() - filecontents = escape_if_needed(strip_pgp_signature(dsc_filename)) - - if dsc.has_key("build-depends"): - builddep = split_depends(dsc["build-depends"]) - builddepstr = create_depends_string(builddep) - filecontents = re_builddep.sub("Build-Depends: "+builddepstr, filecontents) - - if dsc.has_key("build-depends-indep"): - builddepindstr = create_depends_string(split_depends(dsc["build-depends-indep"])) - filecontents = re_builddepind.sub("Build-Depends-Indep: "+builddepindstr, filecontents) + filecontents = strip_pgp_signature(filename) + keysinorder = [] + for l in filecontents.split('\n'): + m = re.match(r'([-a-zA-Z0-9]*):', l) + if m: + keysinorder.append(m.group(1)) + + for k in dsc.keys(): + if k in ("build-depends","build-depends-indep"): + dsc[k] = create_depends_string(split_depends(dsc[k])) + elif k == "architecture": + if (dsc["architecture"] != "any"): + dsc['architecture'] = colour_output(dsc["architecture"], 'arch') + elif k in ("files","changes","description"): + if use_html: + dsc[k] = formatted_text(dsc[k], strip=True) + else: + dsc[k] = ('\n'+'\n'.join(map(lambda x: ' '+x, dsc[k].split('\n')))).rstrip() + else: + dsc[k] = escape_if_needed(dsc[k]) - if dsc.has_key("architecture") : - if (dsc["architecture"] != "any"): - newarch = colour_output(dsc["architecture"], 'arch') - filecontents = re_arch.sub("Architecture: " + newarch, filecontents) + keysinorder = filter(lambda x: not x.lower().startswith('checksums-'), keysinorder) + filecontents = '\n'.join(map(lambda x: format_field(x,dsc[x.lower()]), keysinorder))+'\n' return filecontents def create_depends_string (depends_tree): @@ -297,64 +318,63 @@ def create_depends_string (depends_tree): result = "" comma_count = 1 for l in depends_tree: - if (comma_count >= 2): - result += ", " - or_count = 1 - for d in l: - if (or_count >= 2 ): - result += " | " - # doesn't do version lookup yet. - - q = projectB.query("SELECT DISTINCT(b.package), b.version, c.name, su.suite_name FROM binaries b, files fi, location l, component c, bin_associations ba, suite su WHERE b.package='%s' AND b.file = fi.id AND fi.location = l.id AND l.component = c.id AND ba.bin=b.id AND ba.suite = su.id AND su.suite_name='%s' ORDER BY b.version desc" % (d['name'], suite)) - ql = q.getresult() - if ql: - i = ql[0] - - adepends = d['name'] - if d['version'] != '' : - adepends += " (%s)" % (d['version']) - - if i[2] == "contrib": - result += colour_output(adepends, "contrib") - elif i[2] == "non-free": - result += colour_output(adepends, "nonfree") - else : - result += colour_output(adepends, "main") - else: - adepends = d['name'] - if d['version'] != '' : - adepends += " (%s)" % (d['version']) - result += colour_output(adepends, "bold") - or_count += 1 - comma_count += 1 + if (comma_count >= 2): + result += ", " + or_count = 1 + for d in l: + if (or_count >= 2 ): + result += " | " + # doesn't do version lookup yet. + + q = projectB.query("SELECT DISTINCT(b.package), b.version, c.name, su.suite_name FROM binaries b, files fi, location l, component c, bin_associations ba, suite su WHERE b.package='%s' AND b.file = fi.id AND fi.location = l.id AND l.component = c.id AND ba.bin=b.id AND ba.suite = su.id AND su.suite_name='%s' ORDER BY b.version desc" % (d['name'], suite)) + ql = q.getresult() + if ql: + i = ql[0] + + adepends = d['name'] + if d['version'] != '' : + adepends += " (%s)" % (d['version']) + + if i[2] == "contrib": + result += colour_output(adepends, "contrib") + elif i[2] == "non-free": + result += colour_output(adepends, "nonfree") + else : + result += colour_output(adepends, "main") + else: + adepends = d['name'] + if d['version'] != '' : + adepends += " (%s)" % (d['version']) + result += colour_output(adepends, "bold") + or_count += 1 + comma_count += 1 return result def output_deb_info(filename): (control, control_keys, section, depends, recommends, arch, maintainer) = read_control(filename) if control == '': - return formatted_text("no control info") + return formatted_text("no control info") to_print = "" for key in control_keys : - output = " " + key + ": " if key == 'Depends': - output += create_depends_string(depends) + field_value = create_depends_string(depends) elif key == 'Recommends': - output += create_depends_string(recommends) + field_value = create_depends_string(recommends) elif key == 'Section': - output += section + field_value = section elif key == 'Architecture': - output += arch + field_value = arch elif key == 'Maintainer': - output += maintainer + field_value = maintainer elif key == 'Description': desc = control.Find(key) desc = re_newlinespace.sub('\n ', desc) - output += escape_if_needed(desc) + field_value = escape_if_needed(desc) else: - output += escape_if_needed(control.Find(key)) - to_print += output + '\n' - return escaped_text(to_print) + field_value = escape_if_needed(control.Find(key)) + to_print += " "+format_field(key,field_value)+'\n' + return to_print def do_command (command, filename, escaped=0): o = os.popen("%s %s" % (command, filename)) @@ -387,15 +407,15 @@ def get_copyright (deb_filename): res = "" if printed_copyrights.has_key(copyrightmd5) and printed_copyrights[copyrightmd5] != "%s (%s)" % (package, deb_filename): - res += formatted_text( "NOTE: Copyright is the same as %s.\n" % \ + res += formatted_text( "NOTE: Copyright is the same as %s.\n\n" % \ (printed_copyrights[copyrightmd5])) else: - printed_copyrights[copyrightmd5] = "%s (%s)" % (package, deb_filename) + printed_copyrights[copyrightmd5] = "%s (%s)" % (package, deb_filename) return res+formatted_text(copyright) def check_dsc (dsc_filename): - (dsc) = read_dsc(dsc_filename) - foldable_output(dsc_filename, "dsc", escaped_text(dsc)) + (dsc) = read_changes_or_dsc(dsc_filename) + foldable_output(dsc_filename, "dsc", dsc, norow=True) foldable_output("lintian check for %s" % dsc_filename, "source-lintian", do_lintian(dsc_filename)) def check_deb (deb_filename): @@ -403,13 +423,13 @@ def check_deb (deb_filename): packagename = filename.split('_')[0] if filename.endswith(".udeb"): - is_a_udeb = 1 + is_a_udeb = 1 else: - is_a_udeb = 0 + is_a_udeb = 0 foldable_output("control file for %s" % (filename), "binary-%s-control"%packagename, - output_deb_info(deb_filename)) + output_deb_info(deb_filename), norow=True) if is_a_udeb: foldable_output("skipping lintian check for udeb", "binary-%s-lintian"%packagename, @@ -455,14 +475,13 @@ def strip_pgp_signature (filename): if line.startswith("-----END PGP SIGNATURE"): inside_signature = 0 continue - contents += line + contents += line file.close() return contents -# Display the .changes [without the signature] -# TV-COMMENT: M. Ferrari has more formatting ideas def display_changes(changes_filename): - foldable_output(changes_filename, "changes", formatted_text(strip_pgp_signature(changes_filename))) + changes = read_changes_or_dsc(changes_filename) + foldable_output(changes_filename, "changes", changes, norow=True) def check_changes (changes_filename): display_changes(changes_filename) @@ -470,8 +489,8 @@ def check_changes (changes_filename): changes = daklib.utils.parse_changes (changes_filename) files = daklib.utils.build_file_list(changes) for file in files.keys(): - if file.endswith(".deb") or file.endswith(".udeb"): - check_deb(file) + if file.endswith(".deb") or file.endswith(".udeb"): + check_deb(file) if file.endswith(".dsc"): check_dsc(file) # else: => byhand @@ -485,24 +504,24 @@ def main (): ('H',"html-output","Examine-Package::Options::Html-Output"), ] for i in [ "Help", "Html-Output", "partial-html" ]: - if not Cnf.has_key("Examine-Package::Options::%s" % (i)): - Cnf["Examine-Package::Options::%s" % (i)] = "" + if not Cnf.has_key("Examine-Package::Options::%s" % (i)): + Cnf["Examine-Package::Options::%s" % (i)] = "" args = apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv) Options = Cnf.SubTree("Examine-Package::Options") if Options["Help"]: - usage() + usage() stdout_fd = sys.stdout for file in args: try: - if not Options["Html-Output"]: - # Pipe output for each argument through less - less_fd = os.popen("less -R -", 'w', 0) - # -R added to display raw control chars for colour - sys.stdout = less_fd + if not Options["Html-Output"]: + # Pipe output for each argument through less + less_fd = os.popen("less -R -", 'w', 0) + # -R added to display raw control chars for colour + sys.stdout = less_fd try: if file.endswith(".changes"): check_changes(file) @@ -513,10 +532,10 @@ def main (): else: daklib.utils.fubar("Unrecognised file type: '%s'." % (file)) finally: - if not Options["Html-Output"]: - # Reset stdout here so future less invocations aren't FUBAR - less_fd.close() - sys.stdout = stdout_fd + if not Options["Html-Output"]: + # Reset stdout here so future less invocations aren't FUBAR + less_fd.close() + sys.stdout = stdout_fd except IOError, e: if errno.errorcode[e.errno] == 'EPIPE': daklib.utils.warn("[examine-package] Caught EPIPE; skipping.") @@ -531,4 +550,3 @@ def main (): if __name__ == '__main__': main() -