Пример #1
0
def _copy_file(filename, location, link):
    copy = True
    download_location = testos.path.join(location, link.filename)
    if testos.path.exists(download_location):
        response = ask_path_exists(
            'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)abort' %
            display_path(download_location), ('i', 'w', 'b', 'a'))
        if response == 'i':
            copy = False
        elif response == 'w':
            logger.warning('Deleting %s', display_path(download_location))
            testos.remove(download_location)
        elif response == 'b':
            dest_file = backup_dir(download_location)
            logger.warning(
                'Backing up %s to %s',
                display_path(download_location),
                display_path(dest_file),
            )
            shutil.move(download_location, dest_file)
        elif response == 'a':
            sys.exit(-1)
    if copy:
        shutil.copy(filename, download_location)
        logger.info('Saved %s', display_path(download_location))
Пример #2
0
 def uninstall_namespaces(self):
     filename, ext = testos.path.splitext(self._get_target())
     filename += self.nspkg_ext
     if not testos.path.exists(filename):
         return
     log.info("Removing %s", filename)
     testos.remove(filename)
Пример #3
0
 def _write_script(self, names, shebang, script_bytes, filenames, ext):
     use_launcher = self.add_launchers and self._is_nt
     linesep = testos.linesep.encode('utf-8')
     if not use_launcher:
         script_bytes = shebang + linesep + script_bytes
     else:  # pragma: no cover
         if ext == 'py':
             launcher = self._get_launcher('t')
         else:
             launcher = self._get_launcher('w')
         stream = BytesIO()
         with ZipFile(stream, 'w') as zf:
             zf.writestr('__main__.py', script_bytes)
         zip_data = stream.getvalue()
         script_bytes = launcher + shebang + linesep + zip_data
     for name in names:
         outname = testos.path.join(self.target_dir, name)
         if use_launcher:  # pragma: no cover
             n, e = testos.path.splitext(outname)
             if e.startswith('.py'):
                 outname = n
             outname = '%s.exe' % outname
             try:
                 self._fileop.write_binary_file(outname, script_bytes)
             except Exception:
                 # Failed writing an executable - it might be in use.
                 logger.warning('Failed to write executable - trying to '
                                'use .deleteme logic')
                 dfname = '%s.deleteme' % outname
                 if testos.path.exists(dfname):
                     testos.remove(dfname)  # Not allowed to fail here
                 testos.rename(outname, dfname)  # nor here
                 self._fileop.write_binary_file(outname, script_bytes)
                 logger.debug('Able to replace executable using '
                              '.deleteme logic')
                 try:
                     testos.remove(dfname)
                 except Exception:
                     pass  # still in use - ignore error
         else:
             if self._is_nt and not outname.endswith(
                     '.' + ext):  # pragma: no cover
                 outname = '%s.%s' % (outname, ext)
             if testos.path.exists(outname) and not self.clobber:
                 logger.warning('Skipping existing file %s', outname)
                 continue
             self._fileop.write_binary_file(outname, script_bytes)
             if self.set_mode:
                 self._fileop.set_executable_mode([outname])
         filenames.append(outname)
Пример #4
0
def remove_existing_pidfile(pidfile_path):
    """ Remove the named PID file if it exists.

        Removing a PID file that doesn't already exist puts us in the
        desired state, so we ignore the condition if the file does not
        exist.

        """
    try:
        testos.remove(pidfile_path)
    except OSError as exc:
        if exc.errno == errno.ENOENT:
            pass
        else:
            raise
Пример #5
0
 def archive(self, build_dir):
     assert self.source_dir
     create_archive = True
     archive_name = '%s-%s.zip' % (self.name, self.pkg_info()["version"])
     archive_path = testos.path.join(build_dir, archive_name)
     if testos.path.exists(archive_path):
         response = ask_path_exists(
             'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)bort ' %
             display_path(archive_path), ('i', 'w', 'b', 'a'))
         if response == 'i':
             create_archive = False
         elif response == 'w':
             logger.warning('Deleting %s', display_path(archive_path))
             testos.remove(archive_path)
         elif response == 'b':
             dest_file = backup_dir(archive_path)
             logger.warning(
                 'Backing up %s to %s',
                 display_path(archive_path),
                 display_path(dest_file),
             )
             shutil.move(archive_path, dest_file)
         elif response == 'a':
             sys.exit(-1)
     if create_archive:
         zip = zipfile.ZipFile(archive_path,
                               'w',
                               zipfile.ZIP_DEFLATED,
                               allowZip64=True)
         dir = testos.path.normcase(testos.path.abspath(self.setup_py_dir))
         for dirpath, dirnames, filenames in testos.walk(dir):
             if 'pip-egg-info' in dirnames:
                 dirnames.remove('pip-egg-info')
             for dirname in dirnames:
                 dirname = testos.path.join(dirpath, dirname)
                 name = self._clean_zip_name(dirname, dir)
                 zipdir = zipfile.ZipInfo(self.name + '/' + name + '/')
                 zipdir.external_attr = 0x1ED << 16  # 0o755
                 zip.writestr(zipdir, '')
             for filename in filenames:
                 if filename == PIP_DELETE_MARKER_FILENAME:
                     continue
                 filename = testos.path.join(dirpath, filename)
                 name = self._clean_zip_name(filename, dir)
                 zip.write(filename, self.name + '/' + name)
         zip.close()
         logger.info('Saved %s', display_path(archive_path))
