Skip to content

Commit 63c31a0

Browse files
committed
Preparation for auto-downloading micromamba
We will attempt to download micromamba if we can't find a working one in $PATH. This establishes some of the groundwork for doing that, including the initial check to see if we already have a working `micromamba` command in $PATH, but it does not do attempt the download, yet.
1 parent f1f6c21 commit 63c31a0

2 files changed

Lines changed: 30 additions & 10 deletions

File tree

src/env.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ pub fn run(config: Config, subcommand: Subcommand) -> ExitCode {
9696
error!("No environment name could be determined. You can specify one with --name");
9797
return ExitCode::FAILURE;
9898
};
99-
let mut cmd = micromamba(
99+
let Some(mut cmd) = micromamba(
100100
&config,
101101
vec![
102102
"env",
@@ -107,7 +107,10 @@ pub fn run(config: Config, subcommand: Subcommand) -> ExitCode {
107107
&env_name,
108108
"--yes",
109109
],
110-
);
110+
) else {
111+
// micromamba() will already log an error, so just exit
112+
return ExitCode::FAILURE;
113+
};
111114
if config.noop_mode {
112115
info!("Would run: {:?}", cmd);
113116
ExitCode::SUCCESS

src/micromamba.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
//! This module deals with `micromamba` - obtaining it, calling it, etc.
22
33
use crate::csmrc::Config;
4-
use log::debug;
4+
use log::{debug, error};
55
use std::collections::HashMap;
6-
use std::io::{Error, ErrorKind};
76
use std::path::PathBuf;
87
use std::process::Command;
98

@@ -12,6 +11,7 @@ pub enum MicromambaLocation {
1211
InPath,
1312

1413
/// A working `micromamba` exists at the given path.
14+
#[allow(dead_code)]
1515
Path(PathBuf),
1616
}
1717

@@ -24,17 +24,27 @@ pub fn micromamba_at(location: MicromambaLocation, config: &Config, args: Vec<&s
2424
env_vars.insert("MAMBA_ROOT_PREFIX", mamba_root_prefix.to_string());
2525
}
2626

27-
let mut cmd = Command::new("micromamba");
27+
let binary_path = match location {
28+
MicromambaLocation::InPath => "micromamba",
29+
MicromambaLocation::Path(ref path) => &path.to_string_lossy(),
30+
};
31+
let mut cmd = Command::new(binary_path);
2832
cmd.args(args);
2933
cmd.envs(env_vars);
3034
debug!("About to run: {:?}", cmd);
3135
cmd
3236
}
3337

34-
pub fn micromamba(config: &Config, args: Vec<&str>) -> Result<Command, Error> {
38+
pub fn micromamba(config: &Config, args: Vec<&str>) -> Option<Command> {
3539
match micromamba_path(config) {
36-
None => Err(Error::from(ErrorKind::NotFound)),
37-
Some(location) => Ok(micromamba_at(location, config, args))
40+
None => {
41+
// TODO: Make this error nicer
42+
error!(
43+
"Could not find a micromamba executable to run. Please download it manually, make sure it's executable, and put it somewhere in $PATH."
44+
);
45+
None
46+
}
47+
Some(location) => Some(micromamba_at(location, config, args)),
3848
}
3949
}
4050

@@ -47,6 +57,9 @@ pub fn micromamba(config: &Config, args: Vec<&str>) -> Result<Command, Error> {
4757
/// cache directory. (We cannot rely on this - it could be that the user's
4858
/// cache directory is mounted noexec or similar).
4959
///
60+
/// Note that this function tries to call `micromamba --version`, even in no-op
61+
/// mode.
62+
///
5063
/// Alternative approaches that we do not take here currently:
5164
/// - On Linux, we *could* in theory use memfd_create + fexecve to embed the app
5265
/// and run it from memory. This won't work on Windows.
@@ -56,9 +69,13 @@ pub fn micromamba(config: &Config, args: Vec<&str>) -> Result<Command, Error> {
5669
/// than downloading it. But this inflates our binary size.
5770
pub fn micromamba_path(config: &Config) -> Option<MicromambaLocation> {
5871
// Assume it's in $PATH already and see what happens.
59-
if let Ok(output) = micromamba_at(MicromambaLocation::InPath, config, vec!["--version"]).output() {
72+
let cmd = micromamba_at(MicromambaLocation::InPath, config, vec!["--version"]).output();
73+
if let Ok(output) = cmd {
6074
// The full path doesn't matter, it's in $PATH
61-
debug!("micromamba reported version {}", String::from_utf8_lossy(&output.stdout));
75+
debug!(
76+
"micromamba reported version {}",
77+
String::from_utf8_lossy(&output.stdout)
78+
);
6279
return Some(MicromambaLocation::InPath);
6380
}
6481
None

0 commit comments

Comments
 (0)