Skip to content

Commit

Permalink
Look at local pythons before resolving Python versions
Browse files Browse the repository at this point in the history
  • Loading branch information
tusharsadhwani committed Jun 26, 2024
1 parent 3747402 commit 7c69f55
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 15 deletions.
15 changes: 9 additions & 6 deletions src/yen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,16 @@ def ensure_python(python_version: str) -> tuple[str, str]:
"""Checks if given Python version exists locally. If not, downloads it."""
os.makedirs(PYTHON_INSTALLS_PATH, exist_ok=True)

for python_folder_name in os.listdir(PYTHON_INSTALLS_PATH):
python_folder = os.path.join(PYTHON_INSTALLS_PATH, python_folder_name)
if python_folder_name.startswith(python_version):
# already installed
python_bin_path = _python_bin_path(python_folder)
return python_folder_name, python_bin_path

python_version, download_link = resolve_python_version(python_version)
download_directory = os.path.join(PYTHON_INSTALLS_PATH, python_version)

python_bin_path = _python_bin_path(download_directory)
if os.path.exists(python_bin_path):
# already installed
return python_version, python_bin_path

os.makedirs(download_directory, exist_ok=True)
downloaded_filepath = download(
download_link,
Expand All @@ -141,8 +143,9 @@ def ensure_python(python_version: str) -> tuple[str, str]:
tar.extractall(download_directory)

os.remove(downloaded_filepath)
assert os.path.exists(python_bin_path)

python_bin_path = _python_bin_path(download_directory)
assert os.path.exists(python_bin_path)
return python_version, python_bin_path


Expand Down
28 changes: 19 additions & 9 deletions yen-rs/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,43 @@ pub async fn ensure_python(version: Version) -> miette::Result<(Version, PathBuf
if !PYTHON_INSTALLS_PATH.exists() {
fs::create_dir(PYTHON_INSTALLS_PATH.to_path_buf()).into_diagnostic()?;
}
for path in std::fs::read_dir(PYTHON_INSTALLS_PATH.to_path_buf()).into_diagnostic()? {
let Ok(python_folder) = path else {
continue;
};

let (version, link) = resolve_python_version(version).await?;

let download_dir = PYTHON_INSTALLS_PATH.join(version.to_string());

let python_bin_path = _python_bin_path(&download_dir);
if python_bin_path.exists() {
let resolved_python_version = python_folder.file_name().to_string_lossy().into_owned();
if !resolved_python_version.starts_with(&version.to_string()) {
continue;
}
let Ok(version) = Version::from_str(&resolved_python_version) else {
continue;
};
let python_bin_path = _python_bin_path(&python_folder.path());
return Ok((version, python_bin_path));
}

let (version, link) = resolve_python_version(version).await?;
let download_dir = PYTHON_INSTALLS_PATH.join(version.to_string());
if !download_dir.exists() {
fs::create_dir_all(&download_dir).into_diagnostic()?;
}
let downloaded_file = download(link.as_str(), &download_dir).await?;

let file = File::open(downloaded_file).into_diagnostic()?;

Archive::new(GzDecoder::new(file))
.unpack(download_dir)
.unpack(&download_dir)
.into_diagnostic()?;

let python_bin_path = _python_bin_path(&download_dir);
Ok((version, python_bin_path))
}

/// Finds and returns any Python binary from `PYTHON_INSTALLS_PATH`.
/// If no Pythons exist, downloads the default version and returns that.
pub async fn find_or_download_python() -> miette::Result<PathBuf> {
if !PYTHON_INSTALLS_PATH.exists() {
fs::create_dir(PYTHON_INSTALLS_PATH.to_path_buf()).into_diagnostic()?;
}
for path in std::fs::read_dir(PYTHON_INSTALLS_PATH.to_path_buf()).into_diagnostic()? {
let Ok(python_folder) = path else {
continue;
Expand Down

0 comments on commit 7c69f55

Please sign in to comment.