def fetch_last_version(self, package, allow_pre_releases, service_url, timeout): """ Fetch the last version of a package on Pypi. """ package, specifier = package specifier = SpecifierSet(specifier, allow_pre_releases) max_version = parse_version(self.default_version) package_json_url = '%s/%s/json' % (service_url, package) logger.info('> Fetching latest datas for %s...', package) socket.setdefaulttimeout(timeout) try: content = urlopen(package_json_url).read().decode('utf-8') except URLError as error: content = '{"releases": []}' logger.debug('!> %s %s', package_json_url, error.reason) results = json.loads(content) socket.setdefaulttimeout(None) for version in specifier.filter(results['releases']): version = parse_version(version) if version > max_version: max_version = version logger.debug('-> Last version of %s%s is %s.', package, specifier, max_version) return (package, str(max_version))
def parse_versions(self, source): """ Parses the source file to return the packages with their current versions. """ config = VersionsConfigParser() config.read(source) try: versions = config.items('versions') except NoSectionError: logger.debug("'versions' section not found in %s." % source) return [] logger.info('- %d versions found in %s.' % (len(versions), source)) return versions
def find_updates(self, versions, last_versions): """ Compare the current versions of the packages with the last versions to find updates. """ updates = [] for package, current_version in versions.items(): last_version = last_versions[package] if last_version != current_version: logger.debug('=> %s current version (%s) and last ' 'version (%s) are different.' % (package, current_version, last_version)) updates.append((package, last_version)) logger.info('- %d package updates found.' % len(updates)) return updates
def include_exclude_versions(self, source_versions, includes=[], excludes=[]): """ Includes and excludes packages to be checked in the default dict of packages with versions. """ versions = source_versions.copy() packages_lower = [x.lower() for x in versions.keys()] for include in includes: if include.lower() not in packages_lower: versions[include] = self.default_version excludes_lower = [x.lower() for x in excludes] for package in versions.keys(): if package.lower() in excludes_lower: del versions[package] logger.info('- %d packages need to be checked for updates.' % len(versions)) return versions
def parse_versions(self, source): """ Parses the source file to return the packages with their current versions. """ config = VersionsConfigParser() has_read = config.read(source) if not has_read: logger.warning("'%s' cannot be read.", source) return [] try: versions = config.items('versions') except NoSectionError: logger.debug("'versions' section not found in %s.", source) return [] logger.info('- %d versions found in %s.', len(versions), source) return versions
def cmdline(argv=sys.argv[1:]): parser = ArgumentParser(description='Check availables updates from a ' 'version section of a buildout script') parser.add_argument('source', default='versions.cfg', nargs='?', help='The file where versions are pinned ' '(default: versions.cfg)') version_group = parser.add_argument_group('Allowed versions') version_group.add_argument( '--pre', action='store_true', dest='prereleases', default=False, help='Allow pre-releases and development versions ' '(by default only stable versions are found)') version_group.add_argument( '-s', '--specifier', action=StoreSpecifiers, dest='specifiers', default={}, help='Describe what versions of a package are acceptable. ' 'Example "package:>=1.0,!=1.3.4.*,< 2.0" ' '(can be used multiple times)') filter_group = parser.add_argument_group('Filtering') filter_group.add_argument('-i', '--include', action='append', dest='includes', default=[], help='Include package when checking updates ' '(can be used multiple times)') filter_group.add_argument('-e', '--exclude', action='append', dest='excludes', default=[], help='Exclude package when checking updates ' '(can be used multiple times)') file_group = parser.add_argument_group('File') file_group.add_argument('-w', '--write', action='store_true', dest='write', default=False, help='Write the updates in the source file') file_group.add_argument( '--indent', dest='indentation', type=int, default=32, help='Spaces used when indenting "key = value" (default: 32)') file_group.add_argument( '--sorting', dest='sorting', default='', choices=['alpha', 'length'], help='Sorting algorithm used on the keys when writing source file ' '(default: None)') network_group = parser.add_argument_group('Network') network_group.add_argument( '--service-url', dest='service_url', default='http://pypi.python.org/pypi', help='The service to use for checking the packages ' '(default: http://pypi.python.org/pypi)') network_group.add_argument('--timeout', dest='timeout', type=int, default=10, help='Timeout for each request (default: 10s)') network_group.add_argument( '-t', '--threads', dest='threads', type=int, default=10, help='Threads used for checking the versions in parallel') verbosity_group = parser.add_argument_group('Verbosity') verbosity_group.add_argument( '-v', action='count', dest='verbosity', default=1, help='Increase verbosity (specify multiple times for more)') verbosity_group.add_argument( '-q', action='count', dest='quietly', default=0, help='Decrease verbosity (specify multiple times for more)') if isinstance(argv, string_types): argv = argv.split() options = parser.parse_args(argv) verbose_logs = { 0: 100, 1: logging.WARNING, 2: logging.INFO, 3: logging.DEBUG } verbosity = min(3, max(0, options.verbosity - options.quietly)) console = logging.StreamHandler(sys.stdout) console.setLevel(verbose_logs[verbosity]) logger.addHandler(console) source = options.source try: checker = VersionsChecker(source, options.specifiers, options.prereleases, options.includes, options.excludes, options.service_url, options.timeout, options.threads) except Exception as e: sys.exit(str(e)) if not checker.updates: sys.exit(0) logger.warning('[versions]') for package, version in checker.updates.items(): logger.warning('%s= %s' % (package.ljust(options.indentation), version)) if options.write: config = VersionsConfigParser() config.read(source) if not config.has_section('versions'): config.add_section('versions') for package, version in checker.updates.items(): config.set('versions', package, version) config.write(source, options.indentation, options.sorting) logger.info('- %s updated.' % source) sys.exit(0)
def cmdline(argv=sys.argv[1:]): parser = ArgumentParser(description='Find unused pinned eggs') parser.add_argument('source', default='versions.cfg', nargs='?', help='The file where versions are pinned ' '(default: versions.cfg)') filter_group = parser.add_argument_group('Filtering') filter_group.add_argument('--eggs', dest='eggs', default='./eggs/', help='The directory where the eggs are located ' '(default: ./eggs/)') filter_group.add_argument('-e', '--exclude', action='append', dest='excludes', default=[], help='Exclude package when checking updates ' '(can be used multiple times)') file_group = parser.add_argument_group('File') file_group.add_argument('-w', '--write', action='store_true', dest='write', default=False, help='Write the updates in the source file') file_group.add_argument( '--indent', dest='indentation', type=int, default=-1, help='Spaces used when indenting "key = value" (default: auto)') file_group.add_argument( '--sorting', dest='sorting', default='', choices=['alpha', 'ascii', 'length'], help='Sorting algorithm used on the keys when writing source file ' '(default: None)') verbosity_group = parser.add_argument_group('Verbosity') verbosity_group.add_argument( '-v', action='count', dest='verbosity', default=1, help='Increase verbosity (specify multiple times for more)') verbosity_group.add_argument( '-q', action='count', dest='quietly', default=0, help='Decrease verbosity (specify multiple times for more)') if isinstance(argv, str): argv = argv.split() options = parser.parse_args(argv) verbose_logs = { 0: 100, 1: logging.WARNING, 2: logging.INFO, 3: logging.DEBUG } verbosity = min(3, max(0, options.verbosity - options.quietly)) console = logging.StreamHandler(sys.stdout) console.setLevel(verbose_logs[verbosity]) logger.addHandler(console) source = options.source try: checker = UnusedVersionsChecker(source, options.eggs, options.excludes) except Exception as e: sys.exit(str(e)) if not checker.unused: sys.exit(0) for package in checker.unused: logger.warning('- %s is unused.', package) if options.write: config = VersionsConfigParser(indentation=options.indentation, sorting=options.sorting) config.read(source) for package in checker.unused: config.remove_option('versions', package) config.write(source) logger.info('- %s updated.', source) sys.exit(0)
def cmdline(argv=sys.argv[1:]): parser = ArgumentParser( description='Check availables updates from a ' 'version section of a buildout script') parser.add_argument( 'source', default='versions.cfg', nargs='?', help='The file where versions are pinned ' '(default: versions.cfg)') version_group = parser.add_argument_group('Allowed versions') version_group.add_argument( '--pre', action='store_true', dest='prereleases', default=False, help='Allow pre-releases and development versions ' '(by default only stable versions are found)') version_group.add_argument( '-s', '--specifier', action=StoreSpecifiers, dest='specifiers', default={}, help='Describe what versions of a package are acceptable. ' 'Example "package:>=1.0,!=1.3.4.*,< 2.0" ' '(can be used multiple times)') filter_group = parser.add_argument_group('Filtering') filter_group.add_argument( '-i', '--include', action='append', dest='includes', default=[], help='Include package when checking updates ' '(can be used multiple times)') filter_group.add_argument( '-e', '--exclude', action='append', dest='excludes', default=[], help='Exclude package when checking updates ' '(can be used multiple times)') file_group = parser.add_argument_group('File') file_group.add_argument( '-w', '--write', action='store_true', dest='write', default=False, help='Write the updates in the source file') file_group.add_argument( '--indent', dest='indentation', type=int, default=32, help='Spaces used when indenting "key = value" (default: 32)') file_group.add_argument( '--sorting', dest='sorting', default='', choices=['alpha', 'length'], help='Sorting algorithm used on the keys when writing source file ' '(default: None)') network_group = parser.add_argument_group('Network') network_group.add_argument( '--service-url', dest='service_url', default='http://pypi.python.org/pypi', help='The service to use for checking the packages ' '(default: http://pypi.python.org/pypi)') network_group.add_argument( '--timeout', dest='timeout', type=int, default=10, help='Timeout for each request (default: 10s)') network_group.add_argument( '-t', '--threads', dest='threads', type=int, default=10, help='Threads used for checking the versions in parallel') verbosity_group = parser.add_argument_group('Verbosity') verbosity_group.add_argument( '-v', action='count', dest='verbosity', default=1, help='Increase verbosity (specify multiple times for more)') verbosity_group.add_argument( '-q', action='count', dest='quietly', default=0, help='Decrease verbosity (specify multiple times for more)') if isinstance(argv, string_types): argv = argv.split() options = parser.parse_args(argv) verbose_logs = {0: 100, 1: logging.WARNING, 2: logging.INFO, 3: logging.DEBUG} verbosity = min(3, max(0, options.verbosity - options.quietly)) console = logging.StreamHandler(sys.stdout) console.setLevel(verbose_logs[verbosity]) logger.addHandler(console) source = options.source try: checker = VersionsChecker( source, options.specifiers, options.prereleases, options.includes, options.excludes, options.service_url, options.timeout, options.threads) except Exception as e: sys.exit(str(e)) if not checker.updates: sys.exit(0) logger.warning('[versions]') for package, version in checker.updates.items(): logger.warning('%s= %s' % ( package.ljust(options.indentation), version)) if options.write: config = VersionsConfigParser() config.read(source) if not config.has_section('versions'): config.add_section('versions') for package, version in checker.updates.items(): config.set('versions', package, version) config.write(source, options.indentation, options.sorting) logger.info('- %s updated.' % source) sys.exit(0)