Viewing file: PackageManager.py (8.35 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
import os, sys, types from distutils import core from distutils import fancy_getopt from distutils.core import DEBUG from distutils.errors import * from distutils.util import convert_path from distutils.version import StrictVersion import Dist
# For .pkg data files import Structures
core.USAGE = """\ Usage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] %(script)s --help [cmd1 cmd2 ...] %(script)s cmd --help %(script)s --help-commands %(script)s --help-packages """
# the wrap_text function will collapse 2+ newlines into 1+ newlines INSTALL_SUCCESS = """\ %(name)s version %(version)s has been successfully installed!
Please note the installation locations:
Example repository config files:
%(install_sysconf)s
Machine-specific variable data space:
%(install_localstate)s
Local message catalogs:
%(install_l10n)s
Demos, default XML catalogs, schemas, profiling code, load
tests, and various standard files for installation in new
4Suite repositories:
%(install_data)s
Python library code, including Python C extensions:
%(install_lib)s%(sep)s%(package_root)s
Test suites:
%(install_tests)s
Executable scripts (add this to your executable path):
%(install_scripts)s
Documentation in various formats, if installed:
%(install_docs)s """
class PackageManager(Dist.Dist):
global_options = Dist.Dist.global_options + [ ('package=', 'p', "limit command(s) to a given package"), ]
display_options = [ ('help-packages', None, 'list all available packages'), ] + Dist.Dist.display_options
display_option_names = ['help_packages'] + Dist.Dist.display_option_names
def __init__(self, attrs): self.package = None self.package_root = None self.package_info = {} Dist.Dist.__init__(self, attrs) return
def finalize_options(self): self.distributions = {}
if self.package: if not self.package_info.has_key(self.package): raise DistutilsArgError, \ "package '%s' is unknown, use --help-packages " \ "to get a complete listing" % self.package packages = self.resolve_dependencies(self.package) else: packages = self.package_info.keys()
self.sub_packages = self.sort_dependencies(packages)
# Initialize the list-type data variables before merging if not self.packages: self.packages = [] if not self.py_modules: self.py_modules = [] if not self.libraries: self.libraries = [] if not self.headers: self.headers = [] if not self.ext_modules: self.ext_modules = [] if not self.scripts: self.scripts = [] if not self.data_files: self.data_files = []
# Build a composite of requested package and dependencies for name in self.sub_packages: self.merge_package(self.package_info[name])
self.developer_mode = (os.path.isdir('CVS') or os.path.isdir('RCS') or os.path.exists('CVS.sandboxinfo')) if self.developer_mode: print "developer mode enabled (CVS directory found)"
Dist.Dist.finalize_options(self) return
def get_package_distribution(self, package): if self.distributions.has_key(package): return self.distributions[package]
attrs = {'script_name' : self.script_name, 'script_args' : [], }
metadata = vars(self.metadata) attrs.update(metadata)
pkginfo = self.package_info[package] attrs.update(pkginfo)
dist = self.distributions[package] = Dist.Dist(attrs) return dist
def handle_display_options(self, option_order): from distutils.core import gen_usage if self.help_packages: self.print_packages() print print gen_usage(self.script_name) return 1 return Dist.Dist.handle_display_options(self, option_order)
def print_packages(self): packages = self.package_info.keys() packages.sort()
max_length = 0 for pkg in packages: if len(pkg) > max_length: max_length = len(pkg)
print "Available packages:" for pkg in packages: try: description = self.package_info[pkg]['description'] except KeyError: description = '(no description available)'
print " %-*s %s" % (max_length, pkg, description) return
def run_commands(self): if DEBUG: print "PackageManager.run_commands():"
Dist.Dist.run_commands(self)
if self.have_run.get('install') and not self.developer_mode: install = self.get_command_obj('install') subst = {'sep': os.sep} subst.update(vars(self)) subst.update(vars(self.metadata)) subst.update(vars(install))
message = INSTALL_SUCCESS % subst print '-'*78 print wrap_text(message, 78) return
def merge_package(self, package_info, overwrite=0): # Any attribute that is not already defined is invalid! metadict = self.metadata.__dict__ dict = self.__dict__ for key, val in package_info.items(): if metadict.has_key(key): if overwrite: metadict[key] = val elif dict.has_key(key): if type(val) is types.TupleType: val = list(val) if overwrite or dict[key] is None: dict[key] = val elif type(dict[key]) is type(val) is types.ListType: # Merge two lists dict[key].extend(val) else: raise DistutilsSetupError, \ "incompatiable types for option '%s'" % key else: raise DistutilsSetupError, \ "invalid distribution option '%s'" % key return
def sort_dependencies(self, packages): if DEBUG: print "PackageManager.sort_dependencies():"
# Make sure that the dependencies exist in package_info for pkg in packages: try: pkginfo = self.package_info[pkg] for dep in pkginfo.get('dependencies', []): depinfo = self.package_info[dep] except KeyError, key: raise DistutilsFileError('missing dependency: %s' % key)
# Remove any duplicates set = {} for name in packages: set[name] = 1 packages = set.keys()
# Now we can sort 'em sorted = [] while packages: changed = 0 if DEBUG: print " begin sort:" for pkg in packages[:]: if DEBUG: print " trying", pkg pkginfo = self.package_info[pkg] dependencies = pkginfo.get('dependencies', []) for dep in dependencies: if dep not in sorted: break else: if DEBUG: print " sorted", pkg sorted.append(pkg) packages.remove(pkg) changed = 1 if not changed: raise DistutilsFileError("circular dependency: %s" % packages)
return sorted
def resolve_dependencies(self, package): if DEBUG: print "PackageManager.resolve_dependencies():" packages = [package] pkg_info = self.package_info[package] for name in pkg_info.get('dependencies', []): if self.package_info.has_key(name): packages.extend(self.resolve_dependencies(name)) return packages
def wrap_text (text, width): if text is None: return '' if len(text) <= width: return text
chunks = text.split('\n\n') result = [] for chunk in chunks: if chunk.startswith('\n'): # An odd number of newlines, the empty string will become # a newline when this list is joined. result.append('') chunk = chunk[1:] lines = fancy_getopt.wrap_text(chunk, width) result.append('\n'.join(lines))
return '\n'.join(result)
|