88import schema
99
1010from tsrc .config import parse_config
11- from tsrc .errors import Error , InvalidConfigError , LoadManifestSchemaError
11+ from tsrc .errors import (
12+ Error ,
13+ InvalidConfigError ,
14+ LoadManifestSchemaError ,
15+ LoadManifestSwitchConfigGroupsError ,
16+ )
1217from tsrc .file_system import Copy , FileSystemOperation , Link
1318from tsrc .groups import GroupList
1419from tsrc .manifest_common_data import ManifestsTypeOfData , mtod_can_ignore_remotes
1520from tsrc .repo import Remote , Repo
21+ from tsrc .switch import Switch
1622
1723
1824class RepoNotFound (Error ):
@@ -29,6 +35,7 @@ class Manifest:
2935 def __init__ (self ) -> None :
3036 self ._repos : List [Repo ] = []
3137 self .group_list : Optional [GroupList [str ]] = None
38+ self ._switch : Optional [Switch ] = None
3239
3340 def apply_config (
3441 self ,
@@ -53,6 +60,9 @@ def apply_config(
5360 ignore_on_mtod = ignore_on_mtod ,
5461 )
5562
63+ switch_config = config .get ("switch" )
64+ self ._handle_switch (switch_config )
65+
5666 def _handle_repo (self , repo_config : Any ) -> None :
5767 dest = repo_config ["dest" ]
5868 branch = orig_branch = repo_config .get ("branch" )
@@ -122,15 +132,33 @@ def _handle_groups(
122132 ignore_on_mtod = ignore_on_mtod ,
123133 )
124134
135+ def _handle_switch (self , switch_config : Any ) -> None :
136+ self ._switch = Switch (switch_config )
137+
138+ # verify if groups in switch>config>groups are present in 'groups'
139+ if self .group_list and self .group_list .groups and self ._switch ._groups :
140+ switch_groups = list (self ._switch ._groups )
141+ groups_groups = self .group_list .groups .keys ()
142+ if switch_groups and groups_groups :
143+ if set (switch_groups ) != set (groups_groups ).intersection (switch_groups ):
144+ raise LoadManifestSwitchConfigGroupsError ()
145+ elif self ._switch ._groups :
146+ # you cannot have 'swtich>config>groups' alone (without 'groups')
147+ raise LoadManifestSwitchConfigGroupsError ()
148+
125149 def get_repos (
126150 self ,
127151 groups : Optional [List [str ]] = None ,
152+ do_switch : bool = False ,
128153 all_ : bool = False ,
129154 ignore_if_group_not_found : bool = False ,
130155 ) -> List [Repo ]:
131156 if all_ :
132157 return self ._repos
133158
159+ if do_switch is True :
160+ return self ._get_repos_on_switch (groups )
161+
134162 if not groups :
135163 if self ._has_default_group ():
136164 return self ._get_repos_in_groups (["default" ])
@@ -143,6 +171,13 @@ def _has_default_group(self) -> bool:
143171 assert self .group_list
144172 return self .group_list .get_group ("default" ) is not None
145173
174+ def _get_repos_on_switch (self , groups : Optional [List [str ]]) -> List [Repo ]:
175+ if self ._switch :
176+ if self ._switch ._groups :
177+ matched_groups = list (self ._switch ._groups )
178+ return self ._get_repos_in_groups (matched_groups )
179+ return self ._repos # all repos
180+
146181 def _get_repos_in_groups (
147182 self ,
148183 groups : List [str ],
@@ -220,6 +255,21 @@ def validate_repo_no_remote_required(data: Any) -> None:
220255 )
221256
222257
258+ def validate_switch_config (data : Any ) -> None :
259+ switch_config_schema = schema .Schema (
260+ {
261+ schema .Optional ("groups" ): [str ],
262+ }
263+ )
264+ switch_config_schema .validate (data )
265+
266+
267+ def validate_switch (data : Any ) -> None :
268+ on_config_schema = schema .Use (validate_switch_config )
269+ switch_schema = schema .Schema ({schema .Optional ("config" ): on_config_schema })
270+ switch_schema .validate (data )
271+
272+
223273def load_manifest (manifest_path : Path ) -> Manifest :
224274 """Main entry point: return a manifest instance by parsing
225275 a `manifest.yml` file.
@@ -230,12 +280,14 @@ def load_manifest(manifest_path: Path) -> Manifest:
230280 group_schema = {"repos" : [str ], schema .Optional ("includes" ): [str ]}
231281 # Note: gitlab and github_enterprise_url keys are ignored,
232282 # and kept here only for backward compatibility reasons
283+ on_switch_schema = schema .Use (validate_switch )
233284 manifest_schema = schema .Schema (
234285 {
235286 "repos" : [repo_schema ],
236287 schema .Optional ("gitlab" ): remote_git_server_schema ,
237288 schema .Optional ("github_enterprise" ): remote_git_server_schema ,
238289 schema .Optional ("groups" ): {str : group_schema },
290+ schema .Optional ("switch" ): on_switch_schema ,
239291 }
240292 )
241293 parsed = parse_config (manifest_path , schema = manifest_schema )
@@ -262,12 +314,14 @@ def load_manifest_safe_mode(manifest_path: Path, mtod: ManifestsTypeOfData) -> M
262314 group_schema = {"repos" : [str ], schema .Optional ("includes" ): [str ]}
263315 # Note: gitlab and github_enterprise_url keys are ignored,
264316 # and kept here only for backward compatibility reasons
317+ on_switch_schema = schema .Use (validate_switch )
265318 manifest_schema = schema .Schema (
266319 {
267320 "repos" : [repo_schema ],
268321 schema .Optional ("gitlab" ): remote_git_server_schema ,
269322 schema .Optional ("github_enterprise" ): remote_git_server_schema ,
270323 schema .Optional ("groups" ): {str : group_schema },
324+ schema .Optional ("switch" ): on_switch_schema ,
271325 }
272326 )
273327 try :
0 commit comments