File: aptcleanup

package info (click to toggle)
apt-listbugs 0.1.16
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,088 kB
  • ctags: 108
  • sloc: ruby: 2,280; sh: 210; makefile: 49
file content (130 lines) | stat: -rwxr-xr-x 4,426 bytes parent folder | download
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/ruby
#
# aptcleanup: filters /etc/apt/preferences to unpin packages when bugs are fixed
#
# Copyright (C) 2004       Masato Taruishi <taru@debian.org>
# Copyright (C) 2007       Jean Lepropre <jlepropre@gmail.com>
# Copyright (C) 2008-2014  Francesco Poli <invernomuto@paranoici.org>
# Copyright (C) 2009       Ryan Niebur <ryan@debian.org>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License with
#  the Debian GNU/Linux distribution in file /usr/share/common-licenses/GPL-2;
#  if not, write to the Free Software Foundation, Inc., 51 Franklin St,
#  Fifth Floor, Boston, MA 02110-1301, USA.
#
#

if File.expand_path(__FILE__).match(/^\/usr\/share\/apt-listbugs\//)
  $LOAD_PATH.unshift("/usr/share/apt-listbugs")
else
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "lib"))
end

require 'gettext'
include GetText

GetText::bindtextdomain("apt-listbugs")

require 'debian/apt_preferences'
require 'tmpdir'

APTCACHE = "/usr/bin/apt-cache"
LISTBUGS = "/usr/sbin/apt-listbugs"

# read APT preferences
pref_dir = "/etc/apt/preferences.d"
pref_name = "apt-listbugs"
pref_file = pref_dir + "/" + pref_name
begin
  p = Debian::AptPreferences.new
rescue Errno::ENOENT
  $stderr.puts sprintf("Cannot find %s: exiting!", pref_file) if $DEBUG
  exit 0
rescue Errno::EACCES
  $stderr.puts _("E: ") + sprintf(_("Cannot read from %s"), pref_file)
  exit 1
rescue
  $stderr.puts _("E: ") + "#{$!}"
  exit 1
end
pinned_pkg_keys = []
buggy_pkg_keys = []

# store APT preferences with no apt-listbugs pins in a temporary directory
unpinned_pref_dir = Dir.mktmpdir('apt_preferences_')

begin

FileUtils.cp_r "#{pref_dir}/.", unpinned_pref_dir
unpinned_pref_file = File.open(unpinned_pref_dir + "/" + pref_name, "w")
p.filter( buggy_pkg_keys, unpinned_pref_file )
unpinned_pref_file.flush

p.pins.each do |pin|
  if pin.listbugs?
    pinned_package = pin["Package"]
    pinned_pkg_keys << pinned_package

    # which version would get installed, if the pinning were removed ?
    unpinned_candidate_version = nil
    policy_cand_line = `env LC_ALL=C #{APTCACHE} -o Dir::Etc::PreferencesParts=#{unpinned_pref_dir} policy #{pinned_package} 2> /dev/null`.split("\n").select{|x| x.match("Candidate:")}[0]
    if policy_cand_line != nil
      policy_cand_vers = policy_cand_line.split(" ")[1]
      if policy_cand_vers != nil
        unpinned_candidate_version = "/" + policy_cand_vers
      end
    end
    if unpinned_candidate_version == "/(none)" or unpinned_candidate_version == nil
      unpinned_candidate_version = ""
      $stderr.puts "Warning: no candidate version for #{pinned_package}" if $DEBUG
    end
    pkg_key_with_vers = pinned_package + unpinned_candidate_version

    # read which bugs caused the pinning ("bugs that the user fears")
    feared_bugs = pin["Explanation"].scan(/#(\d+):/)
    feared_list = feared_bugs.join(',')

    # are bugs that the user fears still affecting unpinned_candidate_version ?
    $stderr.puts "Checking bug(s) #{feared_list} for #{pkg_key_with_vers}" if $DEBUG
    optionB = nil
    if feared_list != "" and feared_list != nil
      optionB = "-B #{feared_list}"
    end
    open("|#{LISTBUGS} -y -q #{optionB} list #{pkg_key_with_vers}") { |io|
      array = io.readlines()
      buggy_pkg_keys << pinned_package if array.size != 0
    }
    if $?.exitstatus != 0
      $stderr.puts sprintf("Error while invoking %s: exiting!", LISTBUGS) if $DEBUG
      exit 1
    end
  end
end

ensure

# get rid of the temporary directory along with its content
FileUtils.remove_entry unpinned_pref_dir

end

$stderr.puts "Pinned packages: #{pinned_pkg_keys.sort.join(' ')}" if $DEBUG
$stderr.puts "Buggy packages : #{buggy_pkg_keys.sort.join(' ')}" if $DEBUG

if (pinned_pkg_keys - buggy_pkg_keys).size > 0
  $stderr.puts _("Fixed packages : ") + (pinned_pkg_keys - buggy_pkg_keys).sort.join(' ')
end

# write out filtered preferences file
p.filter( buggy_pkg_keys )