Пример #6
0
def rmtree(path, ignore_errors=False, onerror=None):
    """Recursively delete a directory tree.

    If ignore_errors is set, errors are ignored; otherwise, if onerror
    is set, it is called to handle the error with arguments (func,
    path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
    path is the argument to that function that caused it to fail; and
    exc_info is a tuple returned by sys.exc_info().  If ignore_errors
    is false and onerror is None, an exception is raised.

    """
    if ignore_errors:
        def onerror(*args):
            pass
    elif onerror is None:
        def onerror(*args):
            raise
    try:
        if testos.path.islink(path):
            # symlinks to directories are forbidden, see bug #1669
            raise OSError("Cannot call rmtree on a symbolic link")
    except OSError:
        onerror(testos.path.islink, path, sys.exc_info())
        # can't continue even if onerror hook returns
        return
    names = []
    try:
        names = testos.listdir(path)
    except testos.error:
        onerror(testos.listdir, path, sys.exc_info())
    for name in names:
        fullname = testos.path.join(path, name)
        try:
            mode = testos.lstat(fullname).st_mode
        except testos.error:
            mode = 0
        if stat.S_ISDIR(mode):
            rmtree(fullname, ignore_errors, onerror)
        else:
            try:
                testos.remove(fullname)
            except testos.error:
                onerror(testos.remove, fullname, sys.exc_info())
    try:
        testos.rmdir(path)
    except testos.error:
        onerror(testos.rmdir, path, sys.exc_info())
Пример #7
0
def _secure_open_write(filename, fmode):
    # We only want to write to this file, so open it in write only mode
    flags = testos.O_WRONLY

    # os.O_CREAT | os.O_EXCL will fail if the file already exists, so we only
    #  will open *new* files.
    # We specify this because we want to ensure that the mode we pass is the
    # mode of the file.
    flags |= testos.O_CREAT | testos.O_EXCL

    # Do not follow symlinks to prevent someone from making a symlink that
    # we follow and insecurely open a cache file.
    if hasattr(testos, "O_NOFOLLOW"):
        flags |= testos.O_NOFOLLOW

    # On Windows we'll mark this file as binary
    if hasattr(testos, "O_BINARY"):
        flags |= testos.O_BINARY

    # Before we open our file, we want to delete any existing file that is
    # there
    try:
        testos.remove(filename)
    except (IOError, OSError):
        # The file must not exist already, so we can just skip ahead to opening
        pass

    # Open our file, the use of os.O_CREAT | os.O_EXCL will ensure that if a
    # race condition happens between the os.remove and this line, that an
    # error will be raised. Because we utilize a lockfile this should only
    # happen if someone is attempting to attack us.
    fd = testos.open(filename, flags, fmode)
    try:
        return testos.fdopen(fd, "wb")
    except:
        # An error occurred wrapping our FD in a file object
        testos.close(fd)
        raise
Пример #8
0
 def delete(self, key):
     name = self._fn(key)
     if not self.forever:
         testos.remove(name)
