Skip to content

Commit

Permalink
add option for cache dir
Browse files Browse the repository at this point in the history
  • Loading branch information
jpopesculian committed Feb 22, 2024
1 parent 8931a65 commit 8550dae
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 32 deletions.
78 changes: 55 additions & 23 deletions runner/src/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ pub struct PipOptions {
pub editable: bool,
}

pub struct PyEnv(PathBuf);
pub struct PyEnv {
venv_path: PathBuf,
cache_path: Option<PathBuf>,
}

#[derive(Error, Debug)]
pub enum EnvError {
Expand All @@ -37,13 +40,23 @@ impl PyEnv {
pub async fn init(
uv_path: impl AsRef<Path>,
venv_path: impl AsRef<Path>,
cache_path: Option<impl AsRef<Path>>,
) -> Result<Self, EnvError> {
Self::ensure_venv(&uv_path, &venv_path).await?;
let path = venv_path.as_ref().canonicalize()?;
if INITIALIZED_ENVS.read().await.contains(&path) {
return Ok(Self(path));
let cache_path = if let Some(cache_path) = cache_path {
tokio::fs::create_dir_all(&cache_path).await?;
Some(cache_path.as_ref().canonicalize()?)
} else {
None
};
Self::ensure_venv(&uv_path, &venv_path, cache_path.as_ref()).await?;
let venv_path = venv_path.as_ref().canonicalize()?;
if INITIALIZED_ENVS.read().await.contains(&venv_path) {
return Ok(Self {
venv_path,
cache_path,
});
}
let mut lib_dir_entries = tokio::fs::read_dir(path.join("lib")).await?;
let mut lib_dir_entries = tokio::fs::read_dir(venv_path.join("lib")).await?;
while let Some(entry) = lib_dir_entries.next_entry().await? {
if entry.file_type().await?.is_dir() {
let name = entry.file_name();
Expand Down Expand Up @@ -85,40 +98,48 @@ impl PyEnv {
}
}
}
INITIALIZED_ENVS.write().await.insert(path.clone());
Ok(Self(path))
INITIALIZED_ENVS.write().await.insert(venv_path.clone());
Ok(Self {
venv_path,
cache_path,
})
}

async fn ensure_venv(
uv_path: impl AsRef<Path>,
venv_path: impl AsRef<Path>,
cache_path: Option<impl AsRef<Path>>,
) -> Result<(), EnvError> {
let path = venv_path.as_ref();
if path.join("pyvenv.cfg").exists() {
return Ok(());
}
let output = Command::new(uv_path.as_ref())
.arg("venv")
let mut cmd = Command::new(uv_path.as_ref());
cmd.arg("venv")
.arg("--python")
.arg(PYTHON_VERSION.as_str())
.arg(venv_path.as_ref())
.output()
.await?;
.arg(venv_path.as_ref());
if let Some(cache_path) = cache_path.as_ref() {
cmd.arg("--cache-dir").arg(cache_path.as_ref());
}
let output = cmd.output().await?;
if !output.status.success() {
return Err(EnvError::VenvFailed(
String::from_utf8_lossy(&output.stderr).to_string(),
));
}
let output = Command::new(uv_path.as_ref())
.env("VIRTUAL_ENV", venv_path.as_ref())
let mut cmd = Command::new(uv_path.as_ref());
cmd.env("VIRTUAL_ENV", venv_path.as_ref())
.arg("pip")
.arg("install")
.arg("uv")
.arg("setuptools")
.arg("wheel")
.arg("build")
.output()
.await?;
.arg("build");
if let Some(cache_path) = cache_path.as_ref() {
cmd.arg("--cache-dir").arg(cache_path.as_ref());
}
let output = cmd.output().await?;
if output.status.success() {
Ok(())
} else {
Expand All @@ -128,27 +149,38 @@ impl PyEnv {
}
}

pub fn venv_path(&self) -> &Path {
&self.venv_path
}

pub fn cache_path(&self) -> Option<&Path> {
self.cache_path.as_deref()
}

pub fn python_path(&self) -> PathBuf {
self.0.join("bin").join("python")
self.venv_path.join("bin").join("python")
}

pub fn uv_path(&self) -> PathBuf {
self.0.join("bin").join("uv")
self.venv_path.join("bin").join("uv")
}

pub fn activate_path(&self) -> PathBuf {
self.0.join("bin").join("activate")
self.venv_path.join("bin").join("activate")
}

pub fn python_cmd(&self) -> Command {
let mut cmd = Command::new(self.python_path().as_os_str());
cmd.env("VIRTUAL_ENV", self.0.as_os_str());
cmd.env("VIRTUAL_ENV", self.venv_path.as_os_str());
cmd
}

pub fn uv_cmd(&self) -> Command {
let mut cmd = Command::new(self.uv_path().as_os_str());
cmd.env("VIRTUAL_ENV", self.0.as_os_str());
cmd.env("VIRTUAL_ENV", self.venv_path.as_os_str());
if let Some(cache_path) = self.cache_path.as_ref() {
cmd.arg("--cache-dir").arg(cache_path.as_os_str());
}
cmd
}

Expand Down
20 changes: 11 additions & 9 deletions src/dirs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,15 +162,17 @@ pub async fn init_venv(
pb.set_message("Initializing the Python environment...");
let uv_path = ensure_uv(uv_path, pb).await?;
let venv_dir = project_venv_dir(&project_dir);
let env = PyEnv::init(uv_path, &venv_dir).await.map_err(|e| {
error::user(
&format!("Failed to setup virtualenv: {}", e),
&format!(
"Please make sure you have permissions to write to {}",
venv_dir.display()
),
)
})?;
let env = PyEnv::init(uv_path, &venv_dir, None::<PathBuf>)
.await
.map_err(|e| {
error::user(
&format!("Failed to setup virtualenv: {}", e),
&format!(
"Please make sure you have permissions to write to {}",
venv_dir.display()
),
)
})?;
if let Err(err) = create_venv_symlink(&project_dir) {
eprintln!("WARN: {err}");
}
Expand Down

0 comments on commit 8550dae

Please sign in to comment.