esgvoc 1.1.1__py3-none-any.whl → 1.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of esgvoc might be problematic. Click here for more details.

esgvoc/cli/clean.py ADDED
@@ -0,0 +1,304 @@
1
+ """
2
+ Clean command for managing local repositories and databases.
3
+
4
+ This module provides CLI commands for cleaning up local data,
5
+ including repositories and databases. Useful for resetting state
6
+ or switching between offline/online modes.
7
+ """
8
+
9
+ import typer
10
+ import shutil
11
+ from pathlib import Path
12
+ from rich.console import Console
13
+ from rich.prompt import Confirm
14
+ from typing import Optional, List
15
+
16
+ from esgvoc.core.service import config_manager
17
+
18
+
19
+ app = typer.Typer()
20
+ console = Console()
21
+
22
+
23
+ def _clean_repositories(settings, config_name: Optional[str] = None):
24
+ """Clean all local repositories for the given settings."""
25
+ cleaned_repos = []
26
+
27
+ # Clean universe repository
28
+ universe_path = settings.universe.get_absolute_local_path()
29
+ if universe_path and Path(universe_path).exists():
30
+ shutil.rmtree(universe_path)
31
+ cleaned_repos.append(f"Universe repository: {universe_path}")
32
+
33
+ # Clean project repositories
34
+ for project_name, project in settings.projects.items():
35
+ project_path = project.get_absolute_local_path()
36
+ if project_path and Path(project_path).exists():
37
+ shutil.rmtree(project_path)
38
+ cleaned_repos.append(f"Project '{project_name}' repository: {project_path}")
39
+
40
+ return cleaned_repos
41
+
42
+
43
+ def _clean_databases(settings, config_name: Optional[str] = None):
44
+ """Clean all local databases for the given settings."""
45
+ cleaned_dbs = []
46
+
47
+ # Clean universe database
48
+ universe_db_path = settings.universe.get_absolute_db_path()
49
+ if universe_db_path and Path(universe_db_path).exists():
50
+ Path(universe_db_path).unlink()
51
+ cleaned_dbs.append(f"Universe database: {universe_db_path}")
52
+
53
+ # Clean project databases
54
+ for project_name, project in settings.projects.items():
55
+ project_db_path = project.get_absolute_db_path()
56
+ if project_db_path and Path(project_db_path).exists():
57
+ Path(project_db_path).unlink()
58
+ cleaned_dbs.append(f"Project '{project_name}' database: {project_db_path}")
59
+
60
+ return cleaned_dbs
61
+
62
+
63
+ @app.command()
64
+ def repos(
65
+ config: Optional[str] = typer.Option(
66
+ None,
67
+ "--config",
68
+ "-c",
69
+ help="Configuration name to use. Uses active configuration if not specified."
70
+ ),
71
+ force: bool = typer.Option(
72
+ False,
73
+ "--force",
74
+ "-f",
75
+ help="Skip confirmation prompt"
76
+ )
77
+ ):
78
+ """Clean all local repositories."""
79
+ try:
80
+ if config:
81
+ settings = config_manager.get_config(config)
82
+ config_display = f"configuration '{config}'"
83
+ else:
84
+ settings = config_manager.get_active_config()
85
+ config_display = f"active configuration"
86
+
87
+ # Ask for confirmation unless --force is used
88
+ if not force:
89
+ console.print(f"[yellow]This will delete all local repositories for {config_display}.[/yellow]")
90
+ console.print("[yellow]Any local changes will be lost.[/yellow]")
91
+ if not Confirm.ask("Are you sure you want to continue?"):
92
+ console.print("[blue]Operation cancelled.[/blue]")
93
+ return
94
+
95
+ # Clean repositories
96
+ cleaned_repos = _clean_repositories(settings, config)
97
+
98
+ if cleaned_repos:
99
+ console.print(f"[green]✓ Cleaned {len(cleaned_repos)} repositories:[/green]")
100
+ for repo in cleaned_repos:
101
+ console.print(f" - {repo}")
102
+ else:
103
+ console.print("[yellow]No repositories found to clean.[/yellow]")
104
+
105
+ except Exception as e:
106
+ console.print(f"[red]Error: {str(e)}[/red]")
107
+ raise typer.Exit(1)
108
+
109
+
110
+ @app.command()
111
+ def dbs(
112
+ config: Optional[str] = typer.Option(
113
+ None,
114
+ "--config",
115
+ "-c",
116
+ help="Configuration name to use. Uses active configuration if not specified."
117
+ ),
118
+ force: bool = typer.Option(
119
+ False,
120
+ "--force",
121
+ "-f",
122
+ help="Skip confirmation prompt"
123
+ )
124
+ ):
125
+ """Clean all local databases."""
126
+ try:
127
+ if config:
128
+ settings = config_manager.get_config(config)
129
+ config_display = f"configuration '{config}'"
130
+ else:
131
+ settings = config_manager.get_active_config()
132
+ config_display = f"active configuration"
133
+
134
+ # Ask for confirmation unless --force is used
135
+ if not force:
136
+ console.print(f"[yellow]This will delete all local databases for {config_display}.[/yellow]")
137
+ console.print("[yellow]All cached data will be lost.[/yellow]")
138
+ if not Confirm.ask("Are you sure you want to continue?"):
139
+ console.print("[blue]Operation cancelled.[/blue]")
140
+ return
141
+
142
+ # Clean databases
143
+ cleaned_dbs = _clean_databases(settings, config)
144
+
145
+ if cleaned_dbs:
146
+ console.print(f"[green]✓ Cleaned {len(cleaned_dbs)} databases:[/green]")
147
+ for db in cleaned_dbs:
148
+ console.print(f" - {db}")
149
+ else:
150
+ console.print("[yellow]No databases found to clean.[/yellow]")
151
+
152
+ except Exception as e:
153
+ console.print(f"[red]Error: {str(e)}[/red]")
154
+ raise typer.Exit(1)
155
+
156
+
157
+ @app.command()
158
+ def all(
159
+ config: Optional[str] = typer.Option(
160
+ None,
161
+ "--config",
162
+ "-c",
163
+ help="Configuration name to use. Uses active configuration if not specified."
164
+ ),
165
+ force: bool = typer.Option(
166
+ False,
167
+ "--force",
168
+ "-f",
169
+ help="Skip confirmation prompt"
170
+ )
171
+ ):
172
+ """Clean all local repositories and databases."""
173
+ try:
174
+ if config:
175
+ settings = config_manager.get_config(config)
176
+ config_display = f"configuration '{config}'"
177
+ else:
178
+ settings = config_manager.get_active_config()
179
+ config_display = f"active configuration"
180
+
181
+ # Ask for confirmation unless --force is used
182
+ if not force:
183
+ console.print(f"[yellow]This will delete all local repositories and databases for {config_display}.[/yellow]")
184
+ console.print("[yellow]Any local changes and cached data will be lost.[/yellow]")
185
+ if not Confirm.ask("Are you sure you want to continue?"):
186
+ console.print("[blue]Operation cancelled.[/blue]")
187
+ return
188
+
189
+ # Clean both repositories and databases
190
+ cleaned_repos = _clean_repositories(settings, config)
191
+ cleaned_dbs = _clean_databases(settings, config)
192
+
193
+ total_cleaned = len(cleaned_repos) + len(cleaned_dbs)
194
+
195
+ if total_cleaned > 0:
196
+ console.print(f"[green]✓ Cleaned {total_cleaned} items:[/green]")
197
+
198
+ if cleaned_repos:
199
+ console.print(f"[green] Repositories ({len(cleaned_repos)}):[/green]")
200
+ for repo in cleaned_repos:
201
+ console.print(f" - {repo}")
202
+
203
+ if cleaned_dbs:
204
+ console.print(f"[green] Databases ({len(cleaned_dbs)}):[/green]")
205
+ for db in cleaned_dbs:
206
+ console.print(f" - {db}")
207
+ else:
208
+ console.print("[yellow]No repositories or databases found to clean.[/yellow]")
209
+
210
+ except Exception as e:
211
+ console.print(f"[red]Error: {str(e)}[/red]")
212
+ raise typer.Exit(1)
213
+
214
+
215
+ @app.command()
216
+ def component(
217
+ component_name: str = typer.Argument(
218
+ ...,
219
+ help="Component to clean (universe or project name)"
220
+ ),
221
+ what: str = typer.Option(
222
+ "all",
223
+ "--what",
224
+ "-w",
225
+ help="What to clean: 'repos', 'dbs', or 'all' (default)"
226
+ ),
227
+ config: Optional[str] = typer.Option(
228
+ None,
229
+ "--config",
230
+ "-c",
231
+ help="Configuration name to use. Uses active configuration if not specified."
232
+ ),
233
+ force: bool = typer.Option(
234
+ False,
235
+ "--force",
236
+ "-f",
237
+ help="Skip confirmation prompt"
238
+ )
239
+ ):
240
+ """Clean repositories and/or databases for a specific component."""
241
+ if what not in ["repos", "dbs", "all"]:
242
+ console.print(f"[red]Invalid value for --what: {what}. Must be 'repos', 'dbs', or 'all'[/red]")
243
+ raise typer.Exit(1)
244
+
245
+ try:
246
+ if config:
247
+ settings = config_manager.get_config(config)
248
+ config_display = f"configuration '{config}'"
249
+ else:
250
+ settings = config_manager.get_active_config()
251
+ config_display = f"active configuration"
252
+
253
+ # Validate component exists
254
+ if component_name == "universe":
255
+ component = settings.universe
256
+ elif component_name in settings.projects:
257
+ component = settings.projects[component_name]
258
+ else:
259
+ console.print(f"[red]Component '{component_name}' not found in {config_display}[/red]")
260
+ raise typer.Exit(1)
261
+
262
+ # Ask for confirmation unless --force is used
263
+ if not force:
264
+ what_desc = {"repos": "repositories", "dbs": "databases", "all": "repositories and databases"}[what]
265
+ console.print(f"[yellow]This will delete {what_desc} for component '{component_name}' in {config_display}.[/yellow]")
266
+ if what in ["repos", "all"]:
267
+ console.print("[yellow]Any local changes will be lost.[/yellow]")
268
+ if what in ["dbs", "all"]:
269
+ console.print("[yellow]Any cached data will be lost.[/yellow]")
270
+ if not Confirm.ask("Are you sure you want to continue?"):
271
+ console.print("[blue]Operation cancelled.[/blue]")
272
+ return
273
+
274
+ cleaned_items = []
275
+
276
+ # Clean repository if requested
277
+ if what in ["repos", "all"]:
278
+ component_path = component.get_absolute_local_path()
279
+ if component_path and Path(component_path).exists():
280
+ shutil.rmtree(component_path)
281
+ cleaned_items.append(f"Repository: {component_path}")
282
+
283
+ # Clean database if requested
284
+ if what in ["dbs", "all"]:
285
+ component_db_path = component.get_absolute_db_path()
286
+ if component_db_path and Path(component_db_path).exists():
287
+ Path(component_db_path).unlink()
288
+ cleaned_items.append(f"Database: {component_db_path}")
289
+
290
+ if cleaned_items:
291
+ console.print(f"[green]✓ Cleaned {len(cleaned_items)} items for component '{component_name}':[/green]")
292
+ for item in cleaned_items:
293
+ console.print(f" - {item}")
294
+ else:
295
+ what_desc = {"repos": "repositories", "dbs": "databases", "all": "repositories or databases"}[what]
296
+ console.print(f"[yellow]No {what_desc} found to clean for component '{component_name}'.[/yellow]")
297
+
298
+ except Exception as e:
299
+ console.print(f"[red]Error: {str(e)}[/red]")
300
+ raise typer.Exit(1)
301
+
302
+
303
+ if __name__ == "__main__":
304
+ app()