|
|
@ -244,6 +244,7 @@ class Britney:
|
|
|
|
self.hints = self.read_hints(self.options.unstable)
|
|
|
|
self.hints = self.read_hints(self.options.unstable)
|
|
|
|
self.excuses = []
|
|
|
|
self.excuses = []
|
|
|
|
self.dependencies = {}
|
|
|
|
self.dependencies = {}
|
|
|
|
|
|
|
|
self.selected = []
|
|
|
|
|
|
|
|
|
|
|
|
def __parse_arguments(self):
|
|
|
|
def __parse_arguments(self):
|
|
|
|
"""Parse the command line arguments
|
|
|
|
"""Parse the command line arguments
|
|
|
@ -377,7 +378,7 @@ class Britney:
|
|
|
|
'rdepends': [],
|
|
|
|
'rdepends': [],
|
|
|
|
'rconflicts': [],
|
|
|
|
'rconflicts': [],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for k in ('Pre-Depends', 'Depends', 'Provides', 'Conflicts'):
|
|
|
|
for k in ('Pre-Depends', 'Depends', 'Provides', 'Conflicts', 'Section'):
|
|
|
|
v = get_field(k)
|
|
|
|
v = get_field(k)
|
|
|
|
if v: dpkg[k.lower()] = v
|
|
|
|
if v: dpkg[k.lower()] = v
|
|
|
|
|
|
|
|
|
|
|
@ -483,6 +484,20 @@ class Britney:
|
|
|
|
self.__log("Bugs, unable to parse \"%s\"" % line, type="E")
|
|
|
|
self.__log("Bugs, unable to parse \"%s\"" % line, type="E")
|
|
|
|
return bugs
|
|
|
|
return bugs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def write_bugs(self, basedir, bugs):
|
|
|
|
|
|
|
|
"""Write the release critical bug summary to the specified directory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
For a more detailed explanation of the format, please check the method
|
|
|
|
|
|
|
|
read_bugs.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
filename = os.path.join(basedir, "Bugs")
|
|
|
|
|
|
|
|
self.__log("Writing RC bugs count to %s" % filename)
|
|
|
|
|
|
|
|
f = open(filename, 'w')
|
|
|
|
|
|
|
|
for pkg in sorted(bugs.keys()):
|
|
|
|
|
|
|
|
if bugs[pkg] == 0: continue
|
|
|
|
|
|
|
|
f.write("%s %d\n" % (pkg, bugs[pkg]))
|
|
|
|
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
|
|
|
|
def __maxver(self, pkg, dist):
|
|
|
|
def __maxver(self, pkg, dist):
|
|
|
|
"""Return the maximum version for a given package name
|
|
|
|
"""Return the maximum version for a given package name
|
|
|
|
|
|
|
|
|
|
|
@ -562,6 +577,20 @@ class Britney:
|
|
|
|
self.__log("Dates, unable to parse \"%s\"" % line, type="E")
|
|
|
|
self.__log("Dates, unable to parse \"%s\"" % line, type="E")
|
|
|
|
return dates
|
|
|
|
return dates
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def write_dates(self, basedir, dates):
|
|
|
|
|
|
|
|
"""Write the upload date for the packages to the specified directory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
For a more detailed explanation of the format, please check the method
|
|
|
|
|
|
|
|
read_dates.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
filename = os.path.join(basedir, "Dates")
|
|
|
|
|
|
|
|
self.__log("Writing upload data to %s" % filename)
|
|
|
|
|
|
|
|
f = open(filename, 'w')
|
|
|
|
|
|
|
|
for pkg in sorted(dates.keys()):
|
|
|
|
|
|
|
|
f.write("%s %s %d\n" % ((pkg,) + dates[pkg]))
|
|
|
|
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def read_urgencies(self, basedir):
|
|
|
|
def read_urgencies(self, basedir):
|
|
|
|
"""Read the upload urgency of the packages from the specified directory
|
|
|
|
"""Read the upload urgency of the packages from the specified directory
|
|
|
|
|
|
|
|
|
|
|
@ -680,6 +709,42 @@ class Britney:
|
|
|
|
|
|
|
|
|
|
|
|
return hints
|
|
|
|
return hints
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def write_heidi(self, basedir, filename):
|
|
|
|
|
|
|
|
"""Write the output HeidiResult
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This method write the output for Heidi, which contains all the
|
|
|
|
|
|
|
|
binary packages and the source packages in the form:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<pkg-name> <pkg-version> <pkg-architecture> <pkg-section>
|
|
|
|
|
|
|
|
<src-name> <src-version> <src-section>
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
filename = os.path.join(basedir, filename)
|
|
|
|
|
|
|
|
self.__log("Writing Heidi results to %s" % filename)
|
|
|
|
|
|
|
|
f = open(filename, 'w')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# local copies
|
|
|
|
|
|
|
|
sources = self.sources['testing']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# write binary packages
|
|
|
|
|
|
|
|
for arch in sorted(self.options.architectures):
|
|
|
|
|
|
|
|
binaries = self.binaries['testing'][arch][0]
|
|
|
|
|
|
|
|
for pkg_name in sorted(binaries):
|
|
|
|
|
|
|
|
pkg = binaries[pkg_name]
|
|
|
|
|
|
|
|
pkgv = pkg['version']
|
|
|
|
|
|
|
|
pkgarch = pkg['architecture']
|
|
|
|
|
|
|
|
pkgsec = pkg.get('section', 'unknown')
|
|
|
|
|
|
|
|
f.write('%s %s %s %s\n' % (pkg_name, pkgv, pkgarch, pkgsec))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# write sources
|
|
|
|
|
|
|
|
for src_name in sorted(sources):
|
|
|
|
|
|
|
|
src = sources[src_name]
|
|
|
|
|
|
|
|
srcv = src['version']
|
|
|
|
|
|
|
|
srcsec = 'fake' in src and 'faux' or src.get('section', 'unknown')
|
|
|
|
|
|
|
|
f.write('%s %s source %s\n' % (src_name, srcv, srcsec))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Utility methods for package analisys
|
|
|
|
# Utility methods for package analisys
|
|
|
|
# ------------------------------------
|
|
|
|
# ------------------------------------
|
|
|
|
|
|
|
|
|
|
|
@ -1790,7 +1855,7 @@ class Britney:
|
|
|
|
n = l
|
|
|
|
n = l
|
|
|
|
return packages
|
|
|
|
return packages
|
|
|
|
|
|
|
|
|
|
|
|
def iter_packages(self, packages, output):
|
|
|
|
def iter_packages(self, packages):
|
|
|
|
"""Iter on the list of actions and apply them one-by-one
|
|
|
|
"""Iter on the list of actions and apply them one-by-one
|
|
|
|
|
|
|
|
|
|
|
|
This method apply the changes from `packages` to testing, checking the uninstallability
|
|
|
|
This method apply the changes from `packages` to testing, checking the uninstallability
|
|
|
@ -1817,7 +1882,7 @@ class Britney:
|
|
|
|
dependencies = self.dependencies
|
|
|
|
dependencies = self.dependencies
|
|
|
|
compatible = self.options.compatible
|
|
|
|
compatible = self.options.compatible
|
|
|
|
|
|
|
|
|
|
|
|
output.write("recur: [%s] %s %d/%d\n" % (",".join(self.selected), "", len(packages), len(extra)))
|
|
|
|
self.output_write("recur: [%s] %s %d/%d\n" % (",".join(self.selected), "", len(packages), len(extra)))
|
|
|
|
|
|
|
|
|
|
|
|
# loop on the packages (or better, actions)
|
|
|
|
# loop on the packages (or better, actions)
|
|
|
|
while packages:
|
|
|
|
while packages:
|
|
|
@ -1842,7 +1907,7 @@ class Britney:
|
|
|
|
break
|
|
|
|
break
|
|
|
|
if defer: continue
|
|
|
|
if defer: continue
|
|
|
|
|
|
|
|
|
|
|
|
output.write("trying: %s\n" % (pkg))
|
|
|
|
self.output_write("trying: %s\n" % (pkg))
|
|
|
|
|
|
|
|
|
|
|
|
better = True
|
|
|
|
better = True
|
|
|
|
nuninst = {}
|
|
|
|
nuninst = {}
|
|
|
@ -1911,20 +1976,20 @@ class Britney:
|
|
|
|
self.selected.append(pkg)
|
|
|
|
self.selected.append(pkg)
|
|
|
|
packages.extend(extra)
|
|
|
|
packages.extend(extra)
|
|
|
|
extra = []
|
|
|
|
extra = []
|
|
|
|
output.write("accepted: %s\n" % (pkg))
|
|
|
|
self.output_write("accepted: %s\n" % (pkg))
|
|
|
|
output.write(" ori: %s\n" % (self.eval_nuninst(self.nuninst_orig)))
|
|
|
|
self.output_write(" ori: %s\n" % (self.eval_nuninst(self.nuninst_orig)))
|
|
|
|
output.write(" pre: %s\n" % (self.eval_nuninst(nuninst_comp)))
|
|
|
|
self.output_write(" pre: %s\n" % (self.eval_nuninst(nuninst_comp)))
|
|
|
|
output.write(" now: %s\n" % (self.eval_nuninst(nuninst)))
|
|
|
|
self.output_write(" now: %s\n" % (self.eval_nuninst(nuninst)))
|
|
|
|
if len(self.selected) <= 20:
|
|
|
|
if len(self.selected) <= 20:
|
|
|
|
output.write(" all: %s\n" % (" ".join(self.selected)))
|
|
|
|
self.output_write(" all: %s\n" % (" ".join(self.selected)))
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
output.write(" most: (%d) .. %s\n" % (len(self.selected), " ".join(self.selected[-20:])))
|
|
|
|
self.output_write(" most: (%d) .. %s\n" % (len(self.selected), " ".join(self.selected[-20:])))
|
|
|
|
for k in nuninst:
|
|
|
|
for k in nuninst:
|
|
|
|
nuninst_comp[k] = nuninst[k]
|
|
|
|
nuninst_comp[k] = nuninst[k]
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
output.write("skipped: %s (%d <- %d)\n" % (pkg, len(extra), len(packages)))
|
|
|
|
self.output_write("skipped: %s (%d <- %d)\n" % (pkg, len(extra), len(packages)))
|
|
|
|
output.write(" got: %s\n" % (self.eval_nuninst(nuninst, "/" in pkg and nuninst_comp or None)))
|
|
|
|
self.output_write(" got: %s\n" % (self.eval_nuninst(nuninst, "/" in pkg and nuninst_comp or None)))
|
|
|
|
output.write(" * %s: %s\n" % (arch, ", ".join(sorted([b for b in broken if b not in nuninst_comp[arch]]))))
|
|
|
|
self.output_write(" * %s: %s\n" % (arch, ", ".join(sorted([b for b in broken if b not in nuninst_comp[arch]]))))
|
|
|
|
|
|
|
|
|
|
|
|
extra.append(pkg)
|
|
|
|
extra.append(pkg)
|
|
|
|
if not mark_passed:
|
|
|
|
if not mark_passed:
|
|
|
@ -1959,16 +2024,16 @@ class Britney:
|
|
|
|
del binaries[arch][1][j[1:]]
|
|
|
|
del binaries[arch][1][j[1:]]
|
|
|
|
else: binaries[arch][1][j] = undo['virtual'][p]
|
|
|
|
else: binaries[arch][1][j] = undo['virtual'][p]
|
|
|
|
|
|
|
|
|
|
|
|
output.write(" finish: [%s]\n" % ",".join(self.selected))
|
|
|
|
self.output_write(" finish: [%s]\n" % ",".join(self.selected))
|
|
|
|
output.write("endloop: %s\n" % (self.eval_nuninst(self.nuninst_orig)))
|
|
|
|
self.output_write("endloop: %s\n" % (self.eval_nuninst(self.nuninst_orig)))
|
|
|
|
output.write(" now: %s\n" % (self.eval_nuninst(nuninst_comp)))
|
|
|
|
self.output_write(" now: %s\n" % (self.eval_nuninst(nuninst_comp)))
|
|
|
|
output.write(self.eval_uninst(self.newlyuninst(self.nuninst_orig, nuninst_comp)))
|
|
|
|
self.output_write(self.eval_uninst(self.newlyuninst(self.nuninst_orig, nuninst_comp)))
|
|
|
|
output.write("\n")
|
|
|
|
self.output_write("\n")
|
|
|
|
|
|
|
|
|
|
|
|
output.write("Apparently successful\n")
|
|
|
|
self.output_write("Apparently successful\n")
|
|
|
|
return (nuninst_comp, extra)
|
|
|
|
return (nuninst_comp, extra)
|
|
|
|
|
|
|
|
|
|
|
|
def do_all(self, output, maxdepth=0, init=None):
|
|
|
|
def do_all(self, maxdepth=0, init=None):
|
|
|
|
"""Testing update runner
|
|
|
|
"""Testing update runner
|
|
|
|
|
|
|
|
|
|
|
|
This method tries to update testing checking the uninstallability
|
|
|
|
This method tries to update testing checking the uninstallability
|
|
|
@ -1977,38 +2042,122 @@ class Britney:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
self.__log("> Calculating current uninstallability counters", type="I")
|
|
|
|
self.__log("> Calculating current uninstallability counters", type="I")
|
|
|
|
nuninst_start = self.get_nuninst()
|
|
|
|
nuninst_start = self.get_nuninst()
|
|
|
|
output.write("start: %s\n" % self.eval_nuninst(nuninst_start))
|
|
|
|
|
|
|
|
output.write("orig: %s\n" % self.eval_nuninst(nuninst_start))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.__log("> First loop on the packages with depth = 0", type="I")
|
|
|
|
# these are special parameters for hints processing
|
|
|
|
self.selected = []
|
|
|
|
force = False
|
|
|
|
|
|
|
|
earlyabort = False
|
|
|
|
|
|
|
|
if maxdepth == "easy" or maxdepth == 0:
|
|
|
|
|
|
|
|
force = maxdepth < 0
|
|
|
|
|
|
|
|
earlyabort = True
|
|
|
|
|
|
|
|
maxdepth = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# if we have a list of initial packages, check them
|
|
|
|
|
|
|
|
if init:
|
|
|
|
|
|
|
|
self.output_write("leading: %s\n" % (",".join(init)))
|
|
|
|
|
|
|
|
for x in init:
|
|
|
|
|
|
|
|
if x not in self.upgrade_me:
|
|
|
|
|
|
|
|
self.output_write("failed: %s\n" % (x))
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
self.doop_source(x)
|
|
|
|
|
|
|
|
self.selected.append(x)
|
|
|
|
|
|
|
|
|
|
|
|
self.nuninst_orig = nuninst_start
|
|
|
|
self.nuninst_orig = nuninst_start
|
|
|
|
(nuninst_end, extra) = self.iter_packages(self.upgrade_me[:], output)
|
|
|
|
|
|
|
|
|
|
|
|
if earlyabort:
|
|
|
|
|
|
|
|
nuninst_end = self.get_nuninst()
|
|
|
|
|
|
|
|
self.output_write("easy: %s\n" % (self.eval_nuninst(nuninst_end)))
|
|
|
|
|
|
|
|
self.output_write(self.eval_uninst(self.newlyuninst(nuninst_start, nuninst_end)) + "\n")
|
|
|
|
|
|
|
|
extra = self.upgrade_me[:]
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.__log("> First loop on the packages with depth = 0", type="I")
|
|
|
|
|
|
|
|
(nuninst_end, extra) = self.iter_packages(self.upgrade_me[:])
|
|
|
|
|
|
|
|
|
|
|
|
if nuninst_end:
|
|
|
|
if nuninst_end:
|
|
|
|
output.write("final: %s\n" % ",".join(sorted(self.selected)))
|
|
|
|
self.output_write("final: %s\n" % ",".join(sorted(self.selected)))
|
|
|
|
output.write("start: %s\n" % self.eval_nuninst(nuninst_start))
|
|
|
|
self.output_write("start: %s\n" % self.eval_nuninst(nuninst_start))
|
|
|
|
output.write(" orig: %s\n" % self.eval_nuninst(self.nuninst_orig))
|
|
|
|
self.output_write(" orig: %s\n" % self.eval_nuninst(self.nuninst_orig))
|
|
|
|
output.write(" end: %s\n" % self.eval_nuninst(nuninst_end))
|
|
|
|
self.output_write(" end: %s\n" % self.eval_nuninst(nuninst_end))
|
|
|
|
output.write("SUCCESS (%d/%d)\n" % (len(self.upgrade_me), len(extra)))
|
|
|
|
self.output_write("SUCCESS (%d/%d)\n" % (len(self.upgrade_me), len(extra)))
|
|
|
|
|
|
|
|
|
|
|
|
def upgrade_testing(self):
|
|
|
|
def upgrade_testing(self):
|
|
|
|
"""Upgrade testing using the unstable packages
|
|
|
|
"""Upgrade testing using the unstable packages
|
|
|
|
|
|
|
|
|
|
|
|
This method tries to upgrade testing using the packages from unstable.
|
|
|
|
This method tries to upgrade testing using the packages from unstable.
|
|
|
|
|
|
|
|
Before running the do_all method, it tries the easy and force-hint
|
|
|
|
|
|
|
|
commands.
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
self.__log("Starting the upgrade test", type="I")
|
|
|
|
self.__log("Starting the upgrade test", type="I")
|
|
|
|
output = open(self.options.upgrade_output, 'w')
|
|
|
|
self.__output = open(self.options.upgrade_output, 'w')
|
|
|
|
output.write("Generated on: %s\n" % (time.strftime("%Y.%m.%d %H:%M:%S %z", time.gmtime(time.time()))))
|
|
|
|
self.output_write("Generated on: %s\n" % (time.strftime("%Y.%m.%d %H:%M:%S %z", time.gmtime(time.time()))))
|
|
|
|
output.write("Arch order is: %s\n" % ", ".join(self.options.architectures))
|
|
|
|
self.output_write("Arch order is: %s\n" % ", ".join(self.options.architectures))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# process `easy' hints
|
|
|
|
|
|
|
|
self.hints['easy'].append(('kobold', [('a2ps', '1:4.13b-5'), ('adeos', '20050809-1')]))
|
|
|
|
|
|
|
|
for x in self.hints['easy']:
|
|
|
|
|
|
|
|
self.do_hint("easy", x[0], x[1])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# process `easy' hints
|
|
|
|
|
|
|
|
for x in self.hints["force-hint"]:
|
|
|
|
|
|
|
|
self.do_hint("force-hint", x[0], x[1])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# run the first round of the upgrade
|
|
|
|
|
|
|
|
# FIXME: self.do_all()
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: process hints!
|
|
|
|
# write bugs and dates
|
|
|
|
self.do_all(output)
|
|
|
|
# FIXME: self.write_bugs(self.options.testing, self.bugs['testing'])
|
|
|
|
|
|
|
|
# FIXME: self.write_dates(self.options.testing, self.dates)
|
|
|
|
|
|
|
|
|
|
|
|
output.close()
|
|
|
|
# write HeidiResult
|
|
|
|
|
|
|
|
# FIXME: self.write_heidi(self.options.testing, 'HeidiResult')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.__output.close()
|
|
|
|
self.__log("Test completed!", type="I")
|
|
|
|
self.__log("Test completed!", type="I")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def do_hint(self, type, who, pkgvers):
|
|
|
|
|
|
|
|
"""Process hints
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This method process `easy`, `hint` and `force-hint` hints. If the
|
|
|
|
|
|
|
|
requested version is not in unstable, than the hint is skipped.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
hintinfo = {"easy": "easy",
|
|
|
|
|
|
|
|
"hint": 0,
|
|
|
|
|
|
|
|
"force-hint": -1,}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.output_write("Trying %s from %s: %s\n" % (type, who, " ".join( ["%s/%s" % (p,v) for (p,v) in pkgvers])))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ok = True
|
|
|
|
|
|
|
|
# loop on the requested packages and versions
|
|
|
|
|
|
|
|
for pkg, v in pkgvers:
|
|
|
|
|
|
|
|
# remove architecture
|
|
|
|
|
|
|
|
if "/" in pkg:
|
|
|
|
|
|
|
|
pkg = pkg[:pkg.find("/")]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# skip removal requests
|
|
|
|
|
|
|
|
if pkg[0] == "-":
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
# handle testing-proposed-updates
|
|
|
|
|
|
|
|
elif pkg.endswith("_tpu"):
|
|
|
|
|
|
|
|
pkg = pkg[:-4]
|
|
|
|
|
|
|
|
if pkg not in self.sources['tpu']: continue
|
|
|
|
|
|
|
|
if apt_pkg.VersionCompare(self.sources['tpu'][pkg]['version'], v) != 0:
|
|
|
|
|
|
|
|
self.output_write(" Version mismatch, %s %s != %s\n" % (pkg, v, self.sources['tpu'][pkg]['version']))
|
|
|
|
|
|
|
|
ok = False
|
|
|
|
|
|
|
|
# does the package exist in unstable?
|
|
|
|
|
|
|
|
elif pkg not in self.sources['unstable']:
|
|
|
|
|
|
|
|
self.output_write(" Source %s has no version in unstable\n" % pkg)
|
|
|
|
|
|
|
|
ok = False
|
|
|
|
|
|
|
|
elif apt_pkg.VersionCompare(self.sources['unstable'][pkg]['version'], v) != 0:
|
|
|
|
|
|
|
|
self.output_write(" Version mismatch, %s %s != %s\n" % (pkg, v, self.sources['unstable'][pkg]['version']))
|
|
|
|
|
|
|
|
ok = False
|
|
|
|
|
|
|
|
if not ok:
|
|
|
|
|
|
|
|
self.output_write("Not using hint\n")
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.do_all(hintinfo[type], map(operator.itemgetter(0), pkgvers))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
def sort_actions(self):
|
|
|
|
def sort_actions(self):
|
|
|
|
"""Sort actions in a smart way
|
|
|
|
"""Sort actions in a smart way
|
|
|
|
|
|
|
|
|
|
|
@ -2037,9 +2186,14 @@ class Britney:
|
|
|
|
upgrade_me.remove(e.name)
|
|
|
|
upgrade_me.remove(e.name)
|
|
|
|
upgrade_me.insert(max(pos)+1, e.name)
|
|
|
|
upgrade_me.insert(max(pos)+1, e.name)
|
|
|
|
self.dependencies[e.name] = e.deps
|
|
|
|
self.dependencies[e.name] = e.deps
|
|
|
|
|
|
|
|
|
|
|
|
# replace the list of actions with the new one
|
|
|
|
# replace the list of actions with the new one
|
|
|
|
self.upgrade_me = upgrade_me
|
|
|
|
self.upgrade_me = upgrade_me
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def output_write(self, msg):
|
|
|
|
|
|
|
|
"""Simple wrapper for output writing"""
|
|
|
|
|
|
|
|
self.__output.write(msg)
|
|
|
|
|
|
|
|
|
|
|
|
def main(self):
|
|
|
|
def main(self):
|
|
|
|
"""Main method
|
|
|
|
"""Main method
|
|
|
|
|
|
|
|
|
|
|
|