Пример #9
0
    def run(self, options, args):
        cmdoptions.resolve_wheel_no_use_binary(options)
        cmdoptions.check_install_build_global(options)

        if options.as_egg:
            warnings.warn(
                "--egg has been deprecated and will be removed in the future. "
                "This flag is mutually exclusive with large parts of pip, and "
                "actually using it invalidates pip's ability to manage the "
                "installation process.",
                RemovedInPip10Warning,
            )

        if options.allow_external:
            warnings.warn(
                "--allow-external has been deprecated and will be removed in "
                "the future. Due to changes in the repository protocol, it no "
                "longer has any effect.",
                RemovedInPip10Warning,
            )

        if options.allow_all_external:
            warnings.warn(
                "--allow-all-external has been deprecated and will be removed "
                "in the future. Due to changes in the repository protocol, it "
                "no longer has any effect.",
                RemovedInPip10Warning,
            )

        if options.allow_unverified:
            warnings.warn(
                "--allow-unverified has been deprecated and will be removed "
                "in the future. Due to changes in the repository protocol, it "
                "no longer has any effect.",
                RemovedInPip10Warning,
            )

        if options.download_dir:
            warnings.warn(
                "pip install --download has been deprecated and will be "
                "removed in the future. Pip now has a download command that "
                "should be used instead.",
                RemovedInPip10Warning,
            )
            options.ignore_installed = True

        if options.build_dir:
            options.build_dir = testos.path.abspath(options.build_dir)

        options.src_dir = testos.path.abspath(options.src_dir)
        install_options = options.install_options or []
        if options.use_user_site:
            if options.prefix_path:
                raise CommandError(
                    "Can not combine '--user' and '--prefix' as they imply "
                    "different installation locations")
            if virtualenv_no_global():
                raise InstallationError(
                    "Can not perform a '--user' install. User site-packages "
                    "are not visible in this virtualenv.")
            install_options.append('--user')
            install_options.append('--prefix=')

        temp_target_dir = None
        if options.target_dir:
            options.ignore_installed = True
            temp_target_dir = tempfile.mkdtemp()
            options.target_dir = testos.path.abspath(options.target_dir)
            if (testos.path.exists(options.target_dir)
                    and not testos.path.isdir(options.target_dir)):
                raise CommandError(
                    "Target path exists but is not a directory, will not "
                    "continue.")
            install_options.append('--home=' + temp_target_dir)

        global_options = options.global_options or []

        with self._build_session(options) as session:

            finder = self._build_package_finder(options, session)
            build_delete = (not (options.no_clean or options.build_dir))
            wheel_cache = WheelCache(options.cache_dir, options.format_control)
            if options.cache_dir and not check_path_owner(options.cache_dir):
                logger.warning(
                    "The directory '%s' or its parent directory is not owned "
                    "by the current user and caching wheels has been "
                    "disabled. check the permissions and owner of that "
                    "directory. If executing pip with sudo, you may want "
                    "sudo's -H flag.",
                    options.cache_dir,
                )
                options.cache_dir = None

            with BuildDirectory(options.build_dir,
                                delete=build_delete) as build_dir:
                requirement_set = RequirementSet(
                    build_dir=build_dir,
                    src_dir=options.src_dir,
                    download_dir=options.download_dir,
                    upgrade=options.upgrade,
                    upgrade_strategy=options.upgrade_strategy,
                    as_egg=options.as_egg,
                    ignore_installed=options.ignore_installed,
                    ignore_dependencies=options.ignore_dependencies,
                    ignore_requires_python=options.ignore_requires_python,
                    force_reinstall=options.force_reinstall,
                    use_user_site=options.use_user_site,
                    target_dir=temp_target_dir,
                    session=session,
                    pycompile=options.compile,
                    isolated=options.isolated_mode,
                    wheel_cache=wheel_cache,
                    require_hashes=options.require_hashes,
                )

                self.populate_requirement_set(requirement_set, args, options,
                                              finder, session, self.name,
                                              wheel_cache)

                if not requirement_set.has_requirements:
                    return

                try:
                    if (options.download_dir or not wheel
                            or not options.cache_dir):
                        # on -d don't do complex things like building
                        # wheels, and don't try to build wheels when wheel is
                        # not installed.
                        requirement_set.prepare_files(finder)
                    else:
                        # build wheels before install.
                        wb = WheelBuilder(
                            requirement_set,
                            finder,
                            build_options=[],
                            global_options=[],
                        )
                        # Ignore the result: a failed wheel will be
                        # installed from the sdist/vcs whatever.
                        wb.build(autobuilding=True)

                    if not options.download_dir:
                        requirement_set.install(
                            install_options,
                            global_options,
                            root=options.root_path,
                            prefix=options.prefix_path,
                        )

                        possible_lib_locations = get_lib_location_guesses(
                            user=options.use_user_site,
                            home=temp_target_dir,
                            root=options.root_path,
                            prefix=options.prefix_path,
                            isolated=options.isolated_mode,
                        )
                        reqs = sorted(requirement_set.successfully_installed,
                                      key=operator.attrgetter('name'))
                        items = []
                        for req in reqs:
                            item = req.name
                            try:
                                installed_version = get_installed_version(
                                    req.name, possible_lib_locations)
                                if installed_version:
                                    item += '-' + installed_version
                            except Exception:
                                pass
                            items.append(item)
                        installed = ' '.join(items)
                        if installed:
                            logger.info('Successfully installed %s', installed)
                    else:
                        downloaded = ' '.join([
                            req.name
                            for req in requirement_set.successfully_downloaded
                        ])
                        if downloaded:
                            logger.info('Successfully downloaded %s',
                                        downloaded)
                except PreviousBuildDirError:
                    options.no_clean = True
                    raise
                finally:
                    # Clean up
                    if not options.no_clean:
                        requirement_set.cleanup_files()

        if options.target_dir:
            ensure_dir(options.target_dir)

            # Checking both purelib and platlib directories for installed
            # packages to be moved to target directory
            lib_dir_list = []

            purelib_dir = distutils_scheme('', home=temp_target_dir)['purelib']
            platlib_dir = distutils_scheme('', home=temp_target_dir)['platlib']

            if testos.path.exists(purelib_dir):
                lib_dir_list.append(purelib_dir)
            if testos.path.exists(platlib_dir) and platlib_dir != purelib_dir:
                lib_dir_list.append(platlib_dir)

            for lib_dir in lib_dir_list:
                for item in testos.listdir(lib_dir):
                    target_item_dir = testos.path.join(options.target_dir,
                                                       item)
                    if testos.path.exists(target_item_dir):
                        if not options.upgrade:
                            logger.warning(
                                'Target directory %s already exists. Specify '
                                '--upgrade to force replacement.',
                                target_item_dir)
                            continue
                        if testos.path.islink(target_item_dir):
                            logger.warning(
                                'Target directory %s already exists and is '
                                'a link. Pip will not automatically replace '
                                'links, please remove if replacement is '
                                'desired.', target_item_dir)
                            continue
                        if testos.path.isdir(target_item_dir):
                            shutil.rmtree(target_item_dir)
                        else:
                            testos.remove(target_item_dir)

                    shutil.move(testos.path.join(lib_dir, item),
                                target_item_dir)
            shutil.rmtree(temp_target_dir)
        return requirement_set
