use std::path::Path;
use std::process::ExitCode;
use loftspec::codec;
use loftspec::document::Document;
use loftspec::ids::DocumentId;
use loftspec_store::merge_driver::DRIVER;
use loftspec_store::repository::GitCommand;
use loftspec_store::{FileStore, StoreError};
use serde_json::json;
use crate::merge_driver::NPM_COMMAND;
use crate::stop::Stop;
use crate::{json, skill};
const SCHEMA: &str = "loft-init/1";
pub fn run(root: &Path, with_skill: bool, as_json: bool) -> ExitCode {
let document = Document::empty(DocumentId::mint());
if let Err(error) =
FileStore::open(root).and_then(|store| store.create(codec::write(&document)))
{
return Stop::from(error).exit(SCHEMA, as_json);
}
let skills = if with_skill {
match skill::install(root) {
Ok(skills) => skills,
Err(error) => {
return json::stop(SCHEMA, vec![skill::error_json(&error)], &error, as_json);
}
}
} else {
Vec::new()
};
let key = document.id.to_string();
if as_json {
let fields = json!({ "created": "spec/", "documentKey": key, "skills": skills });
json::print(&json::result(SCHEMA, "created", fields, Vec::new()));
} else {
println!("created spec/, document key {key}");
skill::report(&skills);
if let Some(suggestion) = merge_driver_suggestion(&GitCommand::default(), root) {
println!("{suggestion}");
}
}
ExitCode::SUCCESS
}
fn merge_driver_suggestion(git: &GitCommand, root: &Path) -> Option<String> {
match git.config_get(root, DRIVER) {
Ok(None) => Some(format!(
"next: run `loft merge-driver --install` once in each clone, so git merges spec/ by \
key; where loft runs through npm, add --command \"{NPM_COMMAND}\""
)),
Ok(Some(_)) => None,
Err(_) => matches!(git.prefix(root), Err(StoreError::NotARepository(_))).then(|| {
"next: the merge driver needs a git repository; put the project under git, then run \
`loft merge-driver --install` once in each clone"
.to_owned()
}),
}
}