| 1 |
#!/usr/bin/ruby -w
|
| 2 |
# Parse log files and extract info about packages that failed to build
|
| 3 |
# because of dependancies problems.
|
| 4 |
#
|
| 5 |
# Usage:
|
| 6 |
# (in the directory containing all the logs:)
|
| 7 |
# agf.rb <aptgf|ld> <file with TODO lines>
|
| 8 |
|
| 9 |
def gcc_getlines(lines, file)
|
| 10 |
g = lines.grep(/\d: error: /)
|
| 11 |
ig = lines.index(g[0])
|
| 12 |
ih = ig - 1
|
| 13 |
while (ih > 0)
|
| 14 |
if lines[ih] =~ /^\s+from / or
|
| 15 |
lines[ih] =~ /^In file included from / or
|
| 16 |
lines[ih] =~ /: In (member )?function / or
|
| 17 |
lines[ih] =~ /: warning: / or
|
| 18 |
lines[ih] =~ /: In constructor / or
|
| 19 |
lines[ih] =~ /^\s*\^+\s*$/ or
|
| 20 |
lines[ih] =~ / is deprecated. Use/ or
|
| 21 |
lines[ih] =~ /: At global scope:/
|
| 22 |
ih -= 1
|
| 23 |
else
|
| 24 |
if lines[ih] !~ /^\s*(gcc|cc|g\+\+|c\+\+|nasm)/
|
| 25 |
# puts "FNML: #{lines[ih]}"
|
| 26 |
end
|
| 27 |
ih += 1
|
| 28 |
break
|
| 29 |
end
|
| 30 |
end
|
| 31 |
return lines[ih..ig]
|
| 32 |
end
|
| 33 |
|
| 34 |
def ld_getlines(lines, file)
|
| 35 |
g = lines.grep(/ld returned 1 exit status$/)
|
| 36 |
ig = lines.index(g[0])
|
| 37 |
ih = ig - 1
|
| 38 |
while (ih > 0)
|
| 39 |
if lines[ih] =~ /undefined reference to/ or
|
| 40 |
lines[ih] =~ / In function / or
|
| 41 |
lines[ih] =~ / final link failed:/ or
|
| 42 |
lines[ih] =~ /: first defined here/ or
|
| 43 |
lines[ih] =~ /: cannot find / or
|
| 44 |
lines[ih] =~ /: unknown architecture of input file/ or
|
| 45 |
lines[ih] =~ /: hidden symbol / or
|
| 46 |
lines[ih] =~ /: multiple definition of / or
|
| 47 |
lines[ih] =~ /: warning: .* is deprecated; use .* instead/ or
|
| 48 |
lines[ih] =~ / cannot be preloaded: ignored./
|
| 49 |
ih -= 1
|
| 50 |
else
|
| 51 |
if lines[ih] !~ /^(gcc|cc|g\+\+|ld|c\+\+)/
|
| 52 |
# puts "FNML: #{lines[ih]}"
|
| 53 |
end
|
| 54 |
ih = ih += 1
|
| 55 |
break
|
| 56 |
end
|
| 57 |
end
|
| 58 |
if ih == ig
|
| 59 |
puts "NO LINES FOUND #{file}"
|
| 60 |
exit 1
|
| 61 |
end
|
| 62 |
return lines[ih...ig]
|
| 63 |
end
|
| 64 |
|
| 65 |
def aptgf_getlines(lines, file)
|
| 66 |
if not (g = lines.grep(/^The following packages have unmet dependencies:$/)).empty?
|
| 67 |
bps = lines.index(g[0]) + 1
|
| 68 |
g = lines.grep(/^E: Broken packages$/)
|
| 69 |
agf = lines.index(g[0]) - 1
|
| 70 |
buglog = lines[bps..agf]
|
| 71 |
return buglog
|
| 72 |
elsif not (g = lines.grep(/^E: Couldn't find package /)).empty?
|
| 73 |
return g
|
| 74 |
elsif not (g = lines.grep(/^E: Package .* has no installation candidate$/)).empty?
|
| 75 |
return g
|
| 76 |
elsif not (g = lines.grep(/^Errors were encountered while processing:$/)).empty?
|
| 77 |
bps = lines.index(g[0])
|
| 78 |
g = lines.grep(/^apt-get failed.$/)
|
| 79 |
agf = lines.index(g[0]) - 1
|
| 80 |
buglog = lines[bps..agf]
|
| 81 |
return buglog
|
| 82 |
else
|
| 83 |
puts "NO LINES FOUND #{file}"
|
| 84 |
exit 1
|
| 85 |
end
|
| 86 |
end
|
| 87 |
|
| 88 |
type = ARGV[0]
|
| 89 |
todo = ' TODO'
|
| 90 |
#todo = '' # for debugging
|
| 91 |
regexp = {
|
| 92 |
'aptgf' => / APT_GET_FAILED.*#{todo}/,
|
| 93 |
'ld' => /LD_ERROR.*#{todo}/,
|
| 94 |
'gcc' => /GCC_ERROR.*#{todo}/
|
| 95 |
}
|
| 96 |
IO::read(ARGV[1]).split(/\n/).grep(regexp[type]).each do |l|
|
| 97 |
pkg, rest = l.split(' ')
|
| 98 |
lst = Dir::glob("#{pkg}_*")
|
| 99 |
if lst.length == 0
|
| 100 |
puts "No matching logfile."
|
| 101 |
exit 1
|
| 102 |
elsif lst.length > 1
|
| 103 |
lst2 = lst.join("\n ")
|
| 104 |
puts "Several matching logfiles:\n #{lst2}"
|
| 105 |
exit 1
|
| 106 |
else
|
| 107 |
file = lst[0]
|
| 108 |
end
|
| 109 |
flines = IO::read(file).split(/\n/)
|
| 110 |
case type
|
| 111 |
when 'aptgf' then
|
| 112 |
lines = aptgf_getlines(flines, file)
|
| 113 |
when 'ld' then
|
| 114 |
lines = ld_getlines(flines, file)
|
| 115 |
when 'gcc' then
|
| 116 |
lines = gcc_getlines(flines, file)
|
| 117 |
end
|
| 118 |
lines.each do |l2|
|
| 119 |
printf "%-20s %s\n" % [pkg, l2]
|
| 120 |
end
|
| 121 |
end
|