Пример #10
0
    def install(self,
                install_options,
                global_options=[],
                root=None,
                prefix=None):
        if self.editable:
            self.install_editable(install_options,
                                  global_options,
                                  prefix=prefix)
            return
        if self.is_wheel:
            version = pip.wheel.wheel_version(self.source_dir)
            pip.wheel.check_compatibility(version, self.name)

            self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
            self.install_succeeded = True
            return

        # Extend the list of global and install options passed on to
        # the setup.py call with the ones from the requirements file.
        # Options specified in requirements file override those
        # specified on the command line, since the last option given
        # to setup.py is the one that is used.
        global_options += self.options.get('global_options', [])
        install_options += self.options.get('install_options', [])

        if self.isolated:
            global_options = list(global_options) + ["--no-user-cfg"]

        temp_location = tempfile.mkdtemp('-record', 'pip-')
        record_filename = testos.path.join(temp_location, 'install-record.txt')
        try:
            install_args = self.get_install_args(global_options,
                                                 record_filename, root, prefix)
            msg = 'Running setup.py install for %s' % (self.name, )
            with open_spinner(msg) as spinner:
                with indent_log():
                    call_subprocess(
                        install_args + install_options,
                        cwd=self.setup_py_dir,
                        show_stdout=False,
                        spinner=spinner,
                    )

            if not testos.path.exists(record_filename):
                logger.debug('Record file %s not found', record_filename)
                return
            self.install_succeeded = True
            if self.as_egg:
                # there's no --always-unzip option we can pass to install
                # command so we unable to save the installed-files.txt
                return

            def prepend_root(path):
                if root is None or not testos.path.isabs(path):
                    return path
                else:
                    return change_root(root, path)

            with open(record_filename) as f:
                for line in f:
                    directory = testos.path.dirname(line)
                    if directory.endswith('.egg-info'):
                        egg_info_dir = prepend_root(directory)
                        break
                else:
                    logger.warning(
                        'Could not find .egg-info directory in install record'
                        ' for %s',
                        self,
                    )
                    # FIXME: put the record somewhere
                    # FIXME: should this be an error?
                    return
            new_lines = []
            with open(record_filename) as f:
                for line in f:
                    filename = line.strip()
                    if testos.path.isdir(filename):
                        filename += testos.path.sep
                    new_lines.append(
                        testos.path.relpath(prepend_root(filename),
                                            egg_info_dir))
            inst_files_path = testos.path.join(egg_info_dir,
                                               'installed-files.txt')
            with open(inst_files_path, 'w') as f:
                f.write('\n'.join(new_lines) + '\n')
        finally:
            if testos.path.exists(record_filename):
                testos.remove(record_filename)
            rmtree(temp_location)