Exemplo n.º 1
0
 def chdir(self):
     """Changes directory to the stage path.  Or dies if it is not set up."""
     self.setup()
     if os.path.isdir(self.path):
         os.chdir(self.path)
     else:
         tty.die("Setup failed: no such directory: " + self.path)
Exemplo n.º 2
0
def expand_user(path):
    """Find instances of '%u' in a path and replace with the current user's
       username."""
    username = getpass.getuser()
    if not username and '%u' in path:
        tty.die("Couldn't get username to complete path '%s'" % path)

    return path.replace('%u', username)
Exemplo n.º 3
0
def new_path(prefix, *args):
    path = str(prefix)
    for elt in args:
        path = os.path.join(path, str(elt))

    if re.search(r'\s', path):
        tty.die("Invalid path: '%s'.  Use a path without whitespace." % path)

    return path
Exemplo n.º 4
0
    def restage(self):
        """Removes the expanded archive path if it exists, then re-expands
           the archive.
        """
        if not self.archive_file:
            tty.die("Attempt to restage when not staged.")

        if self.expanded_archive_path:
            shutil.rmtree(self.expanded_archive_path, True)
        self.expand_archive()
Exemplo n.º 5
0
 def chdir_to_archive(self):
     """Changes directory to the expanded archive directory.
        Dies with an error if there was no expanded archive.
     """
     path = self.expanded_archive_path
     if not path:
         tty.die("Attempt to chdir before expanding archive.")
     else:
         os.chdir(path)
         if not os.listdir(path):
             tty.die("Archive was empty for %s" % self.name)
Exemplo n.º 6
0
    def expand_archive(self):
        """Changes to the stage directory and attempt to expand the downloaded
           archive.  Fail if the stage is not set up or if the archive is not yet
           downloaded.
        """
        self.chdir()
        if not self.archive_file:
            tty.die("Attempt to expand archive before fetching.")

        decompress = decompressor_for(self.archive_file)
        decompress(self.archive_file)
Exemplo n.º 7
0
def clean(parser, args):
    if not args.packages:
        tty.die("spack clean requires at least one package argument")

    specs = spack.cmd.parse_specs(args.packages, concretize=True)
    for spec in specs:
        tty.message("Cleaning for spec:", spec)
        package = packages.get(spec.name)
        if args.dist:
            package.do_clean_dist()
        elif args.work:
            package.do_clean_work()
        else:
            package.do_clean()
Exemplo n.º 8
0
def which(name, **kwargs):
    """Finds an executable in the path like command-line which."""
    path     = kwargs.get('path', os.environ.get('PATH', '').split(os.pathsep))
    required = kwargs.get('required', False)

    if not path:
        path = []

    for dir in path:
        exe = os.path.join(dir, name)
        if os.access(exe, os.X_OK):
            return Executable(exe)

    if required:
        tty.die("spack requires %s.  Make sure it is in your path." % name)
    return None
Exemplo n.º 9
0
def get_module(name):
    """Imports the module for a particular command name and returns it."""
    module_name = "%s.%s" % (__name__, name)
    module = __import__(
        module_name, fromlist=[name, SETUP_PARSER, DESCRIPTION],
        level=0)

    attr_setdefault(module, SETUP_PARSER, lambda *args: None) # null-op
    attr_setdefault(module, DESCRIPTION, "")

    fn_name = get_cmd_function_name(name)
    if not hasattr(module, fn_name):
        tty.die("Command module %s (%s) must define function '%s'."
                % (module.__name__, module.__file__, fn_name))

    return module
Exemplo n.º 10
0
def uninstall(parser, args):
    if not args.packages:
        tty.die("uninstall requires at least one package argument.")

    specs = spack.cmd.parse_specs(args.packages)

    # For each spec provided, make sure it refers to only one package.
    # Fail and ask user to be unambiguous if it doesn't
    pkgs = []
    for spec in specs:
        matching_specs = packages.get_installed(spec)
        if len(matching_specs) > 1:
            tty.die("%s matches multiple packages.  Which one did you mean?"
                    % spec, *matching_specs)

        elif len(matching_specs) == 0:
            tty.die("%s does not match any installed packages." % spec)

        installed_spec = matching_specs[0]
        pkgs.append(packages.get(installed_spec))

    # Sort packages to be uninstalled by the number of installed dependents
    # This ensures we do things in the right order
    def num_installed_deps(pkg):
        return len(pkg.installed_dependents)
    pkgs.sort(key=num_installed_deps)

    # Uninstall packages in order now.
    for pkg in pkgs:
        pkg.do_uninstall()
Exemplo n.º 11
0
Arquivo: edit.py Projeto: boegel/spack
def edit(parser, args):
    name = args.name

    # By default open the directory where packages live.
    if not name:
        path = spack.packages_path
    else:
        path = packages.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:
            class_name = packages.class_name_for_package_name(name)

            with closing(open(path, "w")) as pkg_file:
                pkg_file.write(
                    package_template.substitute(name=name, class_name=class_name))

    # If everything checks out, go ahead and edit.
    spack.editor(path)
