use std::path::{Path, PathBuf};
use crate::build_spec::{BuildSpec, TargetTuple};
use crate::error::GomodError;
use crate::interp::{apply, EncodeCtx, GoBuildEnv, RealGoBuildEnv};
pub const SPEC_FILENAME: &str = "Go.build-spec.json";
pub fn to_json(spec: &BuildSpec) -> Result<String, GomodError> {
let mut body = serde_json::to_string_pretty(spec)
.map_err(|e| GomodError::Other(format!("serialize Go.build-spec.json: {e}")))?;
body.push('\n');
Ok(body)
}
pub fn generate_with_env(
env: &dyn GoBuildEnv,
root: &Path,
tuple: TargetTuple,
) -> Result<PathBuf, GomodError> {
let spec = apply(env, &EncodeCtx { root: root.to_path_buf(), tuple })?;
let body = to_json(&spec)?;
let out = root.join(SPEC_FILENAME);
std::fs::write(&out, body).map_err(|source| GomodError::Io { path: out.clone(), source })?;
Ok(out)
}
pub fn generate_and_write(root: &Path) -> Result<PathBuf, GomodError> {
generate_with_env(&RealGoBuildEnv::default(), root, TargetTuple::host())
}
pub fn generate_for_target_and_write(root: &Path, triple: &str) -> Result<PathBuf, GomodError> {
let tuple = TargetTuple::from_rust_triple(triple).unwrap_or_else(TargetTuple::host);
generate_with_env(&RealGoBuildEnv::default(), root, tuple)
}