5252 metavar = "target" ,
5353 nargs = "*" ,
5454 action = commandline .StoreTarget ,
55+ use_sets = "sets" ,
5556 help = "extended atom matching of packages" ,
5657)
5758bugs .add_argument (
@@ -285,6 +286,16 @@ def find_best_match(self, restrict, pkgset: list[package]) -> package:
285286 return match
286287 return matches [0 ]
287288
289+ def extend_targets_stable_groups (self , groups ):
290+ stabilization_groups = self .options .repo .stabilization_groups
291+ search_repo = self .options .search_repo
292+ for group in groups :
293+ for pkg in stabilization_groups [group ]:
294+ try :
295+ yield None , self .find_best_match ([pkg ], search_repo .match (pkg )).versioned_atom
296+ except (ValueError , IndexError ):
297+ self .err .write (f"Unable to find match for { pkg .unversioned_atom } " )
298+
288299 def _find_dependencies (self , pkg : package , keywords : set [str ]):
289300 check = visibility .VisibilityCheck (self .options , profile_addon = self .profile_addon )
290301
@@ -325,7 +336,11 @@ def build_full_graph(self, targets: list[package]):
325336 vertices [pkg ].pkgs [0 ][1 ].update (keywords )
326337 continue
327338
339+ pkg_has_stable = any (x [0 ] not in "-~" for x in pkg .keywords )
328340 keywords .update (_get_suggested_keywords (self .options .repo , pkg ))
341+ if pkg_has_stable and not keywords : # package already done
342+ self .out .write (f"Nothing to stable for { pkg .unversioned_atom } " )
343+ continue
329344 assert (
330345 keywords
331346 ), f"no keywords for { pkg .versioned_atom } , currently unsupported by tool: https://github.com/pkgcore/pkgdev/issues/123"
@@ -342,7 +357,9 @@ def build_full_graph(self, targets: list[package]):
342357
343358 for src , dst in edges :
344359 vertices [src ].edges .add (vertices [dst ])
345- self .starting_nodes = {vertices [starting_node ] for starting_node in targets }
360+ self .starting_nodes = {
361+ vertices [starting_node ] for starting_node in targets if starting_node in vertices
362+ }
346363
347364 def output_dot (self , dot_file ):
348365 with open (dot_file , "w" ) as dot :
@@ -415,8 +432,8 @@ def merge_new_keywords_children(self):
415432 existing_keywords = frozenset ().union (
416433 * (
417434 pkgver .keywords
418- for pkg in node .pkgs
419- for pkgver in repo .match (pkg [ 0 ] .unversioned_atom )
435+ for pkg , _ in node .pkgs
436+ for pkgver in repo .match (pkg .unversioned_atom )
420437 )
421438 )
422439 if existing_keywords & frozenset ().union (* (pkg [1 ] for pkg in node .pkgs )):
@@ -427,6 +444,16 @@ def merge_new_keywords_children(self):
427444 found_someone = True
428445 break
429446
447+ def merge_stabilization_groups (self ):
448+ for group , pkgs in self .options .repo .stabilization_groups .items ():
449+ restrict = packages .OrRestriction (* pkgs )
450+ mergable = tuple (
451+ node for node in self .nodes if any (restrict .match (pkg ) for pkg , _ in node .pkgs )
452+ )
453+ if mergable :
454+ self .out .write (f"Merging @{ group } group nodes: { mergable } " )
455+ self .merge_nodes (mergable )
456+
430457 def scan_existing_bugs (self , api_key : str ):
431458 params = urlencode (
432459 {
@@ -504,12 +531,16 @@ def _parse_targets(search_repo, targets):
504531@bugs .bind_main_func
505532def main (options , out : Formatter , err : Formatter ):
506533 search_repo = options .search_repo
507- options .targets = options .targets or list (_load_from_stdin (out , err ))
508- targets = list (_parse_targets (search_repo , options .targets ))
534+ options .targets = options .targets or []
509535 d = DependencyGraph (out , err , options )
536+ options .targets .extend (d .extend_targets_stable_groups (options .sets or ()))
537+ if not options .targets :
538+ options .targets = list (_load_from_stdin (out , err ))
539+ targets = list (_parse_targets (search_repo , options .targets ))
510540 d .build_full_graph (targets )
511541 d .merge_cycles ()
512542 d .merge_new_keywords_children ()
543+ d .merge_stabilization_groups ()
513544
514545 for node in d .nodes :
515546 node .cleanup_keywords (search_repo )
@@ -518,6 +549,10 @@ def main(options, out: Formatter, err: Formatter):
518549 with contextlib .suppress (Exception ):
519550 options .api_key = (Path .home () / ".bugz_token" ).read_text ().strip () or None
520551
552+ if not d .nodes :
553+ out .write (out .fg ("red" ), "Nothing to do, exiting" , out .reset )
554+ return 1
555+
521556 if userquery ("Check for open bugs matching current graph?" , out , err , default_answer = False ):
522557 d .scan_existing_bugs (options .api_key )
523558
0 commit comments