use crate::state;
use miette::miette;
use std::path::Path;
pub(super) fn resolve_global_virtual_store_override(
settings_ctx: &aube_settings::ResolveCtx<'_>,
manifests: &[(String, aube_manifest::PackageJson)],
env_snapshot: &[(String, String)],
) -> Option<bool> {
let explicit = aube_settings::resolved::enable_global_virtual_store(settings_ctx);
explicit.or_else(|| {
let triggers =
aube_settings::resolved::disable_global_virtual_store_for_packages(settings_ctx);
let triggered_by = super::settings::find_gvs_incompatible_trigger(manifests, &triggers);
let ci_mode = env_snapshot.iter().any(|(k, _)| k == "CI");
let virtual_store_only_setting = aube_settings::resolved::virtual_store_only(settings_ctx);
if let Some(name) = triggered_by
&& !ci_mode
&& !virtual_store_only_setting
{
tracing::warn!(
code = aube_codes::warnings::WARN_AUBE_GVS_INCOMPATIBLE,
"`{name}` isn't compatible with aube's global virtual store — \
installing per-project instead. Install still succeeds; repeat \
installs of this project just won't share materialized packages \
across projects. Fixing this requires an upstream change in \
`{name}` itself (please file it with that project, not aube). \
To silence this warning, run `aube config set \
enableGlobalVirtualStore false --location project` — or set \
`disableGlobalVirtualStoreForPackages=[]` to opt out of this \
auto-detection entirely. \
Details: https://aube.en.dev/package-manager/global-virtual-store"
);
Some(false)
} else {
None
}
})
}
pub(super) fn planned_global_virtual_store(
use_global_virtual_store_override: Option<bool>,
env_snapshot: &[(String, String)],
) -> bool {
use_global_virtual_store_override
.unwrap_or_else(|| !env_snapshot.iter().any(|(k, _)| k == "CI"))
}
pub(super) fn reset_on_mode_change(
cwd: &Path,
aube_dir: &Path,
modules_dir_name: &str,
planned_gvs: bool,
) -> miette::Result<()> {
let Some(existing_gvs) = super::settings::detect_aube_dir_gvs_mode(aube_dir) else {
return Ok(());
};
if existing_gvs == planned_gvs {
return Ok(());
}
let from = if existing_gvs { "enabled" } else { "disabled" };
let to = if planned_gvs { "enabled" } else { "disabled" };
let modules_dir_path = cwd.join(modules_dir_name);
tracing::warn!(
code = aube_codes::warnings::WARN_AUBE_GVS_MODE_CHANGED,
"global virtual store {from} → {to}; removing {} and reinstalling from scratch",
modules_dir_path.display()
);
remove_dir_all_if_exists(&modules_dir_path).map_err(|e| {
miette!(
"global virtual store transition: failed to remove {}: {e}",
modules_dir_path.display()
)
})?;
if !aube_dir.starts_with(&modules_dir_path) {
remove_dir_all_if_exists(aube_dir).map_err(|e| {
miette!(
"global virtual store transition: failed to remove {}: {e}",
aube_dir.display()
)
})?;
}
state::remove_state(cwd).map_err(|e| {
miette!("global virtual store transition: failed to remove install state: {e}")
})
}
fn remove_dir_all_if_exists(path: &Path) -> std::io::Result<()> {
match std::fs::remove_dir_all(path) {
Ok(()) => Ok(()),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(e) => Err(e),
}
}