Пример #1
0
def get_metadata(yml, config):
    with open(yml, "r") as fi:
        d = ruamel.yaml.safe_load(fi)
    o = Output(d, config)
    return MetaData(os.path.dirname(yml), o)
Пример #2
0
def to_build_tree(ydoc, variants, config, selected_features):
    for k in variants:
        table = Table(show_header=True, header_style="bold")
        table.title = f"Output: [bold white]{k}[/bold white]"
        table.add_column("Package")
        table.add_column("Variant versions")
        for pkg, var in variants[k].items():
            table.add_row(pkg, "\n".join(var))
        console.print(table)

    # first we need to perform a topological sort taking into account all the outputs
    if ydoc.get("outputs"):
        outputs = [
            Output(o, config, parent=ydoc, selected_features=selected_features)
            for o in ydoc["outputs"]
        ]
        outputs = {o.name: o for o in outputs}
    else:
        outputs = [Output(ydoc, config, selected_features=selected_features)]
        outputs = {o.name: o for o in outputs}

    if len(outputs) > 1:
        sort_dict = {
            k: [x.name for x in o.all_requirements()] for k, o in outputs.items()
        }
        tsorted = toposort.toposort(sort_dict)
        tsorted = [o for o in tsorted if o in sort_dict.keys()]
    else:
        tsorted = [o for o in outputs.keys()]

    final_outputs = []

    for name in tsorted:
        output = outputs[name]
        if variants.get(output.name):
            v = variants[output.name]
            combos = []

            differentiating_keys = []
            for k in v:
                if len(v[k]) > 1:
                    differentiating_keys.append(k)
                combos.append([(k, x) for x in v[k]])

            all_combinations = tuple(itertools.product(*combos))
            all_combinations = [dict(x) for x in all_combinations]
            for c in all_combinations:
                x = output.apply_variant(c, differentiating_keys)
                final_outputs.append(x)
        else:
            x = output.apply_variant({})
            final_outputs.append(x)

    temp = final_outputs
    final_outputs = []
    has_intermediate = False
    for o in temp:
        if o.sections["build"].get("intermediate"):
            if has_intermediate:
                raise RuntimeError(
                    "Already found an intermediate build. There can be only one!"
                )
            final_outputs.insert(0, o)
            has_intermediate = True
        else:
            final_outputs.append(o)

    # Note: maybe this should happen _before_ apply variant?!
    if has_intermediate:
        # inherit dependencies
        def merge_requirements(a, b):
            b_names = [x.name for x in b]
            for r in a:
                if r.name in b_names:
                    continue
                else:
                    b.append(r)

        intermediate = final_outputs[0]
        for o in final_outputs[1:]:
            merge_requirements(
                intermediate.requirements["host"], o.requirements["host"]
            )
            merge_requirements(
                intermediate.requirements["build"], o.requirements["build"]
            )
            merged_variant = {}
            merged_variant.update(intermediate.config.variant)
            merged_variant.update(o.config.variant)
            o.config.variant = merged_variant

    return final_outputs
