use std::env;
use serial_test::serial;
fn names(paths: Vec<std::path::PathBuf>) -> Vec<String> {
paths
.into_iter()
.map(|p| p.file_name().unwrap().to_string_lossy().to_string())
.collect()
}
fn clear_env(keys: &[&str]) {
for k in keys {
unsafe { env::remove_var(k) };
}
}
const CLEAR_ALL_DIMENSION_VARS: &[&str] = &[
"DOTENVAGE_ENV",
"EKG_ENV",
"VERCEL_ENV",
"NODE_ENV",
"DOTENVAGE_OS",
"EKG_OS",
"DOTENVAGE_ARCH",
"EKG_ARCH",
"CARGO_CFG_TARGET_ARCH",
"TARGET",
"TARGETARCH",
"TARGETPLATFORM",
"RUNNER_ARCH",
"DOTENVAGE_USER",
"EKG_USER",
"GITHUB_ACTOR",
"GITHUB_TRIGGERING_ACTOR",
"GITHUB_REPOSITORY_OWNER",
"USER",
"USERNAME",
"DOTENVAGE_VARIANT",
"EKG_VARIANT",
"VARIANT",
"GITHUB_EVENT_NAME",
"GITHUB_REF",
"PR_NUMBER",
];
#[test]
#[serial]
fn order_no_env_uses_local() {
clear_env(&[
"DOTENVAGE_ENV",
"EKG_ENV",
"DOTENVAGE_ARCH",
"EKG_ARCH",
"DOTENVAGE_USER",
"EKG_USER",
"GITHUB_EVENT_NAME",
"GITHUB_REF",
"PR_NUMBER",
"USER",
"USERNAME",
]);
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.local"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = loader.resolve_env_paths(tmp.path());
let got = names(got);
assert_eq!(got, vec![".env", ".env.local"]);
}
#[test]
#[serial]
fn order_env_prod() {
clear_env(&[
"DOTENVAGE_ENV",
"EKG_ENV",
"DOTENVAGE_ARCH",
"EKG_ARCH",
"DOTENVAGE_USER",
"EKG_USER",
"GITHUB_EVENT_NAME",
"GITHUB_REF",
"PR_NUMBER",
"USER",
"USERNAME",
]);
unsafe {
env::set_var("DOTENVAGE_ENV", "prod");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(got, vec![".env", ".env.prod"]);
}
#[test]
#[serial]
fn order_env_arch() {
clear_env(&[
"DOTENVAGE_ENV",
"EKG_ENV",
"DOTENVAGE_ARCH",
"EKG_ARCH",
"DOTENVAGE_USER",
"EKG_USER",
"GITHUB_EVENT_NAME",
"GITHUB_REF",
"PR_NUMBER",
"USER",
"USERNAME",
]);
unsafe {
env::set_var("EKG_ENV", "prod");
}
unsafe {
env::set_var("DOTENVAGE_ARCH", "docker-s3");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod.docker-s3"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(got, vec![".env", ".env.prod", ".env.prod.docker-s3"]);
}
#[test]
#[serial]
fn order_user_and_arch() {
clear_env(&[
"DOTENVAGE_ENV",
"EKG_ENV",
"DOTENVAGE_ARCH",
"EKG_ARCH",
"DOTENVAGE_USER",
"EKG_USER",
"GITHUB_EVENT_NAME",
"GITHUB_REF",
"PR_NUMBER",
"USER",
"USERNAME",
]);
unsafe {
env::set_var("DOTENVAGE_ENV", "prod");
}
unsafe {
env::set_var("DOTENVAGE_ARCH", "docker-s3");
}
unsafe {
env::set_var("DOTENVAGE_USER", "alice");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod.docker-s3"), "").unwrap();
std::fs::write(tmp.path().join(".env.alice"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod.alice"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod.docker-s3.alice"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(
got,
vec![
".env",
".env.prod",
".env.prod.docker-s3",
".env.alice",
".env.prod.alice",
".env.prod.docker-s3.alice"
]
);
}
#[test]
#[serial]
fn order_user_without_env() {
clear_env(&[
"DOTENVAGE_ENV",
"EKG_ENV",
"DOTENVAGE_ARCH",
"EKG_ARCH",
"DOTENVAGE_USER",
"EKG_USER",
"GITHUB_EVENT_NAME",
"GITHUB_REF",
"PR_NUMBER",
"USER",
"USERNAME",
]);
unsafe {
env::set_var("DOTENVAGE_USER", "bob");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.local"), "").unwrap();
std::fs::write(tmp.path().join(".env.bob"), "").unwrap();
std::fs::write(tmp.path().join(".env.local.bob"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(
got,
vec![".env", ".env.local", ".env.bob", ".env.local.bob"]
);
}
#[test]
#[serial]
fn order_cargo_target_arch() {
clear_env(&[
"DOTENVAGE_ENV",
"EKG_ENV",
"DOTENVAGE_ARCH",
"EKG_ARCH",
"CARGO_CFG_TARGET_ARCH",
"TARGET",
"DOTENVAGE_USER",
"EKG_USER",
"GITHUB_EVENT_NAME",
"GITHUB_REF",
"PR_NUMBER",
"USER",
"USERNAME",
]);
unsafe {
env::set_var("CARGO_CFG_TARGET_ARCH", "aarch64");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.local"), "").unwrap();
std::fs::write(tmp.path().join(".env.local.arm64"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(got, vec![".env", ".env.local", ".env.local.arm64"]);
}
#[test]
#[serial]
fn order_target_triple() {
clear_env(&[
"DOTENVAGE_ENV",
"EKG_ENV",
"DOTENVAGE_ARCH",
"EKG_ARCH",
"CARGO_CFG_TARGET_ARCH",
"TARGET",
"DOTENVAGE_USER",
"EKG_USER",
"GITHUB_EVENT_NAME",
"GITHUB_REF",
"PR_NUMBER",
"USER",
"USERNAME",
]);
unsafe {
env::set_var("TARGET", "x86_64-unknown-linux-gnu");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.local"), "").unwrap();
std::fs::write(tmp.path().join(".env.local.amd64"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(got, vec![".env", ".env.local", ".env.local.amd64"]);
}
#[test]
#[serial]
fn order_github_pr_number() {
clear_env(&[
"DOTENVAGE_ENV",
"EKG_ENV",
"DOTENVAGE_ARCH",
"EKG_ARCH",
"DOTENVAGE_USER",
"EKG_USER",
"GITHUB_EVENT_NAME",
"GITHUB_REF",
"PR_NUMBER",
"USER",
"USERNAME",
]);
unsafe {
env::set_var("GITHUB_EVENT_NAME", "pull_request");
}
unsafe {
env::set_var("PR_NUMBER", "123");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.pr-123"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(got, vec![".env", ".env.pr-123"]);
}
#[test]
#[serial]
fn order_github_ref_parsing() {
clear_env(&[
"DOTENVAGE_ENV",
"EKG_ENV",
"DOTENVAGE_ARCH",
"EKG_ARCH",
"DOTENVAGE_USER",
"EKG_USER",
"GITHUB_EVENT_NAME",
"GITHUB_REF",
"PR_NUMBER",
"USER",
"USERNAME",
]);
unsafe {
env::set_var("GITHUB_REF", "refs/pull/456/merge");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.pr-456"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(got, vec![".env", ".env.pr-456"]);
}
#[test]
#[serial]
fn case_insensitive_and_separators() {
clear_env(&[
"DOTENVAGE_ENV",
"EKG_ENV",
"DOTENVAGE_ARCH",
"EKG_ARCH",
"DOTENVAGE_USER",
"EKG_USER",
"GITHUB_EVENT_NAME",
"GITHUB_REF",
"PR_NUMBER",
"USER",
"USERNAME",
]);
unsafe {
env::set_var("DOTENVAGE_ENV", "PrOd");
}
unsafe {
env::set_var("DOTENVAGE_ARCH", "DoCkEr-S3");
}
unsafe {
env::set_var("DOTENVAGE_USER", "AlIcE");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".ENV"), "").unwrap();
std::fs::write(tmp.path().join(".ENV.PROD"), "").unwrap();
std::fs::write(tmp.path().join(".ENV.PROD.DOCKER-S3.ALICE"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(got, vec![".ENV", ".ENV.PROD", ".ENV.PROD.DOCKER-S3.ALICE"]);
}
#[test]
#[serial]
fn order_variant_basic() {
clear_env(CLEAR_ALL_DIMENSION_VARS);
unsafe {
env::set_var("DOTENVAGE_ENV", "prod");
}
unsafe {
env::set_var("DOTENVAGE_VARIANT", "docker");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod"), "").unwrap();
std::fs::write(tmp.path().join(".env.docker"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod.docker"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(
got,
vec![".env", ".env.prod", ".env.docker", ".env.prod.docker"]
);
}
#[test]
#[serial]
fn order_all_five_dimensions() {
clear_env(CLEAR_ALL_DIMENSION_VARS);
unsafe {
env::set_var("DOTENVAGE_ENV", "prod");
}
unsafe {
env::set_var("DOTENVAGE_ARCH", "arm64");
}
unsafe {
env::set_var("DOTENVAGE_USER", "alice");
}
unsafe {
env::set_var("DOTENVAGE_VARIANT", "k8s");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod"), "").unwrap();
std::fs::write(tmp.path().join(".env.arm64"), "").unwrap();
std::fs::write(tmp.path().join(".env.alice"), "").unwrap();
std::fs::write(tmp.path().join(".env.k8s"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod.arm64"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod.alice"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod.k8s"), "").unwrap();
std::fs::write(tmp.path().join(".env.arm64.alice"), "").unwrap();
std::fs::write(tmp.path().join(".env.alice.k8s"), "").unwrap();
std::fs::write(tmp.path().join(".env.prod.arm64.alice.k8s"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(
got,
vec![
".env",
".env.prod", ".env.arm64", ".env.prod.arm64", ".env.alice", ".env.prod.alice", ".env.arm64.alice", ".env.k8s", ".env.prod.k8s", ".env.alice.k8s", ".env.prod.arm64.alice.k8s" ]
);
}
#[test]
#[serial]
fn order_variant_with_ekg_prefix() {
clear_env(CLEAR_ALL_DIMENSION_VARS);
unsafe {
env::set_var("EKG_VARIANT", "canary");
}
let tmp = tempfile::tempdir().unwrap();
std::fs::write(tmp.path().join(".env"), "").unwrap();
std::fs::write(tmp.path().join(".env.local"), "").unwrap();
std::fs::write(tmp.path().join(".env.canary"), "").unwrap();
std::fs::write(tmp.path().join(".env.local.canary"), "").unwrap();
let loader = dotenvage::EnvLoader::with_manager(dotenvage::SecretManager::generate().unwrap());
let got = names(loader.resolve_env_paths(tmp.path()));
assert_eq!(
got,
vec![".env", ".env.local", ".env.canary", ".env.local.canary"]
);
}