use crate::cli::MigrateSource;
use crate::core::migrate::{
CondaDiscovery, EnvironmentSource, PyenvDiscovery, SourceEnvironment, SourceType,
VenvWrapperDiscovery,
};
use crate::error::{Result, ScoopError};
pub fn scan_all_environments(source_filter: Option<MigrateSource>) -> Vec<SourceEnvironment> {
let mut all_envs = Vec::new();
let scan_pyenv = source_filter.is_none() || source_filter == Some(MigrateSource::Pyenv);
let scan_venv =
source_filter.is_none() || source_filter == Some(MigrateSource::Virtualenvwrapper);
let scan_conda = source_filter.is_none() || source_filter == Some(MigrateSource::Conda);
if scan_pyenv {
if let Some(discovery) = PyenvDiscovery::default_root() {
if let Ok(envs) = discovery.scan_environments() {
all_envs.extend(envs);
}
}
}
if scan_venv {
if let Some(discovery) = VenvWrapperDiscovery::default_root() {
if let Ok(envs) = discovery.scan_environments() {
all_envs.extend(envs);
}
}
}
if scan_conda {
if let Some(discovery) = CondaDiscovery::default_roots() {
if let Ok(envs) = discovery.scan_environments() {
all_envs.extend(envs);
}
}
}
all_envs.sort_by(|a, b| {
let source_order = |s: &SourceType| match s {
SourceType::Pyenv => 0,
SourceType::VirtualenvWrapper => 1,
SourceType::Conda => 2,
};
source_order(&a.source_type)
.cmp(&source_order(&b.source_type))
.then(a.name.cmp(&b.name))
});
all_envs
}
pub fn find_environment_by_name(
name: &str,
source_filter: Option<MigrateSource>,
) -> Result<SourceEnvironment> {
if source_filter.is_none() || source_filter == Some(MigrateSource::Pyenv) {
if let Some(discovery) = PyenvDiscovery::default_root() {
if let Ok(env) = discovery.find_environment(name) {
return Ok(env);
}
}
}
if source_filter.is_none() || source_filter == Some(MigrateSource::Virtualenvwrapper) {
if let Some(discovery) = VenvWrapperDiscovery::default_root() {
if let Ok(env) = discovery.find_environment(name) {
return Ok(env);
}
}
}
if source_filter.is_none() || source_filter == Some(MigrateSource::Conda) {
if let Some(discovery) = CondaDiscovery::default_roots() {
if let Ok(env) = discovery.find_environment(name) {
return Ok(env);
}
}
}
match source_filter {
Some(MigrateSource::Pyenv) => Err(ScoopError::PyenvEnvNotFound {
name: name.to_string(),
}),
Some(MigrateSource::Virtualenvwrapper) => Err(ScoopError::VenvWrapperEnvNotFound {
name: name.to_string(),
}),
Some(MigrateSource::Conda) => Err(ScoopError::CondaEnvNotFound {
name: name.to_string(),
}),
None => Err(ScoopError::PyenvEnvNotFound {
name: name.to_string(),
}),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_utils::with_isolated_migrate_env;
#[test]
fn find_environment_by_name_no_filter_returns_pyenv_error() {
with_isolated_migrate_env(|| {
let result = find_environment_by_name("nonexistent_env_12345", None);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
ScoopError::PyenvEnvNotFound { .. }
));
});
}
#[test]
fn find_environment_by_name_pyenv_filter_returns_pyenv_error() {
with_isolated_migrate_env(|| {
let result =
find_environment_by_name("nonexistent_env_12345", Some(MigrateSource::Pyenv));
assert!(result.is_err());
let err = result.unwrap_err();
assert!(
matches!(err, ScoopError::PyenvEnvNotFound { ref name } if name == "nonexistent_env_12345")
);
});
}
#[test]
fn find_environment_by_name_venvwrapper_filter_returns_venvwrapper_error() {
with_isolated_migrate_env(|| {
let result = find_environment_by_name(
"nonexistent_env_12345",
Some(MigrateSource::Virtualenvwrapper),
);
assert!(result.is_err());
let err = result.unwrap_err();
assert!(
matches!(err, ScoopError::VenvWrapperEnvNotFound { ref name } if name == "nonexistent_env_12345")
);
});
}
#[test]
fn find_environment_by_name_conda_filter_returns_conda_error() {
with_isolated_migrate_env(|| {
let result =
find_environment_by_name("nonexistent_env_12345", Some(MigrateSource::Conda));
assert!(result.is_err());
let err = result.unwrap_err();
assert!(
matches!(err, ScoopError::CondaEnvNotFound { ref name } if name == "nonexistent_env_12345")
);
});
}
#[test]
fn scan_all_environments_empty_when_no_sources() {
with_isolated_migrate_env(|| {
let envs = scan_all_environments(None);
assert!(envs.is_empty());
});
}
#[test]
fn scan_all_environments_with_pyenv_filter_returns_empty() {
with_isolated_migrate_env(|| {
let envs = scan_all_environments(Some(MigrateSource::Pyenv));
assert!(envs.is_empty());
});
}
#[test]
fn scan_all_environments_with_venvwrapper_filter_returns_empty() {
with_isolated_migrate_env(|| {
let envs = scan_all_environments(Some(MigrateSource::Virtualenvwrapper));
assert!(envs.is_empty());
});
}
#[test]
fn scan_all_environments_with_conda_filter_returns_empty() {
with_isolated_migrate_env(|| {
let envs = scan_all_environments(Some(MigrateSource::Conda));
assert!(envs.is_empty());
});
}
}