Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
beckermr authored Sep 25, 2024
2 parents 1ef8b85 + 8508dfb commit c372619
Show file tree
Hide file tree
Showing 14 changed files with 652 additions and 14 deletions.
1 change: 1 addition & 0 deletions conda_forge_tick/migration_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ def run_migration_containerized(
if isinstance(node_attrs, LazyJson)
else dumps(node_attrs)
),
extra_container_args=["-e", "RUN_URL"],
)

sync_dirs(
Expand Down
27 changes: 16 additions & 11 deletions conda_forge_tick/migrators/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import logging
import re
import typing
from pathlib import Path
from typing import Any, List, Sequence, Set

import dateutil.parser
Expand All @@ -14,7 +15,7 @@
from conda_forge_tick.lazy_json_backends import LazyJson
from conda_forge_tick.make_graph import make_outputs_lut_from_graph
from conda_forge_tick.path_lengths import cyclic_topological_sort
from conda_forge_tick.update_recipe import update_build_number
from conda_forge_tick.update_recipe import update_build_number, v1_recipe
from conda_forge_tick.utils import (
frozen_to_json_friendly,
get_bot_run_url,
Expand Down Expand Up @@ -592,25 +593,29 @@ def order(
}
return cyclic_topological_sort(graph, top_level)

def set_build_number(self, filename: str) -> None:
def set_build_number(self, filename: str | Path) -> None:
"""Bump the build number of the specified recipe.
Parameters
----------
filename : str
Path the the meta.yaml
"""
with open(filename) as f:
raw = f.read()
filename = Path(filename)
if filename.name == "recipe.yaml":
filename.write_text(
v1_recipe.update_build_number(filename, self.new_build_number)
)
else:
raw = filename.read_text()

new_myaml = update_build_number(
raw,
self.new_build_number,
build_patterns=self.build_patterns,
)
new_myaml = update_build_number(
raw,
self.new_build_number,
build_patterns=self.build_patterns,
)

with open(filename, "w") as f:
f.write(new_myaml)
filename.write_text(new_myaml)

def new_build_number(self, old_number: int) -> int:
"""Determine the new build number to use.
Expand Down
5 changes: 4 additions & 1 deletion conda_forge_tick/migrators/migration_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,10 @@ def migrate(
yaml_safe_dump(cfg, fp)

with pushd(recipe_dir):
self.set_build_number("meta.yaml")
if os.path.exists("recipe.yaml"):
self.set_build_number("recipe.yaml")
else:
self.set_build_number("meta.yaml")

return super().migrate(recipe_dir, attrs)

Expand Down
4 changes: 2 additions & 2 deletions conda_forge_tick/recipe_parser/_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
BAD_MULTILINE_STRING_WITH_SELECTOR = re.compile(r"[^|#]*\|\s+#")


def _get_yaml_parser():
def _get_yaml_parser(typ="jinja2"):
"""yaml parser that is jinja2 aware"""
# using a function here so settings are always the same
parser = YAML(typ="jinja2")
parser = YAML(typ=typ)
parser.indent(mapping=2, sequence=4, offset=2)
parser.width = 320
parser.preserve_quotes = True
Expand Down
3 changes: 3 additions & 0 deletions conda_forge_tick/update_recipe/v1_recipe/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .build_number import update_build_number

__all__ = ["update_build_number"]
103 changes: 103 additions & 0 deletions conda_forge_tick/update_recipe/v1_recipe/build_number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from __future__ import annotations

import io
import logging
import re
from typing import TYPE_CHECKING, Any, Callable, Literal

from conda_forge_tick.recipe_parser._parser import _get_yaml_parser

if TYPE_CHECKING:
from pathlib import Path

logger = logging.getLogger(__name__)

HashType = Literal["md5", "sha256"]

RE_PATTERN = re.compile(r"(?:build|build_number|number):\s*(\d+)")


def old_build_number(recipe_text: str) -> int:
"""
Extract the build number from the recipe text.
Arguments:
----------
* `recipe_text` - The recipe text.
Returns:
--------
* The build number.
"""
match = re.search(RE_PATTERN, recipe_text)
if match is not None:
return int(match.group(1))
return 0


def _update_build_number_in_context(
recipe: dict[str, Any], new_build_number: int
) -> bool:
for key in recipe.get("context", {}):
if key in {"build_number", "build", "number"}:
recipe["context"][key] = new_build_number
return True
return False


def _update_build_number_in_recipe(
recipe: dict[str, Any], new_build_number: int
) -> bool:
is_modified = False
if "build" in recipe and "number" in recipe["build"]:
recipe["build"]["number"] = new_build_number
is_modified = True

if "outputs" in recipe:
for output in recipe["outputs"]:
if "build" in output and "number" in output["build"]:
output["build"]["number"] = new_build_number
is_modified = True

return is_modified


def _load_yaml(file: Path):
yaml = _get_yaml_parser(typ="rt")
with file.open("r") as f:
return yaml.load(f)


def _dump_yaml_to_str(data: dict) -> str:
"""Dump a dictionary to a YAML string."""
yaml = _get_yaml_parser(typ="rt")
with io.StringIO() as f:
yaml.dump(data, f)
return f.getvalue()


def update_build_number(file: Path, new_build_number: int | Callable = 0) -> str:
"""
Update the build number in the recipe file.
Arguments:
----------
* `file` - The path to the recipe file.
* `new_build_number` - The new build number to use. (default: 0)
Returns:
--------
* The updated recipe as a string.
"""
data = _load_yaml(file)

if callable(new_build_number):
detected_build_number = old_build_number(file.read_text())
new_build_number = new_build_number(detected_build_number)

build_number_modified = _update_build_number_in_context(data, new_build_number)

if not build_number_modified:
_update_build_number_in_recipe(data, new_build_number)

return _dump_yaml_to_str(data)
10 changes: 10 additions & 0 deletions tests/recipe_v1/build_number/test_1/expected.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# set the build number to something
context:
build: 0

package:
name: recipe_1
version: "0.1.0"

build:
number: ${{ build }}
10 changes: 10 additions & 0 deletions tests/recipe_v1/build_number/test_1/recipe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# set the build number to something
context:
build: 123

package:
name: recipe_1
version: "0.1.0"

build:
number: ${{ build }}
11 changes: 11 additions & 0 deletions tests/recipe_v1/build_number/test_2/expected.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# set the build number to something
package:
name: recipe_1
version: "0.1.0"

# set the build number to something directly in the recipe text
build:
number: 0

source:
- url: foo
11 changes: 11 additions & 0 deletions tests/recipe_v1/build_number/test_2/recipe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# set the build number to something
package:
name: recipe_1
version: "0.1.0"

# set the build number to something directly in the recipe text
build:
number: 321

source:
- url: foo
Loading

0 comments on commit c372619

Please sign in to comment.