def extract(self, destination): filenames = Paths(verify=False) if self.format == '.egg': # Eggs are not in a directory for themselves... # Add a directory destination = os.path.join( destination, os.path.splitext(os.path.basename(self.filename))[0]) for filename in self._zip.namelist(): target_filename = os.path.join(destination, filename) target_info = self._zip.getinfo(filename) # ZIP specs uses / as path separator is_dir = (filename[-1] == '/' or target_info.external_attr & 0x10 == 0x10) if not is_dir: # Extract the file if it is not a folder target_path = os.path.dirname(target_filename) if not os.path.exists(target_path): os.makedirs(target_path) output = open(target_filename, 'wb') output.write(self._zip.read(filename)) output.close() else: filename = filename.rstrip('/') if not os.path.exists(target_filename): os.makedirs(target_filename) filenames.add(filename, directory=is_dir) return filenames
def manifest(self): manifest_name = DEFAULT_MANIFEST egginfo = self.configuration['egginfo'] if 'manifest' in egginfo: manifest_name = egginfo['manifest'].as_file() files = Paths(verify=False) files.listdir(self.prefix) return files.as_manifest(*parse_manifest(manifest_name))
def install(self): __status__ = u"Install files." target_directory = self.directory for filename, parts in self.files: archive = open_archive(filename, 'r') if archive is not None: extract_path = tempfile.mkdtemp('monteur.archive') extracted = archive.extract(extract_path) try: if parts: for source_part, destination_part in parts: files = extracted.as_dict( prefixes={source_part: destination_part}) if not files: raise ConfigurationError( u'Missing wanted path in archive') self.install_files( extract_path, target_directory, files) else: self.install_files( extract_path, target_directory, extracted.as_dict()) finally: shutil.rmtree(extract_path) else: if not os.path.isdir(filename): raise ConfigurationError( u"Cannot not directly install files, only directories", filename) files = Paths(verify=False) files.listdir(filename) if parts: for source_part, destination_part in parts: part_files = files.as_dict( prefixes={source_part: destination_part}) if not part_files: raise ConfigurationError( u'Missing wanted path in archive') self.install_files( filename, target_directory, part_files) else: target_path = os.path.join( target_directory, os.path.basename(filename)) self.install_files( target_path, target_directory, files)
def install(self, path): egg_info = self.configuration['egginfo'] manifest_url = egg_info['manifest'].as_file() files = Paths(verify=False) files.listdir(self.distribution.package_path) prefixes = [] if 'source' in egg_info: prefixes = [egg_info['source'].as_text()] for filename, info in files.as_manifest(*parse_manifest(manifest_url), prefixes=prefixes): install_file(info['full'], os.path.join(path, filename)) # XXX This needs review # if self.distribution.extensions: # builder.install( # self.distribution, install_path, self.interpretor) write_egg_info(self.distribution, package_path=path)
def __init__(self, section, installer, strategy=STRATEGY_UPDATE): setup = section.configuration['setup'] self._name = section.name self._installed_name = 'installed:' + self._name self._prefix = setup['prefix_directory'].as_text() self.requirements = [] self.packages = ReleaseSet() self.paths = Paths() self.override_rules = [('fail', '*')] self.installed_paths = Paths() self.depends = set(section.get('depends', '').as_list()) self.depends_paths = Paths() self.parts = installer.parts_status self.strategy = strategy installed_cfg = section.utilities.get('installed') if installed_cfg is not None: # We have a previous configuration self._installed_section = installed_cfg.get( self._installed_name, None) if self._installed_section is not None: get = self._installed_section.get # The part is installed if an installed path is missing # Or depending paths are missing, or install prefix changed # Or the configuration changed. self._enabled = ( not (self.installed_paths.extend( get('paths', '').as_list()) and Paths().extend(get('depends', '').as_list()) and installed_cfg.get(self._name, None) == section) or installer.prefix_changed) else: self._enabled = True # Register ourselves to be seen by other status installer.parts_status[section.name] = self else: # With no previous configuration, we are uninstalling. self._installed_section = section.configuration.get( self._installed_name, None) if self._installed_section is not None: self.installed_paths.extend( self._installed_section.get('paths', '').as_list()) self._enabled = True
def extract(self, destination): filenames = Paths(verify=False, separator='/') for entry in self._tar: self._tar.extract(entry, destination) filenames.add(entry.name, directory=entry.isdir()) return filenames
class PartStatus(object): """Hold the status information about a part: which are the packages and files that got installed, and dependencies information. """ def __init__(self, section, installer, strategy=STRATEGY_UPDATE): setup = section.configuration['setup'] self._name = section.name self._installed_name = 'installed:' + self._name self._prefix = setup['prefix_directory'].as_text() self.requirements = [] self.packages = ReleaseSet() self.paths = Paths() self.override_rules = [('fail', '*')] self.installed_paths = Paths() self.depends = set(section.get('depends', '').as_list()) self.depends_paths = Paths() self.parts = installer.parts_status self.strategy = strategy installed_cfg = section.utilities.get('installed') if installed_cfg is not None: # We have a previous configuration self._installed_section = installed_cfg.get( self._installed_name, None) if self._installed_section is not None: get = self._installed_section.get # The part is installed if an installed path is missing # Or depending paths are missing, or install prefix changed # Or the configuration changed. self._enabled = ( not (self.installed_paths.extend( get('paths', '').as_list()) and Paths().extend(get('depends', '').as_list()) and installed_cfg.get(self._name, None) == section) or installer.prefix_changed) else: self._enabled = True # Register ourselves to be seen by other status installer.parts_status[section.name] = self else: # With no previous configuration, we are uninstalling. self._installed_section = section.configuration.get( self._installed_name, None) if self._installed_section is not None: self.installed_paths.extend( self._installed_section.get('paths', '').as_list()) self._enabled = True def add_override_rule(self, rule, pattern): """Add a rule to allow or reject overriding given paths. """ assert rule in ('fail', 'allow', 'ask') for existing_rule, existing_pattern in self.override_rules: if existing_pattern == pattern: if existing_rule != rule: raise ConfigurationError('Conflictuous rules for', pattern) break else: self.override_rules.insert(0, (rule, pattern)) def test_override_rule(self, pathname, directory=False): """Test if it is possible to override the given path. """ if not os.path.exists(pathname): return False if directory: if not os.path.isdir(pathname): raise InstallationError( u"Target directory already exists, but is a file", pathname) message = u"Directory already exists" else: if os.path.isdir(pathname): raise InstallationError( u"Target file already exists, but is a directory", pathname) message = u"File already exists" for method, pattern in self.override_rules: if fnmatch.fnmatch(pathname, pattern): if method == 'fail': raise InstallationError(message, pathname) if method == 'allow': return True if method == 'ask': raise NotImplementedError() raise InstallationError(message, pathname) def enable(self, flag=True): """Enable the part: if the part is enabled it will be called during the installation or uninstallation process. """ if flag: self._enabled = True def is_enabled(self): """Return True if the part is enabled for installation or installation. """ return self._enabled def save(self, configuration): """Save the current part status in the given configuration. If the part is not enabled, it will just recopy the status of the previous installation in the given configuration. """ if self.is_enabled(): # Save new information section = Section(self._installed_name, configuration=configuration) if self.paths: section['paths'] = self.paths.as_list( replaces={self._prefix: '${setup:prefix_directory}'}) if self.packages: #section['packages'] = self.packages.as_requirements() self.depends_paths.extend( [p.path for p in self.packages if p.path is not None], verify=False) if self.depends_paths: section['depends'] = self.depends_paths.as_list( replaces={self._prefix: '${setup:prefix_directory}'}) else: # Save old information section = self._installed_section.__copy__() configuration[self._installed_name] = section return section def __repr__(self): return '<%s for %s>' % (self.__class__.__name__, self._name)