File: aptcleanup

package info (click to toggle)
apt-listbugs 0.1.47
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,048 kB
  • sloc: ruby: 2,339; sh: 166; makefile: 64
file content (128 lines) | stat: -rwxr-xr-x 4,395 bytes parent folder | download | duplicates (2)
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
#!/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-2019  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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
#

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

require 'gettext'
include GetText

GetText::bindtextdomain("apt-listbugs")

require 'aptlistbugs/debian/apt_preferences'
require 'tmpdir'

APTCACHE = "/usr/bin/apt-cache"
LISTBUGS = "/usr/bin/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} -a -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 )