This is an automated email from the git hooks/post-receive script. smcv pushed a commit to branch master in repository game-data-packager.
commit 5fe449739788ffdf3a1c9f4dcdce77ca74337077 Author: Simon McVittie <[email protected]> Date: Mon Jan 4 23:47:51 2016 +0000 Reduce circular imports by introducing packaging modules Also stop deleting non-native packaging systems in g-d-p's packaging: in principle, there's nothing to stop us producing a working .deb on a Fedora system or a working RPM on a Debian system, if the right tools are installed. --- debian/rules | 4 - game_data_packager/build.py | 33 +++-- game_data_packager/games/z_code.py | 5 +- game_data_packager/gog.py | 7 +- game_data_packager/packaging/__init__.py | 70 ++++++++++ .../{util_arch.py => packaging/arch.py} | 35 ++--- .../{util_deb.py => packaging/deb.py} | 103 +++++++-------- game_data_packager/packaging/rpm.py | 146 +++++++++++++++++++++ game_data_packager/steam.py | 11 +- game_data_packager/util.py | 10 +- game_data_packager/util_deb.py | 99 +------------- game_data_packager/util_fedora.py | 53 -------- game_data_packager/util_rpm.py | 33 ----- game_data_packager/util_suse.py | 53 -------- tools/babel.py | 5 +- tools/game-data-packager.spec | 3 - 16 files changed, 318 insertions(+), 352 deletions(-) diff --git a/debian/rules b/debian/rules index 1b99807..afcc122 100755 --- a/debian/rules +++ b/debian/rules @@ -38,10 +38,6 @@ override_dh_install: touch debian/game-data-packager/usr/share/games/game-data-packager/is-ubuntu-derived; \ fi install -D -m755 runtime/doom2-masterlevels.py debian/game-data-packager/usr/games/doom2-masterlevels - rm -f debian/game-data-packager/usr/share/games/game-data-packager/game_data_packager/util_arch.py - rm -f debian/game-data-packager/usr/share/games/game-data-packager/game_data_packager/util_fedora.py - rm -f debian/game-data-packager/usr/share/games/game-data-packager/game_data_packager/util_rpm.py - rm -f debian/game-data-packager/usr/share/games/game-data-packager/game_data_packager/util_suse.py override_dh_installdocs: dh_installdocs -XTODO diff --git a/game_data_packager/build.py b/game_data_packager/build.py index 8c5bd88..221fbf9 100644 --- a/game_data_packager/build.py +++ b/game_data_packager/build.py @@ -40,18 +40,17 @@ except ImportError: from distutils.version import LooseVersion as Version from .gog import GOG +from .packaging import (get_native_packaging_system) from .paths import (DATADIR, ETCDIR) from .unpack import (TarUnpacker, ZipUnpacker) from .unpack.umod import (Umod) from .util import (AGENT, MEBIBYTE, - PACKAGE_CACHE, TemporaryUmask, check_call, check_output, copy_with_substitutions, human_size, - install_packages, lang_score, lintian_license, mkdir_p, @@ -344,10 +343,16 @@ def iter_fat_mounts(folder): yield path class PackagingTask(object): - def __init__(self, game): + def __init__(self, game, packaging=None): # A GameData object. self.game = game + if packaging is None: + packaging = get_native_packaging_system() + + # A packaging system. + self.packaging = packaging + # A temporary directory. self.__workdir = None @@ -1418,7 +1423,8 @@ class PackagingTask(object): size = int(size.split()[0]) with open(PKGINFO, 'w', encoding='utf-8') as pkginfo: pkginfo.write('# Generated by game-data-packager %s\n' % package.version.split('+')[-1]) - pkginfo.write('# using fakeroot version %s\n' % PACKAGE_CACHE.current_version('fakeroot')) + pkginfo.write('# using fakeroot version %s\n' % + self.packaging.current_version('fakeroot')) pkginfo.write('# %s\n' % time.strftime("%a %b %d %H:%M:%S UTC %Y", time.gmtime())) pkginfo.write('pkgname = %s\n' % package.name) pkginfo.write('pkgver = %s-1\n' % package.version) @@ -1882,8 +1888,8 @@ class PackagingTask(object): ver = None # check engine - is_installed = PACKAGE_CACHE.is_installed(engine) - if not is_installed and not PACKAGE_CACHE.is_available(engine): + is_installed = self.packaging.is_installed(engine) + if not is_installed and not self.packaging.is_available(engine): return FillResult.IMPOSSIBLE if ver is None: if is_installed: @@ -1893,9 +1899,9 @@ class PackagingTask(object): # check version if is_installed: - current_ver = PACKAGE_CACHE.current_version(engine) + current_ver = self.packaging.current_version(engine) else: - current_ver = PACKAGE_CACHE.available_version(engine) + current_ver = self.packaging.available_version(engine) if current_ver and Version(current_ver) >= Version(ver): return FillResult.COMPLETE @@ -2070,7 +2076,8 @@ class PackagingTask(object): print('generated "%s"' % os.path.abspath(deb)) if install_debs: - install_packages(debs, args.install_method, args.gain_root_command) + self.packaging.install_packages(debs, method=args.install_method, + gain_root=args.gain_root_command) engines_alt = set((p.engine or self.game.engine) for p in ready) engines_alt.discard(None) @@ -2078,7 +2085,7 @@ class PackagingTask(object): for engine_alt in engines_alt: for engine in reversed(engine_alt.split('|')): engine = engine.split('(')[0].strip() - if PACKAGE_CACHE.is_installed(engine): + if self.packaging.is_installed(engine): break else: engines.add(engine) @@ -2268,7 +2275,7 @@ class PackagingTask(object): if 'build-depends' in package.debian: for tool in package.debian['build-depends']: tool = tool.strip() - if not which(tool) and not PACKAGE_CACHE.is_installed(tool): + if not which(tool) and not self.packaging.is_installed(tool): logger.error('package "%s" is needed to build "%s"' % (tool, package.name)) possible.discard(package) @@ -2319,7 +2326,7 @@ class PackagingTask(object): if (package.expansion_for and (package.expansion_for not in self.game.packages or self.game.packages[package.expansion_for] not in possible) - and not PACKAGE_CACHE.is_installed(package.expansion_for)): + and not self.packaging.is_installed(package.expansion_for)): for fullgame in possible: if fullgame.type == 'full': logger.warning("won't generate '%s' expansion, because " @@ -2719,7 +2726,7 @@ class PackagingTask(object): # unace-nonfree package diverts /usr/bin/unace from unace package if (fmt == 'unace-nonfree' and - PACKAGE_CACHE.is_installed('unace-nonfree')): + self.packaging.is_installed('unace-nonfree')): return True logger.warning('cannot unpack "%s": tool "%s" is not ' + diff --git a/game_data_packager/games/z_code.py b/game_data_packager/games/z_code.py index 7f244a8..010b03b 100644 --- a/game_data_packager/games/z_code.py +++ b/game_data_packager/games/z_code.py @@ -23,7 +23,6 @@ import os from .. import GameData from ..build import (PackagingTask) from ..util import (TemporaryUmask, - PACKAGE_CACHE, mkdir_p, lintian_desktop) from ..version import (BINDIR) @@ -59,8 +58,8 @@ class ZCodeTask(PackagingTask): entry['Categories'] = 'Game;' entry['GenericName'] = self.game.genre + ' Game' entry['Name'] = package.longname or self.game.longname - if (PACKAGE_CACHE.is_installed('frotz') and - not PACKAGE_CACHE.is_installed('gargoyle-free')): + if (self.packaging.is_installed('frotz') and + not self.packaging.is_installed('gargoyle-free')): engine = 'frotz' entry['Terminal'] = 'true' else: diff --git a/game_data_packager/gog.py b/game_data_packager/gog.py index c09ec86..eb4c47c 100644 --- a/game_data_packager/gog.py +++ b/game_data_packager/gog.py @@ -20,8 +20,8 @@ import logging import os import subprocess -from .util import (PACKAGE_CACHE, - ascii_safe, +from .packaging import (get_native_packaging_system) +from .util import (ascii_safe, check_output, lang_score, which) @@ -132,6 +132,7 @@ def run_gog_meta_mode(parsed, games): owned = GOG.owned_games() logger.info("Found %d game(s) !" % len(owned)) + packaging = get_native_packaging_system() found_games = set() found_packages = [] for game, data in games.items(): @@ -144,7 +145,7 @@ def run_gog_meta_mode(parsed, games): if package.better_version: if data.gog_download_name(data.packages[package.better_version]): continue - installed = PACKAGE_CACHE.is_installed(package.name) + installed = packaging.is_installed(package.name) if parsed.new and installed: continue found_games.add(game) diff --git a/game_data_packager/packaging/__init__.py b/game_data_packager/packaging/__init__.py new file mode 100644 index 0000000..93bcd1d --- /dev/null +++ b/game_data_packager/packaging/__init__.py @@ -0,0 +1,70 @@ +#!/usr/bin/python3 +# encoding=utf-8 +# +# Copyright © 2014-2016 Simon McVittie <[email protected]> +# © 2015 Alexandre Detiste <[email protected]> +# +# 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. +# +# You can find the GPL license text on a Debian system under +# /usr/share/common-licenses/GPL-2. + +from abc import (ABCMeta, abstractmethod) + +class PackagingSystem(metaclass=ABCMeta): + + def is_installed(self, package): + """Return boolean: is a package with the given name installed?""" + return (self.current_version(package) is not None) + + def is_available(self, package): + """Return boolean: is a package with the given name available + to apt or equivalent? + """ + try: + self.available_version(package) + except: + return False + else: + return True + + @abstractmethod + def current_version(self, package): + """Return the version number of the given package as a string, + or None. + """ + raise NotImplementedError + + @abstractmethod + def available_version(self, package): + """Return the version number of the given package available in + apt or equivalent, or raise an exception if unavailable. + """ + raise NotImplementedError + + @abstractmethod + def install_packages(self, packages, method=None, gain_root='su'): + """Install one or more packages (a list of filenames).""" + raise NotImplementedError + +def get_native_packaging_system(): + # lazy import when actually needed + from ..version import (FORMAT) + + if FORMAT == 'deb': + from .deb import (get_distro_packaging) + elif FORMAT == 'arch': + from .arch import (get_distro_packaging) + elif FORMAT == 'rpm': + from .rpm import (get_distro_packaging) + else: + raise RuntimeError('Unable to determine native packaging system') + + return get_distro_packaging() diff --git a/game_data_packager/util_arch.py b/game_data_packager/packaging/arch.py similarity index 76% rename from game_data_packager/util_arch.py rename to game_data_packager/packaging/arch.py index 33438f3..c772783 100644 --- a/game_data_packager/util_arch.py +++ b/game_data_packager/packaging/arch.py @@ -2,6 +2,7 @@ # encoding=utf-8 # # Copyright © 2015 Alexandre Detiste <[email protected]> +# Copyright © 2016 Simon McVittie <[email protected]> # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -11,32 +12,36 @@ # 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. +# +# You can find the GPL license text on a Debian system under +# /usr/share/common-licenses/GPL-2. import logging import subprocess -from .util import (run_as_root, check_output) +from . import (PackagingSystem) +from ..util import (run_as_root, check_output) -logger = logging.getLogger('game-data-packager.util_arch') +logger = logging.getLogger(__name__) -class PackageCache: +class ArchPackaging(PackagingSystem): def is_installed(self, package): return subprocess.call(['pacman', '-Q', package], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0 - def is_available(self, package): - return subprocess.call(['pacman', '-Si', package], - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL) == 0 - def current_version(self, package): try: return check_output(['pacman', '-Q', package], stderr=subprocess.DEVNULL, universal_newlines=True).split()[1] except subprocess.CalledProcessError: - return + return None + + def is_available(self, package): + return subprocess.call(['pacman', '-Si', package], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) == 0 def available_version(self, package): try: @@ -47,12 +52,12 @@ class PackageCache: k, _, v = line.split(maxsplit=2) if k == 'Version': return v - + except subprocess.CalledProcessError: - return + return None -PACKAGE_CACHE = PackageCache() + def install_packages(self, pkgs, method=None, gain_root='su'): + run_as_root(['pacman', '-U'] + list(pkgs), gain_root) -def install_packages(pkgs, method, gain_root='su'): - """Install one or more packages (a list of filenames).""" - run_as_root(['pacman', '-U'] + list(pkgs), gain_root) +def get_distro_packaging(): + return ArchPackaging() diff --git a/game_data_packager/util_deb.py b/game_data_packager/packaging/deb.py similarity index 56% copy from game_data_packager/util_deb.py copy to game_data_packager/packaging/deb.py index cd9d766..9c8f44f 100644 --- a/game_data_packager/util_deb.py +++ b/game_data_packager/packaging/deb.py @@ -1,7 +1,7 @@ #!/usr/bin/python3 # encoding=utf-8 # -# Copyright © 2014-2015 Simon McVittie <[email protected]> +# Copyright © 2014-2016 Simon McVittie <[email protected]> # © 2015 Alexandre Detiste <[email protected]> # # This program is free software; you can redistribute it and/or @@ -20,14 +20,17 @@ import logging import os import subprocess -from .util import (run_as_root, check_output, mkdir_p) from debian.debian_support import Version -logger = logging.getLogger('game-data-packager.util_deb') +from . import (PackagingSystem) +from ..util import (check_output, run_as_root) -class PackageCache: - installed = None - available = None +logger = logging.getLogger(__name__) + +class DebPackaging(PackagingSystem): + def __init__(self): + self.__installed = None + self.__available = None def is_installed(self, package): # FIXME: this shouldn't be hard-coded @@ -48,7 +51,7 @@ class PackageCache: if os.path.isdir(os.path.join('/usr/share/doc', package)): return True - if self.installed is None: + if self.__installed is None: cache = set() proc = subprocess.Popen(['dpkg-query', '--show', '--showformat', '${Package}\\n'], @@ -56,21 +59,21 @@ class PackageCache: stdout=subprocess.PIPE) for line in proc.stdout: cache.add(line.rstrip()) - self.installed = cache + self.__installed = cache - return package in self.installed + return package in self.__installed def is_available(self, package): - if self.available is None: + if self.__available is None: cache = set() proc = subprocess.Popen(['apt-cache', 'pkgnames'], universal_newlines=True, stdout=subprocess.PIPE) for line in proc.stdout: cache.add(line.rstrip()) - self.available = cache + self.__available = cache - return package in self.available + return package in self.__available def current_version(self, package): # 'dpkg-query: no packages found matching $package' @@ -80,7 +83,7 @@ class PackageCache: return check_output(['dpkg-query', '--show', '--showformat', '${Version}', package], universal_newlines=True) except subprocess.CalledProcessError: - return + return None def available_version(self, package): current_ver = check_output(['apt-cache', 'madison', package], @@ -89,50 +92,32 @@ class PackageCache: current_ver = current_ver.split('|')[1].strip() return current_ver -PACKAGE_CACHE = PackageCache() - -def install_packages(debs, method, gain_root='su'): - """Install one or more packages (a list of filenames).""" - - if method and method not in ( - 'apt', 'dpkg', - 'gdebi', 'gdebi-gtk', 'gdebi-kde', - ): - logger.warning(('Unknown installation method %r, using apt or dpkg ' + - 'instead') % method) - method = None - - if not method: - apt_ver = PACKAGE_CACHE.current_version('apt') - if Version(apt_ver.strip()) >= Version('1.1~0'): - method = 'apt' + def install_packages(self, debs, method=None, gain_root='su'): + if method and method not in ( + 'apt', 'dpkg', + 'gdebi', 'gdebi-gtk', 'gdebi-kde', + ): + logger.warning(('Unknown installation method %r, using apt or ' + + 'dpkg instead') % method) + method = None + + if not method: + apt_ver = self.current_version('apt') + if Version(apt_ver.strip()) >= Version('1.1~0'): + method = 'apt' + else: + method = 'dpkg' + + if method == 'apt': + run_as_root(['apt-get', 'install', '--install-recommends'] + + list(debs), gain_root) + elif method == 'dpkg': + run_as_root(['dpkg', '-i'] + list(debs), gain_root) + elif method == 'gdebi': + run_as_root(['gdebi'] + list(debs), gain_root) else: - method = 'dpkg' - - if method == 'apt': - run_as_root(['apt-get', 'install', '--install-recommends'] + list(debs), - gain_root) - elif method == 'dpkg': - run_as_root(['dpkg', '-i'] + list(debs), gain_root) - elif method == 'gdebi': - run_as_root(['gdebi'] + list(debs), gain_root) - else: - # gdebi-gtk etc. - subprocess.call([method] + list(debs)) - -def lintian_license(destdir, package, file): - assert type(package) is str - lintiandir = os.path.join(destdir, 'usr/share/lintian/overrides') - mkdir_p(lintiandir) - with open(os.path.join(lintiandir, package), 'a', encoding='utf-8') as l: - l.write('%s: extra-license-file usr/share/doc/%s/%s\n' - % (package, package, file)) - -def lintian_desktop(destdir, package, program): - assert type(package) is str - lintiandir = os.path.join(destdir, 'usr/share/lintian/overrides') - mkdir_p(lintiandir) - with open(os.path.join(lintiandir, package), 'a', encoding='utf-8') as l: - l.write('%s: desktop-command-not-in-package ' - 'usr/share/applications/%s.desktop %s\n' - % (package, package, program)) + # gdebi-gtk etc. + subprocess.call([method] + list(debs)) + +def get_distro_packaging(): + return DebPackaging() diff --git a/game_data_packager/packaging/rpm.py b/game_data_packager/packaging/rpm.py new file mode 100644 index 0000000..b74f8f9 --- /dev/null +++ b/game_data_packager/packaging/rpm.py @@ -0,0 +1,146 @@ +#!/usr/bin/python3 +# encoding=utf-8 +# +# Copyright © 2015 Alexandre Detiste <[email protected]> +# Copyright © 2016 Simon McVittie <[email protected]> +# +# 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. +# +# You can find the GPL license text on a Debian system under +# /usr/share/common-licenses/GPL-2. + +import logging +import os +import subprocess + +from . import (PackagingSystem) +from ..util import (check_output, run_as_root) + +logger = logging.getLogger(__name__) + +class RpmPackaging(PackagingSystem): + def is_installed(self, package): + return 0 == subprocess.call(['rpm', '-q', package], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) + + def current_version(self, package): + try: + return check_output(['rpm', '-q', + '--qf', '%{VERSION}', package], universal_newlines=True) + except subprocess.CalledProcessError: + return None + + def is_available(self, package): + # assume no apt-like system in this base class + return self.is_installed(package) + + def available_version(self, package): + # assume no apt-like system in this base class + return self.current_version(package) + + def install_packages(self, rpms, method=None, gain_root='su'): + """Install one or more packages (a list of filenames).""" + + if method is None: + method = 'rpm' + + if method == 'dnf': + run_as_root(['dnf', 'install'] + list(rpms), gain_root) + elif method == 'zypper': + run_as_root(['zypper', 'install'] + list(rpms), gain_root) + elif method == 'rpm': + run_as_root(['rpm', '-U'] + list(rpms), gain_root) + +class DnfPackaging(RpmPackaging): + def __init__(self): + self.__available = None + + def is_available(self, package): + if self.available is None: + cache = set() + proc = subprocess.Popen(['dnf', 'list'], + universal_newlines=True, + stdout=subprocess.PIPE) + for line in proc.stdout: + if '.' in line: + cache.add(line.split('.')[0]) + self.available = cache + + return package in self.available + + def available_version(self, package): + proc = subprocess.Popen(['dnf', 'list', package], + universal_newlines=True, + stderr=subprocess.DEVNULL, + stdout=subprocess.PIPE) + # keep only last line + for line in proc.stdout: + pass + return line.split()[1] + + def install_packages(self, rpms, method='dnf', gain_root='su'): + super(DnfPackaging, self).install_packages(rpms, method=method, + gain_root=gain_root) + +class ZypperPackaging(RpmPackaging): + def is_available(self, package): + proc = subprocess.Popen(['zypper', 'info', package], + universal_newlines=True, + stdout=subprocess.PIPE, + env={'LANG':'C'}) + for line in proc.stdout: + if ':' not in line: + continue + k, _, v = line.split(maxsplit=2) + if k == 'Version': + return True + return False + + def available_version(self, package): + proc = subprocess.Popen(['zypper', 'info', package], + universal_newlines=True, + stdout=subprocess.PIPE, + env={'LANG':'C'}) + for line in proc.stdout: + if ':' not in line: + continue + k, _, v = line.split(maxsplit=2) + if k == 'Version': + return v + + def install_packages(self, rpms, method='zypper', gain_root='su'): + super(ZypperPackaging, self).install_packages(rpms, method=method, + gain_root=gain_root) + +def get_distro_packaging(): + if os.path.isfile('/etc/redhat-release'): + return ZypperPackaging() + + if os.path.isfile('/etc/SuSE-release'): + return DnfPackaging() + + try: + maybe = DnfPackaging() + + if maybe.is_available('rpm'): + return maybe + except: + pass + + try: + maybe = ZypperPackaging() + + if maybe.is_available('rpm'): + return maybe + except: + pass + + return RpmPackaging() diff --git a/game_data_packager/steam.py b/game_data_packager/steam.py index 4f11a9a..2950a49 100644 --- a/game_data_packager/steam.py +++ b/game_data_packager/steam.py @@ -25,10 +25,9 @@ import urllib.request from .build import (BinaryExecutablesNotAllowed, DownloadsFailed, NoPackagesPossible) +from .packaging import (get_native_packaging_system) from .util import (AGENT, - PACKAGE_CACHE, ascii_safe, - install_packages, lang_score, rm_rf) @@ -114,6 +113,8 @@ def run_steam_meta_mode(args, games): found_games = [] found_packages = [] tasks = {} + packaging = get_native_packaging_system() + for game, gamedata in games.items(): for package in gamedata.packages.values(): id = package.steam.get('id') or gamedata.steam.get('id') @@ -126,12 +127,12 @@ def run_steam_meta_mode(args, games): if lang_score(package.lang) == 0: continue - installed = PACKAGE_CACHE.is_installed(package.name) + installed = packaging.is_installed(package.name) if args.new and installed: continue if game not in tasks: - tasks[game] = gamedata.construct_task() + tasks[game] = gamedata.construct_task(packaging=packaging) paths = [] for path in tasks[game].iter_steam_paths((package,)): @@ -236,6 +237,6 @@ def run_steam_meta_mode(args, games): raise SystemExit(1) if install_debs: - install_packages(all_debs, args.install_method, args.gain_root_command) + packaging.install_packages(all_debs, args.install_method, args.gain_root_command) if workdir: rm_rf(workdir) diff --git a/game_data_packager/util.py b/game_data_packager/util.py index ea22d5e..84edbb0 100644 --- a/game_data_packager/util.py +++ b/game_data_packager/util.py @@ -217,25 +217,17 @@ def recursive_utime(directory, orig_time): # loaded at the end to avoid failed cyclic loads if FORMAT == 'deb': - from .util_deb import (PACKAGE_CACHE, - install_packages, - lintian_license, - lintian_desktop) + from .util_deb import (lintian_license, lintian_desktop) elif FORMAT == 'arch': - from .util_arch import (PACKAGE_CACHE, install_packages) lintian_license = lambda a,b,c: None lintian_desktop = lambda a,b,c: None elif DISTRO == 'fedora': - from .util_fedora import (PACKAGE_CACHE, install_packages) lintian_license = lambda a,b,c: None lintian_desktop = lambda a,b,c: None elif DISTRO == 'suse': - from .util_suse import (PACKAGE_CACHE, install_packages) lintian_license = lambda a,b,c: None lintian_desktop = lambda a,b,c: None # pyflakes -PACKAGE_CACHE -install_packages lintian_license lintian_desktop diff --git a/game_data_packager/util_deb.py b/game_data_packager/util_deb.py index cd9d766..e502b9a 100644 --- a/game_data_packager/util_deb.py +++ b/game_data_packager/util_deb.py @@ -18,108 +18,11 @@ import logging import os -import subprocess -from .util import (run_as_root, check_output, mkdir_p) -from debian.debian_support import Version +from .util import (mkdir_p) logger = logging.getLogger('game-data-packager.util_deb') -class PackageCache: - installed = None - available = None - - def is_installed(self, package): - # FIXME: this shouldn't be hard-coded - if package == 'doom-engine': - return (self.is_installed('chocolate-doom') - or self.is_installed('prboom-plus') - or self.is_installed('doomsday')) - if package == 'boom-engine': - return (self.is_installed('prboom-plus') - or self.is_installed('doomsday')) - if package == 'heretic-engine': - return (self.is_installed('chocolate-heretic') - or self.is_installed('doomsday')) - if package == 'hexen-engine': - return (self.is_installed('chocolate-hexen') - or self.is_installed('doomsday')) - - if os.path.isdir(os.path.join('/usr/share/doc', package)): - return True - - if self.installed is None: - cache = set() - proc = subprocess.Popen(['dpkg-query', '--show', - '--showformat', '${Package}\\n'], - universal_newlines=True, - stdout=subprocess.PIPE) - for line in proc.stdout: - cache.add(line.rstrip()) - self.installed = cache - - return package in self.installed - - def is_available(self, package): - if self.available is None: - cache = set() - proc = subprocess.Popen(['apt-cache', 'pkgnames'], - universal_newlines=True, - stdout=subprocess.PIPE) - for line in proc.stdout: - cache.add(line.rstrip()) - self.available = cache - - return package in self.available - - def current_version(self, package): - # 'dpkg-query: no packages found matching $package' - # will leak on stderr if called with an unknown package, - # but that should never happen - try: - return check_output(['dpkg-query', '--show', - '--showformat', '${Version}', package], universal_newlines=True) - except subprocess.CalledProcessError: - return - - def available_version(self, package): - current_ver = check_output(['apt-cache', 'madison', package], - universal_newlines=True) - current_ver = current_ver.splitlines()[0] - current_ver = current_ver.split('|')[1].strip() - return current_ver - -PACKAGE_CACHE = PackageCache() - -def install_packages(debs, method, gain_root='su'): - """Install one or more packages (a list of filenames).""" - - if method and method not in ( - 'apt', 'dpkg', - 'gdebi', 'gdebi-gtk', 'gdebi-kde', - ): - logger.warning(('Unknown installation method %r, using apt or dpkg ' + - 'instead') % method) - method = None - - if not method: - apt_ver = PACKAGE_CACHE.current_version('apt') - if Version(apt_ver.strip()) >= Version('1.1~0'): - method = 'apt' - else: - method = 'dpkg' - - if method == 'apt': - run_as_root(['apt-get', 'install', '--install-recommends'] + list(debs), - gain_root) - elif method == 'dpkg': - run_as_root(['dpkg', '-i'] + list(debs), gain_root) - elif method == 'gdebi': - run_as_root(['gdebi'] + list(debs), gain_root) - else: - # gdebi-gtk etc. - subprocess.call([method] + list(debs)) - def lintian_license(destdir, package, file): assert type(package) is str lintiandir = os.path.join(destdir, 'usr/share/lintian/overrides') diff --git a/game_data_packager/util_fedora.py b/game_data_packager/util_fedora.py deleted file mode 100644 index c2caa03..0000000 --- a/game_data_packager/util_fedora.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/python3 -# encoding=utf-8 -# -# Copyright © 2015 Alexandre Detiste <[email protected]> -# -# 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. - -import logging -import subprocess - -from .util import (run_as_root) -from .util_rpm import (RPM_PackageCache) - -logger = logging.getLogger('game-data-packager.util_fedora') - -class PackageCache(RPM_PackageCache): - available = None - - def is_available(self, package): - if self.available is None: - cache = set() - proc = subprocess.Popen(['dnf', 'list'], - universal_newlines=True, - stdout=subprocess.PIPE) - for line in proc.stdout: - if '.' in line: - cache.add(line.split('.')[0]) - self.available = cache - - return package in self.available - - def available_version(self, package): - proc = subprocess.Popen(['dnf', 'list', package], - universal_newlines=True, - stderr=subprocess.DEVNULL, - stdout=subprocess.PIPE) - # keep only last line - for line in proc.stdout: - pass - return line.split()[1] - -PACKAGE_CACHE = PackageCache() - -def install_packages(debs, method, gain_root='su'): - """Install one or more packages (a list of filenames).""" - run_as_root(['dnf', 'install'] + list(debs), gain_root) diff --git a/game_data_packager/util_rpm.py b/game_data_packager/util_rpm.py deleted file mode 100644 index 03e9fa0..0000000 --- a/game_data_packager/util_rpm.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/python3 -# encoding=utf-8 -# -# Copyright © 2015 Alexandre Detiste <[email protected]> -# -# 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. - -import logging -import subprocess - -from .util import (check_output) - -logger = logging.getLogger('game-data-packager.util_rpm') - -class RPM_PackageCache: - def is_installed(self, package): - return 0 == subprocess.call(['rpm', '-q', package], - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL) - - def current_version(self, package): - try: - return check_output(['rpm', '-q', - '--qf', '%{VERSION}', package], universal_newlines=True) - except subprocess.CalledProcessError: - return diff --git a/game_data_packager/util_suse.py b/game_data_packager/util_suse.py deleted file mode 100644 index 60d8ecb..0000000 --- a/game_data_packager/util_suse.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/python3 -# encoding=utf-8 -# -# Copyright © 2015 Alexandre Detiste <[email protected]> -# -# 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. - -import logging -import subprocess - -from .util import (run_as_root) -from .util_rpm import (RPM_PackageCache) - -logger = logging.getLogger('game-data-packager.util_suse') - -class PackageCache(RPM_PackageCache): - def is_available(self, package): - proc = subprocess.Popen(['zypper', 'info', package], - universal_newlines=True, - stdout=subprocess.PIPE, - env={'LANG':'C'}) - for line in proc.stdout: - if ':' not in line: - continue - k, _, v = line.split(maxsplit=2) - if k == 'Version': - return True - return False - - def available_version(self, package): - proc = subprocess.Popen(['zypper', 'info', package], - universal_newlines=True, - stdout=subprocess.PIPE, - env={'LANG':'C'}) - for line in proc.stdout: - if ':' not in line: - continue - k, _, v = line.split(maxsplit=2) - if k == 'Version': - return v - -PACKAGE_CACHE = PackageCache() - -def install_packages(rpms, method, gain_root='su'): - """Install one or more packages (a list of filenames).""" - run_as_root(['zypper', 'install'] + list(rpms), gain_root) diff --git a/tools/babel.py b/tools/babel.py index 7826b25..b618e14 100755 --- a/tools/babel.py +++ b/tools/babel.py @@ -20,11 +20,14 @@ from game_data_packager import (load_games) from game_data_packager.build import (FillResult) +from game_data_packager.packaging import (get_native_packaging_system) games = [] genres = dict() langs = dict() langs['total'] = 0 +packaging = get_native_packaging_system() + for name, game in load_games().items(): stats = dict() for package in game.packages.values(): @@ -43,7 +46,7 @@ for name, game in load_games().items(): for m_lang in package.langs: if m_lang not in stats: stats[m_lang] = '*' - with game.construct_task() as task: + with game.construct_task(packaging=packaging) as task: if task.fill_gaps(package=package, log=False) is FillResult.IMPOSSIBLE: if package.better_version is None: diff --git a/tools/game-data-packager.spec b/tools/game-data-packager.spec index 21936d3..6481ca0 100644 --- a/tools/game-data-packager.spec +++ b/tools/game-data-packager.spec @@ -79,9 +79,6 @@ echo 'DISTRO = "fedora"' >> $VERSION_PY echo 'BINDIR = "usr/bin"' >> $VERSION_PY echo 'LICENSEDIR = "usr/share/licenses"' >> $VERSION_PY echo 'ASSETS = "usr/share"' >> $VERSION_PY -rm $RPM_BUILD_ROOT/usr/share/games/game-data-packager/game_data_packager/util_arch.py -rm $RPM_BUILD_ROOT/usr/share/games/game-data-packager/game_data_packager/util_deb.py -rm $RPM_BUILD_ROOT/usr/share/games/game-data-packager/game_data_packager/util_suse.py find $RPM_BUILD_ROOT/usr/share/games/game-data-packager/game_data_packager -name '*.py' -exec chmod 755 {} \; find $RPM_BUILD_ROOT/etc/game-data-packager -empty -exec sh -c "echo '# we need more mirrors' > {}" \; -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/game-data-packager.git _______________________________________________ Pkg-games-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits

