Exemple #1
0
def sort_yaml_obj(obj):
    if isinstance(obj, Mapping):
        return syaml.syaml_dict(
            (k, sort_yaml_obj(v))
            for k, v in sorted(obj.items(), key=(lambda item: str(item[0]))))

    if isinstance(obj, Sequence) and not isinstance(obj, str):
        return syaml.syaml_list(sort_yaml_obj(x) for x in obj)

    return obj
Exemple #2
0
def _mark_overrides(data):
    if isinstance(data, list):
        return syaml.syaml_list(_mark_overrides(elt) for elt in data)

    elif isinstance(data, dict):
        marked = syaml.syaml_dict()
        for key, val in iteritems(data):
            if isinstance(key, string_types) and key.endswith(':'):
                key = syaml.syaml_str(key[:-1])
                key.override = True
            marked[key] = _mark_overrides(val)
        return marked

    else:
        return data
Exemple #3
0
def _mark_overrides(data):
    if isinstance(data, list):
        return syaml.syaml_list(_mark_overrides(elt) for elt in data)

    elif isinstance(data, dict):
        marked = syaml.syaml_dict()
        for key, val in iteritems(data):
            if isinstance(key, string_types) and key.endswith(':'):
                key = syaml.syaml_str(key[:-1])
                key.override = True
            marked[key] = _mark_overrides(val)
        return marked

    else:
        return data
Exemple #4
0
def _mark_internal(data, name):
    """Add a simple name mark to raw YAML/JSON data.

    This is used by `spack config blame` to show where config lines came from.
    """
    if isinstance(data, dict):
        d = syaml.syaml_dict((_mark_internal(k, name), _mark_internal(v, name))
                             for k, v in data.items())
    elif isinstance(data, list):
        d = syaml.syaml_list(_mark_internal(e, name) for e in data)
    else:
        d = syaml.syaml_type(data)

    if syaml.markable(d):
        d._start_mark = yaml.Mark(name, None, None, None, None, None)
        d._end_mark = yaml.Mark(name, None, None, None, None, None)

    return d
Exemple #5
0
def _mark_internal(data, name):
    """Add a simple name mark to raw YAML/JSON data.

    This is used by `spack config blame` to show where config lines came from.
    """
    if isinstance(data, dict):
        d = syaml.syaml_dict((_mark_internal(k, name), _mark_internal(v, name))
                             for k, v in data.items())
    elif isinstance(data, list):
        d = syaml.syaml_list(_mark_internal(e, name) for e in data)
    else:
        d = syaml.syaml_type(data)

    if syaml.markable(d):
        d._start_mark = yaml.Mark(name, None, None, None, None, None)
        d._end_mark = yaml.Mark(name, None, None, None, None, None)

    return d
