|
|
|
@ -29,12 +29,13 @@ from calculate.lib.datavars import DataVars, Variable
|
|
|
|
|
from calculate.lib.utils.colortext import (TextState, get_color_print)
|
|
|
|
|
from calculate.lib.utils.common import CmdlineParams, getTupleVersion
|
|
|
|
|
from calculate.lib.utils.portage import (BinaryPackage, get_binary_file,
|
|
|
|
|
clear_binhost_garbage)
|
|
|
|
|
EixVersionParser,
|
|
|
|
|
clear_binhost_garbage, WorldFile)
|
|
|
|
|
from calculate.lib.utils.files import (
|
|
|
|
|
pathJoin, PercentProgress, getProgPath, process, STDOUT, removeDir,
|
|
|
|
|
makeDirectory, writeFile, readLinesFile, chmod, chown, FilePermission,
|
|
|
|
|
find, FindFileType, removeFileWithEmptyDirectory, check_rw,
|
|
|
|
|
tar_xz_directory, sha256sum,
|
|
|
|
|
tar_xz_directory, sha256sum, quite_unlink,
|
|
|
|
|
copyWithPath, countFiles, listDirectory, getRunCommands, readFile,
|
|
|
|
|
DirectoryRCS, RCSError)
|
|
|
|
|
from calculate.lib.utils.mount import isMount
|
|
|
|
@ -100,6 +101,7 @@ class Builder(Update):
|
|
|
|
|
self.emerge_cache = EmergeCache()
|
|
|
|
|
self.pkgnum = None
|
|
|
|
|
self.pkgnummax = None
|
|
|
|
|
self.world_data = ""
|
|
|
|
|
|
|
|
|
|
def mount_target(self, target):
|
|
|
|
|
dir_distro = target.convertToDirectory()
|
|
|
|
@ -369,6 +371,113 @@ class Builder(Update):
|
|
|
|
|
raise BuilderError(_("Failed to set the profile: %s") % str(e))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def get_world_snapshot_filename(self, builder_path):
|
|
|
|
|
return pathJoin(builder_path, "var/lib/calculate/world.snapshot")
|
|
|
|
|
|
|
|
|
|
def world_snapshot(self, builder_path):
|
|
|
|
|
worldfile = pathJoin(builder_path, "var/lib/portage/world")
|
|
|
|
|
worldfile_snapshot = self.get_world_snapshot_filename(builder_path)
|
|
|
|
|
if not path.exists(worldfile_snapshot):
|
|
|
|
|
with writeFile(worldfile_snapshot) as f:
|
|
|
|
|
f.write(readFile(worldfile, grab=True))
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def world_diff(self, builder_path):
|
|
|
|
|
worldfile_snapshot = self.get_world_snapshot_filename(builder_path)
|
|
|
|
|
worldfile = pathJoin(builder_path, "var/lib/portage/world")
|
|
|
|
|
if self._world_diff(self._chroot_eix_versions(builder_path),
|
|
|
|
|
readFile(worldfile_snapshot),
|
|
|
|
|
readFile(worldfile),
|
|
|
|
|
premess=_("List of worlds differences")):
|
|
|
|
|
answer = self.askConfirm(
|
|
|
|
|
_("Would you like to continue?"), "yes")
|
|
|
|
|
if answer == "no":
|
|
|
|
|
raise KeyboardInterrupt
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def _chroot_eix_versions(self, builder_path):
|
|
|
|
|
chroot_eix = ChrootEix(builder_path, [], ChrootEix.Option.Exact)
|
|
|
|
|
chroot_eix.parser = EixVersionParser()
|
|
|
|
|
return chroot_eix
|
|
|
|
|
|
|
|
|
|
def _display_versions(self, versions):
|
|
|
|
|
"""
|
|
|
|
|
Вывести версии как в eix
|
|
|
|
|
:param versions:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
_print = self.color_print
|
|
|
|
|
Colors = TextState.Colors
|
|
|
|
|
|
|
|
|
|
def _print_version(ver):
|
|
|
|
|
__print = _print
|
|
|
|
|
if ver.stable:
|
|
|
|
|
__print = __print.foreground(Colors.GREEN)
|
|
|
|
|
out = ver.version
|
|
|
|
|
else:
|
|
|
|
|
if ver.hardmask or ver.missing_keyword:
|
|
|
|
|
color = Colors.RED
|
|
|
|
|
else:
|
|
|
|
|
color = Colors.BROWN
|
|
|
|
|
if ver.missing_keyword:
|
|
|
|
|
out = "**%s" % ver.version
|
|
|
|
|
elif ver.unstable_keyword:
|
|
|
|
|
out = "~%s" % ver.version
|
|
|
|
|
else:
|
|
|
|
|
out = ver.version
|
|
|
|
|
if ver.hardmask:
|
|
|
|
|
out = "[M]%s" % out
|
|
|
|
|
__print = __print.foreground(color)
|
|
|
|
|
|
|
|
|
|
if out and ver.installed:
|
|
|
|
|
return __print.invert(out)
|
|
|
|
|
return __print(out)
|
|
|
|
|
|
|
|
|
|
getslot = lambda x:x.slot
|
|
|
|
|
for slot, data in groupby(sorted(versions, key=getslot), getslot):
|
|
|
|
|
self.printPre(" {slot} {versions}".format(
|
|
|
|
|
slot=_print.foreground(Colors.LIGHT_RED)("(%s)"%slot),
|
|
|
|
|
versions=" ".join(_print_version(ver) for ver in data)
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
def _world_diff(self, eix, snapshot_data, current_data, premess=None):
|
|
|
|
|
"""
|
|
|
|
|
Вывести изменения между двума world файлами
|
|
|
|
|
:param eix:
|
|
|
|
|
:param snapshot_data:
|
|
|
|
|
:param current_data:
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
_print = self.color_print
|
|
|
|
|
Colors = TextState.Colors
|
|
|
|
|
newsuffix = "[%s]" % _print.invert.foreground(Colors.GREEN)("N")
|
|
|
|
|
removesuffix = "[%s]" % _print.invert.foreground(Colors.RED)("D")
|
|
|
|
|
|
|
|
|
|
world_snapshot = WorldFile(snapshot_data)
|
|
|
|
|
world_current = WorldFile(current_data)
|
|
|
|
|
|
|
|
|
|
predisplay = False
|
|
|
|
|
|
|
|
|
|
for pkg, added, removed, ommited in world_snapshot.category_diff(
|
|
|
|
|
world_current):
|
|
|
|
|
if not predisplay and premess:
|
|
|
|
|
self.printSUCCESS(premess)
|
|
|
|
|
predisplay = True
|
|
|
|
|
if added:
|
|
|
|
|
self.printPre("%s %s" % (newsuffix,
|
|
|
|
|
" ".join(str(x) for x in added)))
|
|
|
|
|
if removed:
|
|
|
|
|
self.printPre("%s %s" % (removesuffix,
|
|
|
|
|
" ".join(str(x) for x in removed)))
|
|
|
|
|
eix.package = [pkg]
|
|
|
|
|
self._display_versions(eix.get_packages())
|
|
|
|
|
return predisplay
|
|
|
|
|
|
|
|
|
|
def world_snapshot_clean(self, builder_path):
|
|
|
|
|
worldfile_snapshot = self.get_world_snapshot_filename(builder_path)
|
|
|
|
|
quite_unlink(worldfile_snapshot)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def apply_templates(self, target=None, useClt=None, cltFilter=False,
|
|
|
|
|
root=None,
|
|
|
|
|
useDispatch=True, action="merge", distro_dv=None,
|
|
|
|
|