Skip to content

Commit

Permalink
misc: cleanup and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ruben-arts committed May 23, 2024
1 parent 7b6ec35 commit 3b1d097
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/cli/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub async fn execute(args: Args) -> miette::Result<()> {

// Message what's installed
let detached_envs_message =
if let Some(path) = project.config().detached_environments().map(|d| d.path()) {
if let Ok(Some(path)) = project.config().detached_environments().path() {
format!(" in '{}'", console::style(path.display()).bold())
} else {
"".to_string()
Expand Down
60 changes: 41 additions & 19 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,17 @@ pub struct PyPIConfig {

#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(untagged)]
enum DetachedEnvironments {
pub enum DetachedEnvironments {
Boolean(bool),
Path(PathBuf),
}
impl DetachedEnvironments {
fn as_ref(&self) -> &DetachedEnvironments {
self
pub fn is_false(&self) -> bool {
matches!(self, DetachedEnvironments::Boolean(false))
}

// Get the path to the detached-environments directory. None means the default directory.
pub(crate) fn path(&self) -> miette::Result<Option<PathBuf>> {
pub fn path(&self) -> miette::Result<Option<PathBuf>> {
match self {
DetachedEnvironments::Path(p) => Ok(Some(p.clone())),
DetachedEnvironments::Boolean(b) if *b => {
Expand Down Expand Up @@ -267,7 +267,6 @@ pub struct Config {
/// When using 'true', it defaults to the cache directory.
/// When using a path, it uses the specified path.
/// When using 'false', it disables detached environments, meaning it moves it back to the .pixi folder.
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub detached_environments: Option<DetachedEnvironments>,
}
Expand Down Expand Up @@ -298,6 +297,7 @@ impl From<ConfigCli> for Config {
.pypi_keyring_provider
.map(|val| PyPIConfig::default().with_keyring(val))
.unwrap_or_default(),
detached_environments: None,
..Default::default()
}
}
Expand Down Expand Up @@ -567,8 +567,8 @@ impl Config {
}

/// Retrieve the value for the target_environments_directory field.
pub fn detached_environments(&self) -> Option<&DetachedEnvironments> {
self.detached_environments.as_ref()
pub fn detached_environments(&self) -> DetachedEnvironments {
self.detached_environments.clone().unwrap_or_default()
}

/// Modify this config with the given key and value
Expand All @@ -584,6 +584,7 @@ impl Config {
"authentication-override-file",
"tls-no-verify",
"mirrors",
"detached-environments",
"repodata-config",
"repodata-config.disable-jlap",
"repodata-config.disable-bzip2",
Expand Down Expand Up @@ -622,6 +623,13 @@ impl Config {
.into_diagnostic()?
.unwrap_or_default();
}
"detached-environments" => {
self.detached_environments = value.map(|v| match v.as_str() {
"true" => DetachedEnvironments::Boolean(true),
"false" => DetachedEnvironments::Boolean(false),
_ => DetachedEnvironments::Path(PathBuf::from(v)),
});
}
key if key.starts_with("repodata-config") => {
if key == "repodata-config" {
self.repodata_config = value
Expand Down Expand Up @@ -766,21 +774,15 @@ UNUSED = "unused"
assert_eq!(config.default_channels, vec!["conda-forge"]);
assert_eq!(config.tls_no_verify, Some(true));
assert_eq!(
config.detached_environments().unwrap().path().unwrap(),
config.detached_environments().path().unwrap(),
Some(PathBuf::from(env!("CARGO_MANIFEST_DIR")))
);
assert!(unused.contains(&"UNUSED".to_string()));

let toml = r#"detached-environments = true
"#;
let (config, unused) = Config::from_toml(toml).unwrap();
let toml = r"detached-environments = true";
let (config, _) = Config::from_toml(toml).unwrap();
assert_eq!(
config
.detached_environments()
.unwrap()
.path()
.unwrap()
.unwrap(),
config.detached_environments().path().unwrap().unwrap(),
get_cache_dir()
.unwrap()
.join(consts::ENVIRONMENTS_DIR)
Expand Down Expand Up @@ -850,7 +852,7 @@ UNUSED = "unused"
assert_eq!(config.default_channels, vec!["conda-forge"]);
assert_eq!(config.tls_no_verify, Some(true));
assert_eq!(
config.detached_environments().unwrap().path().unwrap(),
config.detached_environments().path().unwrap(),
Some(PathBuf::from("/path/to/envs"))
);

Expand All @@ -868,7 +870,7 @@ UNUSED = "unused"
assert_eq!(config.default_channels, vec!["channel"]);
assert_eq!(config.tls_no_verify, Some(false));
assert_eq!(
config.detached_environments().unwrap().path().unwrap(),
config.detached_environments().path().unwrap(),
Some(PathBuf::from("/path/to/envs2"))
);

Expand All @@ -880,6 +882,7 @@ UNUSED = "unused"
let config_2 = Config::from_path(&d.join("config_2.toml")).unwrap();
let config_2 = Config {
channel_config: ChannelConfig::default_with_root_dir(PathBuf::from("/root/dir")),
detached_environments: Some(DetachedEnvironments::Boolean(true)),
..config_2
};

Expand Down Expand Up @@ -969,6 +972,25 @@ UNUSED = "unused"
Some(PathBuf::from("/path/to/your/override.json"))
);

config
.set("detached-environments", Some("true".to_string()))
.unwrap();
assert_eq!(
config.detached_environments().path().unwrap().unwrap(),
get_cache_dir()
.unwrap()
.join(consts::ENVIRONMENTS_DIR)
.as_path()
);

config
.set("detached-environments", Some("/path/to/envs".to_string()))
.unwrap();
assert_eq!(
config.detached_environments().path().unwrap(),
Some(PathBuf::from("/path/to/envs"))
);

config
.set("mirrors", Some(r#"{"https://conda.anaconda.org/conda-forge": ["https://prefix.dev/conda-forge"]}"#.to_string()))
.unwrap();
Expand Down
15 changes: 6 additions & 9 deletions src/project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,14 +300,12 @@ impl Project {
let default_envs_dir = self.pixi_dir().join(consts::ENVIRONMENTS_DIR);

// Early out if detached-environments is not set
if self.config().detached_environments().is_none() {
if self.config().detached_environments().is_false() {
return default_envs_dir;
}

let detached_environments_path = self.config().detached_environments().unwrap().path();

// If the detached-environments path is set, use it instead of the default directory.
if let Ok(Some(detached_environments_path)) = detached_environments_path {
if let Ok(Some(detached_environments_path)) = self.config().detached_environments().path() {
let environments_dir_name = detached_environments_path.join(format!(
"{}-{}",
self.name(),
Expand All @@ -317,14 +315,13 @@ impl Project {
let _ = CUSTOM_TARGET_DIR_WARN.get_or_init(|| {

#[cfg(not(windows))]
if default_envs_dir.join(consts::ENVIRONMENTS_DIR).exists() && !default_envs_dir.is_symlink() {
if default_envs_dir.exists() && !default_envs_dir.is_symlink() {
tracing::warn!(
"Environments found in '{}', this will be ignored and the environment will be installed in the detached-environments directory '{}'\n\
\t\tIt's advised to remove the {} folder from the default directory to avoid confusion{}.",
"Environments found in '{}', this will be ignored and the environment will be installed in the 'detached-environments' directory: '{}'. It's advised to remove the {} folder from the default directory to avoid confusion{}.",
default_envs_dir.display(),
detached_environments_path.display(),
consts::PIXI_DIR,
if cfg!(windows) { "" } else { " and a symlink to be made. Re-install if needed." }
format!("{}/{}", consts::PIXI_DIR, consts::ENVIRONMENTS_DIR),
if cfg!(windows) { "" } else { " as a symlink can be made, please re-install after removal." }
);
} else {
create_symlink(&environments_dir_name, &default_envs_dir);
Expand Down
6 changes: 5 additions & 1 deletion src/snapshots/pixi__config__tests__config_merge.snap
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,9 @@ Config {
extra_index_urls: [],
keyring_provider: None,
},
target_environments_directory: None,
detached_environments: Some(
Boolean(
true,
),
),
}

0 comments on commit 3b1d097

Please sign in to comment.