git_same/commands/
workspace.rs1use crate::cli::{WorkspaceArgs, WorkspaceCommand};
4use crate::config::{Config, WorkspaceManager};
5use crate::errors::Result;
6use crate::output::Output;
7
8pub fn run(args: &WorkspaceArgs, config: &Config, output: &Output) -> Result<()> {
10 match &args.command {
11 WorkspaceCommand::List => list(config, output),
12 WorkspaceCommand::Default(default_args) => {
13 if default_args.clear {
14 clear_default(output)
15 } else if let Some(ref selector) = default_args.name {
16 set_default(selector, config, output)
17 } else {
18 show_default(config, output)
19 }
20 }
21 }
22}
23
24fn list(config: &Config, output: &Output) -> Result<()> {
25 let workspaces = WorkspaceManager::list()?;
26
27 if workspaces.is_empty() {
28 output.info("No workspaces configured. Run 'gisa setup' to create one.");
29 return Ok(());
30 }
31
32 let default_path = config.default_workspace.as_deref().unwrap_or("");
33
34 for ws in &workspaces {
35 let ws_path = crate::config::workspace::tilde_collapse_path(&ws.root_path);
36 let marker = if ws_path == default_path { "*" } else { " " };
37 let last_synced = ws.last_synced.as_deref().unwrap_or("never");
38 let org_info = if ws.orgs.is_empty() {
39 "all orgs".to_string()
40 } else {
41 format!("{} orgs", ws.orgs.len())
42 };
43 let provider_label = ws.provider.kind.display_name();
44
45 output.plain(&format!(
46 " {} {} ({}, {}, last synced: {})",
47 marker, ws_path, provider_label, org_info, last_synced
48 ));
49 }
50
51 if !default_path.is_empty() {
52 let expanded = shellexpand::tilde(default_path);
53 let root = std::path::Path::new(expanded.as_ref());
54 if let Ok(default_ws) = WorkspaceManager::load(root) {
55 output.plain("");
56 output.info(&format!("Default: {}", default_ws.display_label()));
57 }
58 }
59
60 Ok(())
61}
62
63fn show_default(config: &Config, output: &Output) -> Result<()> {
64 match &config.default_workspace {
65 Some(path_str) => {
66 let expanded = shellexpand::tilde(path_str);
67 let root = std::path::Path::new(expanded.as_ref());
68 if let Ok(ws) = WorkspaceManager::load(root) {
69 output.info(&format!("Default workspace: {}", ws.display_label()));
70 } else {
71 output.info(&format!("Default workspace: {} (not found)", path_str));
72 }
73 }
74 None => output.info("No default workspace set. Use 'gisa workspace default <path|name>'."),
75 }
76 Ok(())
77}
78
79fn set_default(selector: &str, config: &Config, output: &Output) -> Result<()> {
80 let ws = WorkspaceManager::resolve(Some(selector), config)?;
81
82 let tilde_path = crate::config::workspace::tilde_collapse_path(&ws.root_path);
83 Config::save_default_workspace(Some(&tilde_path))?;
84 output.success(&format!(
85 "Default workspace set to '{}'",
86 ws.display_label()
87 ));
88 Ok(())
89}
90
91fn clear_default(output: &Output) -> Result<()> {
92 Config::save_default_workspace(None)?;
93 output.success("Default workspace cleared");
94 Ok(())
95}
96
97#[cfg(test)]
98#[path = "workspace_tests.rs"]
99mod tests;