[game-data-packager] 05/11: Reduce circular imports by introducing packaging modules
Simon McVittie
smcv at debian.org
Tue Jan 5 09:55:27 UTC 2016
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 <smcv at debian.org>
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 <smcv at debian.org>
+# © 2015 Alexandre Detiste <alexandre at detiste.be>
+#
+# 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 <alexandre at detiste.be>
+# Copyright © 2016 Simon McVittie <smcv at debian.org>
#
# 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 <smcv at debian.org>
+# Copyright © 2014-2016 Simon McVittie <smcv at debian.org>
# © 2015 Alexandre Detiste <alexandre at detiste.be>
#
# 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 <alexandre at detiste.be>
+# Copyright © 2016 Simon McVittie <smcv at debian.org>
+#
+# 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 <alexandre at detiste.be>
-#
-# 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 <alexandre at detiste.be>
-#
-# 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 <alexandre at detiste.be>
-#
-# 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
More information about the Pkg-games-commits
mailing list