Exemplo n.º 12
0
def bootstrap(parser, args):
    origin_url = get_origin_url()
    prefix = args.prefix

    tty.msg("Fetching spack from origin: %s" % origin_url)

    if os.path.exists(new_path(prefix, ".git")):
        tty.die("There already seems to be a git repository in %s" % prefix)

    files_in_the_way = os.listdir(prefix)
    if files_in_the_way:
        tty.die("There are already files there!  Delete these files before boostrapping spack.", *files_in_the_way)

    tty.msg("Installing:", "%s/bin/spack" % prefix, "%s/lib/spack/..." % prefix)

    os.chdir(prefix)
    check_call(["git", "init", "--shared", "-q"])
    check_call(["git", "remote", "add", "origin", origin_url])
    check_call(["git", "fetch", "origin", "master:refs/remotes/origin/master", "-n", "-q"])
    check_call(["git", "reset", "--hard", "origin/master", "-q"])

    tty.msg("Successfully created a new spack in %s" % prefix, "Run %s/bin/spack to use this installation." % prefix)
Exemplo n.º 13
0
def checksum(parser, args):
    # get the package we're going to generate checksums for
    pkg = packages.get(args.package)

    # If the user asked for specific versions, use those.
    versions = [ver(v) for v in args.versions]

    if not all(type(v) == Version for v in versions):
        tty.die("Cannot generate checksums for version lists or " +
                "version ranges.  Use unambiguous versions.")

    if not versions:
        versions = pkg.fetch_available_versions()
        if not versions:
            tty.die("Could not fetch any available versions for %s." % pkg.name)

    versions = list(reversed(versions))
    urls = [pkg.url_for_version(v) for v in versions]


    tty.msg("Found %s versions of %s." % (len(urls), pkg.name),
            *spack.cmd.elide_list(
            ["%-10s%s" % (v,u) for v, u in zip(versions, urls)]))
    print
    archives_to_fetch = tty.get_number(
        "How many would you like to checksum?", default=5, abort='q')

    if not archives_to_fetch:
        tty.msg("Aborted.")
        return

    version_hashes = get_checksums(
        versions[:archives_to_fetch], urls[:archives_to_fetch])

    if not version_hashes:
        tty.die("Could not fetch any available versions for %s." % pkg.name)

    dict_string = ["    '%s' : '%s'," % (v, h) for v, h in version_hashes]
    dict_string = ['{'] + dict_string + ["}"]

    tty.msg("Checksummed new versions of %s:" % pkg.name, *dict_string)
Exemplo n.º 14
0
def get_class_for_package_name(pkg_name):
    file_name = filename_for_package_name(pkg_name)

    if os.path.exists(file_name):
        if not os.path.isfile(file_name):
            tty.die("Something's wrong. '%s' is not a file!" % file_name)
        if not os.access(file_name, os.R_OK):
            tty.die("Cannot read '%s'!" % file_name)
    else:
        raise UnknownPackageError(pkg_name)

    # Figure out pacakges module from spack.packages_path
    # This allows us to change the module path.
    if not re.match(r'%s' % spack.module_path, spack.packages_path):
        raise RuntimeError("Packages path is not a submodule of spack.")

    class_name = class_name_for_package_name(pkg_name)
    try:
        module_name = "%s.%s" % (packages_module(), pkg_name)
        module = __import__(module_name, fromlist=[class_name])
    except ImportError, e:
        tty.die("Error while importing %s.%s:\n%s" % (pkg_name, class_name, e.message))
Exemplo n.º 15
0
    # Figure out pacakges module from spack.packages_path
    # This allows us to change the module path.
    if not re.match(r'%s' % spack.module_path, spack.packages_path):
        raise RuntimeError("Packages path is not a submodule of spack.")

    class_name = class_name_for_package_name(pkg_name)
    try:
        module_name = "%s.%s" % (packages_module(), pkg_name)
        module = __import__(module_name, fromlist=[class_name])
    except ImportError, e:
        tty.die("Error while importing %s.%s:\n%s" % (pkg_name, class_name, e.message))

    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 compute_dependents():
    """Reads in all package files and sets dependence information on
       Package objects in memory.
    """
    if not hasattr(compute_dependents, index):
        compute_dependents.index = {}

    for pkg in all_packages():
        if pkg._dependents is None:
            pkg._dependents = []
Exemplo n.º 16
0
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.")
        while not name:
            new_name = raw_input("Name: ")
            if packages.valid_name(name):
                name = new_name
            else:
                print "Package name can only contain A-Z, a-z, 0-9, '_' and '-'"

    if not version:
        tty.die("Couldn't guess a version string from %s." % url)

    tty.msg("Creating template for package %s" % name)

    pkg_path = packages.filename_for_package_name(name)
    if os.path.exists(pkg_path) and not args.force:
        tty.die("%s already exists." % pkg_path)

    class_name = packages.class_name_for_package_name(name)
    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)

    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=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)
Exemplo n.º 17
0
def ensure_access(file=spack.stage_path):
    """Ensure we can access a directory and die with an error if we can't."""
    if not can_access(file):
        tty.die("Insufficient permissions for %s" % file)