-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapt-downgrade.py
More file actions
executable file
·108 lines (99 loc) · 3.87 KB
/
apt-downgrade.py
File metadata and controls
executable file
·108 lines (99 loc) · 3.87 KB
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
#!/usr/bin/env python
def user_proceed(prompt, default=True):
if default == True and opts.yes:
return True
while True:
rin = raw_input(prompt)
if not rin:
return default
if "yes".startswith(rin.lower()):
return True
if "no".startswith(rin.lower()):
return False
def pick_origin(pkgver):
from sys import stderr
goodors = filter(lambda x: x.archive != "now", pkgver.origins)
if len(goodors) != 0:
if len(goodors) != 1:
print >>stderr, "Package %s-%s has multiple archives: " % (
pkgver.package.name, pkgver.version) + ", ".join(
map(lambda x: x.archive, goodors))
return goodors[0]
else:
assert len(pkgver.origins) == 1, pkgver.origins
return pkgver.origins[0]
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-u", "--update", action="store_true", default=False,
help="update the package cache first")
parser.add_option("-y", "--yes", action="store_true", default=False,
help="assume yes to all questions for which yes is the default")
parser.add_option("-f", "--force", action="store_true", default=False,
help="force the requested changes, don't resolve problems")
opts, args = parser.parse_args()
import apt, apt.progress, apt_pkg
# try to grab the system lock briefly, so we're not caught without it later
try:
with apt_pkg.SystemLock():
pass
except SystemError as exc:
print exc
raise SystemExit(100) # see apt-get(8)
print "Loading package cache..."
cache = apt.Cache()
if opts.update:
print "Updating package cache..."
cache.update(apt.progress.TextFetchProgress())
print "Searching for installed packages that are no longer available..."
for pkg in cache:
if pkg.installed and not pkg.candidate.downloadable:
cand = None
for ver in pkg.versions:
if ver.downloadable and ver > cand:
cand = ver
#print pkg.installed, "->", cand
if cand is None:
if user_proceed(
"Remove '%s' version %s [y]?" % (
pkg.name, pkg.installed.version)):
#pkg.candidate = None
pkg.mark_delete(autoFix=False, purge=False)
assert pkg.marked_delete
if cand != None:
if user_proceed(
"Force '%s' version\n from %s\n to %s (%s) [y]? "
% ( pkg.name,
pkg.installed.version,
cand.version,
pick_origin(cand).archive)):
pkg.candidate = cand
pkg.mark_install(autoFix=False, fromUser=False)
#pkg.mark_upgrade()
print "Resolving package problems (pass -f to disable this step)..."
apt.cache.ProblemResolver(cache).resolve()
if cache.get_changes():
print "The following changes will be made..."
for pkg in cache.get_changes():
print " %s %s => %s (%s)" % (
pkg.name,
pkg.installed and pkg.installed.version,
None if pkg.marked_delete else pkg.candidate.version,
pick_origin(pkg.candidate).archive)
print "%.1f MB will be downloaded" % (cache.required_download / 1e6)
if user_proceed("Do you wish to make the changes above? [n]? ", default=False):
while True:
try:
cache.commit(
apt.progress.TextFetchProgress(),
apt.progress.InstallProgress())
except SystemError as exc:
print exc
if not user_proceed("An error occurred, try again? [y]? "):
raise SystemExit(100) # see apt-get(8)
continue
else:
break
else:
print "User cancelled."
else:
print "There are no changes to be made."