def list(self, options, args): if args: raise InstallationError("You cannot give an argument with --list") for path in sorted(self.paths()): if not os.path.exists(path): continue basename = os.path.basename(path.rstrip(os.path.sep)) if os.path.isfile(path) and zipfile.is_zipfile(path): if os.path.dirname(path) not in self.paths(): logger.notify("Zipped egg: %s" % display_path(path)) continue if ( basename != "site-packages" and basename != "dist-packages" and not path.replace("\\", "/").endswith("lib/python") ): continue logger.notify("In %s:" % display_path(path)) logger.indent += 2 zipped = [] unzipped = [] try: for filename in sorted(os.listdir(path)): ext = os.path.splitext(filename)[1].lower() if ext in (".pth", ".egg-info", ".egg-link"): continue if ext == ".py": logger.info("Not displaying %s: not a package" % display_path(filename)) continue full = os.path.join(path, filename) if os.path.isdir(full): unzipped.append((filename, self.count_package(full))) elif zipfile.is_zipfile(full): zipped.append(filename) else: logger.info("Unknown file: %s" % display_path(filename)) if zipped: logger.notify("Zipped packages:") logger.indent += 2 try: for filename in zipped: logger.notify(filename) finally: logger.indent -= 2 else: logger.notify("No zipped packages.") if unzipped: if options.sort_files: unzipped.sort(key=lambda x: -x[1]) logger.notify("Unzipped packages:") logger.indent += 2 try: for filename, count in unzipped: logger.notify("%s (%i files)" % (filename, count)) finally: logger.indent -= 2 else: logger.notify("No unzipped packages.") finally: logger.indent -= 2
def run(self, options, args): deprecation = textwrap.dedent(""" ############################################### ## ## ## Due to lack of interest and maintenance, ## ## 'pip bundle' and support for installing ## ## from *.pybundle files is now deprecated, ## ## and will be removed in pip v1.5. ## ## ## ############################################### """) logger.notify(deprecation) if not args: raise InstallationError('You must give a bundle filename') # We have to get everything when creating a bundle: options.ignore_installed = True logger.notify('Putting temporary main files in %s and source/develop files in %s' % (display_path(options.build_dir), display_path(options.src_dir))) self.bundle_filename = args.pop(0) requirement_set = super(BundleCommand, self).run(options, args) return requirement_set
def correct_build_location(self): """If the build location was a temporary directory, this will move it to a new more permanent location""" if self.source_dir is not None: return assert self.req is not None assert self._temp_build_dir old_location = self._temp_build_dir new_build_dir = self._ideal_build_dir del self._ideal_build_dir if self.editable: name = self.name.lower() else: name = self.name new_location = os.path.join(new_build_dir, name) if not os.path.exists(new_build_dir): logger.debug('Creating directory %s' % new_build_dir) _make_build_dir(new_build_dir) if os.path.exists(new_location): raise InstallationError( 'A package already exists in %s; please remove it to continue' % display_path(new_location)) logger.debug( 'Moving package %s from %s to new location %s' % (self, display_path(old_location), display_path(new_location))) shutil.move(old_location, new_location) self._temp_build_dir = new_location self.source_dir = new_location self._egg_info_path = None
def remove_filename_from_pth(self, filename): for pth in self.pth_files(): f = open(pth, 'r') lines = f.readlines() f.close() new_lines = [ l for l in lines if l.strip() != filename] if lines != new_lines: logger.info('Removing reference to %s from .pth file %s' % (display_path(filename), display_path(pth))) if not [line for line in new_lines if line]: logger.info( '%s file would be empty: deleting' % display_path(pth) ) if not self.simulate: os.unlink(pth) else: if not self.simulate: f = open(pth, 'wb') f.writelines(new_lines) f.close() return logger.warn( 'Cannot find a reference to %s in any .pth file' % display_path(filename) )
def run(self, options, args): deprecation = textwrap.dedent(""" ############################################### ## ## ## Due to lack of interest and maintenance, ## ## 'pip bundle' and support for installing ## ## from *.pybundle files is deprecated, as ## ## of v1.4 and will be removed in a ## ## future release. ## ## ## ############################################### """) logger.warn(deprecation) if not args: raise InstallationError('You must give a bundle filename') # We have to get everything when creating a bundle: options.ignore_installed = True logger.notify( 'Putting temporary build files in %s and source/develop files in %s' % (display_path(options.build_dir), display_path(options.src_dir))) self.bundle_filename = args.pop(0) requirement_set = super(BundleCommand, self).run(options, args) return requirement_set
def correct_build_location(self): """If the build location was a temporary directory, this will move it to a new more permanent location""" if self.source_dir is not None: return assert self.req is not None assert self._temp_build_dir old_location = self._temp_build_dir new_build_dir = self._ideal_build_dir del self._ideal_build_dir if self.editable: name = self.name.lower() else: name = self.name new_location = os.path.join(new_build_dir, name) if not os.path.exists(new_build_dir): logger.debug('Creating directory %s' % new_build_dir) _make_build_dir(new_build_dir) if os.path.exists(new_location): raise InstallationError( 'A package already exists in %s; please remove it to continue' % display_path(new_location)) logger.debug( 'Moving package %s from %s to new location %s' % (self, display_path(old_location), display_path(new_location)) ) shutil.move(old_location, new_location) self._temp_build_dir = new_location self.source_dir = new_location self._egg_info_path = None
def get_info(self, location): """Returns (url, revision), where both are strings""" assert not location.rstrip('/').endswith(self.dirname), \ 'Bad directory: %s' % location output = call_subprocess( [self.cmd, 'info', location], show_stdout=False, extra_environ={'LANG': 'C'}, ) match = _svn_url_re.search(output) if not match: logger.warn( 'Cannot determine URL of svn checkout %s' % display_path(location) ) return None, None url = match.group(1).strip() match = _svn_revision_re.search(output) if not match: logger.warn( 'Cannot determine revision of svn checkout %s' % display_path(location) ) logger.info('Output that cannot be parsed: \n%s' % output) return url, None return url, match.group(1)
def list(self, options, args): if args: raise InstallationError('You cannot give an argument with --list') for path in sorted(self.paths()): if not os.path.exists(path): continue basename = os.path.basename(path.rstrip(os.path.sep)) if os.path.isfile(path) and zipfile.is_zipfile(path): if os.path.dirname(path) not in self.paths(): logger.notify('Zipped egg: %s' % display_path(path)) continue if (basename != 'site-packages' and basename != 'dist-packages' and not path.replace('\\', '/').endswith('lib/python')): continue logger.notify('In %s:' % display_path(path)) logger.indent += 2 zipped = [] unzipped = [] try: for filename in sorted(os.listdir(path)): ext = os.path.splitext(filename)[1].lower() if ext in ('.pth', '.egg-info', '.egg-link'): continue if ext == '.py': logger.info('Not displaying %s: not a package' % display_path(filename)) continue full = os.path.join(path, filename) if os.path.isdir(full): unzipped.append((filename, self.count_package(full))) elif zipfile.is_zipfile(full): zipped.append(filename) else: logger.info('Unknown file: %s' % display_path(filename)) if zipped: logger.notify('Zipped packages:') logger.indent += 2 try: for filename in zipped: logger.notify(filename) finally: logger.indent -= 2 else: logger.notify('No zipped packages.') if unzipped: if options.sort_files: unzipped.sort(key=lambda x: -x[1]) logger.notify('Unzipped packages:') logger.indent += 2 try: for filename, count in unzipped: logger.notify('%s (%i files)' % (filename, count)) finally: logger.indent -= 2 else: logger.notify('No unzipped packages.') finally: logger.indent -= 2
def list(self, options, args): if args: raise InstallationError( 'You cannot give an argument with --list') for path in sorted(self.paths()): if not os.path.exists(path): continue basename = os.path.basename(path.rstrip(os.path.sep)) if os.path.isfile(path) and zipfile.is_zipfile(path): if os.path.dirname(path) not in self.paths(): logger.notify('Zipped egg: %s' % display_path(path)) continue if (basename != 'site-packages' and basename != 'dist-packages' and not path.replace('\\', '/').endswith('lib/python')): continue logger.notify('In %s:' % display_path(path)) logger.indent += 2 zipped = [] unzipped = [] try: for filename in sorted(os.listdir(path)): ext = os.path.splitext(filename)[1].lower() if ext in ('.pth', '.egg-info', '.egg-link'): continue if ext == '.py': logger.info('Not displaying %s: not a package' % display_path(filename)) continue full = os.path.join(path, filename) if os.path.isdir(full): unzipped.append((filename, self.count_package(full))) elif zipfile.is_zipfile(full): zipped.append(filename) else: logger.info('Unknown file: %s' % display_path(filename)) if zipped: logger.notify('Zipped packages:') logger.indent += 2 try: for filename in zipped: logger.notify(filename) finally: logger.indent -= 2 else: logger.notify('No zipped packages.') if unzipped: if options.sort_files: unzipped.sort(key=lambda x: -x[1]) logger.notify('Unzipped packages:') logger.indent += 2 try: for filename, count in unzipped: logger.notify('%s (%i files)' % (filename, count)) finally: logger.indent -= 2 else: logger.notify('No unzipped packages.') finally: logger.indent -= 2
def zip_package(self, module_name, filename, no_pyc): orig_filename = filename logger.notify('Zip %s (in %s)' % (module_name, display_path(filename))) logger.indent += 2 if filename.endswith('.egg'): dest_filename = filename else: dest_filename = filename + '.zip' try: # FIXME: I think this needs to be undoable: if filename == dest_filename: filename = backup_dir(orig_filename) logger.notify( 'Moving %s aside to %s' % (orig_filename, filename) ) if not self.simulate: shutil.move(orig_filename, filename) try: logger.info( 'Creating zip file in %s' % display_path(dest_filename) ) if not self.simulate: zip = zipfile.ZipFile(dest_filename, 'w') zip.writestr(module_name + '/', '') for dirpath, dirnames, filenames in os.walk(filename): if no_pyc: filenames = [f for f in filenames if not f.lower().endswith('.pyc')] for fns, is_dir in [ (dirnames, True), (filenames, False)]: for fn in fns: full = os.path.join(dirpath, fn) dest = os.path.join( module_name, dirpath[len(filename):].lstrip( os.path.sep ), fn, ) if is_dir: zip.writestr(dest + '/', '') else: zip.write(full, dest) zip.close() logger.info( 'Removing old directory %s' % display_path(filename) ) if not self.simulate: rmtree(filename) except: # FIXME: need to do an undo here raise # FIXME: should also be undone: self.add_filename_to_pth(dest_filename) finally: logger.indent -= 2
def run(self, options, args): if not args: raise InstallationError('You must give a bundle filename') # We have to get everything when creating a bundle: options.ignore_installed = True logger.notify('Putting temporary build files in %s and source/develop files in %s' % (display_path(options.build_dir), display_path(options.src_dir))) self.bundle_filename = args.pop(0) requirement_set = super(BundleCommand, self).run(options, args) return requirement_set
def run(self, options, args): if not args: raise InstallationError('You must give a bundle filename') # We have to get everything when creating a bundle: options.ignore_installed = True logger.notify( 'Putting temporary build files in %s and source/develop files in %s' % (display_path(options.build_dir), display_path(options.src_dir))) self.bundle_filename = args.pop(0) requirement_set = super(BundleCommand, self).run(options, args) return requirement_set
def zip_package(self, module_name, filename, no_pyc): orig_filename = filename logger.notify('Zip %s (in %s)' % (module_name, display_path(filename))) logger.indent += 2 if filename.endswith('.egg'): dest_filename = filename else: dest_filename = filename + '.zip' try: # FIXME: I think this needs to be undoable: if filename == dest_filename: filename = backup_dir(orig_filename) logger.notify('Moving %s aside to %s' % (orig_filename, filename)) if not self.simulate: shutil.move(orig_filename, filename) try: logger.info('Creating zip file in %s' % display_path(dest_filename)) if not self.simulate: zip = zipfile.ZipFile(dest_filename, 'w') zip.writestr(module_name + '/', '') for dirpath, dirnames, filenames in os.walk(filename): if no_pyc: filenames = [ f for f in filenames if not f.lower().endswith('.pyc') ] for fns, is_dir in [(dirnames, True), (filenames, False)]: for fn in fns: full = os.path.join(dirpath, fn) dest = os.path.join( module_name, dirpath[len(filename):].lstrip( os.path.sep), fn, ) if is_dir: zip.writestr(dest + '/', '') else: zip.write(full, dest) zip.close() logger.info('Removing old directory %s' % display_path(filename)) if not self.simulate: rmtree(filename) except: # FIXME: need to do an undo here raise # FIXME: should also be undone: self.add_filename_to_pth(dest_filename) finally: logger.indent -= 2
def run(self, options, args): logger.deprecated('1.6', "DEPRECATION: 'pip bundle' and support for installing from *.pybundle files is deprecated. " "See https://github.com/pypa/pip/pull/1046") if not args: raise InstallationError('You must give a bundle filename') # We have to get everything when creating a bundle: options.ignore_installed = True logger.notify('Putting temporary build files in %s and source/develop files in %s' % (display_path(options.build_dir), display_path(options.src_dir))) self.bundle_filename = args.pop(0) requirement_set = super(BundleCommand, self).run(options, args) return requirement_set
def unzip_package(self, module_name, filename): zip_filename = os.path.dirname(filename) if not os.path.isfile(zip_filename) and zipfile.is_zipfile(zip_filename): raise InstallationError( 'Module %s (in %s) isn\'t located in a zip file in %s' % (module_name, filename, zip_filename)) package_path = os.path.dirname(zip_filename) if not package_path in self.paths(): logger.warn( 'Unpacking %s into %s, but %s is not on sys.path' % (display_path(zip_filename), display_path(package_path), display_path(package_path))) logger.notify('Unzipping %s (in %s)' % (module_name, display_path(zip_filename))) if self.simulate: logger.notify('Skipping remaining operations because of --simulate') return logger.indent += 2 try: ## FIXME: this should be undoable: zip = zipfile.ZipFile(zip_filename) to_save = [] for info in zip.infolist(): name = info.filename if name.startswith(module_name + os.path.sep): content = zip.read(name) dest = os.path.join(package_path, name) if not os.path.exists(os.path.dirname(dest)): os.makedirs(os.path.dirname(dest)) if not content and dest.endswith(os.path.sep): if not os.path.exists(dest): os.makedirs(dest) else: f = open(dest, 'wb') f.write(content) f.close() else: to_save.append((name, zip.read(name))) zip.close() if not to_save: logger.info('Removing now-empty zip file %s' % display_path(zip_filename)) os.unlink(zip_filename) self.remove_filename_from_pth(zip_filename) else: logger.info('Removing entries in %s/ from zip file %s' % (module_name, display_path(zip_filename))) zip = zipfile.ZipFile(zip_filename, 'w') for name, content in to_save: zip.writestr(name, content) zip.close() finally: logger.indent -= 2
def unzip_package(self, module_name, filename): zip_filename = os.path.dirname(filename) if not os.path.isfile(zip_filename) and zipfile.is_zipfile(zip_filename): raise InstallationError( 'Module %s (in %s) isn\'t located in a zip file in %s' % (module_name, filename, zip_filename)) package_path = os.path.dirname(zip_filename) if not package_path in self.paths(): logger.warn( 'Unpacking %s into %s, but %s is not on sys.path' % (display_path(zip_filename), display_path(package_path), display_path(package_path))) logger.notify('Unzipping %s (in %s)' % (module_name, display_path(zip_filename))) if self.simulate: logger.notify('Skipping remaining operations because of --simulate') return logger.indent += 2 try: ## FIXME: this should be undoable: zip = zipfile.ZipFile(zip_filename) to_save = [] for name in zip.namelist(): if name.startswith(module_name + os.path.sep): content = zip.read(name) dest = os.path.join(package_path, name) if not os.path.exists(os.path.dirname(dest)): os.makedirs(os.path.dirname(dest)) if not content and dest.endswith(os.path.sep): if not os.path.exists(dest): os.makedirs(dest) else: f = open(dest, 'wb') f.write(content) f.close() else: to_save.append((name, zip.read(name))) zip.close() if not to_save: logger.info('Removing now-empty zip file %s' % display_path(zip_filename)) os.unlink(zip_filename) self.remove_filename_from_pth(zip_filename) else: logger.info('Removing entries in %s/ from zip file %s' % (module_name, display_path(zip_filename))) zip = zipfile.ZipFile(zip_filename, 'w') for name, content in to_save: zip.writestr(name, content) zip.close() finally: logger.indent -= 2
def check_destination(self, dest, url, rev_options, rev_display): """ Prepare a location to receive a checkout/clone. Return True if the location is ready for (and requires) a checkout/clone, False otherwise. """ checkout = True prompt = False if os.path.exists(dest): checkout = False if os.path.exists(os.path.join(dest, self.dirname)): existing_url = self.get_url(dest) if self.compare_urls(existing_url, url): logger.info( "%s in %s exists, and has correct URL (%s)" % (self.repo_name.title(), display_path(dest), url) ) logger.notify("Updating %s %s%s" % (display_path(dest), self.repo_name, rev_display)) self.update(dest, rev_options) else: logger.warn( "%s %s in %s exists with URL %s" % (self.name, self.repo_name, display_path(dest), existing_url) ) prompt = ("(s)witch, (i)gnore, (w)ipe, (b)ackup ", ("s", "i", "w", "b")) else: logger.warn("Directory %s already exists, " "and is not a %s %s." % (dest, self.name, self.repo_name)) prompt = ("(i)gnore, (w)ipe, (b)ackup ", ("i", "w", "b")) if prompt: logger.warn("The plan is to install the %s repository %s" % (self.name, url)) response = ask_path_exists("What to do? %s" % prompt[0], prompt[1]) if response == "s": logger.notify("Switching %s %s to %s%s" % (self.repo_name, display_path(dest), url, rev_display)) self.switch(dest, url, rev_options) elif response == "i": # do nothing pass elif response == "w": logger.warn("Deleting %s" % display_path(dest)) rmtree(dest) checkout = True elif response == "b": dest_dir = backup_dir(dest) logger.warn("Backing up %s to %s" % (display_path(dest), dest_dir)) shutil.move(dest, dest_dir) checkout = True return checkout
def run(self, options, args): logger.deprecated( '1.6', "DEPRECATION: 'pip bundle' and support for installing from *.pybundle files is deprecated. " "See https://github.com/pypa/pip/pull/1046") if not args: raise InstallationError('You must give a bundle filename') # We have to get everything when creating a bundle: options.ignore_installed = True logger.notify( 'Putting temporary build files in %s and source/develop files in %s' % (display_path(options.build_dir), display_path(options.src_dir))) self.bundle_filename = args.pop(0) requirement_set = super(BundleCommand, self).run(options, args) return requirement_set
def pkg_info(self): p = FeedParser() data = self.egg_info_data('PKG-INFO') if not data: logger.warn('No PKG-INFO file found in %s' % display_path(self.egg_info_path('PKG-INFO'))) p.feed(data or '') return p.close()
def _copy_file(filename, location, content_type, link): copy = True download_location = os.path.join(location, link.filename) if os.path.exists(download_location): response = ask('The file {0!s} exists. (i)gnore, (w)ipe, (b)ackup '.format(display_path(download_location)), ('i', 'w', 'b')) if response == 'i': copy = False elif response == 'w': logger.warn('Deleting {0!s}'.format(display_path(download_location))) os.remove(download_location) elif response == 'b': dest_file = backup_dir(download_location) logger.warn('Backing up {0!s} to {1!s}'.format(display_path(download_location), display_path(dest_file))) shutil.move(download_location, dest_file) if copy: shutil.copy(filename, download_location) logger.indent -= 2 logger.notify('Saved {0!s}'.format(display_path(download_location)))
def run(self, options, args): if not args: raise InstallationError('You must give a bundle filename') if not options.build_dir: options.build_dir = backup_dir(build_prefix, '-bundle') if not options.src_dir: options.src_dir = backup_dir(src_prefix, '-bundle') # We have to get everything when creating a bundle: options.ignore_installed = True logger.notify('Putting temporary build files in %s and source/develop files in %s' % (display_path(options.build_dir), display_path(options.src_dir))) bundle_filename = args[0] args = args[1:] requirement_set = super(BundleCommand, self).run(options, args) # FIXME: here it has to do something requirement_set.create_bundle(bundle_filename) logger.notify('Created bundle in %s' % bundle_filename) return requirement_set
def assert_source_matches_version(self): assert self.source_dir version = self.installed_version if version not in self.req: logger.warn('Requested %s, but installing version %s' % (self, self.installed_version)) else: logger.debug( 'Source in %s has version %s, which satisfies requirement %s' % (display_path(self.source_dir), version, self))
def check_destination(self, dest, url, rev_options, rev_display): """ Prepare a location to receive a checkout/clone. Return True if the location is ready for (and requires) a checkout/clone, False otherwise. """ checkout = True prompt = False if os.path.exists(dest): checkout = False if os.path.exists(os.path.join(dest, self.dirname)): existing_url = self.get_url(dest) if self.compare_urls(existing_url, url): logger.info('{0!s} in {1!s} exists, and has correct URL ({2!s})'.format(self.repo_name.title(), display_path(dest), url)) logger.notify('Updating {0!s} {1!s}{2!s}'.format(display_path(dest), self.repo_name, rev_display)) self.update(dest, rev_options) else: logger.warn('{0!s} {1!s} in {2!s} exists with URL {3!s}'.format(self.name, self.repo_name, display_path(dest), existing_url)) prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', ('s', 'i', 'w', 'b')) else: logger.warn('Directory {0!s} already exists, and is not a {1!s} {2!s}.'.format(dest, self.name, self.repo_name)) prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) if prompt: logger.warn('The plan is to install the {0!s} repository {1!s}'.format(self.name, url)) response = ask('What to do? {0!s}'.format(prompt[0]), prompt[1]) if response == 's': logger.notify('Switching {0!s} {1!s} to {2!s}{3!s}'.format(self.repo_name, display_path(dest), url, rev_display)) self.switch(dest, url, rev_options) elif response == 'i': # do nothing pass elif response == 'w': logger.warn('Deleting {0!s}'.format(display_path(dest))) rmtree(dest) checkout = True elif response == 'b': dest_dir = backup_dir(dest) logger.warn('Backing up {0!s} to {1!s}'.format(display_path(dest), dest_dir)) shutil.move(dest, dest_dir) checkout = True return checkout
def pkg_info(self): p = FeedParser() data = self.egg_info_data('PKG-INFO') if not data: logger.warn( 'No PKG-INFO file found in %s' % display_path(self.egg_info_path('PKG-INFO')) ) p.feed(data or '') return p.close()
def obtain(self, dest): url, rev = self.get_url_rev() rev_options = get_rev_options(url, rev) if rev: rev_display = " (to revision %s)" % rev else: rev_display = "" if self.check_destination(dest, url, rev_options, rev_display): logger.notify("Checking out %s%s to %s" % (url, rev_display, display_path(dest))) call_subprocess([self.cmd, "checkout", "-q"] + rev_options + [url, dest])
def copy_file(self, filename, location, content_type, link): copy = True download_location = os.path.join(location, link.filename) if os.path.exists(download_location): copy = False logger.notify('Ignoring already existing file.') if copy: shutil.copy(filename, download_location) logger.indent -= 2 logger.notify('Saved %s' % display_path(download_location))
def _copy_file(filename, location, content_type, link): copy = True download_location = os.path.join(location, link.filename) if os.path.exists(download_location): response = ask_path_exists( "The file %s exists. (i)gnore, (w)ipe, (b)ackup " % display_path(download_location), ("i", "w", "b") ) if response == "i": copy = False elif response == "w": logger.warn("Deleting %s" % display_path(download_location)) os.remove(download_location) elif response == "b": dest_file = backup_dir(download_location) logger.warn("Backing up %s to %s" % (display_path(download_location), display_path(dest_file))) shutil.move(download_location, dest_file) if copy: shutil.copy(filename, download_location) logger.notify("Saved %s" % display_path(download_location))
def archive(self, build_dir): assert self.source_dir create_archive = True archive_name = '%s-%s.zip' % (self.name, self.installed_version) archive_path = os.path.join(build_dir, archive_name) if os.path.exists(archive_path): response = ask_path_exists( 'The file %s exists. (i)gnore, (w)ipe, (b)ackup ' % display_path(archive_path), ('i', 'w', 'b')) if response == 'i': create_archive = False elif response == 'w': logger.warn('Deleting %s' % display_path(archive_path)) os.remove(archive_path) elif response == 'b': dest_file = backup_dir(archive_path) logger.warn( 'Backing up %s to %s' % (display_path(archive_path), display_path(dest_file)) ) shutil.move(archive_path, dest_file) if create_archive: zip = zipfile.ZipFile(archive_path, 'w', zipfile.ZIP_DEFLATED) dir = os.path.normcase(os.path.abspath(self.source_dir)) for dirpath, dirnames, filenames in os.walk(dir): if 'pip-egg-info' in dirnames: dirnames.remove('pip-egg-info') for dirname in dirnames: dirname = os.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 = os.path.join(dirpath, filename) name = self._clean_zip_name(filename, dir) zip.write(filename, self.name + '/' + name) zip.close() logger.indent -= 2 logger.notify('Saved %s' % display_path(archive_path))
def is_download(self): if self.download_dir: self.download_dir = os.path.expanduser(self.download_dir) if os.path.exists(self.download_dir): return True else: logger.fatal('Could not find download directory') raise InstallationError( "Could not find or access download directory '%s'" % display_path(self.download_dir)) return False
def _copy_file(filename, location, content_type, link): copy = True download_location = os.path.join(location, link.filename) if os.path.exists(download_location): response = ask('The file %s exists. (i)gnore, (w)ipe, (b)ackup ' % display_path(download_location), ('i', 'w', 'b')) if response == 'i': copy = False elif response == 'w': logger.warn('Deleting %s' % display_path(download_location)) os.remove(download_location) elif response == 'b': dest_file = backup_dir(download_location) logger.warn('Backing up %s to %s' % (display_path(download_location), display_path(dest_file))) shutil.move(download_location, dest_file) if copy: shutil.copy(filename, download_location) logger.indent -= 2 logger.notify('Saved %s' % display_path(download_location))
def obtain(self, dest): url, rev = self.get_url_rev() rev_options = get_rev_options(url, rev) if rev: rev_display = ' (to revision %s)' % rev else: rev_display = '' if self.check_destination(dest, url, rev_options, rev_display): logger.notify('Checking out %s%s to %s' % (url, rev_display, display_path(dest))) call_subprocess( [self.cmd, 'checkout', '-q'] + rev_options + [url, dest])
def remove_filename_from_pth(self, filename): for pth in self.pth_files(): f = open(pth, 'r') lines = f.readlines() f.close() new_lines = [ l for l in lines if l.strip() != filename] if lines != new_lines: logger.info('Removing reference to %s from .pth file %s' % (display_path(filename), display_path(pth))) if not filter(None, new_lines): logger.info('%s file would be empty: deleting' % display_path(pth)) if not self.simulate: os.unlink(pth) else: if not self.simulate: f = open(pth, 'wb') f.writelines(new_lines) f.close() return logger.warn('Cannot find a reference to %s in any .pth file' % display_path(filename))
def obtain(self, dest): url, rev = self.get_url_rev() if rev: rev_options = [rev] rev_display = " (to revision %s)" % rev else: rev_options = [] rev_display = "" if self.check_destination(dest, url, rev_options, rev_display): logger.notify("Cloning hg %s%s to %s" % (url, rev_display, display_path(dest))) call_subprocess([self.cmd, "clone", "--noupdate", "-q", url, dest]) call_subprocess([self.cmd, "update", "-q"] + rev_options, cwd=dest)
def obtain(self, dest): url, rev = self.get_url_rev() if rev: rev_options = [rev] rev_display = ' (to revision {0!s})'.format(rev) else: rev_options = [] rev_display = '' if self.check_destination(dest, url, rev_options, rev_display): logger.notify('Cloning hg {0!s}{1!s} to {2!s}'.format(url, rev_display, display_path(dest))) call_subprocess([self.cmd, 'clone', '--noupdate', '-q', url, dest]) call_subprocess([self.cmd, 'update', '-q'] + rev_options, cwd=dest)
def obtain(self, dest): url, rev = self.get_url_rev() rev_options = get_rev_options(url, rev) if rev: rev_display = ' (to revision %s)' % rev else: rev_display = '' if self.check_destination(dest, url, rev_options, rev_display): logger.notify('Checking out %s%s to %s' % (url, rev_display, display_path(dest))) call_subprocess([self.cmd, 'checkout', '-q'] + rev_options + [url, dest])
def obtain(self, dest): url, rev = self.get_url_rev() if rev: rev_options = [rev] rev_display = ' (to revision %s)' % rev else: rev_options = [] rev_display = '' if self.check_destination(dest, url, rev_options, rev_display): logger.notify('Cloning hg %s%s to %s' % (url, rev_display, display_path(dest))) call_subprocess([self.cmd, 'clone', '--noupdate', '-q', url, dest]) call_subprocess([self.cmd, 'update', '-q'] + rev_options, cwd=dest)
def assert_source_matches_version(self): assert self.source_dir version = self.installed_version if version not in self.req: logger.warn( 'Requested %s, but installing version %s' % (self, self.installed_version) ) else: logger.debug( 'Source in %s has version %s, which satisfies requirement %s' % (display_path(self.source_dir), version, self) )
def check_destination(self, dest, url, rev_options, rev_display): """ Prepare a location to receive a checkout/clone. Return True if the location is ready for (and requires) a checkout/clone, False otherwise. """ checkout = True prompt = False if os.path.exists(dest): checkout = False if os.path.exists(os.path.join(dest, self.dirname)): existing_url = self.get_url(dest) if self.compare_urls(existing_url, url): logger.info( '%s in %s exists, and has correct URL (%s)' % (self.repo_name.title(), display_path(dest), url)) logger.notify( 'Updating %s %s%s' % (display_path(dest), self.repo_name, rev_display)) self.update(dest, rev_options) else: logger.warn('%s %s in %s exists with URL %s' % (self.name, self.repo_name, display_path(dest), existing_url)) prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', ('s', 'i', 'w', 'b')) else: logger.warn('Directory %s already exists, ' 'and is not a %s %s.' % (dest, self.name, self.repo_name)) prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) if prompt: logger.warn('The plan is to install the %s repository %s' % (self.name, url)) response = ask_path_exists('What to do? %s' % prompt[0], prompt[1]) if response == 's': logger.notify( 'Switching %s %s to %s%s' % (self.repo_name, display_path(dest), url, rev_display)) self.switch(dest, url, rev_options) elif response == 'i': # do nothing pass elif response == 'w': logger.warn('Deleting %s' % display_path(dest)) rmtree(dest) checkout = True elif response == 'b': dest_dir = backup_dir(dest) logger.warn('Backing up %s to %s' % (display_path(dest), dest_dir)) shutil.move(dest, dest_dir) checkout = True return checkout
def obtain(self, dest): url, rev = self.get_url_rev() if rev: rev_options = [rev] rev_display = ' (to %s)' % rev else: rev_options = ['origin/master'] rev_display = '' if self.check_destination(dest, url, rev_options, rev_display): logger.notify('Cloning %s%s to %s' % (url, rev_display, display_path(dest))) call_subprocess([self.cmd, 'clone', '-q', url, dest]) rev_options = self.check_rev_options(rev, dest, rev_options) call_subprocess([self.cmd, 'checkout', '-q'] + rev_options, cwd=dest)
def obtain(self, dest): url, rev = self.get_url_rev() if rev: rev_options = [rev] rev_display = ' (to %s)' % rev else: rev_options = ['origin/master'] rev_display = '' if self.check_destination(dest, url, rev_options, rev_display): logger.notify('Cloning %s%s to %s' % (url, rev_display, display_path(dest))) call_subprocess( [self.cmd, 'clone', '-q', url, dest]) rev_options = self.check_rev_options(rev, dest, rev_options) call_subprocess( [self.cmd, 'checkout', '-q'] + rev_options, cwd=dest)
def obtain(self, dest): url, rev = self.get_url_rev() if rev: rev_options = [rev] rev_display = ' (to {0!s})'.format(rev) else: rev_options = ['origin/master'] rev_display = '' if self.check_destination(dest, url, rev_options, rev_display): logger.notify('Cloning {0!s}{1!s} to {2!s}'.format(url, rev_display, display_path(dest))) call_subprocess([self.cmd, 'clone', '-q', url, dest]) if rev: rev_options = self.check_rev_options(rev, dest, rev_options) # Only do a checkout if rev_options differs from HEAD if not self.get_revision(dest).startswith(rev_options[0]): call_subprocess([self.cmd, 'checkout', '-q'] + rev_options, cwd=dest)
def __str__(self): if self.req: s = str(self.req) if self.url: s += ' from %s' % self.url else: s = self.url if self.satisfied_by is not None: s += ' in %s' % display_path(self.satisfied_by.location) if self.comes_from: if isinstance(self.comes_from, string_types): comes_from = self.comes_from else: comes_from = self.comes_from.from_path() if comes_from: s += ' (from %s)' % comes_from return s
def obtain(self, dest): url, rev = self.get_url_rev() if rev: rev_options = [rev] rev_display = ' (to %s)' % rev else: rev_options = ['master'] rev_display = '' if self.check_destination(dest, url, rev_options, rev_display): logger.notify('Cloning %s%s to %s' % (url, rev_display, display_path(dest))) call_subprocess([self.cmd, 'clone', '-q', url, dest]) checked_rev = self.check_rev_options(rev, dest, rev_options) # only explicitely checkout the "revision" in case the check # found a valid tag, commit or branch if rev_options != checked_rev: call_subprocess( [self.cmd, 'checkout', '-q'] + checked_rev, cwd=dest)
def obtain(self, dest): url, rev = self.get_url_rev() if rev: rev_options = [rev] rev_display = ' (to %s)' % rev else: rev_options = ['origin/master'] rev_display = '' if self.check_destination(dest, url, rev_options, rev_display): logger.notify('Cloning %s%s to %s' % (url, rev_display, display_path(dest))) call_subprocess([self.cmd, 'clone', '-q', url, dest]) #: repo may contain submodules self.update_submodules(dest) if rev: rev_options = self.check_rev_options(rev, dest, rev_options) # Only do a checkout if rev_options differs from HEAD if not self.get_revision(dest).startswith(rev_options[0]): call_subprocess([self.cmd, 'checkout', '-q'] + rev_options, cwd=dest)
def add_filename_to_pth(self, filename): path = os.path.dirname(filename) dest = os.path.join(path, filename + '.pth') if path not in self.paths(): logger.warn('Adding .pth file %s, but it is not on sys.path' % display_path(dest)) if not self.simulate: if os.path.exists(dest): f = open(dest) lines = f.readlines() f.close() if lines and not lines[-1].endswith('\n'): lines[-1] += '\n' lines.append(filename+'\n') else: lines = [filename + '\n'] f = open(dest, 'wb') f.writelines(lines) f.close()
def add_filename_to_pth(self, filename): path = os.path.dirname(filename) dest = filename + '.pth' if path not in self.paths(): logger.warn('Adding .pth file %s, but it is not on sys.path' % display_path(dest)) if not self.simulate: if os.path.exists(dest): f = open(dest) lines = f.readlines() f.close() if lines and not lines[-1].endswith('\n'): lines[-1] += '\n' lines.append(filename+'\n') else: lines = [filename + '\n'] f = open(dest, 'wb') f.writelines(lines) f.close()
def prepare_files(self, finder, force_root_egg_info=False, bundle=False): """Prepare process. Create temp directories, download and/or unpack files.""" unnamed = list(self.unnamed_requirements) reqs = list(self.requirements.values()) while reqs or unnamed: if unnamed: req_to_install = unnamed.pop(0) else: req_to_install = reqs.pop(0) install = True best_installed = False if not self.ignore_installed and not req_to_install.editable: req_to_install.check_if_exists() if req_to_install.satisfied_by: if self.upgrade: if not self.force_reinstall: try: url = finder.find_requirement( req_to_install, self.upgrade) except BestVersionAlreadyInstalled: best_installed = True install = False else: # Avoid the need to call find_requirement again req_to_install.url = url.url if not best_installed: req_to_install.conflicts_with = req_to_install.satisfied_by req_to_install.satisfied_by = None else: install = False if req_to_install.satisfied_by: if best_installed: logger.notify('Requirement already up-to-date: %s' % req_to_install) else: logger.notify('Requirement already satisfied ' '(use --upgrade to upgrade): %s' % req_to_install) if req_to_install.editable: logger.notify('Obtaining %s' % req_to_install) elif install: if req_to_install.url and req_to_install.url.lower().startswith( 'file:'): logger.notify('Unpacking %s' % display_path(url_to_path(req_to_install.url))) else: logger.notify('Downloading/unpacking %s' % req_to_install) logger.indent += 2 try: is_bundle = False if req_to_install.editable: if req_to_install.source_dir is None: location = req_to_install.build_location(self.src_dir) req_to_install.source_dir = location else: location = req_to_install.source_dir if not os.path.exists(self.build_dir): _make_build_dir(self.build_dir) req_to_install.update_editable(not self.is_download) if self.is_download: req_to_install.run_egg_info() req_to_install.archive(self.download_dir) else: req_to_install.run_egg_info() elif install: ##@@ if filesystem packages are not marked ##editable in a req, a non deterministic error ##occurs when the script attempts to unpack the ##build directory location = req_to_install.build_location( self.build_dir, not self.is_download) ## FIXME: is the existance of the checkout good enough to use it? I don't think so. unpack = True url = None if not os.path.exists(os.path.join(location, 'setup.py')): ## FIXME: this won't upgrade when there's an existing package unpacked in `location` if req_to_install.url is None: url = finder.find_requirement(req_to_install, upgrade=self.upgrade) else: ## FIXME: should req_to_install.url already be a link? url = Link(req_to_install.url) assert url if url: try: self.unpack_url(url, location, self.is_download) except HTTPError: e = sys.exc_info()[1] logger.fatal( 'Could not install requirement %s because of error %s' % (req_to_install, e)) raise InstallationError( 'Could not install requirement %s because of HTTP error %s for URL %s' % (req_to_install, e, url)) else: unpack = False if unpack: is_bundle = req_to_install.is_bundle if is_bundle: req_to_install.move_bundle_files( self.build_dir, self.src_dir) for subreq in req_to_install.bundle_requirements(): reqs.append(subreq) self.add_requirement(subreq) elif self.is_download: req_to_install.source_dir = location req_to_install.run_egg_info() if url and url.scheme in vcs.all_schemes: req_to_install.archive(self.download_dir) else: req_to_install.source_dir = location req_to_install.run_egg_info() if force_root_egg_info: # We need to run this to make sure that the .egg-info/ # directory is created for packing in the bundle req_to_install.run_egg_info( force_root_egg_info=True) req_to_install.assert_source_matches_version() #@@ sketchy way of identifying packages not grabbed from an index if bundle and req_to_install.url: self.copy_to_build_dir(req_to_install) install = False # req_to_install.req is only avail after unpack for URL pkgs # repeat check_if_exists to uninstall-on-upgrade (#14) req_to_install.check_if_exists() if req_to_install.satisfied_by: if self.upgrade or self.ignore_installed: req_to_install.conflicts_with = req_to_install.satisfied_by req_to_install.satisfied_by = None else: install = False if not is_bundle: ## FIXME: shouldn't be globally added: finder.add_dependency_links(req_to_install.dependency_links) if (req_to_install.extras): logger.notify("Installing extra requirements: %r" % ','.join(req_to_install.extras)) if not self.ignore_dependencies: for req in req_to_install.requirements( req_to_install.extras): try: name = pkg_resources.Requirement.parse( req).project_name except ValueError: e = sys.exc_info()[1] ## FIXME: proper warning logger.error( 'Invalid requirement: %r (%s) in requirement %s' % (req, e, req_to_install)) continue subreq = InstallRequirement(req, req_to_install) if self.has_requirement(name): investigate.append( [self.get_requirement(name), subreq]) continue reqs.append(subreq) self.add_requirement(subreq) if req_to_install.name not in self.requirements: self.requirements[req_to_install.name] = req_to_install if self.is_download: self.reqs_to_cleanup.append(req_to_install) else: self.reqs_to_cleanup.append(req_to_install) if install: self.successfully_downloaded.append(req_to_install) if bundle and (req_to_install.url and req_to_install.url.startswith('file:///')): self.copy_to_build_dir(req_to_install) finally: logger.indent -= 2
def prepare_files(self, finder, force_root_egg_info=False, bundle=False): """ Prepare process. Create temp directories, download and/or unpack files. """ unnamed = list(self.unnamed_requirements) reqs = list(self.requirements.values()) while reqs or unnamed: if unnamed: req_to_install = unnamed.pop(0) else: req_to_install = reqs.pop(0) install = True best_installed = False not_found = None # ############################################# # # # Search for archive to fulfill requirement # # # ############################################# # if not self.ignore_installed and not req_to_install.editable: req_to_install.check_if_exists() if req_to_install.satisfied_by: if self.upgrade: if not self.force_reinstall and not req_to_install.url: try: url = finder.find_requirement( req_to_install, self.upgrade) except BestVersionAlreadyInstalled: best_installed = True install = False except DistributionNotFound as exc: not_found = exc else: # Avoid the need to call find_requirement again req_to_install.url = url.url if not best_installed: # don't uninstall conflict if user install and # conflict is not user install if not (self.use_user_site and not dist_in_usersite( req_to_install.satisfied_by )): req_to_install.conflicts_with = \ req_to_install.satisfied_by req_to_install.satisfied_by = None else: install = False if req_to_install.satisfied_by: if best_installed: logger.notify('Requirement already up-to-date: %s' % req_to_install) else: logger.notify('Requirement already satisfied ' '(use --upgrade to upgrade): %s' % req_to_install) if req_to_install.editable: logger.notify('Obtaining %s' % req_to_install) elif install: if (req_to_install.url and req_to_install.url.lower().startswith('file:')): logger.notify( 'Unpacking %s' % display_path(url_to_path(req_to_install.url)) ) else: logger.notify('Downloading/unpacking %s' % req_to_install) logger.indent += 2 # ################################ # # # vcs update or unpack archive # # # ################################ # try: is_bundle = False is_wheel = False if req_to_install.editable: if req_to_install.source_dir is None: location = req_to_install.build_location(self.src_dir) req_to_install.source_dir = location else: location = req_to_install.source_dir if not os.path.exists(self.build_dir): _make_build_dir(self.build_dir) req_to_install.update_editable(not self.is_download) if self.is_download: req_to_install.run_egg_info() req_to_install.archive(self.download_dir) else: req_to_install.run_egg_info() elif install: # @@ if filesystem packages are not marked # editable in a req, a non deterministic error # occurs when the script attempts to unpack the # build directory # NB: This call can result in the creation of a temporary # build directory location = req_to_install.build_location( self.build_dir, not self.is_download, ) unpack = True url = None # In the case where the req comes from a bundle, we should # assume a build dir exists and move on if req_to_install.from_bundle: pass # If a checkout exists, it's unwise to keep going. version # inconsistencies are logged later, but do not fail the # installation. elif os.path.exists(os.path.join(location, 'setup.py')): raise PreviousBuildDirError( "pip can't proceed with requirements '%s' due to a" " pre-existing buld directory (%s). This is likely" " due to a previous installation that failed. pip " "is being responsible and not assuming it can " "delete this. Please delete it and try again." % (req_to_install, location) ) else: # FIXME: this won't upgrade when there's an existing # package unpacked in `location` if req_to_install.url is None: if not_found: raise not_found url = finder.find_requirement( req_to_install, upgrade=self.upgrade, ) else: # FIXME: should req_to_install.url already be a # link? url = Link(req_to_install.url) assert url if url: try: if ( url.filename.endswith(wheel_ext) and self.wheel_download_dir ): # when doing 'pip wheel` download_dir = self.wheel_download_dir do_download = True else: download_dir = self.download_dir do_download = self.is_download self.unpack_url( url, location, download_dir, do_download, ) except HTTPError as exc: logger.fatal( 'Could not install requirement %s because ' 'of error %s' % (req_to_install, exc) ) raise InstallationError( 'Could not install requirement %s because ' 'of HTTP error %s for URL %s' % (req_to_install, exc, url) ) else: unpack = False if unpack: is_bundle = req_to_install.is_bundle is_wheel = url and url.filename.endswith(wheel_ext) if is_bundle: req_to_install.move_bundle_files( self.build_dir, self.src_dir, ) for subreq in req_to_install.bundle_requirements(): reqs.append(subreq) self.add_requirement(subreq) elif self.is_download: req_to_install.source_dir = location if not is_wheel: # FIXME:https://github.com/pypa/pip/issues/1112 req_to_install.run_egg_info() if url and url.scheme in vcs.all_schemes: req_to_install.archive(self.download_dir) elif is_wheel: req_to_install.source_dir = location req_to_install.url = url.url else: req_to_install.source_dir = location req_to_install.run_egg_info() if force_root_egg_info: # We need to run this to make sure that the # .egg-info/ directory is created for packing # in the bundle req_to_install.run_egg_info( force_root_egg_info=True, ) req_to_install.assert_source_matches_version() # @@ sketchy way of identifying packages not # grabbed from an index if bundle and req_to_install.url: self.copy_to_build_dir(req_to_install) install = False # req_to_install.req is only avail after unpack for URL # pkgs repeat check_if_exists to uninstall-on-upgrade # (#14) if not self.ignore_installed: req_to_install.check_if_exists() if req_to_install.satisfied_by: if self.upgrade or self.ignore_installed: # don't uninstall conflict if user install and # conflict is not user install if not (self.use_user_site and not dist_in_usersite( req_to_install.satisfied_by)): req_to_install.conflicts_with = \ req_to_install.satisfied_by req_to_install.satisfied_by = None else: logger.notify( 'Requirement already satisfied (use ' '--upgrade to upgrade): %s' % req_to_install ) install = False # ###################### # # # parse dependencies # # # ###################### # if is_wheel: dist = list( pkg_resources.find_distributions(location) )[0] if not req_to_install.req: req_to_install.req = dist.as_requirement() self.add_requirement(req_to_install) if not self.ignore_dependencies: for subreq in dist.requires( req_to_install.extras): if self.has_requirement( subreq.project_name): continue subreq = InstallRequirement(str(subreq), req_to_install) reqs.append(subreq) self.add_requirement(subreq) # sdists elif not is_bundle: if (req_to_install.extras): logger.notify( "Installing extra requirements: %r" % ','.join(req_to_install.extras) ) if not self.ignore_dependencies: for req in req_to_install.requirements( req_to_install.extras): try: name = pkg_resources.Requirement.parse( req ).project_name except ValueError as exc: # FIXME: proper warning logger.error( 'Invalid requirement: %r (%s) in ' 'requirement %s' % (req, exc, req_to_install) ) continue if self.has_requirement(name): # FIXME: check for conflict continue subreq = InstallRequirement(req, req_to_install) reqs.append(subreq) self.add_requirement(subreq) if not self.has_requirement(req_to_install.name): # 'unnamed' requirements will get added here self.add_requirement(req_to_install) # cleanup tmp src if not is_bundle: if ( self.is_download or req_to_install._temp_build_dir is not None ): self.reqs_to_cleanup.append(req_to_install) if install: self.successfully_downloaded.append(req_to_install) if (bundle and ( req_to_install.url and req_to_install.url.startswith('file:///') )): self.copy_to_build_dir(req_to_install) finally: logger.indent -= 2