From: Michael Tremer Date: Thu, 4 Mar 2021 23:29:22 +0000 (+0000) Subject: packages: Drop base module X-Git-Tag: 0.9.28~1285^2~633 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b6cdd748fef417da641258e8be00551af5f2188;p=pakfire.git packages: Drop base module Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index f4a0bf598..97fb5f9d4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -139,7 +139,6 @@ pakfiredir = $(pythondir)/pakfire pakfire_packages_PYTHON = \ src/pakfire/packages/__init__.py \ - src/pakfire/packages/base.py \ src/pakfire/packages/packager.py \ src/pakfire/packages/tar.py diff --git a/src/pakfire/packages/__init__.py b/src/pakfire/packages/__init__.py index c7a28cdfb..fa9a2b6e9 100644 --- a/src/pakfire/packages/__init__.py +++ b/src/pakfire/packages/__init__.py @@ -18,5 +18,3 @@ # along with this program. If not, see . # # # ############################################################################### - -from .base import Package diff --git a/src/pakfire/packages/base.py b/src/pakfire/packages/base.py deleted file mode 100644 index b4bef3f7a..000000000 --- a/src/pakfire/packages/base.py +++ /dev/null @@ -1,611 +0,0 @@ -#!/usr/bin/python -############################################################################### -# # -# Pakfire - The IPFire package management system # -# Copyright (C) 2011 Pakfire development team # -# # -# 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 3 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 # -# along with this program. If not, see . # -# # -############################################################################### - -import datetime -import os -import shutil -import xml.sax.saxutils - -import logging -log = logging.getLogger("pakfire") - -import pakfire.util as util - -from pakfire.constants import * -from pakfire.i18n import _ - -class Package(object): - def __init__(self, pakfire, repo=None): - self.pakfire = pakfire - self._repo = repo - - # Pointer to a package that is updated by this one. - self.old_package = None - - def __repr__(self): - return "<%s %s>" % (self.__class__.__name__, self.friendly_name) - - def __cmp__(self, other): - # if packages differ names return in alphabetical order - if not self.name == other.name: - return cmp(self.name, other.name) - - # If UUIDs match, the packages are absolutely equal. - if self.uuid == other.uuid: - #log.debug("%s is equal to %s by UUID" % (self, other)) - return 0 - - ret = self.pakfire.version_compare(self.friendly_version, other.friendly_version) - - # XXX this is to move packages that have been built a while ago and - # do not have all the meta information that they won't be evaluated - # as the best match. - #if not ret: - # if "X"*3 in (self.build_id, other.build_id): - # if self.build_id == "X"*3 and not other.build_id == "X"*3: - # ret = -1 - # - # elif not self.build_id == "X"*3 and other.build_id == "X"*3: - # ret = 1 - # XXX hack end - - # Compare the build times if we have a rebuilt package. - if not ret and self.build_time and other.build_time: - ret = cmp(self.build_time, other.build_time) - - #if ret == 0: - # log.debug("%s is equal to %s" % (self, other)) - #elif ret < 0: - # log.debug("%s is more recent than %s" % (other, self)) - #elif ret > 0: - # log.debug("%s is more recent than %s" % (self, other)) - - # If no rank could be created, sort by repository priority - if not ret: - ret = cmp(self.repo, other.repo) - - return ret - - def __hash__(self): - hashstr = ["%s" % s for s in (self.name, self.epoch, self.version, - self.release, self.arch,)] - - return hash("-".join(hashstr)) - - def dump(self, short=False, long=False, filelist=False): - if short: - return "%s.%s : %s" % (self.name, self.arch, self.summary) - - items = [ - (_("Name"), self.name), - ] - - # Show supported arches if available. - if hasattr(self, "supported_arches") and not self.supported_arches == "all": - arch = "%s (%s)" % (self.arch, self.supported_arches) - else: - arch = self.arch - items.append((_("Arch"), arch)) - - items += [ - (_("Version"), self.version), - (_("Release"), self.release), - ] - - if self.size: - items.append((_("Size"), util.format_size(self.size))) - - if self.inst_size: - items.append( - (_("Installed size"), - util.format_size(self.inst_size)) - ) - - # filter dummy repository - if not self.repo == self.pakfire.repos.dummy: - items.append((_("Repo"), self.repo.name)) - - items += [ - (_("Summary"), self.summary), - (_("Groups"), " ".join(self.groups)), - (_("URL"), self.url), - (_("License"), self.license), - ] - - caption = _("Description") - for line in util.text_wrap(self.description): - items.append((caption, line)) - caption = "" - - if long: - if self.maintainer: - items.append((_("Maintainer"), self.maintainer)) - - items.append((_("Vendor"), self.vendor)) - - items.append((_("UUID"), self.uuid)) - items.append((_("Build ID"), self.build_id)) - items.append((_("Build date"), self.build_date)) - items.append((_("Build host"), self.build_host)) - - caption = _("Signatures") - for sig in self.signatures: - items.append((caption, sig)) - caption = "" - - caption = _("Provides") - for prov in sorted(self.provides): - items.append((caption, prov)) - caption = "" - - caption = _("Pre-requires") - for req in sorted(self.prerequires): - items.append((caption, req)) - caption = "" - - caption = _("Requires") - for req in sorted(self.requires): - items.append((caption, req)) - caption = "" - - caption = _("Conflicts") - for req in sorted(self.conflicts): - items.append((caption, req)) - caption = "" - - caption = _("Obsoletes") - for req in sorted(self.obsoletes): - items.append((caption, req)) - caption = "" - - caption = _("Recommends") - for req in sorted(self.recommends): - items.append((caption, req)) - caption = "" - - caption = _("Suggests") - for req in sorted(self.suggests): - items.append((caption, req)) - caption = "" - - # Append filelist if requested. - if filelist: - for file in self.filelist: - items.append((_("File"), file)) - - format = "%%-%ds : %%s" % (max([len(k) for k, v in items])) - - s = [] - for caption, value in items: - s.append(format % (caption, value)) - - s.append("") # New line at the end - - # XXX why do we need to decode this? - return "\n".join([str.decode("utf-8") for str in s]) - - @property - def info(self): - info = { - "name" : self.name, - "version" : self.version, - "release" : self.release, - "epoch" : self.epoch, - "arch" : self.arch, - "supported_arches" : self.supported_arches, - "groups" : self.groups, - "summary" : self.summary, - "description" : self.description, - "maintainer" : self.maintainer, - "url" : self.url, - "license" : self.license, - "hash1" : self.hash1, - "vendor" : self.vendor, - "build_date" : self.build_date, - "build_host" : self.build_host, - "build_id" : self.build_id, - "build_time" : self.build_time, - "size" : self.size, - "inst_size" : self.inst_size, - } - - return info - - @property - def hash1(self): - return "0"*40 - - @property - def size(self): - """ - Return the size of the package file. - - This should be overloaded by another class and returns 0 for - virtual packages. - """ - return 0 - - @property - def inst_size(self): - """ - The used disk space when the package is installed. - - Returns None if inst_size is unknown. - """ - return None - - @property - def local(self): - """ - Indicates whether a package is located "local" means on disk - and has not be downloaded. - """ - return False - - ### META INFORMATION ### - - @property - def metadata(self): - raise NotImplementedError(self) - - @property - def friendly_name(self): - return "%s-%s.%s" % (self.name, self.friendly_version, self.arch) - - @property - def friendly_version(self): - s = "%s-%s" % (self.version, self.release) - - if self.epoch: - s = "%d:%s" % (self.epoch, s) - - return s - - @property - def repo(self): - if self._repo: - return self._repo - - # By default, every package is connected to a dummy repository - return self.pakfire.repos.dummy - - @property - def name(self): - return self.metadata.get("PKG_NAME") - - @property - def version(self): - return self.metadata.get("PKG_VER") - - @property - def release(self): - ret = None - - for i in ("PKG_RELEASE", "PKG_REL"): - ret = self.metadata.get(i, None) - if ret: - break - - return ret - - @property - def epoch(self): - epoch = self.metadata.get("PKG_EPOCH", 0) - - return int(epoch) - - @property - def arch(self): - raise NotImplementedError - - @property - def base(self): - """ - Say if a package belongs to the basic set - that is installed by default. - """ - return "Base" in self.groups - - @property - def critical(self): - """ - Return if a package is marked "critial". - """ - return "Critical" in self.groups - - def is_installed(self): - return self.repo.name == "@system" - - @property - def type(self): - return self.metadata.get("TYPE", "unknown") - - @property - def maintainer(self): - return self.metadata.get("PKG_MAINTAINER") - - @property - def license(self): - return self.metadata.get("PKG_LICENSE") - - @property - def summary(self): - return self.metadata.get("PKG_SUMMARY") - - @property - def description(self): - return self.metadata.get("PKG_DESCRIPTION") - - @property - def groups(self): - return self.metadata.get("PKG_GROUPS", "").split() - - @property - def url(self): - return self.metadata.get("PKG_URL") - - @property - def triggers(self): - triggers = self.metadata.get("PKG_TRIGGERS", "") - - return triggers.split() - - @property - def signatures(self): - return [] - - @property - def build_date(self): - """ - Automatically convert the UNIX timestamp from self.build_time to - a humanly readable format. - """ - if self.build_time is None: - return _("Not set") - - return "%s UTC" % datetime.datetime.utcfromtimestamp(self.build_time) - - @property - def build_host(self): - return self.metadata.get("BUILD_HOST") - - @property - def build_id(self): - return self.metadata.get("BUILD_ID") - - @property - def build_time(self): - build_time = self.metadata.get("BUILD_TIME", 0) - - return int(build_time) - - @property - def uuid(self): - return self.metadata.get("PKG_UUID", None) - - @property - def supported_arches(self): - return self.metadata.get("PKG_SUPPORTED_ARCHES", "all") - - @property - def vendor(self): - return self.metadata.get("PKG_VENDOR", "") - - @staticmethod - def filter_deps(deps): - """ - Filter out invalid dependencies. - - This is just for reading packages and skipping comments - or empty lines. - """ - ret = [] - - for dep in deps: - # Remove any leading or trailing spaces. - dep = dep.strip() - - # Skip empty strings. - if not dep: - continue - - # Skip comment lines. - if dep.startswith("#"): - continue - - ret.append(dep) - - return ret - - @property - def prerequires(self): - requires = self.metadata.get("PKG_PREREQUIRES", "") - - return requires.split() - - @property - def requires(self): - ret = "" - - # The default attributes, that are process for the requires. - attrs = ["PKG_REQUIRES", "PKG_DEPS",] - - if self.arch == "src": - attrs += ["PKG_BUILD_DEPS",] - - for i in attrs: - ret = self.metadata.get(i, ret) - if ret: - break - - return ret.splitlines() - - @property - def provides(self): - return self.metadata.get("PKG_PROVIDES", "").splitlines() - - @property - def conflicts(self): - return self.metadata.get("PKG_CONFLICTS", "").splitlines() - - @property - def obsoletes(self): - return self.metadata.get("PKG_OBSOLETES", "").splitlines() - - @property - def recommends(self): - return [] - - @property - def suggests(self): - return [] - - @property - def scriptlets(self): - return self.metadata.get("PKG_SCRIPTLETS", "").splitlines() - - def get_scriptlet(self, action): - raise NotImplementedError - - @property - def filelist(self): - raise NotImplementedError - - @property - def configfiles(self): - return [] - - @property - def datafiles(self): - return [] - - def extract(self, path, prefix=None): - raise NotImplementedError("%s" % repr(self)) - - def remove(self, message=None, prefix=None): - # Make two filelists. One contains all binary files that need to be - # removed, the other one contains the configuration files which are - # kept. files and configfiles are disjunct. - files = [] - configfiles = self.configfiles - datafiles = self.datafiles - - for file in self.filelist: - if file in configfiles: - continue - - if file in datafiles: - continue - - assert file.startswith("/") - files.append(file) - - self._remove_files(files, message, prefix) - - def _remove_files(self, files, message, prefix): - if prefix in ("/", None): - prefix = "" - - # Load progressbar. - pb = None - if message: - message = "%-10s : %s" % (message, self.friendly_name) - pb = util.make_progress(message, len(files), eta=False) - - # Sort files by the length of their name to remove all files in - # a directory first and then check, if there are any files left. - files.sort(cmp=lambda x,y: cmp(len(x.name), len(y.name)), reverse=True) - - # Messages to the user. - messages = [] - - i = 0 - for _file in files: - # Update progress. - if pb: - i += 1 - pb.update(i) - - log.debug("Removing file: %s" % _file) - - if prefix: - file = os.path.join(prefix, _file.name[1:]) - assert file.startswith("%s/" % prefix) - else: - file = _file.name - - # Rename configuration files. - if _file.is_config(): - # Skip already removed config files. - try: - os.lstat(file) - except OSError: - continue - - file_save = "%s%s" % (file, CONFIG_FILE_SUFFIX_SAVE) - - try: - shutil.move(file, file_save) - except shutil.Error as e: - print(e) - - if prefix: - file_save = os.path.relpath(file_save, prefix) - messages.append(_("Config file saved as %s.") % file_save) - continue - - # Preserve datafiles. - if _file.is_datafile(): - log.debug(_("Preserving datafile '/%s'") % _file) - continue - - # Handle regular files and symlinks. - if os.path.isfile(file) or os.path.islink(file): - log.debug("Removing %s..." % _file) - try: - os.remove(file) - except OSError: - log.error("Cannot remove file: %s. Remove manually." % _file) - - # Handle directories. - # Skip removal if the directory is a mountpoint. - elif os.path.isdir(file) and not os.path.ismount(file): - # Try to remove the directory. If it is not empty, OSError is raised, - # but we are okay with that. - try: - os.rmdir(file) - except OSError: - pass - - # Handle files that have already been removed - # by somebody else. - elif not os.path.exists(file): - pass - - # Log all unhandled types. - else: - log.warning("Cannot remove file: %s. Filetype is unhandled." % file) - - if pb: - pb.finish() - - for msg in messages: - log.warning(msg)