Exemple #6
0
def export(parser, args):
    q_args = {"explicit": True if args.explicit else any}
    specs = args.specs(**q_args)

    # Exit early if no package matches the constraint
    if not args.specs and args.constraint:
        msg = "No package matches the query: {0}"
        msg = msg.format(' '.join(args.constraint))
        tty.msg(msg)
        return

    packages = spack.config.get('packages', scope=args.scope)

    # If tags have been specified on the command line, filter by tags
    if args.tags:
        packages_with_tags = spack.repo.path.packages_with_tags(*args.tags)
        specs = [x for x in specs if x.name in packages_with_tags]

    if args.exclude:
        specs = set(filter_exclude(specs, args.exclude))

    cls = None
    if args.module:
        cls = spack.modules.module_types[args.module]

    # Collect packages per package name
    pkgs = {}
    for spec in specs:
        pkgs.setdefault(spec.name, []).append(spec)

    pymods = {}

    # Dump per package, make sure that none are forgotten
    for pkg, pkg_specs in pkgs.items():
        paths = syaml_dict()
        modules = syaml_dict()
        package = packages.setdefault(pkg, syaml_dict())
        versions = None
        if 'version' in package:
            versions = [str(v) for v in package['version']]

        for spec in pkg_specs:
            key = spec.format(args.format)
            sflags = []
            bflags = []
            for k, v in spec.variants.items():
                default = None
                if k in spec.package.variants:
                    default = spec.package.variants[k].default
                if v.value != default or args.variants == 'all':
                    if v.value in (True, False):
                        bflags.append(v)
                    elif v.name != 'patches':
                        sflags.append(v)

            sflags = ' '.join(str(f) for f in sorted(sflags))
            bflags = ''.join(str(f) for f in sorted(bflags))
            key = ' '.join([e for e in (key, sflags, bflags) if len(e) > 0])
            key = str(key)

            if isinstance(spec.package, PythonPackage):
                py = spec['python']
                if args.dependencies:
                    key += " ^{0}".format(py.format("$_$@"))

                if not spec.package.is_activated(py.package.view()):
                    # For external packages, setup_environment is not
                    # called, and thus they are not included in
                    # PYTHON_PATH.
                    msg = "python package not activated, skipping: {0}"
                    msg = msg.format(spec.format("$_$@"))
                    tty.warn(msg)
                    # paths[key] = str(spec.prefix)
                else:
                    mod = pymods.setdefault(py, cls(py) if cls else None)
                    if mod and not mod.conf.blacklisted:
                        if os.path.exists(mod.layout.filename):
                            paths[key] = '/activated'
                            # modules[key] = mod.layout.use_name
                            # paths[key] = str(spec.prefix)
                    else:
                        msg = "python package activated in inactive module, skipping: {0}"
                        msg = msg.format(spec.format("$_$@"))
                        tty.warn(msg)
                        continue
            else:
                mod = cls(spec) if cls else None
                if mod and not mod.conf.blacklisted:
                    if os.path.exists(mod.layout.filename):
                        modules[key] = str(mod.layout.use_name)
                    else:
                        msg = "module not present for {0}"
                        msg = msg.format(spec.format("$_$@"))
                        tty.warn(msg)
                # Even with modules, the path needs to be present to, e.g.,
                # have `spack setup` work!
                paths.setdefault(key, []).append(spec)

            if versions and str(spec.version) not in versions:
                versions.append(str(spec.version))

        if versions:
            package['version'] = syaml_list(sorted(versions, reverse=True))
        if len(paths) > 0:

            def install_date(s):
                _, record = spack.store.db.query_by_spec_hash(s.dag_hash())
                return record.installation_time

            for k in paths.keys():
                values = paths[k]
                if values == '/activated':
                    continue
                paths[k] = str(
                    sorted(values, key=install_date, reverse=True)[0].prefix)
            package.setdefault('paths', syaml_dict()).update(paths)
        if len(modules) > 0:
            package.setdefault('modules', syaml_dict()).update(modules)

    # Trim empty items from the yaml
    for cfg in packages.values():
        for k, v in list(cfg.items()):
            if (k == 'buildable' and v) or (hasattr(v, '__iter__')
                                            and len(v) == 0):
                del cfg[k]

    # Restore ordering
    packages = syaml_dict(
        sorted((k, v) for (k, v) in packages.items() if len(v) > 0))
    if 'all' in packages:
        packages['all'] = packages.pop('all')
    yaml.dump({'packages': packages},
              stream=sys.stdout,
              default_flow_style=False,
              Dumper=PackagesDumper)
Exemple #7
0
def export(parser, args):
    q_args = {"explicit": True if args.explicit else any}
    specs = args.specs(**q_args)

    # Exit early if no package matches the constraint
    if not args.specs and args.constraint:
        msg = "No package matches the query: {0}"
        msg = msg.format(' '.join(args.constraint))
        tty.msg(msg)
        return

    packages = spack.config.get('packages', scope=args.scope)

    # If tags have been specified on the command line, filter by tags
    if args.tags:
        packages_with_tags = spack.repo.path.packages_with_tags(*args.tags)
        specs = [x for x in specs if x.name in packages_with_tags]

    if args.exclude:
        specs = set(filter_exclude(specs, args.exclude))

    cls = None
    if args.module:
        cls = spack.modules.module_types[args.module]

    # Add all selected specs to the external packages
    new_packages = {}
    for spec in specs:
        pkg_toplevel = new_packages.setdefault(spec.name, {})
        pkg_externals = pkg_toplevel.setdefault("externals", [])
        pkg_versions = pkg_toplevel.setdefault("version", syaml_list())

        key = _to_key(spec, args.format, args.variants)
        externality = dict(spec=key, prefix=str(spec.prefix))

        if key in [ext["spec"] for ext in pkg_externals]:
            tty.warn("spec already present, skipping: {0}".format(key))
            continue

        mod = cls(spec, 'default') if cls else None
        if mod and not mod.conf.blacklisted:
            if os.path.exists(mod.layout.filename):
                externality["modules"] = [str(mod.layout.use_name)]
            else:
                msg = "module not present for {0}"
                msg = msg.format(spec.format("$_$@"))
                tty.warn(msg)

        version = str(spec.version)
        if version not in pkg_versions:
            pkg_versions.append(version)
        pkg_externals.append(externality)

    spack.config.merge_yaml(packages, new_packages)

    # Restore ordering
    packages = syaml_dict(
        sorted((k, v) for (k, v) in packages.items() if len(v) > 0))
    for pkg in args.unbuildable:
        packages.setdefault(pkg, {})['buildable'] = False
    if 'all' in packages:
        packages['all'] = packages.pop('all')
    yaml.dump({'packages': packages},
              stream=sys.stdout,
              default_flow_style=False,
              Dumper=PackagesDumper)