def edit(parser, args): name = args.name # By default open the directory where packages live. if not name: path = spack.packages_path else: path = spack.db.filename_for_package_name(name) if os.path.exists(path): if not os.path.isfile(path): tty.die("Something's wrong. '%s' is not a file!" % path) if not os.access(path, os.R_OK|os.W_OK): tty.die("Insufficient permissions on '%s'!" % path) elif not args.force: tty.die("No package '%s'. Use spack create, or supply -f/--force " "to edit a new file." % name) else: mkdirp(os.path.dirname(path)) with closing(open(path, "w")) as pkg_file: pkg_file.write( package_template.substitute(name=name, class_name=mod_to_class(name))) # If everything checks out, go ahead and edit. spack.editor(path)
def edit_package(name, repo_path, namespace, force=False): if repo_path: repo = Repo(repo_path) elif namespace: repo = spack.repo.get_repo(namespace) else: repo = spack.repo path = repo.filename_for_package_name(name) spec = Spec(name) if os.path.exists(path): if not os.path.isfile(path): tty.die("Something's wrong. '%s' is not a file!" % path) if not os.access(path, os.R_OK|os.W_OK): tty.die("Insufficient permissions on '%s'!" % path) elif not force: tty.die("No package '%s'. Use spack create, or supply -f/--force " "to edit a new file." % spec.name) else: mkdirp(os.path.dirname(path)) with open(path, "w") as pkg_file: pkg_file.write( package_template.substitute( name=spec.name, class_name=mod_to_class(spec.name))) spack.editor(path)
def augment(parser, args): name = args.package target_repo = spack.repo.path.get_repo(args.namespace) target_path = target_repo.filename_for_package_name(name) repos = spack.repo.path.repos namespaces = [r.namespace for r in repos] target_index = namespaces.index(args.namespace) for repo in repos[target_index:]: if repo.namespace == args.namespace: continue source_path = repo.filename_for_package_name(name) if os.path.exists(source_path): break else: tty.die("No package for '{0}' was found.".format(name), " Use `spack create` to create a new package") spec = Spec(".".join([repo.namespace, name])) if not os.path.exists(target_path): mkdirp(os.path.dirname(target_path)) with open(target_path, "w") as pkg_file: pkg_file.write( PACKAGE_TEMPLATE.format(module=spec.package.fullname.replace( '-', '_'), namespace=repo.namespace.capitalize(), cls=mod_to_class(name))) if args.split: editor("-o", source_path, target_path) else: editor(target_path)
def get_class_for_package_name(self, pkg_name): """Get an instance of the class for a particular package. This method uses Python's ``imp`` package to load python source from a Spack package's ``package.py`` file. A normal python import would only load each package once, but because we do this dynamically, the method needs to be memoized to ensure there is only ONE package class instance, per package, per database. """ file_path = self.filename_for_package_name(pkg_name) if os.path.exists(file_path): if not os.path.isfile(file_path): tty.die("Something's wrong. '%s' is not a file!" % file_path) if not os.access(file_path, os.R_OK): tty.die("Cannot read '%s'!" % file_path) else: raise UnknownPackageError(pkg_name) class_name = mod_to_class(pkg_name) try: module_name = _imported_packages_module + '.' + pkg_name module = imp.load_source(module_name, file_path) except ImportError, e: tty.die("Error while importing %s from %s:\n%s" % ( pkg_name, file_path, e.message))
def edit_package(name, repo_path, namespace, force=False): if repo_path: repo = Repo(repo_path) elif namespace: repo = spack.repo.get_repo(namespace) else: repo = spack.repo path = repo.filename_for_package_name(name) spec = Spec(name) if os.path.exists(path): if not os.path.isfile(path): tty.die("Something's wrong. '%s' is not a file!" % path) if not os.access(path, os.R_OK | os.W_OK): tty.die("Insufficient permissions on '%s'!" % path) elif not force: tty.die("No package '%s'. Use spack create, or supply -f/--force " "to edit a new file." % spec.name) else: mkdirp(os.path.dirname(path)) with open(path, "w") as pkg_file: pkg_file.write( package_template.substitute(name=spec.name, class_name=mod_to_class( spec.name))) spack.editor(path)
def get_pkg_class(self, pkg_name): """Get the class for the package out of its module. First loads (or fetches from cache) a module for the package. Then extracts the package class from the module according to Spack's naming convention. """ namespace, _, pkg_name = pkg_name.rpartition('.') if namespace and (namespace != self.namespace): raise InvalidNamespaceError('Invalid namespace for %s repo: %s' % (self.namespace, namespace)) class_name = nm.mod_to_class(pkg_name) fullname = "{0}.{1}".format(self.full_namespace, pkg_name) try: module = importlib.import_module(fullname) except ImportError: raise UnknownPackageError(pkg_name) cls = getattr(module, class_name) if not inspect.isclass(cls): tty.die("%s.%s is not a class" % (pkg_name, class_name)) return cls
def class_for_compiler_name(compiler_name): """Given a compiler module name, get the corresponding Compiler class.""" assert(supported(compiler_name)) file_path = join_path(spack.compilers_path, compiler_name + ".py") compiler_mod = imp.load_source(_imported_compilers_module, file_path) cls = getattr(compiler_mod, mod_to_class(compiler_name)) # make a note of the name in the module so we can get to it easily. cls.name = compiler_name return cls
def class_for_compiler_name(compiler_name): """Given a compiler module name, get the corresponding Compiler class.""" assert (supported(compiler_name)) file_path = join_path(spack.compilers_path, compiler_name + ".py") compiler_mod = imp.load_source(_imported_compilers_module, file_path) cls = getattr(compiler_mod, mod_to_class(compiler_name)) # make a note of the name in the module so we can get to it easily. cls.name = compiler_name return cls
def class_for_compiler_name(compiler_name): """Given a compiler module name, get the corresponding Compiler class.""" assert (supported(compiler_name)) # Hack to be able to call the compiler `apple-clang` while still # using a valid python name for the module module_name = compiler_name if compiler_name == 'apple-clang': module_name = compiler_name.replace('-', '_') file_path = os.path.join(spack.paths.compilers_path, module_name + ".py") compiler_mod = simp.load_source(_imported_compilers_module, file_path) cls = getattr(compiler_mod, mod_to_class(compiler_name)) # make a note of the name in the module so we can get to it easily. cls.name = compiler_name return cls
def all_platforms(): classes = [] mod_path = spack.platform_path parent_module = "spack.platforms" for name in list_modules(mod_path): mod_name = '%s.%s' % (parent_module, name) class_name = mod_to_class(name) mod = __import__(mod_name, fromlist=[class_name]) if not hasattr(mod, class_name): tty.die('No class %s defined in %s' % (class_name, mod_name)) cls = getattr(mod, class_name) if not inspect.isclass(cls): tty.die('%s.%s is not a class' % (mod_name, class_name)) classes.append(cls) return classes
def _all_platforms(): classes = [] mod_path = spack.paths.platform_path parent_module = "spack.platforms" for name in lang.list_modules(mod_path): mod_name = '%s.%s' % (parent_module, name) class_name = mod_to_class(name) mod = __import__(mod_name, fromlist=[class_name]) if not hasattr(mod, class_name): tty.die('No class %s defined in %s' % (class_name, mod_name)) cls = getattr(mod, class_name) if not inspect.isclass(cls): tty.die('%s.%s is not a class' % (mod_name, class_name)) classes.append(cls) return classes
def class_for_compiler_name(compiler_name): """Given a compiler module name, get the corresponding Compiler class.""" assert supported(compiler_name) # Hack to be able to call the compiler `apple-clang` while still # using a valid python name for the module submodule_name = compiler_name if compiler_name == 'apple-clang': submodule_name = compiler_name.replace('-', '_') module_name = '.'.join(['spack', 'compilers', submodule_name]) module_obj = __import__(module_name, fromlist=[None]) cls = getattr(module_obj, mod_to_class(compiler_name)) # make a note of the name in the module so we can get to it easily. cls.name = compiler_name return cls
def list_classes(parent_module, mod_path): """Given a parent path (e.g., spack.platforms or spack.analyzers), use list_modules to derive the module names, and then mod_to_class to derive class names. Import the classes and return them in a list """ classes = [] for name in list_modules(mod_path): mod_name = '%s.%s' % (parent_module, name) class_name = mod_to_class(name) mod = __import__(mod_name, fromlist=[class_name]) if not hasattr(mod, class_name): tty.die('No class %s defined in %s' % (class_name, mod_name)) cls = getattr(mod, class_name) if not inspect.isclass(cls): tty.die('%s.%s is not a class' % (mod_name, class_name)) classes.append(cls) return classes
def get_pkg_class(self, pkg_name): """Get the class for the package out of its module. First loads (or fetches from cache) a module for the package. Then extracts the package class from the module according to Spack's naming convention. """ namespace, _, pkg_name = pkg_name.rpartition('.') if namespace and (namespace != self.namespace): raise InvalidNamespaceError('Invalid namespace for %s repo: %s' % (self.namespace, namespace)) class_name = mod_to_class(pkg_name) module = self._get_pkg_module(pkg_name) cls = getattr(module, class_name) if not inspect.isclass(cls): tty.die("%s.%s is not a class" % (pkg_name, class_name)) return cls
def edit(parser, args): name = args.name if args.edit_command: if not name: path = spack.cmd.command_path else: path = join_path(spack.cmd.command_path, name + ".py") if not os.path.exists(path): tty.die("No command named '%s'." % name) else: # By default open the directory where packages or commands live. if not name: path = spack.packages_path else: path = spack.db.filename_for_package_name(name) if os.path.exists(path): if not os.path.isfile(path): tty.die("Something's wrong. '%s' is not a file!" % path) if not os.access(path, os.R_OK | os.W_OK): tty.die("Insufficient permissions on '%s'!" % path) elif not args.force: tty.die( "No package '%s'. Use spack create, or supply -f/--force " "to edit a new file." % name) else: mkdirp(os.path.dirname(path)) with closing(open(path, "w")) as pkg_file: pkg_file.write( package_template.substitute( name=name, class_name=mod_to_class(name))) # If everything checks out, go ahead and edit. spack.editor(path)
def test_package_class_names(self): self.assertEqual('Mpich', mod_to_class('mpich')) self.assertEqual('PmgrCollective', mod_to_class('pmgr_collective')) self.assertEqual('PmgrCollective', mod_to_class('pmgr-collective')) self.assertEqual('Pmgrcollective', mod_to_class('PmgrCollective')) self.assertEqual('_3db', mod_to_class('3db'))
def create(parser, args): url = args.url # Try to deduce name and version of the new package from the URL name, version = spack.url.parse_name_and_version(url) if not name: tty.msg("Couldn't guess a name for this package.") name = get_name() if not version: tty.die("Couldn't guess a version string from %s." % url) tty.msg("This looks like a URL for %s version %s." % (name, version)) tty.msg("Creating template for package %s" % name) # Create a directory for the new package. pkg_path = spack.db.filename_for_package_name(name) if os.path.exists(pkg_path) and not args.force: tty.die("%s already exists." % pkg_path) else: mkdirp(os.path.dirname(pkg_path)) versions = list(reversed(spack.package.find_versions_of_archive(url))) archives_to_fetch = 1 if not versions: # If the fetch failed for some reason, revert to what the user provided versions = [version] urls = [url] else: urls = [spack.url.substitute_version(url, v) for v in versions] if len(urls) > 1: tty.msg( "Found %s versions of %s:" % (len(urls), name), *spack.cmd.elide_list(["%-10s%s" % (v, u) for v, u in zip(versions, urls)]) ) print archives_to_fetch = tty.get_number("Include how many checksums in the package file?", default=5, abort="q") if not archives_to_fetch: tty.msg("Aborted.") return guesser = ConfigureGuesser() ver_hash_tuples = spack.cmd.checksum.get_checksums( versions[:archives_to_fetch], urls[:archives_to_fetch], first_stage_function=guesser, keep_stage=args.keep_stage ) if not ver_hash_tuples: tty.die("Could not fetch any tarballs for %s." % name) # Write out a template for the file with closing(open(pkg_path, "w")) as pkg_file: pkg_file.write( package_template.substitute( name=name, configure=guesser.configure, class_name=mod_to_class(name), url=url, versions=make_version_dict(ver_hash_tuples), ) ) # If everything checks out, go ahead and edit. spack.editor(pkg_path) tty.msg("Created package %s." % pkg_path)
def __init__(self, name, url, versions): self.name = name self.class_name = mod_to_class(name) self.url = url self.versions = versions
def test_package_class_names(self): assert 'Mpich' == mod_to_class('mpich') assert 'PmgrCollective' == mod_to_class('pmgr_collective') assert 'PmgrCollective' == mod_to_class('pmgr-collective') assert 'Pmgrcollective' == mod_to_class('PmgrCollective') assert '_3db' == mod_to_class('3db')
def visit_ClassDef(self, node): if node.name == mod_to_class(self.spec.name): node.body = [ c for c in node.body if (not self.is_directive(c) and not self.is_spack_attr(c))] return node