Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add win-arm64 migrator #3194

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion conda_forge_tick/make_migrators.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
Version,
make_from_lazy_json_data,
)
from conda_forge_tick.migrators.arch import OSXArm
from conda_forge_tick.migrators.arch import OSXArm, WinArm64
from conda_forge_tick.migrators.migration_yaml import (
MigrationYamlCreator,
create_rebuild_graph,
Expand Down Expand Up @@ -206,6 +206,15 @@
),
)

with fold_log_lines("making win-arm64 migrator"):
migrators.append(

Check warning on line 210 in conda_forge_tick/make_migrators.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/make_migrators.py#L209-L210

Added lines #L209 - L210 were not covered by tests
WinArm64(
graph=total_graph,
pr_limit=PR_LIMIT,
name="arm64 win addition",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No piggy back migrators?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im not sure what a piggy back migrator is?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a look at the piggy back migrators list in OSX Arm migrator. They do additional stuff other than rerendering.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you merge main into your pr, there is now a default set you can use with a function to instantiate them. See the other samples.

),
)


def add_rebuild_migration_yaml(
migrators: MutableSequence[Migrator],
Expand Down
2 changes: 1 addition & 1 deletion conda_forge_tick/migrators/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# flake8: noqa
from .arch import ArchRebuild, OSXArm
from .arch import ArchRebuild, OSXArm, WinArm64
from .broken_rebuild import RebuildBroken
from .conda_forge_yaml_cleanup import CondaForgeYAMLCleanup
from .core import GraphMigrator, Migrator, MiniMigrator, make_from_lazy_json_data
Expand Down
147 changes: 147 additions & 0 deletions conda_forge_tick/migrators/arch.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,3 +413,150 @@

def remote_branch(self, feedstock_ctx: FeedstockContext) -> str:
return super().remote_branch(feedstock_ctx) + "_arm_osx"


class WinArm64(GraphMigrator):
"""
A Migrator that add win-arm64 builds to feedstocks
"""

migrator_version = 1
rerender = True
# We purposefully don't want to bump build number for this migrator
bump_number = 0
ignored_packages = {}
arches = {"win_arm64": "win_64"}

def __init__(
self,
graph: nx.DiGraph = None,
name: Optional[str] = None,
pr_limit: int = 0,
piggy_back_migrations: Optional[Sequence[MiniMigrator]] = None,
target_packages: Optional[Sequence[str]] = None,
effective_graph: nx.DiGraph = None,
_do_init: bool = True,
):
if _do_init:
if target_packages is None:
# We are constraining the scope of this migrator
with open(

Check warning on line 443 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L443

Added line #L443 was not covered by tests
os.path.join(
os.environ["CONDA_PREFIX"],
"share",
"conda-forge",
"migrations",
"win_arm64.txt",
beckermr marked this conversation as resolved.
Show resolved Hide resolved
)
) as f:
target_packages = set(f.read().split())

Check warning on line 452 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L452

Added line #L452 was not covered by tests

if "outputs_lut" not in graph.graph:
graph.graph["outputs_lut"] = make_outputs_lut_from_graph(graph)

# rebuild the graph to only use edges from the arm and power requirements
graph2 = nx.create_empty_copy(graph)
for node, attrs in graph.nodes(data="payload"):
for plat_arch in self.arches:
deps = set().union(
*attrs.get(
f"{plat_arch}_requirements",
attrs.get("requirements", {}),
).values()
)
for dep in get_deps_from_outputs_lut(
deps, graph.graph["outputs_lut"]
):
graph2.add_edge(dep, node)

Check warning on line 470 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L470

Added line #L470 was not covered by tests
pass

graph = graph2
target_packages = set(target_packages)
if target_packages:
target_packages.add("python") # hack that is ~harmless?
_cut_to_target_packages(graph, target_packages)

# filter out stub packages and ignored packages
_filter_stubby_and_ignored_nodes(graph, self.ignored_packages)

if not hasattr(self, "_init_args"):
self._init_args = []

if not hasattr(self, "_init_kwargs"):
self._init_kwargs = {
"graph": graph,
"name": name,
"pr_limit": pr_limit,
"piggy_back_migrations": piggy_back_migrations,
"target_packages": target_packages,
"effective_graph": effective_graph,
"_do_init": False,
}

super().__init__(
graph=graph,
pr_limit=pr_limit,
check_solvable=False,
piggy_back_migrations=piggy_back_migrations,
effective_graph=effective_graph,
)

assert not self.check_solvable, "We don't want to check solvability for aarch!"
self.target_packages = target_packages
self.name = name

if _do_init:
self._reset_effective_graph()

def filter(self, attrs: "AttrsTypedDict", not_bad_str_start: str = "") -> bool:
if super().filter(attrs):
return True
muid = frozen_to_json_friendly(self.migrator_uid(attrs))
for arch in self.arches:
configured_arch = (

Check warning on line 516 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L512-L516

Added lines #L512 - L516 were not covered by tests
attrs.get("conda-forge.yml", {}).get("provider", {}).get(arch)
)
if configured_arch:
return muid in _sanitized_muids(

Check warning on line 520 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L519-L520

Added lines #L519 - L520 were not covered by tests
attrs.get("pr_info", {}).get("PRed", []),
)
else:
return False

Check warning on line 524 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L524

Added line #L524 was not covered by tests

def migrate(
self, recipe_dir: str, attrs: "AttrsTypedDict", **kwargs: Any
) -> "MigrationUidTypedDict":
with pushd(recipe_dir + "/.."):
self.set_build_number("recipe/meta.yaml")
with open("conda-forge.yml") as f:
y = yaml_safe_load(f)
if "provider" not in y:
y["provider"] = {}
for k, v in self.arches.items():
if k not in y["provider"]:
y["provider"][k] = v

Check warning on line 537 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L529-L537

Added lines #L529 - L537 were not covered by tests

with open("conda-forge.yml", "w") as f:
yaml_safe_dump(y, f)

Check warning on line 540 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L539-L540

Added lines #L539 - L540 were not covered by tests

return super().migrate(recipe_dir, attrs, **kwargs)

Check warning on line 542 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L542

Added line #L542 was not covered by tests

def pr_title(self, feedstock_ctx: FeedstockContext) -> str:
return "Windows ARM Migrator"

Check warning on line 545 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L545

Added line #L545 was not covered by tests

def pr_body(self, feedstock_ctx: ClonedFeedstockContext) -> str:
body = super().pr_body(feedstock_ctx)
body = body.format(

Check warning on line 549 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L548-L549

Added lines #L548 - L549 were not covered by tests
dedent(
"""\
This feedstock is being rebuilt as part of the windows arm migration.

**Feel free to merge the PR if CI is all green, but please don't close it
without reaching out the the ARM Windows team first at <code>@</code>conda-forge/help-win-arm64.**
beckermr marked this conversation as resolved.
Show resolved Hide resolved
""",
),
)
return body

Check warning on line 559 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L559

Added line #L559 was not covered by tests

def remote_branch(self, feedstock_ctx: FeedstockContext) -> str:
return super().remote_branch(feedstock_ctx) + "_arm_win"

Check warning on line 562 in conda_forge_tick/migrators/arch.py

View check run for this annotation

Codecov / codecov/patch

conda_forge_tick/migrators/arch.py#L562

Added line #L562 was not covered by tests
1 change: 1 addition & 0 deletions conda_forge_tick/models/pr_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class MigratorName(StrEnum):
VERSION = "Version"
ARCH_REBUILD = "ArchRebuild"
OSX_ARM = "OSXArm"
WIN_ARM64 = "WinArm64"
MIGRATION_YAML = "MigrationYaml"
REBUILD = "Rebuild"
BLAS_REBUILD = "BlasRebuild"
Expand Down
2 changes: 2 additions & 0 deletions conda_forge_tick/status_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
OSXArm,
Replacement,
Version,
WinArm64,
)
from conda_forge_tick.os_utils import eval_cmd
from conda_forge_tick.path_lengths import cyclic_topological_sort
Expand Down Expand Up @@ -436,6 +437,7 @@ def main() -> None:
mgconf.get("longterm", False)
or isinstance(migrator, ArchRebuild)
or isinstance(migrator, OSXArm)
or isinstance(migrator, WinArm64)
):
longterm_status[migrator_name] = f"{migrator.name} Migration Status"
else:
Expand Down
27 changes: 27 additions & 0 deletions tests/test_migrator_to_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,30 @@ def test_migrator_to_json_osx_arm():
]
assert isinstance(migrator2, conda_forge_tick.migrators.OSXArm)
assert dumps(migrator2.to_lazy_json_data()) == lzj_data


def test_migrator_to_json_win_arm64():
gx = nx.DiGraph()
gx.add_node("conda", reqs=["python"], payload={}, blah="foo")

migrator = conda_forge_tick.migrators.WinArm64(
target_packages=["python"],
graph=gx,
pr_limit=5,
name="arm64 win addition",
)

data = migrator.to_lazy_json_data()
pprint.pprint(data)
lzj_data = dumps(data)
print("lazy json data:\n", lzj_data)
assert data["__migrator__"] is True
assert data["class"] == "WinArm64"
assert data["name"] == "arm64_win_addition"

migrator2 = make_from_lazy_json_data(loads(lzj_data))
assert [pgm.__class__.__name__ for pgm in migrator2.piggy_back_migrations] == [
pgm.__class__.__name__ for pgm in migrator.piggy_back_migrations
]
assert isinstance(migrator2, conda_forge_tick.migrators.WinArm64)
assert dumps(migrator2.to_lazy_json_data()) == lzj_data