Browse Source

allow HostInfo.getPackages() to return all platforms; fix some other package-referencing issues

David Rose 16 years ago
parent
commit
b2e2877d89
3 changed files with 74 additions and 36 deletions
  1. 9 3
      direct/src/p3d/HostInfo.py
  2. 58 33
      direct/src/p3d/Packager.py
  3. 7 0
      direct/src/p3d/packp3d.py

+ 9 - 3
direct/src/p3d/HostInfo.py

@@ -351,9 +351,15 @@ class HostInfo:
             if name and pn != name:
             if name and pn != name:
                 continue
                 continue
 
 
-            package = self.getPackage(pn, version, platform = platform)
-            if package:
-                packages.append(package)
+            if platform is None:
+                for p2 in platforms:
+                    package = self.getPackage(pn, version, platform = p2)
+                    if package:
+                        packages.append(package)
+            else:
+                package = self.getPackage(pn, version, platform = platform)
+                if package:
+                    packages.append(package)
 
 
         return packages
         return packages
 
 

+ 58 - 33
direct/src/p3d/Packager.py

@@ -2310,13 +2310,17 @@ class Packager:
         package = self.packages.get((packageName, platform or self.platform, version, host), None)
         package = self.packages.get((packageName, platform or self.platform, version, host), None)
         if package:
         if package:
             return package
             return package
-
+        
         # Look on the searchlist.
         # Look on the searchlist.
         for dirname in self.installSearch:
         for dirname in self.installSearch:
             package = self.__scanPackageDir(dirname, packageName, platform or self.platform, version, host, requires = requires)
             package = self.__scanPackageDir(dirname, packageName, platform or self.platform, version, host, requires = requires)
             if not package:
             if not package:
                 package = self.__scanPackageDir(dirname, packageName, platform, version, host, requires = requires)
                 package = self.__scanPackageDir(dirname, packageName, platform, version, host, requires = requires)
 
 
+            if package and host and package.host != host:
+                # Wrong host.
+                package = None
+
             if package:
             if package:
                 break
                 break
 
 
@@ -2385,7 +2389,7 @@ class Packager:
 
 
         self.__sortImportPackages(packages)
         self.__sortImportPackages(packages)
         for package in packages:
         for package in packages:
-            if package and self.__packageIsValid(package, requires):
+            if package and self.__packageIsValid(package, requires, platform):
                 return package
                 return package
 
 
         return None
         return None
@@ -2404,38 +2408,45 @@ class Packager:
         if not host.readContentsFile():
         if not host.readContentsFile():
             if not host.downloadContentsFile(appRunner.http):
             if not host.downloadContentsFile(appRunner.http):
                 return None
                 return None
-        
-        package = host.getPackage(packageName, version, platform = platform)
-        if not package and not version:
+
+        packageInfos = []
+        packageInfo = host.getPackage(packageName, version, platform = platform)
+        if not packageInfo and not version:
             # No explicit version is specified, first fallback: look
             # No explicit version is specified, first fallback: look
             # for the compiled-in version.
             # for the compiled-in version.
-            package = host.getPackage(packageName, PandaSystem.getPackageVersionString(), platform = platform)
+            packageInfo = host.getPackage(packageName, PandaSystem.getPackageVersionString(), platform = platform)
             
             
-        if not package and not version:
+        if not packageInfo and not version:
             # No explicit version is specified, second fallback: get
             # No explicit version is specified, second fallback: get
             # the highest-numbered version available.
             # the highest-numbered version available.
