Skip to content

Commit db7d96e

Browse files
committed
Split recipe processing in a separate function
1 parent b45b369 commit db7d96e

File tree

1 file changed

+129
-68
lines changed

1 file changed

+129
-68
lines changed

conda_build/_rattler_build/compat.py

Lines changed: 129 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from rattler_build.variant_config import VariantConfig
1313

1414
from ..config import CondaPkgFormat, Config
15+
from ..exceptions import CondaBuildUserError
1516

1617
CONFIG_FILES = {"conda_build_config.yaml", "variants.yaml"}
1718

@@ -87,28 +88,124 @@ def check_arguments_rattler(
8788
)
8889

8990

91+
def process_recipes(
92+
recipes: list[str],
93+
variant_config: VariantConfig,
94+
render_config: RenderConfig,
95+
tool_config: ToolConfiguration,
96+
command: str,
97+
output_dir: str,
98+
channels: list[str],
99+
show_logs: bool,
100+
no_build_id: bool,
101+
package_format: str,
102+
no_include_recipe: bool,
103+
debug: bool,
104+
) -> int:
105+
import yaml
106+
107+
succeeded: list[str] = []
108+
failed: dict[str, str] = {}
109+
110+
for recipe_path in recipes:
111+
recipe_path_str = str(recipe_path)
112+
try:
113+
# load the recipe file
114+
try:
115+
recipe = Stage0Recipe.from_file(Path(recipe_path))
116+
except Exception as e:
117+
raise CondaBuildUserError(
118+
f"Failed to process recipe {recipe_path}: {str(e)}"
119+
)
120+
121+
# render the recipe
122+
try:
123+
rendered = recipe.render(variant_config, render_config)
124+
except Exception as e:
125+
raise CondaBuildUserError(
126+
f"Failed to render recipe {recipe_path}: {str(e)}"
127+
)
128+
129+
if command == "render":
130+
data = rendered[0].recipe.to_dict()
131+
print(yaml.safe_dump(data, indent=2, sort_keys=False))
132+
succeeded.append(recipe_path_str)
133+
continue
134+
135+
# build all rendered variants
136+
for i, variant in enumerate(rendered, 1):
137+
print(
138+
f"\n🔨 Building variant {i}/{len(rendered)} "
139+
f"for recipe {recipe_path}"
140+
)
141+
142+
try:
143+
with RichProgressCallback(show_logs=show_logs) as progress_callback:
144+
variant.run_build(
145+
tool_config=tool_config,
146+
output_dir=output_dir,
147+
channels=channels,
148+
progress_callback=progress_callback,
149+
no_build_id=no_build_id,
150+
package_format=package_format,
151+
no_include_recipe=no_include_recipe,
152+
debug=debug,
153+
)
154+
except Exception as e:
155+
print(f"Build failed for recipe {recipe_path}: {str(e)}")
156+
raise
157+
158+
# if all variants built without raising, mark recipe as succeeded
159+
succeeded.append(recipe_path_str)
160+
161+
except Exception as e:
162+
# catch any failure for this recipe and continue with the next
163+
failed[recipe_path_str] = str(e)
164+
print(f"Skipping remaining work for recipe {recipe_path}.")
165+
166+
# summary
167+
print("\n=== Build summary ===")
168+
if succeeded:
169+
print("Succeeded:")
170+
for path in succeeded:
171+
print(f" - {path}")
172+
else:
173+
print("Succeeded: none")
174+
175+
if failed:
176+
print("\nFailed:")
177+
for path, error in failed.items():
178+
print(f" - {path}: {error}")
179+
else:
180+
print("\nFailed: none")
181+
182+
return 1 if failed else 0
183+
184+
90185
def run_rattler(command: str, parsed_args: argparse.Namespace, config: Config) -> int:
91186
"""Run rattler-build for v1 recipes"""
92187
if command not in ("build", "render", "debug"):
93188
raise ValueError(f"Unrecognized subcommand: {command}")
94189

