1111from  py_trees .display  import  unicode_tree 
1212from  py_trees .trees  import  BehaviourTree 
1313from  py_trees .visitors  import  SnapshotVisitor 
14- from  rich .pretty  import  pretty_repr 
1514from  rich .text  import  Text 
1615
1716from  ..config  import  Config 
5251logger  =  logging .getLogger (__name__ )
5352
5453
54+ class  TreeInspector :
55+     """Inspector for creating and inspecting behavior tree branches and PPAs.""" 
56+ 
57+     # List of available branch/PPA names 
58+     AVAILABLE_NAMES  =  [
59+         "workflow_success" ,
60+         "workflow_completion" ,
61+         "find_workflow" ,
62+         "trigger_workflow" ,
63+         "identify_target_ref" ,
64+         "download_artifacts" ,
65+         "extract_artifact_result" ,
66+         "workflow_complete_branch" ,
67+         "workflow_with_result_branch" ,
68+         "publish_workflow_branch" ,
69+         "build_workflow_branch" ,
70+         "demo_sequence" ,
71+         "demo_selector" ,
72+     ]
73+ 
74+     def  __init__ (self , release_tag : str ):
75+         """Initialize TreeInspector. 
76+ 
77+         Args: 
78+             release_tag: Release tag for creating mock ReleaseMeta 
79+         """ 
80+         self .release_tag  =  release_tag 
81+ 
82+     def  get_names (self ) ->  List [str ]:
83+         """Get list of available branch/PPA names. 
84+ 
85+         Returns: 
86+             List of available names that can be passed to create_by_name() 
87+         """ 
88+         return  self .AVAILABLE_NAMES .copy ()
89+ 
90+     def  create_by_name (self , name : str ) ->  Union [Selector , Sequence , Behaviour ]:
91+         """Create a branch or PPA by name. 
92+ 
93+         Args: 
94+             name: Name of the branch or PPA to create 
95+ 
96+         Returns: 
97+             The created behavior tree branch or PPA 
98+ 
99+         Raises: 
100+             ValueError: If the name is not found in the available branches 
101+         """ 
102+         if  name  not  in   self .AVAILABLE_NAMES :
103+             available  =  ", " .join (self .get_names ())
104+             raise  ValueError (f"Unknown name '{ name }  '. Available options: { available }  " )
105+ 
106+         # Create mock objects for PPA/branch creation 
107+         workflow  =  Workflow (workflow_file = "test.yml" , inputs = {})
108+         package_meta  =  PackageMeta (repo = "redis/redis" , ref = "main" )
109+         release_meta  =  ReleaseMeta (tag = self .release_tag )
110+         github_client  =  GitHubClientAsync (token = "dummy" )
111+         package  =  Package (
112+             meta = package_meta ,
113+             build = workflow ,
114+             publish = Workflow (workflow_file = "publish.yml" , inputs = {}),
115+         )
116+         log_prefix  =  "test" 
117+ 
118+         # Create and return the requested branch/PPA 
119+         if  name  ==  "workflow_success" :
120+             return  create_workflow_success_ppa (workflow , log_prefix )
121+         elif  name  ==  "workflow_completion" :
122+             return  create_workflow_completion_ppa (
123+                 workflow , package_meta , github_client , log_prefix 
124+             )
125+         elif  name  ==  "find_workflow" :
126+             return  create_find_workflow_by_uuid_ppa (
127+                 workflow , package_meta , github_client , log_prefix 
128+             )
129+         elif  name  ==  "trigger_workflow" :
130+             return  create_trigger_workflow_ppa (
131+                 workflow , package_meta , release_meta , github_client , log_prefix 
132+             )
133+         elif  name  ==  "identify_target_ref" :
134+             return  create_identify_target_ref_ppa (
135+                 package_meta , release_meta , github_client , log_prefix 
136+             )
137+         elif  name  ==  "download_artifacts" :
138+             return  create_download_artifacts_ppa (
139+                 workflow , package_meta , github_client , log_prefix 
140+             )
141+         elif  name  ==  "extract_artifact_result" :
142+             return  create_extract_artifact_result_ppa (
143+                 "test-artifact" , workflow , package_meta , github_client , log_prefix 
144+             )
145+         elif  name  ==  "workflow_complete_branch" :
146+             return  create_workflow_complete_tree_branch (
147+                 workflow , package_meta , release_meta , github_client , "" 
148+             )
149+         elif  name  ==  "workflow_with_result_branch" :
150+             return  create_workflow_with_result_tree_branch (
151+                 "artifact" , workflow , package_meta , release_meta , github_client , "" 
152+             )
153+         elif  name  ==  "publish_workflow_branch" :
154+             return  create_publish_workflow_tree_branch (
155+                 workflow ,
156+                 workflow ,
157+                 package_meta ,
158+                 release_meta ,
159+                 workflow ,
160+                 github_client ,
161+                 "" ,
162+             )
163+         elif  name  ==  "build_workflow_branch" :
164+             return  create_build_workflow_tree_branch (
165+                 package , release_meta , package , github_client , "" 
166+             )
167+         elif  name  ==  "demo_sequence" :
168+             return  create_sequence_branch ()
169+         else :  # name == "demo_selector" 
170+             return  create_selector_branch ()
171+ 
172+ 
55173async  def  async_tick_tock (tree : BehaviourTree , cutoff : int  =  100 ) ->  None :
56174    """Drive Behaviour tree using async event loop 
57175
@@ -98,6 +216,7 @@ def initialize_tree_and_state(
98216    config : Config ,
99217    args : ReleaseArgs ,
100218    storage : Optional [StateStorage ] =  None ,
219+     read_only : bool  =  False ,
101220) ->  Iterator [Tuple [BehaviourTree , StateSyncer ]]:
102221    github_client  =  GitHubClientAsync (token = os .getenv ("GITHUB_TOKEN" ))
103222
@@ -109,9 +228,13 @@ def initialize_tree_and_state(
109228        storage = storage ,
110229        config = config ,
111230        args = args ,
231+         read_only = read_only ,
112232    ) as  state_syncer :
113233        root  =  create_root_node (
114-             state_syncer .state , state_syncer .default_state (), github_client 
234+             state_syncer .state ,
235+             state_syncer .default_state (),
236+             github_client ,
237+             args .only_packages ,
115238        )
116239        tree  =  BehaviourTree (root )
117240
@@ -149,14 +272,20 @@ def log_tree_state_with_markup(tree: BehaviourTree) -> None:
149272
150273
151274def  create_root_node (
152-     state : ReleaseState , default_state : ReleaseState , github_client : GitHubClientAsync 
275+     state : ReleaseState ,
276+     default_state : ReleaseState ,
277+     github_client : GitHubClientAsync ,
278+     only_packages : Optional [List [str ]] =  None ,
153279) ->  Behaviour :
154280
155281    root  =  ParallelBarrier (
156282        "Redis Release" ,
157283        children = [],
158284    )
159285    for  package_name , package  in  state .packages .items ():
286+         if  only_packages  and  package_name  not  in   only_packages :
287+             logger .info (f"Skipping package { package_name }   as it's not in only_packages" )
288+             continue 
160289        root .add_child (
161290            create_package_release_tree_branch (
162291                package ,
0 commit comments