Example #1
0
    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
Example #2
0
    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))
Example #3
0
 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)
Example #4
0
    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)
Example #5
0
    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
Example #6
0
 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
Example #7
0
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)