From 8e79e3950fc7554f3178b24891530675c4eb59e3 Mon Sep 17 00:00:00 2001 From: Arkasha Date: Sun, 15 Feb 2026 11:36:45 +0300 Subject: [PATCH] feat: auto-detect project name from pyproject.toml or directory basename On init, detect project name by: 1. Parsing pyproject.toml [project] name field 2. Falling back to directory basename Replace placeholder in ARCHITECTURE.md template. --- archdoc-cli/src/commands/init.rs | 43 +++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/archdoc-cli/src/commands/init.rs b/archdoc-cli/src/commands/init.rs index 6c4a81b..932a423 100644 --- a/archdoc-cli/src/commands/init.rs +++ b/archdoc-cli/src/commands/init.rs @@ -1,9 +1,48 @@ use anyhow::Result; use colored::Colorize; +/// Detect project name from pyproject.toml or directory basename. +fn detect_project_name(root: &str) -> String { + let root_path = std::path::Path::new(root); + + // Try pyproject.toml + let pyproject_path = root_path.join("pyproject.toml"); + if let Ok(content) = std::fs::read_to_string(&pyproject_path) { + let mut in_project = false; + for line in content.lines() { + let trimmed = line.trim(); + if trimmed == "[project]" { + in_project = true; + continue; + } + if trimmed.starts_with('[') { + in_project = false; + continue; + } + if in_project && trimmed.starts_with("name") { + if let Some(val) = trimmed.split('=').nth(1) { + let name = val.trim().trim_matches('"').trim_matches('\''); + if !name.is_empty() { + return name.to_string(); + } + } + } + } + } + + // Fallback: directory basename + root_path + .canonicalize() + .ok() + .and_then(|p| p.file_name().map(|n| n.to_string_lossy().to_string())) + .unwrap_or_else(|| "Project".to_string()) +} + pub fn init_project(root: &str, out: &str) -> Result<()> { println!("{}", "Initializing archdoc project...".cyan().bold()); + let project_name = detect_project_name(root); + let out_path = std::path::Path::new(out); std::fs::create_dir_all(out_path)?; std::fs::create_dir_all(out_path.join("modules"))?; @@ -95,8 +134,10 @@ pub fn init_project(root: &str, out: &str) -> Result<()> { "#; + let architecture_md_content = architecture_md_content.replace("", &project_name); + let architecture_md_path = std::path::Path::new(root).join("ARCHITECTURE.md"); - std::fs::write(&architecture_md_path, architecture_md_content)?; + std::fs::write(&architecture_md_path, &architecture_md_content)?; let config_toml_content = r#"[project] root = "."