@@ -413,6 +413,43 @@ def __getattr__(self, attr):
413
413
return getattr (self .parser , attr )
414
414
415
415
416
+ class GroupReference :
417
+ """
418
+ Simple class to hold tools command group names comparable to how
419
+ they would be invoked using the CLI.
420
+
421
+ For example, tools vm create is stored as ("tools", "vm", "create")
422
+ """
423
+
424
+ _instance : GroupReference | None = None
425
+ _commands : list [str ]
426
+
427
+ def __new__ (cls ):
428
+ """
429
+ Method that instantiates a singleton class and returns it.
430
+ """
431
+ if cls ._instance is None :
432
+ instance = super ().__new__ (cls )
433
+ instance ._commands = {}
434
+ cls ._instance = instance
435
+ return cls ._instance
436
+
437
+ @classmethod
438
+ def add_command (cls , cli_name : tuple [str ], group : CommandGroup ) -> None :
439
+ """
440
+ Add a tools command.
441
+ """
442
+ instance = cls ()
443
+ if cli_name not in instance ._commands :
444
+ instance ._commands [cli_name ] = group
445
+
446
+ def __getitem__ (self , item ):
447
+ """
448
+ Propogate getting a command parser to the underlying dict.
449
+ """
450
+ return self ._commands [item ]
451
+
452
+
416
453
class CommandGroup :
417
454
"""
418
455
Command group which holds the available tool functions.
@@ -424,6 +461,16 @@ def __init__(self, name, help, description=None, parent=None, venv_config=None):
424
461
description = help
425
462
if parent is None :
426
463
parent = Parser ()
464
+ GroupReference .add_command ((name ,), self )
465
+ # We can also pass a string or list of strings that specify the parent commands.
466
+ # This should help avoid circular imports
467
+ if isinstance (parent , str ):
468
+ parent = [parent ]
469
+ if isinstance (parent , list ):
470
+ # NOTE: This means ordering of imports is important, but better than risking circular imports
471
+ GroupReference .add_command (tuple (parent + [name ]), self )
472
+ parent = GroupReference ()[tuple (parent )]
473
+
427
474
self .venv_config = venv_config or {}
428
475
self .parser = parent .subparsers .add_parser (
429
476
name .replace ("_" , "-" ),
0 commit comments