@@ -234,17 +234,30 @@ def _clean_req_nones(reqs):
234
234
235
235
def populate_feedstock_attributes (
236
236
name : str ,
237
- sub_graph : typing .MutableMapping ,
237
+ existing_node_attrs : typing .MutableMapping [ str , typing . Any ] ,
238
238
meta_yaml : str | None = None ,
239
239
recipe_yaml : str | None = None ,
240
240
conda_forge_yaml : str | None = None ,
241
241
mark_not_archived : bool = False ,
242
242
feedstock_dir : str | Path | None = None ,
243
- ) -> typing .MutableMapping :
244
- """Parse the various configuration information into something usable"""
243
+ ) -> dict [str , typing .Any ]:
244
+ """
245
+ Parse the various configuration information into the node_attrs of a feedstock.
246
+
247
+ :param name: The name of the feedstock
248
+ :param existing_node_attrs: The existing node_attrs of the feedstock. Pass an empty dict if none.
249
+ :param meta_yaml: The meta.yaml file as a string
250
+ :param recipe_yaml: The recipe.yaml file as a string
251
+ :param conda_forge_yaml: The conda-forge.yaml file as a string
252
+ :param mark_not_archived: If True, forcibly mark the feedstock as not archived in the node attrs, even if it is archived.
253
+ :param feedstock_dir: The directory where the feedstock is located. If None, some information will not be available.
245
254
255
+ :return: A dictionary with the new node_attrs of the feedstock, with only some fields populated.
256
+ """
246
257
from conda_forge_tick .chaindb import ChainDB , _convert_to_dict
247
258
259
+ node_attrs = {key : value for key , value in existing_node_attrs .items ()}
260
+
248
261
if isinstance (feedstock_dir , str ):
249
262
feedstock_dir = Path (feedstock_dir )
250
263
@@ -253,35 +266,37 @@ def populate_feedstock_attributes(
253
266
):
254
267
raise ValueError ("Either `meta_yaml` or `recipe_yaml` needs to be given." )
255
268
256
- sub_graph .update ({"feedstock_name" : name , "parsing_error" : False , "branch" : "main" })
269
+ node_attrs .update (
270
+ {"feedstock_name" : name , "parsing_error" : False , "branch" : "main" }
271
+ )
257
272
258
273
if mark_not_archived :
259
- sub_graph .update ({"archived" : False })
274
+ node_attrs .update ({"archived" : False })
260
275
261
276
# strip out old keys - this removes old platforms when one gets disabled
262
- for key in list (sub_graph .keys ()):
277
+ for key in list (node_attrs .keys ()):
263
278
if key .endswith ("meta_yaml" ) or key .endswith ("requirements" ) or key == "req" :
264
- del sub_graph [key ]
279
+ del node_attrs [key ]
265
280
266
281
if isinstance (meta_yaml , str ):
267
- sub_graph ["raw_meta_yaml" ] = meta_yaml
282
+ node_attrs ["raw_meta_yaml" ] = meta_yaml
268
283
elif isinstance (recipe_yaml , str ):
269
- sub_graph ["raw_meta_yaml" ] = recipe_yaml
284
+ node_attrs ["raw_meta_yaml" ] = recipe_yaml
270
285
271
286
# Get the conda-forge.yml
272
287
if isinstance (conda_forge_yaml , str ):
273
288
try :
274
- sub_graph ["conda-forge.yml" ] = {
289
+ node_attrs ["conda-forge.yml" ] = {
275
290
k : v for k , v in yaml .safe_load (conda_forge_yaml ).items ()
276
291
}
277
292
except Exception as e :
278
293
import traceback
279
294
280
295
trb = traceback .format_exc ()
281
- sub_graph ["parsing_error" ] = sanitize_string (
296
+ node_attrs ["parsing_error" ] = sanitize_string (
282
297
f"feedstock parsing error: cannot load conda-forge.yml: { e } \n { trb } "
283
298
)
284
- return sub_graph
299
+ return node_attrs
285
300
286
301
if feedstock_dir is not None :
287
302
logger .debug (
@@ -385,7 +400,7 @@ def populate_feedstock_attributes(
385
400
else :
386
401
logger .debug ("doing generic parsing" )
387
402
plat_archs = [("win" , "64" ), ("osx" , "64" ), ("linux" , "64" )]
388
- for k in set (sub_graph ["conda-forge.yml" ].get ("provider" , {})):
403
+ for k in set (node_attrs ["conda-forge.yml" ].get ("provider" , {})):
389
404
if "_" in k :
390
405
plat_archs .append (tuple (k .split ("_" )))
391
406
if isinstance (meta_yaml , str ):
@@ -401,46 +416,46 @@ def populate_feedstock_attributes(
401
416
import traceback
402
417
403
418
trb = traceback .format_exc ()
404
- sub_graph ["parsing_error" ] = sanitize_string (
419
+ node_attrs ["parsing_error" ] = sanitize_string (
405
420
f"feedstock parsing error: cannot rendering recipe: { e } \n { trb } "
406
421
)
407
422
raise
408
423
409
424
logger .debug ("platforms: %s" , plat_archs )
410
- sub_graph ["platforms" ] = ["_" .join (k ) for k in plat_archs ]
425
+ node_attrs ["platforms" ] = ["_" .join (k ) for k in plat_archs ]
411
426
412
427
# this makes certain that we have consistent ordering
413
428
sorted_variant_yamls = [x for _ , x in sorted (zip (plat_archs , variant_yamls ))]
414
429
yaml_dict = ChainDB (* sorted_variant_yamls )
415
430
if not yaml_dict :
416
431
logger .error (f"Something odd happened when parsing recipe { name } " )
417
- sub_graph ["parsing_error" ] = (
432
+ node_attrs ["parsing_error" ] = (
418
433
"feedstock parsing error: could not combine metadata dicts across platforms"
419
434
)
420
- return sub_graph
435
+ return node_attrs
421
436
422
- sub_graph ["meta_yaml" ] = _dedupe_meta_yaml (_convert_to_dict (yaml_dict ))
423
- meta_yaml = sub_graph ["meta_yaml" ]
437
+ node_attrs ["meta_yaml" ] = _dedupe_meta_yaml (_convert_to_dict (yaml_dict ))
438
+ meta_yaml = node_attrs ["meta_yaml" ]
424
439
425
440
# remove all plat-arch specific keys to remove old ones if a combination is disabled
426
- for k in list (sub_graph .keys ()):
441
+ for k in list (node_attrs .keys ()):
427
442
if k in ["raw_meta_yaml" , "total_requirements" ]:
428
443
continue
429
444
if k .endswith ("_meta_yaml" ) or k .endswith ("_requirements" ):
430
- sub_graph .pop (k )
445
+ node_attrs .pop (k )
431
446
432
447
for k , v in zip (plat_archs , variant_yamls ):
433
448
plat_arch_name = "_" .join (k )
434
- sub_graph [f"{ plat_arch_name } _meta_yaml" ] = v
435
- _ , sub_graph [f"{ plat_arch_name } _requirements" ], _ = _extract_requirements (
449
+ node_attrs [f"{ plat_arch_name } _meta_yaml" ] = v
450
+ _ , node_attrs [f"{ plat_arch_name } _requirements" ], _ = _extract_requirements (
436
451
v ,
437
452
outputs_to_keep = BOOTSTRAP_MAPPINGS .get (name , None ),
438
453
)
439
454
440
455
(
441
- sub_graph ["total_requirements" ],
442
- sub_graph ["requirements" ],
443
- sub_graph ["strong_exports" ],
456
+ node_attrs ["total_requirements" ],
457
+ node_attrs ["requirements" ],
458
+ node_attrs ["strong_exports" ],
444
459
) = _extract_requirements (
445
460
meta_yaml ,
446
461
outputs_to_keep = BOOTSTRAP_MAPPINGS .get (name , None ),
@@ -455,56 +470,56 @@ def populate_feedstock_attributes(
455
470
),
456
471
)
457
472
# handle implicit meta packages
458
- if "run" in sub_graph .get ("meta_yaml" , {}).get ("requirements" , {}):
473
+ if "run" in node_attrs .get ("meta_yaml" , {}).get ("requirements" , {}):
459
474
outputs_names .add (meta_yaml ["package" ]["name" ])
460
475
# add in single package name
461
476
else :
462
477
outputs_names = {meta_yaml ["package" ]["name" ]}
463
- sub_graph ["outputs_names" ] = outputs_names
478
+ node_attrs ["outputs_names" ] = outputs_names
464
479
465
480
# TODO: Write schema for dict
466
481
# TODO: remove this
467
482
req = _get_requirements (
468
483
yaml_dict ,
469
484
outputs_to_keep = BOOTSTRAP_MAPPINGS .get (name , []),
470
485
)
471
- sub_graph ["req" ] = req
486
+ node_attrs ["req" ] = req
472
487
473
488
# set name and version
474
489
keys = [("package" , "name" ), ("package" , "version" )]
475
490
missing_keys = [k [1 ] for k in keys if k [1 ] not in yaml_dict .get (k [0 ], {})]
476
491
for k in keys :
477
492
if k [1 ] not in missing_keys :
478
- sub_graph [k [1 ]] = yaml_dict [k [0 ]][k [1 ]]
493
+ node_attrs [k [1 ]] = yaml_dict [k [0 ]][k [1 ]]
479
494
480
495
# sometimes a version is not given at the top level, so we check outputs
481
496
# we do not know which version to take, but hopefully they are all the same
482
497
if (
483
- "version" not in sub_graph
498
+ "version" not in node_attrs
484
499
and "outputs" in yaml_dict
485
500
and len (yaml_dict ["outputs" ]) > 0
486
501
and "version" in yaml_dict ["outputs" ][0 ]
487
502
):
488
- sub_graph ["version" ] = yaml_dict ["outputs" ][0 ]["version" ]
503
+ node_attrs ["version" ] = yaml_dict ["outputs" ][0 ]["version" ]
489
504
490
505
# set the url and hash
491
- sub_graph .pop ("url" , None )
492
- sub_graph .pop ("hash_type" , None )
506
+ node_attrs .pop ("url" , None )
507
+ node_attrs .pop ("hash_type" , None )
493
508
494
509
source = yaml_dict .get ("source" , [])
495
510
if isinstance (source , collections .abc .Mapping ):
496
511
source = [source ]
497
512
source_keys : Set [str ] = set ()
498
513
for s in source :
499
- if not sub_graph .get ("url" ):
500
- sub_graph ["url" ] = s .get ("url" )
514
+ if not node_attrs .get ("url" ):
515
+ node_attrs ["url" ] = s .get ("url" )
501
516
source_keys |= s .keys ()
502
517
503
518
kl = list (sorted (source_keys & hashlib .algorithms_available , reverse = True ))
504
519
if kl :
505
- sub_graph ["hash_type" ] = kl [0 ]
520
+ node_attrs ["hash_type" ] = kl [0 ]
506
521
507
- return sub_graph
522
+ return node_attrs
508
523
509
524
510
525
def load_feedstock_local (
@@ -514,7 +529,7 @@ def load_feedstock_local(
514
529
recipe_yaml : str | None = None ,
515
530
conda_forge_yaml : str | None = None ,
516
531
mark_not_archived : bool = False ,
517
- ):
532
+ ) -> dict [ str , typing . Any ] :
518
533
"""Load a feedstock into subgraph based on its name. If meta_yaml and/or
519
534
conda_forge_yaml are not provided, they will be fetched from the feedstock.
520
535
@@ -538,6 +553,7 @@ def load_feedstock_local(
538
553
sub_graph : MutableMapping
539
554
The sub_graph, now updated with the feedstock metadata
540
555
"""
556
+ new_sub_graph = {key : value for key , value in sub_graph .items ()}
541
557
542
558
if meta_yaml is not None and recipe_yaml is not None :
543
559
raise ValueError ("Only either `meta_yaml` or `recipe_yaml` can be overridden." )
@@ -552,17 +568,17 @@ def load_feedstock_local(
552
568
# if nothing is overridden and no file is present, error out
553
569
if meta_yaml is None and recipe_yaml is None :
554
570
if isinstance (feedstock_dir , Response ):
555
- sub_graph .update (
571
+ new_sub_graph .update (
556
572
{"feedstock_name" : name , "parsing_error" : False , "branch" : "main" }
557
573
)
558
574
559
575
if mark_not_archived :
560
- sub_graph .update ({"archived" : False })
576
+ new_sub_graph .update ({"archived" : False })
561
577
562
- sub_graph ["parsing_error" ] = sanitize_string (
578
+ new_sub_graph ["parsing_error" ] = sanitize_string (
563
579
f"make_graph: { feedstock_dir .status_code } "
564
580
)
565
- return sub_graph
581
+ return new_sub_graph
566
582
567
583
meta_yaml_path = Path (feedstock_dir ).joinpath ("recipe" , "meta.yaml" )
568
584
recipe_yaml_path = Path (feedstock_dir ).joinpath ("recipe" , "recipe.yaml" )
@@ -580,18 +596,16 @@ def load_feedstock_local(
580
596
if conda_forge_yaml_path .exists ():
581
597
conda_forge_yaml = conda_forge_yaml_path .read_text ()
582
598
583
- populate_feedstock_attributes (
599
+ return populate_feedstock_attributes (
584
600
name ,
585
- sub_graph ,
601
+ new_sub_graph ,
586
602
meta_yaml = meta_yaml ,
587
603
recipe_yaml = recipe_yaml ,
588
604
conda_forge_yaml = conda_forge_yaml ,
589
605
mark_not_archived = mark_not_archived ,
590
606
feedstock_dir = feedstock_dir ,
591
607
)
592
608
593
- return sub_graph
594
-
595
609
596
610
def load_feedstock_containerized (
597
611
name : str ,
0 commit comments