Пример #3
0
def to_build_tree(ydoc, variants, config, cbc, selected_features):
    for k in variants:
        table = Table(show_header=True, header_style="bold")
        table.title = f"Output: [bold white]{k}[/bold white]"
        table.add_column("Package")
        table.add_column("Variant versions")
        for pkg, var in variants[k].items():
            table.add_row(pkg, "\n".join(var))
        console.print(table)

    # first we need to perform a topological sort taking into account all the outputs
    if ydoc.get("outputs"):
        outputs = [
            Output(
                o,
                config,
                parent=ydoc,
                conda_build_config=cbc,
                selected_features=selected_features,
            )
            for o in ydoc["outputs"]
        ]
        outputs = {o.name: o for o in outputs}
    else:
        outputs = [
            Output(
                ydoc,
                config,
                conda_build_config=cbc,
                selected_features=selected_features,
            )
        ]
        outputs = {o.name: o for o in outputs}

    if len(outputs) > 1:
        sort_dict = {
            k: [x.name for x in o.all_requirements()] for k, o in outputs.items()
        }
        tsorted = toposort.toposort(sort_dict)
        tsorted = [o for o in tsorted if o in sort_dict.keys()]
    else:
        tsorted = [o for o in outputs.keys()]

    final_outputs = []

    # need to strip static away from output name... :/
    static_feature = selected_features.get("static", False)

    for name in tsorted:
        output = outputs[name]

        # this is all a bit hacky ... will have to clean that up eventually
        variant_name = name
        if static_feature and name.endswith("-static"):
            variant_name = name[: -len("-static")]

        # zip keys need to be contracted
        zipped_keys = cbc.get("zip_keys", [])

        if variants.get(variant_name):
            v = variants[variant_name]
            import copy

            vzipped = copy.copy(v)
            zippers = {}
            for zkeys in zipped_keys:
                # we check if our variant contains keys that need to be zipped
                if sum(k in v for k in zkeys) > 1:
                    filtered_zip_keys = [k for k in v if k in zkeys]
                    print("Filtered zip keys: ", filtered_zip_keys)

                    zkname = "__zip_" + "_".join(filtered_zip_keys)

                    zklen = None
                    for zk in filtered_zip_keys:
                        if zk not in cbc:
                            raise RuntimeError(
                                f"Trying to zip keys, but not all zip keys found on conda-build-config {zk}"
                            )

                        zkl = len(cbc[zk])
                        if not zklen:
                            zklen = zkl

                        if zklen and zkl != zklen:
                            raise RuntimeError(
                                f"Trying to zip keys, but not all zip keys have the same length {zkeys}"
                            )

                    vzipped[zkname] = [str(i) for i in range(zklen)]
                    zippers[zkname] = {zk: cbc[zk] for zk in filtered_zip_keys}

                    for zk in filtered_zip_keys:
                        del vzipped[zk]

            combos = []
            differentiating_keys = []
            for k, vz in vzipped.items():
                if len(vz) > 1:
                    differentiating_keys.append(k)
                combos.append([(k, x) for x in vz])

            all_combinations = tuple(itertools.product(*combos))
            all_combinations = [dict(x) for x in all_combinations]

            # unzip the zipped keys
            unzipped_combinations = []
            for c in all_combinations:
                unz_combo = {}
                for vc in c:
                    if vc.startswith("__zip_"):
                        ziptask = zippers[vc]
                        zipindex = int(c[vc])
                        for zippkg in ziptask:
                            unz_combo[zippkg] = ziptask[zippkg][zipindex]
                        if vc in differentiating_keys:
                            differentiating_keys.remove(vc)
                            differentiating_keys.extend(zippers[vc].keys())
                    else:
                        unz_combo[vc] = c[vc]

                unzipped_combinations.append(unz_combo)

            for c in unzipped_combinations:
                x = output.apply_variant(c, differentiating_keys)
                final_outputs.append(x)
        else:
            x = output.apply_variant({})
            final_outputs.append(x)

    temp = final_outputs
    final_outputs = []
    has_intermediate = False
    for o in temp:
        if o.sections["build"].get("intermediate"):
            if has_intermediate:
                raise RuntimeError(
                    "Already found an intermediate build. There can be only one!"
                )
            final_outputs.insert(0, o)
            has_intermediate = True
        else:
            final_outputs.append(o)

    # Note: maybe this should happen _before_ apply variant?!
    if has_intermediate:
        # inherit dependencies
        def merge_requirements(a, b):
            b_names = [x.name for x in b]
            for r in a:
                if r.name in b_names:
                    continue
                else:
                    b.append(r)

        intermediate = final_outputs[0]
        for o in final_outputs[1:]:
            merge_requirements(
                intermediate.requirements["host"], o.requirements["host"]
            )
            merge_requirements(
                intermediate.requirements["build"], o.requirements["build"]
            )
            merged_variant = {}
            merged_variant.update(intermediate.config.variant)
            merged_variant.update(o.config.variant)
            o.config.variant = merged_variant

    return final_outputs