storkit: merge 429_story_interactive_project_setup_wizard_for_new_storkit_projects

This commit is contained in:
dave
2026-03-28 13:26:29 +00:00
parent 9feed0f882
commit 0b50c66caa
10 changed files with 1217 additions and 59 deletions
+49 -3
View File
@@ -39,6 +39,8 @@ enum CliDirective {
Help,
/// `--version` / `-V`
Version,
/// `init [PATH]` — scaffold and start the setup wizard.
Init,
/// An unrecognised flag (starts with `-`).
UnknownFlag(String),
/// A positional path argument.
@@ -53,6 +55,7 @@ fn classify_cli_args(args: &[String]) -> CliDirective {
None => CliDirective::None,
Some("--help" | "-h") => CliDirective::Help,
Some("--version" | "-V") => CliDirective::Version,
Some("init") => CliDirective::Init,
Some(a) if a.starts_with('-') => CliDirective::UnknownFlag(a.to_string()),
Some(_) => CliDirective::Path,
}
@@ -79,14 +82,22 @@ async fn main() -> Result<(), std::io::Error> {
let cli_args: Vec<String> = std::env::args().skip(1).collect();
// Handle CLI flags before treating anything as a project path.
let is_init = matches!(classify_cli_args(&cli_args), CliDirective::Init);
match classify_cli_args(&cli_args) {
CliDirective::Help => {
println!("storkit [PATH]");
println!("storkit init [PATH]");
println!();
println!("Serve a storkit project.");
println!();
println!("USAGE:");
println!(" storkit [PATH]");
println!(" storkit init [PATH]");
println!();
println!("COMMANDS:");
println!(
" init Scaffold a new .storkit/ project and start the interactive setup wizard."
);
println!();
println!("ARGS:");
println!(
@@ -108,10 +119,15 @@ async fn main() -> Result<(), std::io::Error> {
eprintln!("Run 'storkit --help' for usage.");
std::process::exit(1);
}
CliDirective::Path | CliDirective::None => {}
CliDirective::Init | CliDirective::Path | CliDirective::None => {}
}
let explicit_path = parse_project_path_arg(&cli_args, &cwd);
// For `storkit init [PATH]`, the path argument follows "init".
let explicit_path = if is_init {
parse_project_path_arg(&cli_args[1..], &cwd)
} else {
parse_project_path_arg(&cli_args, &cwd)
};
// When a path is given explicitly on the CLI, it must already exist as a
// directory. We do not create directories from the command line.
@@ -126,7 +142,37 @@ async fn main() -> Result<(), std::io::Error> {
}
}
if let Some(explicit_root) = explicit_path {
if is_init {
// `storkit init [PATH]` — always scaffold, never search parents.
let init_root = explicit_path.unwrap_or_else(|| cwd.clone());
if !init_root.exists() {
std::fs::create_dir_all(&init_root).unwrap_or_else(|e| {
eprintln!("error: cannot create directory {}: {e}", init_root.display());
std::process::exit(1);
});
}
match io::fs::open_project(
init_root.to_string_lossy().to_string(),
&app_state,
store.as_ref(),
port,
)
.await
{
Ok(_) => {
if let Some(root) = app_state.project_root.lock().unwrap().as_ref() {
config::ProjectConfig::load(root)
.unwrap_or_else(|e| panic!("Invalid project.toml: {e}"));
// Initialize wizard state for the setup flow.
io::wizard::WizardState::init_if_missing(root);
}
}
Err(e) => {
eprintln!("error: {e}");
std::process::exit(1);
}
}
} else if let Some(explicit_root) = explicit_path {
// An explicit path was given on the command line.
// Open it directly — scaffold .storkit/ if it is missing — and
// exit with a clear error message if the path is invalid.