-            packages = host.getPackages(packageName, platform = platform)
-            self.__sortPackageInfos(packages)
-            for p in packages:
-                if p and self.__packageIsValid(p, requires):
-                    package = p
-                    break
-            
-        if not package or not package.importDescFile:
-            return None
-
-        # Now we've retrieved a PackageInfo.  Get the import desc file
-        # from it.
-        filename = Filename(host.hostDir, 'imports/' + package.importDescFile.basename)
-        if not appRunner.freshenFile(host, package.importDescFile, filename):
-            self.notify.error("Couldn't download import file.")
-            return None
+            packageInfos = host.getPackages(packageName, platform = platform)
+            self.__sortPackageInfos(packageInfos)
+
+        if packageInfo and not packageInfos:
+            packageInfos = [packageInfo]
+
+        for packageInfo in packageInfos:
+            if not packageInfo or not packageInfo.importDescFile:
+                continue
+
+            # Now we've retrieved a PackageInfo.  Get the import desc file
+            # from it.
+            filename = Filename(host.hostDir, 'imports/' + packageInfo.importDescFile.basename)
+            if not appRunner.freshenFile(host, packageInfo.importDescFile, filename):
+                self.notify.error("Couldn't download import file.")
+                continue
+
+            # Now that we have the import desc file, use it to load one of
+            # our Package objects.
+            package = self.Package('', self)
+            if not package.readImportDescFile(filename):
+                continue
+
+            if self.__packageIsValid(package, requires, platform):
+                return package
 
 
-        # Now that we have the import desc file, use it to load one of
-        # our Package objects.
-        package = self.Package('', self)
-        if package.readImportDescFile(filename):
-            return package
+        # Couldn't find a suitable package.
+        return None
 
 
     def __sortImportPackages(self, packages):
     def __sortImportPackages(self, packages):
         """ Given a list of Packages read from *.import.xml filenames,
         """ Given a list of Packages read from *.import.xml filenames,
@@ -2491,20 +2502,25 @@ class Packager:
 
 
         return tuple(words)
         return tuple(words)
 
 
-    def __packageIsValid(self, package, requires):
+    def __packageIsValid(self, package, requires, platform):
         """ Returns true if the package is valid, meaning it can be
         """ Returns true if the package is valid, meaning it can be
         imported without conflicts with existing packages already
         imported without conflicts with existing packages already
         required (such as different versions of panda3d). """
         required (such as different versions of panda3d). """
 
 
+        if package.platform and package.platform != platform:
+            # Incorrect platform.
+            return False
+
         if not requires:
         if not requires:
+            # No other restrictions.
             return True
             return True
 
 
         # Really, we only check the panda3d package.  The other
         # Really, we only check the panda3d package.  The other
         # packages will list this as a dependency, and this is all
         # packages will list this as a dependency, and this is all
         # that matters.
         # that matters.
 
 
-        panda1 = self.__findPackageInList('panda3d', [package] + package.requires)
-        panda2 = self.__findPackageInList('panda3d', requires)
+        panda1 = self.__findPackageInRequires('panda3d', [package] + package.requires)
+        panda2 = self.__findPackageInRequires('panda3d', requires)
 
 
         if not panda1 or not panda2:
         if not panda1 or not panda2:
             return True
             return True
@@ -2512,13 +2528,22 @@ class Packager:
         if panda1.version == panda2.version:
         if panda1.version == panda2.version:
             return True
             return True
 
 
+        print 'Rejecting package %s, version "%s": depends on %s, version "%s" instead of version "%s"' % (
+            package.packageName, package.version,
+            panda1.packageName, panda1.version, panda2.version)
         return False
         return False
 
 
-    def __findPackageInList(self, packageName, list):
-        """ Returns the first package with the indicated name in the list. """
+    def __findPackageInRequires(self, packageName, list):
+        """ Returns the first package with the indicated name in the
+        list of packages, or in the list of packages required by the
+        packages in the list. """
+        
         for package in list:
         for package in list:
             if package.packageName == packageName:
             if package.packageName == packageName:
                 return package
                 return package
+            p2 = self.__findPackageInRequires(packageName, package.requires)
+            if p2:
+                return p2
 
 
         return None
         return None
 
 

+ 7 - 0
direct/src/p3d/packp3d.py

@@ -191,6 +191,13 @@ def makePackedApp(args):
     try:
     try:
         packager.setup()
         packager.setup()
         packager.beginPackage(appBase, p3dApplication = True)
         packager.beginPackage(appBase, p3dApplication = True)
+
+        # Pre-require panda3d, to give a less-confusing error message
+        # if one of our requirements pulls in a wrong version of
+        # panda3d.
+        if 'panda3d' not in map(lambda t: t[0], requires):
+            packager.do_require('panda3d')
+        
         for name, version, host in requires:
         for name, version, host in requires:
             packager.do_require(name, version = version, host = host)
             packager.do_require(name, version = version, host = host)