use std::path::Path;
use chrono::{SecondsFormat, Utc};
use colored::Colorize;
use crate::cli;
use crate::error::{Error, Result};
use crate::parser;
use crate::store::queries::{self, SaveInput};
use crate::util::fs as util_fs;
pub fn run(
cwd: &Path,
file: Option<&str>,
key_file: Option<&str>,
message: Option<&str>,
) -> Result<()> {
let mut conn = cli::require_store()?;
let aes_key = cli::load_encryption_key(&conn, key_file)?;
let (project_path, git_ctx) = cli::resolve_project(cwd)?;
let file_name = file.unwrap_or(".env");
let disk_path = cwd.join(file_name);
if !disk_path.exists() {
return Err(Error::FileNotFound(disk_path));
}
util_fs::refuse_symlink(&disk_path, "save")?;
let content = std::fs::read_to_string(&disk_path)?;
let entries = parser::parse(&content)?;
let hash = parser::content_hash(&entries);
let file_path = cli::resolve_file_path(file_name, cwd, &git_ctx)?;
let (branch, commit) = match &git_ctx {
Some(ctx) => (ctx.branch.as_str(), ctx.commit.as_str()),
None => ("", ""),
};
let timestamp = Utc::now().to_rfc3339_opts(SecondsFormat::Secs, true);
queries::insert_save_input(
&mut conn,
&SaveInput {
project_path: &project_path,
file_path: &file_path,
branch,
commit_hash: commit,
timestamp: ×tamp,
content_hash: &hash,
entries: &entries,
aes_key: aes_key.as_deref(),
message,
},
)?;
let msg_suffix = match message {
Some(m) => format!(" {}", format!("-- {m}").dimmed()),
None => String::new(),
};
println!(
"{} {} ({} variables){}",
"Saved".green().bold(),
file_path,
entries.len(),
msg_suffix
);
Ok(())
}