(&self)
| 104 | |
| 105 | impl ProjectInit { |
| 106 | async fn execute(&self) -> CliResult<()> { |
| 107 | // 1. Ensure we're inside an Atomic repository. |
| 108 | let repo_root = find_repository_root()?; |
| 109 | let repo = Repository::open(&repo_root).map_err(|e| match e { |
| 110 | atomic_repository::RepositoryError::NotFound { path } => CliError::RepositoryNotFound { |
| 111 | searched_path: path.into(), |
| 112 | }, |
| 113 | other => CliError::Repository(other), |
| 114 | })?; |
| 115 | |
| 116 | // 2. Build the storage client and resolve the workspace. |
| 117 | let (client, org_slug) = build_client_with_org(self.org.as_deref(), None).await?; |
| 118 | let workspace = resolve_workspace(&org_slug, self.workspace.as_deref())?; |
| 119 | |
| 120 | // 3. Ensure the workspace exists — create it if necessary. |
| 121 | // A 409 (Conflict) means it already exists, which is fine. |
| 122 | match client.get_workspace(&workspace).await { |
| 123 | Ok(_ws) => { |
| 124 | // Already exists — nothing to do. |
| 125 | } |
| 126 | Err(_) => { |
| 127 | // Try to create it. If the server returns 409 we ignore it. |
| 128 | let ws_req = CreateWorkspaceRequest { |
| 129 | name: workspace.clone(), |
| 130 | description: None, |
| 131 | visibility: self.visibility, |
| 132 | }; |
| 133 | |
| 134 | match client.create_workspace(&ws_req).await { |
| 135 | Ok(ws) => { |
| 136 | print_success(&format!("Created workspace: {}", ws.slug)); |
| 137 | } |
| 138 | Err(e) => { |
| 139 | // 409 means already exists — that's fine. |
| 140 | let msg = e.to_string(); |
| 141 | if msg.contains("409") |
| 142 | || msg.contains("conflict") |
| 143 | || msg.contains("Conflict") |
| 144 | { |
| 145 | print_info(&format!( |
| 146 | "Workspace '{}' already exists, using it.", |
| 147 | workspace |
| 148 | )); |
| 149 | } else { |
| 150 | return Err(remote_err(e)); |
| 151 | } |
| 152 | } |
| 153 | } |
| 154 | } |
| 155 | } |
| 156 | |
| 157 | // 4. Create the project on the server. |
| 158 | let proj_req = CreateProjectRequest { |
| 159 | name: self.name.clone(), |
| 160 | description: self.description.clone(), |
| 161 | default_view: "dev".to_string(), |
| 162 | kind: self.kind.clone(), |
| 163 | visibility: self.visibility, |
no test coverage detected