storkit: merge 429_story_interactive_project_setup_wizard_for_new_storkit_projects
This commit is contained in:
+49
-3
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user