95190
# Initialize configuration defaults
96-
test_strategy = None
97-
skip_existing = None
98-
noarch_build_platform = None
99-
channel_priority = None
100-
output_dir = config.croot
101-
no_include_recipe = False
102-
no_build_id = False
103-
package_format = None
104-
debug = False
105-
channels = []
106-
extra_context = {}
107-
show_logs = not parsed_args.quiet
108-
target_platform = config.variant.get("host_platform", config.subdir)
109-
build_platform = config.variant.get("build_platform", config.subdir)
110-
host_platform = config.variant.get("target_platform", config.subdir)
111-
noarch_build_platform = config.variant.get("noarch_build_platform", config.subdir)
191+
test_strategy: str | None = None
192+
skip_existing: bool | None = None
193+
noarch_build_platform: str | None = None
194+
channel_priority: str | None = None
195+
output_dir: str = config.croot
196+
no_include_recipe: bool = False
197+
no_build_id: bool = False
198+
package_format: str | None = None
199+
debug: bool = False
200+
channels: list[str] = []
201+
extra_context: dict[str] = {}
202+
show_logs: bool = getattr(parsed_args, "quiet", False) is False
203+
target_platform: str = config.variant.get("host_platform", config.subdir)
204+
build_platform: str = config.variant.get("build_platform", config.subdir)
205+
host_platform: str = config.variant.get("target_platform", config.subdir)
206+
noarch_build_platform: str = config.variant.get(
207+
"noarch_build_platform", config.subdir
208+
)
112209

113210
# TODO: investigate why is config.channel_urls
114211
# does not pick up condarc settings, need to use context.channels
@@ -169,7 +266,7 @@ def run_rattler(command: str, parsed_args: argparse.Namespace, config: Config) -
169266
# TODO: output_name does not exist in python bindings
170267
# if parsed_args.output_id:
171268
# cmd.extend(["--output-name", parsed_args.output_id])
172-
elif command == "build":
269+
if command == "build":
173270
if parsed_args.extra_meta:
174271
extra_context.update(parsed_args.extra_meta)
175272
if parsed_args.output_folder:
@@ -198,13 +295,11 @@ def run_rattler(command: str, parsed_args: argparse.Namespace, config: Config) -
198295

199296
from ..variants import find_config_files
200297

201-
results = []
202-
203298
# configure variant
204299
for variant in config_files:
205300
variant_config = VariantConfig.from_file(variant)
206301

207-
# coon tool / platform / render configuration
302+
# common tool / platform / render configuration
208303
tool_config = ToolConfiguration(
209304
test_strategy=test_strategy,
210305
skip_existing=skip_existing,
@@ -223,51 +318,17 @@ def run_rattler(command: str, parsed_args: argparse.Namespace, config: Config) -
223318
extra_context=extra_context,
224319
)
225320

226-
# iterate over all recipes
227-
for recipe_path in recipes:
228-
recipe = Stage0Recipe.from_file(Path(recipe_path))
229-
230-
variant_config = None
231-
for variant_file in config_files:
232-
variant_config = VariantConfig.from_file(variant_file)
233-
234-
# render the recipe
235-
rendered = recipe.render(variant_config, render_config)
236-
237-
if command == "render":
238-
import json
239-
240-
data = rendered[0].recipe.to_dict()
241-
print(json.dumps(data, indent=2, sort_keys=True))
242-
continue
243-
244-
# build all rendered variants
245-
for i, variant in enumerate(rendered, 1):
246-
print(
247-
f"\n🔨 Building variant {i}/{len(rendered)} "
248-
f"for recipe {recipe_path}"
249-
)
250-
251-
with RichProgressCallback(show_logs=show_logs) as progress_callback:
252-
result = variant.run_build(
253-
tool_config=tool_config,
254-
output_dir=output_dir,
255-
channels=channels,
256-
progress_callback=progress_callback,
257-
recipe_path=recipe_path,
258-
no_build_id=no_build_id,
259-
package_format=package_format,
260-
no_include_recipe=no_include_recipe,
261-
debug=debug,
262-
)
263-
results.append(result)
264-
265-
print("\n" + "=" * 60)
266-
print("Build Result:")
267-
print("=" * 60)
268-
print(f" Package: {result.name} {result.version}")
269-
print(f" Build string: {result.build_string}")
270-
print(f" Platform: {result.platform}")
271-
print(f" Build time: {result.build_time:.2f}s")
272-
273-
return 0
321+
return process_recipes(
322+
recipes=recipes,
323+
variant_config=variant_config,
324+
render_config=render_config,
325+
tool_config=tool_config,
326+
command=command,
327+
output_dir=output_dir,
328+
channels=channels,
329+
show_logs=show_logs,
330+
no_build_id=no_build_id,
331+
package_format=package_format,
332+
no_include_recipe=no_include_recipe,
333+
debug=debug,
334+
)

0 commit comments

Comments
 (0)