use std::{collections::HashMap, path::PathBuf, vec};
use libpkgx::{
env::expand_moustaches, pantry_db,
platform_case_aware_env_key::construct_platform_case_aware_env_key, types::Installation,
};
use serde::Serialize;
use serde_json::json;
pub fn dump(
conn: rusqlite::Connection,
installations: Vec<Installation>,
flags: &crate::args::Flags,
) -> Result<(), Box<dyn std::error::Error>> {
if let Some(v) = flags.json {
if v < 2 {
let env = libpkgx::env::map(&installations);
let mut runtime_env = HashMap::new();
for pkg in installations.clone() {
let pkg_runtime_env =
libpkgx::pantry_db::runtime_env_for_project(&pkg.pkg.project, &conn)?;
if !pkg_runtime_env.is_empty() {
runtime_env.insert(pkg.pkg.project, pkg_runtime_env);
}
}
let json = json!({
"pkgs": installations,
"env": env,
"runtime_env": runtime_env
});
println!("{}", json);
} else {
let mut pkgs: HashMap<String, JsonV2Pkg> = HashMap::new();
for installation in installations.clone() {
let env = libpkgx::env::map(&vec![installation.clone()]);
let project = installation.pkg.project.clone();
let mut runtime_env = libpkgx::pantry_db::runtime_env_for_project(&project, &conn)?;
for (installation_key, installation_value) in runtime_env.clone() {
let installation_value =
expand_moustaches(&installation_value, &installation, &installations);
runtime_env.insert(installation_key, installation_value);
}
let programs = pantry_db::programs_for_project(&project, &conn)?;
let companions =
pantry_db::companions_for_projects(std::slice::from_ref(&project), &conn)?
.iter()
.map(|c| c.to_string())
.collect::<Vec<String>>();
let pkg = JsonV2Pkg {
path: installation.path,
project,
version: installation.pkg.version,
env,
runtime_env,
programs,
companions,
};
pkgs.insert(pkg.project.clone(), pkg);
}
let json = json!({
"pkgs": pkgs, "env": libpkgx::env::map(&installations)
});
println!("{}", json);
}
} else {
let env = libpkgx::env::map(&installations);
let env = env
.iter()
.map(|(k, v)| {
(
construct_platform_case_aware_env_key(k.clone()),
v.join(":"),
)
})
.collect();
let env = libpkgx::env::mix_runtime(&env, &installations, &conn)?;
for (key, value) in env {
println!(
"{}=\"{}\"",
key,
value.replace(&format!(":${}", key), &format!("${{{}:+:${}}}", key, key))
);
}
}
Ok(())
}
#[derive(Serialize)]
struct JsonV2Pkg {
project: String,
version: libpkgx::Version,
#[serde(skip_serializing_if = "HashMap::is_empty")]
env: HashMap<String, Vec<String>>,
#[serde(skip_serializing_if = "HashMap::is_empty")]
runtime_env: HashMap<String, String>,
path: PathBuf,
#[serde(skip_serializing_if = "Vec::is_empty")]
programs: Vec<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
companions: Vec<String>,
}