def cache_packages(): preexisting = set([model.name for model in PackageModel.select()]) output = [] for pkg in Package.all(): pkg_data = dict( name = pkg.name, sha1 = pkg.sha1, version = pkg.version, patchlevel = pkg.patchlevel, filename = pkg.tarball_filename, description = gracefully_read(pkg, 'SPKG.txt'), pkgtype = gracefully_read(pkg, 'type'), ) try: with database.atomic(): model = PackageModel.create(**pkg_data) except peewee.IntegrityError: PackageModel.update( **pkg_data ).where( PackageModel.name == pkg.name ).execute() output.append(pformat(pkg_data)) preexisting.discard(pkg.name) for pkg_name in preexisting: PackageModel.delete().where(PackageModel.name == pkg_name) return '\n'.join(output)
def __init__(self, tarball_name, package=None): """ A (third-party downloadable) tarball Note that the tarball might also be a different kind of archive format that is supported, it does not necessarily have to be tar. INPUT: - ``name`` - string. The full filename (``foo-1.3.tar.bz2``) of a tarball on the Sage mirror network. """ self.__filename = tarball_name if package is None: self.__package = None for pkg in Package.all(): if pkg.tarball_filename == tarball_name: self.__package = pkg if self.package is None: error = 'tarball {0} is not referenced by any Sage package'.format(tarball_name) log.error(error) raise ValueError(error) else: self.__package = package if package.tarball_filename != tarball_name: error = 'tarball {0} is not referenced by the {1} package'.format(tarball_name, package.name) log.error(error) raise ValueError(error)
def apropos(self, incorrect_name): """ Find up to 5 package names that are close to the given name $ sage --package apropos python Did you mean: cython, ipython, python2, python3, patch? """ log.debug('Apropos for %s', incorrect_name) from sage_bootstrap.levenshtein import Levenshtein, DistanceExceeded levenshtein = Levenshtein(5) names = [] for pkg in Package.all(): try: names.append([levenshtein(pkg.name, incorrect_name), pkg.name]) except DistanceExceeded: pass if names: names = sorted(names)[:5] print('Did you mean: {0}?'.format(', '.join(name[1] for name in names))) else: print('There is no package similar to {0}'.format(incorrect_name)) print( 'You can find further packages at http://files.sagemath.org/spkg/' )
def test_tarball(self): pkg = Package('configure') rc, stdout, stderr = self.run_command(EXECUTABLE, 'tarball', pkg.name) # Prints nothing to stderr self.assertEqual(stderr, '') # returns successfully self.assertEqual(rc, 0) # Prints to stdout self.assertEqual(stdout.rstrip(), pkg.tarball_filename)
def run_tarball(self, package_name): """ tarball: Find the tarball filename given a package name $ sage-package tarball pari pari-2.8-1564-gdeac36e.tar.gz """ package = Package(package_name) print(package.tarball.filename)
def update(self): package = Package(self.name) if package.version == self.version: log.info('%s is already at the latest version', self.name) return log.info('Updating %s: %s -> %s', self.name, package.version, self.version) update = PackageUpdater(self.name, self.version) update.download_upstream(self.url) update.fix_checksum()
def tarball(self, package_name): """ Find the tarball filename given a package name $ sage --package tarball pari pari-2.8-1564-gdeac36e.tar.gz """ log.debug('Looking up tarball name for %s', package_name) package = Package(package_name) print(package.tarball.filename)
def test_tarball(self): pkg = Package('configure') tarball = Tarball(pkg.tarball_filename) self.assertEqual(tarball, pkg.tarball) self.assertEqual(pkg, tarball.package) with CapturedOutput() as (stdout, stderr): with CapturedLog() as _: tarball.download() self.assertEqual(stdout.getvalue(), '') self.assertTrue(tarball.checksum_verifies())
def test_download(self): pkg = Package('configure') with CapturedLog() as _: pkg.tarball.download() rc, stdout, stderr = self.run_command(EXECUTABLE, 'download', pkg.name) # Prints info to stderr self.assertTrue(stderr.startswith('Using cached file')) # returns successfully self.assertEqual(rc, 0) # Prints filename to stdout self.assertEqual(stdout.rstrip(), pkg.tarball.upstream_fqn)
def test_package(self): pkg = Package('pari') self.assertTrue(pkg.name, 'pari') self.assertTrue(pkg.path.endswith('build/pkgs/pari')) self.assertEqual(pkg.tarball_pattern, 'pari-VERSION.tar.gz') self.assertEqual(pkg.tarball_filename, pkg.tarball.filename) self.assertTrue(pkg.tarball.filename.startswith('pari-') and pkg.tarball.filename.endswith('.tar.gz')) self.assertTrue(pkg.tarball.filename.startswith('pari-') and pkg.tarball.filename.endswith('.tar.gz')) self.assertTrue(isinstance(pkg.tarball, Tarball))
def update_latest(self, package_name): """ Update a package to the latest version. This modifies the Sage sources. """ try: pypi = PyPiVersion(package_name) except PyPiNotFound: log.debug('%s is not a pypi package', package_name) return else: pypi.update(Package(package_name))
def download(self, package_name, allow_upstream=False): """ Download a package $ sage --package download pari Using cached file /home/vbraun/Code/sage.git/upstream/pari-2.8-2044-g89b0f1e.tar.gz /home/vbraun/Code/sage.git/upstream/pari-2.8-2044-g89b0f1e.tar.gz """ log.debug('Downloading %s', package_name) package = Package(package_name) package.tarball.download(allow_upstream=allow_upstream) print(package.tarball.upstream_fqn)
def test_update(self): pkg = Package('configure') # The confball never has a patchlevel since we are upstream... self.assertEqual(pkg.patchlevel, -1) rc, stdout, stderr = self.run_command(EXECUTABLE, 'update', pkg.name, pkg.version) # Prints nothing to stderr self.assertEqual(stderr, '') # returns successfully self.assertEqual(rc, 0) # Prints nothing to stdout self.assertEqual(stdout, '')
def test_fix_checksum(self): pkg = Package('configure') rc, stdout, stderr = self.run_command(EXECUTABLE, 'fix-checksum', 'configure') # Prints nothing to stderr self.assertEqual(stderr, '') # returns successfully self.assertEqual(rc, 0) # Prints to stdout self.assertEqual( stdout.rstrip(), 'Checksum of {0} (tarball {1}) unchanged'.format( pkg.name, pkg.tarball_filename))
def run_list(self): """ list: Print a list of all available packages $ sage-package list | sort 4ti2 arb atlas autotools [...] zn_poly """ for pkg in Package.all(): print(pkg.name)
def upload(self, package_name): """ Upload a package to the Sage mirror network $ sage --package upload pari Uploading /home/vbraun/Code/sage.git/upstream/pari-2.8-2044-g89b0f1e.tar.gz """ package = Package(package_name) if not os.path.exists(package.tarball.upstream_fqn): log.debug('Skipping %s because there is no local tarbal', package_name) return log.info('Uploading %s', package.tarball.upstream_fqn) fs = FileServer() fs.upload(package)
def list(self): """ Print a list of all available packages $ sage --package list | sort 4ti2 arb atlas autotools [...] zn_poly """ log.debug('Listing packages') for pkg in Package.all(): print(pkg.name)
def fix_all_checksums(self): """ Fix the checksum of a package $ sage --package fix-checksum """ for pkg in Package.all(): if not os.path.exists(pkg.tarball.upstream_fqn): log.debug('Ignoring {0} because tarball is not cached'.format(pkg.tarball_filename)) continue if pkg.tarball.checksum_verifies(): log.debug('Checksum of {0} unchanged'.format(pkg.tarball_filename)) continue update = ChecksumUpdater(pkg.name) print('Updating checksum of {0}'.format(pkg.tarball_filename)) update.fix_checksum()
def fix_all_checksums(self): """ Fix the checksum of a package $ sage --package fix-checksum """ for pkg in Package.all(): if not os.path.exists(pkg.tarball.upstream_fqn): log.debug('Ignoring {0} because tarball is not cached'.format(pkg.tarball_filename)) continue if pkg.tarball.checksum_verifies(): log.debug('Checksum of {0} (tarball {1}) unchanged'.format(pkg.name, pkg.tarball_filename)) continue update = ChecksumUpdater(pkg.name) print('Updating checksum of {0} (tarball {1})'.format(pkg.name, pkg.tarball_filename)) update.fix_checksum()
def run_apropos(self, incorrect_name): """ apropos: Find up to 5 package names that are close to the given name $ sage-package apropos python Did you mean: cython, ipython, python2, python3, patch? """ from sage_bootstrap.levenshtein import Levenshtein, DistanceExceeded levenshtein = Levenshtein(5) names = [] for pkg in Package.all(): try: names.append([levenshtein(pkg.name, incorrect_name), pkg.name]) except DistanceExceeded: pass if names: names = sorted(names)[:5] print('Did you mean: {0}?'.format(', '.join(name[1] for name in names))) else: print('There is no package similar to {0}'.format(incorrect_name)) print('You can find further packages at http://files.sagemath.org/spkg/')
def test_checksum(self): pkg = Package('configure') tarball = pkg.tarball with CapturedOutput() as (stdout, stderr): with CapturedLog() as log: tarball.download() self.assertTrue(tarball.checksum_verifies()) with open(tarball.upstream_fqn, 'w') as f: f.write('foobar') self.assertFalse(tarball.checksum_verifies()) with CapturedOutput() as (stdout, stderr): with CapturedLog() as log: tarball.download() msg = log.messages() self.assertTrue( ('INFO', 'Attempting to download package {0} from mirrors'.format( pkg.tarball_filename)) in msg) self.assertEqual(stdout.getvalue(), '') self.assertEqual( stderr.getvalue(), '[......................................................................]\n' ) self.assertTrue(tarball.checksum_verifies())
def package(self): if self.__package is None: self.__package = Package(self.package_name) return self.__package
def test_all(self): pari = Package('pari') self.assertTrue(pari in Package.all())
def _init_huge(self, predicate): self.names.extend(pkg.name for pkg in Package.all() if pkg.type == 'huge' and predicate(pkg))
def _init_optional(self, predicate): self.names.extend(pkg.name for pkg in Package.all() if pkg.type == 'optional' and predicate(pkg))
def _init_standard(self, predicate): self.names.extend(pkg.name for pkg in Package.all() if pkg.type == 'standard' and predicate(pkg))
def _init_all(self, predicate): self.names.extend(pkg.name for pkg in Package.all() if predicate(pkg))
def _init_huge(self): self.names = [pkg.name for pkg in Package.all() if pkg.type == 'huge']
def _init_experimental(self): self.names = [ pkg.name for pkg in Package.all() if pkg.type == 'experimental' ]
def _init_optional(self): self.names = [ pkg.name for pkg in Package.all() if pkg.type == 'optional' ]
def _init_standard(self): self.names = [ pkg.name for pkg in Package.all() if pkg.type == 'standard' ]
def _update_version(self, new_version): old = Package(self.package_name) package_version_txt = os.path.join(old.path, 'package-version.txt') with open(package_version_txt, 'w') as f: f.write(new_version.strip() + '\n')
def _init_all(self): self.names = [pkg.name for pkg in Package.all()]
def _init_experimental(self, predicate): self.names.extend(pkg.name for pkg in Package.all() if pkg.type == 'experimental' and predicate(pkg))