Skip to content

Commit

Permalink
Send installer output to stderr (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
yeetfield authored Feb 10, 2023
1 parent fe0dc45 commit d3f79a8
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 39 deletions.
11 changes: 11 additions & 0 deletions rozy/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rozy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ zip = "0.6.3"
openssl = { version = "0.10.45", features = ["vendored"] }
exec = "0.3.1"
semver = "1.0.16"
os_pipe = "1.1.2"
infer = "0.12.0"
29 changes: 12 additions & 17 deletions rozy/src/installers/conda.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::super::files::delete_if_exists;
use super::installer::Installer;
use super::installer::{run_subcommand_for_installer, Installer};
use crate::files::delete_if_exists;
use anyhow::{anyhow, Error, Result};

use tempfile::tempdir;
Expand All @@ -13,7 +13,7 @@ pub struct Conda {
}

pub fn conda_install(
conda_bin: &String,
conda_bin: &str,
channels: &[String],
to_dir: &std::path::Path,
to_install: &[String],
Expand All @@ -26,27 +26,22 @@ pub fn conda_install(
delete_if_exists(to_dir)?;

let conda_cache_dir = tempdir()?;
let mut command = std::process::Command::new(conda_bin);
command.env("CONDA_PKGS_DIRS", conda_cache_dir.path());

command.arg("create");
command.arg("-y");
let env = vec![("CONDA_PKGS_DIRS", conda_cache_dir.path().to_str().unwrap())];

let mut args = vec!["create", "-y", "-p", to_dir.to_str().unwrap()];
for arg in channels.iter() {
command.arg("-c");
command.arg(arg);
args.push("-c");
args.push(arg);
}

command.arg("-p");
command.arg(to_dir);

for arg in to_install.iter() {
command.arg(arg);
args.push(arg);
}

let output = command.output().unwrap();
if !output.status.success() {
return Err(anyhow!("Conda installation exited with {:#?}", output));
let subcommand_result =
run_subcommand_for_installer(conda_bin, args.into_iter(), env.into_iter());
if subcommand_result.is_err() {
return Err(anyhow!("Conda installation exited with error"));
}

Ok(())
Expand Down
33 changes: 32 additions & 1 deletion rozy/src/installers/installer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,37 @@
use anyhow::Result;
use anyhow::{anyhow, Result};
use std::process::{Command, Stdio};

pub trait Installer {
fn install(&self, to_dir: &std::path::Path) -> Result<()>;
fn describe(&self) -> String;
}

pub fn run_subcommand_for_installer<'a>(
command: &str,
args: impl Iterator<Item = &'a str>,
env: impl Iterator<Item = (&'a str, &'a str)>,
) -> Result<()> {
let mut command = Command::new(command);
// Directing /dev/null to stdin breaks Conda's progress bar, for some reason
// command.stdin(Stdio::null())
command.stderr(Stdio::inherit());
command.stdout(os_pipe::dup_stderr()?);

for (env_key, env_val) in env {
command.env(env_key, env_val);
}

for arg in args {
command.arg(arg);
}

let mut output = command.spawn().unwrap();
if !output.wait()?.success() {
return Err(anyhow!(
"Installer subcommand {:?} exited with error",
command
));
}

Ok(())
}
24 changes: 13 additions & 11 deletions rozy/src/installers/pip.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::installers::conda::conda_install;

use super::installer::Installer;

use crate::installers::{conda::conda_install, installer::run_subcommand_for_installer};
use anyhow::{anyhow, Error, Result};

pub struct Pip {
Expand Down Expand Up @@ -41,14 +39,18 @@ impl Installer for Pip {
to_dir,
&[String::from("pip")],
)?;
let pip_path = to_dir.join("bin").join("pip");
let mut command = std::process::Command::new(pip_path);
command.arg("install");
command.arg(format!("{}=={}", self.package, self.version));

let output = command.output().unwrap();
if !output.status.success() {
return Err(anyhow!("Pip installation exited with {:?}", output));

let pip_command = to_dir.join("bin").join("pip");
let version_arg = format!("{}=={}", self.package, self.version);
let args = vec!["install", &version_arg];

let subcommand_result = run_subcommand_for_installer(
pip_command.to_str().unwrap(),
args.into_iter(),
std::iter::empty(),
);
if subcommand_result.is_err() {
return Err(anyhow!("Pip installation exited with error"));
}

Ok(())
Expand Down
21 changes: 11 additions & 10 deletions rozy/src/installers/shell.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::installer::Installer;
use crate::utils::download_to;
use crate::{installers::installer::run_subcommand_for_installer, utils::download_to};
use tempfile::tempdir;

use anyhow::{anyhow, Context, Error, Result};
Expand Down Expand Up @@ -58,26 +58,27 @@ impl Installer for Shell {
let file = dir.path().join("installer.sh");
download_to(&file, &self.url)?;

let mut command = std::process::Command::new("/bin/bash");
let path;
let mut env = vec![("INSTALL_DIR", to_dir.as_os_str().to_str().unwrap())];

if let Some(extra_path) = &self.extra_path_during_install {
let path = format!(
path = format!(
"{}:{}",
extra_path,
std::env::var("PATH").context("While checking $PATH")?
);
command.env("PATH", path);
env.push(("PATH", &path));
}
command.env("INSTALL_DIR", to_dir.as_os_str().to_str().unwrap());

command.arg(file.as_os_str().to_str().unwrap());
let mut args = vec![file.as_os_str().to_str().unwrap()];
for arg in &self.shell_args {
command.arg(arg);
args.push(arg);
}

let output = command.output().unwrap();
if !output.status.success() {
return Err(anyhow!("Shell installer exited with {:?}", output));
let subcommand_result =
run_subcommand_for_installer("/bin/bash", args.into_iter(), env.into_iter());
if subcommand_result.is_err() {
return Err(anyhow!("Conda installation exited with error"));
}

Ok(())
Expand Down

0 comments on commit d3f79a8

Please sign in to comment.