Пример #1
0
def create_migration_yaml_creator(migrators: MutableSequence[Migrator], gx: nx.DiGraph):
    with indir(os.environ["CONDA_PREFIX"]):
        pinnings = parse_config_file(
            "conda_build_config.yaml", config=Config(**CB_CONFIG),
        )
    feedstocks_to_be_repinned = []
    for k, package_pin_list in pinnings.items():
        # we need the package names for the migrator itself but need the
        # feedstock for everything else
        package_name = k
        # exclude non-package keys
        if k not in gx.nodes and k not in gx.graph["outputs_lut"]:
            # conda_build_config.yaml can't have `-` unlike our package names
            k = k.replace("_", "-")
        # replace sub-packages with their feedstock names
        k = gx.graph["outputs_lut"].get(k, k)

        if (
            (k in gx.nodes)
            and not gx.nodes[k]["payload"].get("archived", False)
            and gx.nodes[k]["payload"].get("version")
            and k not in feedstocks_to_be_repinned
        ):

            current_pins = list(map(str, package_pin_list))
            current_version = str(gx.nodes[k]["payload"]["version"])

            # we need a special parsing for pinning stuff
            meta_yaml = parse_meta_yaml(
                gx.nodes[k]["payload"]["raw_meta_yaml"], for_pinning=True,
            )

            # find the most stringent max pin for this feedstock if any
            pin_spec = ""
            for block in [meta_yaml] + meta_yaml.get("outputs", []) or []:
                build = block.get("build", {}) or {}
                # and check the exported package is within the feedstock
                exports = [
                    p.get("max_pin", "")
                    for p in build.get("run_exports", [{}])
                    # make certain not direct hard pin
                    if isinstance(p, MutableMapping)
                    # if the pinned package is in an output of the parent feedstock
                    and (
                        gx.graph["outputs_lut"].get(p.get("package_name", ""), "") == k
                        # if the pinned package is the feedstock itself
                        or p.get("package_name", "") == k
                    )
                ]
                if not exports:
                    continue
                # get the most stringent pin spec from the recipe block
                max_pin = max(exports, key=len)
                if len(max_pin) > len(pin_spec):
                    pin_spec = max_pin

            # fall back to the pinning file or "x"
            if not pin_spec:
                pin_spec = (
                    pinnings["pin_run_as_build"].get(k, {}).get("max_pin", "x") or "x"
                )

            current_pins = list(
                map(lambda x: re.sub("[^0-9.]", "", x).rstrip("."), current_pins),
            )
            current_version = re.sub("[^0-9.]", "", current_version).rstrip(".")
            if current_pins == [""]:
                continue

            current_pin = str(max(map(VersionOrder, current_pins)))
            # If the current pin and the current version is the same nothing
            # to do even if the pin isn't accurate to the spec
            if current_pin != current_version and _outside_pin_range(
                pin_spec, current_pin, current_version,
            ):
                feedstocks_to_be_repinned.append(k)
                print(package_name, current_version, current_pin, pin_spec)
                migrators.append(
                    MigrationYamlCreator(
                        package_name, current_version, current_pin, pin_spec, k, gx,
                    ),
                )
Пример #2
0
def create_migration_yaml_creator(migrators: MutableSequence[Migrator],
                                  gx: nx.DiGraph):
    cfp_gx = copy.deepcopy(gx)
    for node in list(cfp_gx.nodes):
        if node != "conda-forge-pinning":
            pluck(cfp_gx, node)

    print("pinning migrations", flush=True)
    with indir(os.environ["CONDA_PREFIX"]):
        pinnings = parse_config_file(
            "conda_build_config.yaml",
            config=Config(**CB_CONFIG),
        )
    feedstocks_to_be_repinned = []
    for pinning_name, package_pin_list in pinnings.items():
        # there are three things:
        # pinning_name - entry in pinning file
        # package_name - the actual package, could differ via `-` -> `_`
        #                from pinning_name
        # feedstock_name - the feedstock that outputs the package
        # we need the package names for the migrator itself but need the
        # feedstock for everything else

        # exclude non-package keys
        if pinning_name not in gx.graph["outputs_lut"]:
            # conda_build_config.yaml can't have `-` unlike our package names
            package_name = pinning_name.replace("_", "-")
        else:
            package_name = pinning_name

        # replace sub-packages with their feedstock names
        # TODO - we are grabbing one element almost at random here
        # the sorted call makes it stable at least?
        fs_name = next(
            iter(
                sorted(gx.graph["outputs_lut"].get(package_name,
                                                   {package_name})), ), )

        if ((fs_name in gx.nodes)
                and not gx.nodes[fs_name]["payload"].get("archived", False)
                and gx.nodes[fs_name]["payload"].get("version")
                and fs_name not in feedstocks_to_be_repinned):

            current_pins = list(map(str, package_pin_list))
            current_version = str(gx.nodes[fs_name]["payload"]["version"])

            # we need a special parsing for pinning stuff
            meta_yaml = parse_meta_yaml(
                gx.nodes[fs_name]["payload"]["raw_meta_yaml"],
                for_pinning=True,
            )

            # find the most stringent max pin for this feedstock if any
            pin_spec = ""
            for block in [meta_yaml] + meta_yaml.get("outputs", []) or []:
                build = block.get("build", {}) or {}
                # and check the exported package is within the feedstock
                exports = [
                    p.get("max_pin", "")
                    for p in build.get("run_exports", [{}])
                    # make certain not direct hard pin
                    if isinstance(p, MutableMapping)
                    # ensure the export is for this package
                    and p.get("package_name", "") == package_name
                    # ensure the pinned package is in an output of the parent feedstock
                    and (fs_name in gx.graph["outputs_lut"].get(
                        p.get("package_name", ""), set()))
                ]
                if not exports:
                    continue
                # get the most stringent pin spec from the recipe block
                max_pin = max(exports, key=len)
                if len(max_pin) > len(pin_spec):
                    pin_spec = max_pin

            # fall back to the pinning file or "x"
            if not pin_spec:
                pin_spec = (pinnings["pin_run_as_build"].get(
                    pinning_name, {}).get("max_pin", "x")) or "x"

            current_pins = list(
                map(lambda x: re.sub("[^0-9.]", "", x).rstrip("."),
                    current_pins), )
            current_pins = [
                cp.strip() for cp in current_pins if cp.strip() != ""
            ]
            current_version = re.sub("[^0-9.]", "",
                                     current_version).rstrip(".")
            if not current_pins or current_version == "":
                continue

            current_pin = str(max(map(VersionOrder, current_pins)))
            # If the current pin and the current version is the same nothing
            # to do even if the pin isn't accurate to the spec
            if current_pin != current_version and _outside_pin_range(
                    pin_spec,
                    current_pin,
                    current_version,
            ):
                feedstocks_to_be_repinned.append(fs_name)
                print(
                    "    %s:\n"
                    "        curr version: %s\n"
                    "        curr pin: %s\n"
                    "        pin_spec: %s" %
                    (pinning_name, current_version, current_pin, pin_spec),
                    flush=True,
                )
                migrators.append(
                    MigrationYamlCreator(
                        pinning_name,
                        current_version,
                        current_pin,
                        pin_spec,
                        fs_name,
                        cfp_gx,
                        full_graph=gx,
                    ), )
    print(" ", flush=True)