Execute the init command. This method: 1. Resolves and validates the target path 2. Validates the view name 3. Creates the directory if it doesn't exist 4. Initializes the repository 5. Creates the initial view 6. Optionally creates a .atomicignore file 7. Prints success message and next steps # Errors Returns an error if: - The path cannot be resolved - A repository already exists at the path
(&self)
| 493 | /// - The view name is invalid |
| 494 | /// - The repository cannot be created |
| 495 | fn run(&self) -> CliResult<()> { |
| 496 | // Validate inputs |
| 497 | self.validate_view_name()?; |
| 498 | |
| 499 | // Resolve the target path |
| 500 | let target_path = self.resolve_path()?; |
| 501 | |
| 502 | // Create the directory if it doesn't exist |
| 503 | if !target_path.exists() { |
| 504 | std::fs::create_dir_all(&target_path) |
| 505 | .map_err(|e| CliError::invalid_path(&target_path, Some(e)))?; |
| 506 | } |
| 507 | |
| 508 | // Check if a repository already exists |
| 509 | let dot_dir = target_path.join(".atomic"); |
| 510 | if dot_dir.exists() { |
| 511 | return Err(CliError::repository_exists(&target_path)); |
| 512 | } |
| 513 | |
| 514 | // ── Step 1: Create .atomic/ and the pristine database ──────── |
| 515 | let mut repo = Repository::init(&target_path).map_err(|e| match e { |
| 516 | atomic_repository::RepositoryError::AlreadyExists { .. } => { |
| 517 | CliError::repository_exists(&target_path) |
| 518 | } |
| 519 | other => CliError::Repository(other), |
| 520 | })?; |
| 521 | |
| 522 | // Create the initial view if it's different from the default |
| 523 | if self.view != atomic_repository::DEFAULT_VIEW { |
| 524 | repo.create_view(&self.view).map_err(CliError::Repository)?; |
| 525 | repo.align_to_view(&self.view) |
| 526 | .map_err(CliError::Repository)?; |
| 527 | } |
| 528 | |
| 529 | print_success(&format!( |
| 530 | "Initialized empty Atomic repository in {}", |
| 531 | dot_dir.display() |
| 532 | )); |
| 533 | println!("Created view: {}", self.view); |
| 534 | |
| 535 | // ── Step 2: Create .atomicignore → add → record ───────────── |
| 536 | // |
| 537 | // The .atomicignore MUST contain ".atomic" so the VCS internals |
| 538 | // are never tracked. Create it even without --kind (with a minimal |
| 539 | // default), then add and record it as the first change. |
| 540 | { |
| 541 | let ignore_path = target_path.join(".atomicignore"); |
| 542 | if !ignore_path.exists() { |
| 543 | if let Some(ref kind) = self.kind { |
| 544 | // Use the language-specific template |
| 545 | if let Some(template) = get_ignore_template(kind) { |
| 546 | std::fs::write(&ignore_path, template).map_err(CliError::Io)?; |
| 547 | println!("Created .atomicignore for {} project", kind); |
| 548 | } else { |
| 549 | // Unknown kind — write minimal default |
| 550 | std::fs::write(&ignore_path, ".atomic\n.git\n").map_err(CliError::Io)?; |
| 551 | } |
| 552 | } else { |