[game-data-packager] 02/04: Add a consistency check for file collisions within a package

Simon McVittie smcv at debian.org
Wed Jul 5 08:34:10 UTC 2017


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 f2eb6286909148381a38750372abf47233e918f5
Author: Simon McVittie <smcv at debian.org>
Date:   Wed Jul 5 08:36:01 2017 +0100

    Add a consistency check for file collisions within a package
---
 debian/changelog                         |  1 +
 game_data_packager/__init__.py           | 48 ++++++++++++++++++++++++++++++++
 game_data_packager/packaging/__init__.py | 31 +++++++++++++++++++++
 3 files changed, 80 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 297f49d..31aa13f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,7 @@ game-data-packager (54) UNRELEASED; urgency=medium
     - drbrain2, morrowind, ut99: Do not try to install two files to the
       same destination in the same package. This would result in one
       of them being included and the other being omitted. [smcv]
+    - Add a consistency check to prevent the above happening again [smcv]
 
  -- Simon McVittie <smcv at debian.org>  Wed, 05 Jul 2017 08:31:13 +0100
 
diff --git a/game_data_packager/__init__.py b/game_data_packager/__init__.py
index 69f2ccd..05ab7e0 100644
--- a/game_data_packager/__init__.py
+++ b/game_data_packager/__init__.py
@@ -32,6 +32,7 @@ import yaml
 
 from .build import (PackagingTask)
 from .data import (FileGroup, Package, WantedFile)
+from .packaging import (NoPackaging)
 from .paths import (DATADIR, USE_VFS)
 from .util import ascii_safe
 from .version import (GAME_PACKAGE_VERSION)
@@ -779,6 +780,53 @@ class GameData(object):
                 if self.files[file.name].filename == 'version':
                     assert package.version != GAME_PACKAGE_VERSION, package.name
 
+            might_install = {}
+
+            no_packaging = NoPackaging()
+
+            for wanted in (package.install_files | package.optional_files):
+                install_as = wanted.install_as
+                install_to = no_packaging.substitute(package.install_to,
+                        package.name)
+
+                if wanted.alternatives and install_as == '$alternative':
+                    batch = [self.files[alt] for alt in wanted.alternatives]
+                else:
+                    batch = [wanted]
+
+                # Do not add them to might_install immediately so that
+                # alternatives with install_as = '$alternative' are allowed to
+                # collide with each other (perhaps we have alternatives
+                # foo.dat?1.0, foo.dat?2.0 and foo_censored.dat - that's fine
+                # if we are never going to install both copies of foo.dat
+                # together)
+                batch_might_install = {}
+
+                for installable in batch:
+                    if installable.install_to is not None:
+                        install_to = no_packaging.substitute(
+                                installable.install_to, installable.name,
+                                install_to=install_to)
+
+                    if install_as == '$alternative':
+                        install_to = os.path.join(install_to.strip('/'),
+                                installable.install_as)
+                    else:
+                        install_to = os.path.join(install_to.strip('/'),
+                                install_as)
+
+                    if install_to in might_install:
+                        raise AssertionError(
+                                'Package {} tries to install both {} and '
+                                '{} as {}'.format(
+                                    package.name, installable.name,
+                                    might_install[install_to].name,
+                                    install_to))
+
+                    batch_might_install[install_to] = installable
+
+                might_install.update(batch_might_install)
+
         for filename, wanted in self.files.items():
             if wanted.unpack:
                 assert 'format' in wanted.unpack, filename
diff --git a/game_data_packager/packaging/__init__.py b/game_data_packager/packaging/__init__.py
index f490968..630b9f7 100644
--- a/game_data_packager/packaging/__init__.py
+++ b/game_data_packager/packaging/__init__.py
@@ -324,6 +324,37 @@ class PackagingSystem(metaclass=ABCMeta):
         """
         raise NotImplementedError
 
+class NoPackaging(PackagingSystem):
+    """
+    A stub PackagingSystem used while checking consistency.
+    """
+
+    def __init__(self):
+        super(NoPackaging, self).__init__()
+        self._contexts = ('generic',)
+
+    def current_version(self, package):
+        return None
+
+    def available_version(self, package):
+        return None
+
+    def install_packages(self, packages, method=None, gain_root='su'):
+        pass
+
+    def build_package(self, per_package_dir, game, package,
+            destination, compress=True, md5sums=None, component=None):
+        pass
+
+    def format_relation(self, pr):
+        assert not pr.contextual
+        assert not pr.alternatives
+
+        if pr.version is not None:
+            return '%s (%s %s)' % (pr.package, pr.version_operator, pr.version)
+
+        return pr.package
+
 def get_packaging_system(format, distro=None):
     mod = 'game_data_packager.packaging.{}'.format(format)
     return importlib.import_module(mod).get_packaging_system(distro)

-- 
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