Skip to content

Commit

Permalink
Add simplified rye fetch (#545)
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Jan 20, 2024
1 parent 7a9ce9a commit 95ba033
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 14 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ that were not yet released.

_Unreleased_

- Improved the behavior of `rye fetch`. When invoked without arguments it will now try to
fetch the version of the requested Python interpreter. Specifically this combining
`pin` and `fetch` work in a much simplified manner. #545

- Fixed an issue where `rye init` would pin a much too specific version in the `.python-version`
file that is generated. #545

<!-- released start -->

## 0.18.0
Expand Down
8 changes: 8 additions & 0 deletions docs/guide/toolchains/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ with `rye toolchain fetch` (also aliased to `rye fetch`):
rye toolchain fetch [email protected]
```

Starting with Rye 0.19.0 the argument to `fetch` is inferred from the current pin. This means
you can also fetch as follows:

```
rye pin 3.10
rye fetch
```

Toolchains are fetched from two sources:

* [Indygreg's Portable Python Builds](https://github.com/indygreg/python-build-standalone) for CPython
Expand Down
25 changes: 22 additions & 3 deletions rye/src/cli/fetch.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
use anyhow::{Context, Error};
use anyhow::{anyhow, Context, Error};
use clap::Parser;

use crate::bootstrap::fetch;
use crate::platform::get_python_version_request_from_pyenv_pin;
use crate::pyproject::PyProject;
use crate::sources::PythonVersionRequest;
use crate::utils::CommandOutput;

/// Fetches a Python interpreter for the local machine.
#[derive(Parser, Debug)]
pub struct Args {
/// The version of Python to fetch.
version: String,
///
/// If no version is provided, the requested version will be fetched.
version: Option<String>,
/// Overrides the architecture to fetch.
///
/// When a non native architecture is fetched, the toolchain is
Expand All @@ -24,6 +29,20 @@ pub struct Args {

pub fn execute(cmd: Args) -> Result<(), Error> {
let output = CommandOutput::from_quiet_and_verbose(cmd.quiet, cmd.verbose);
fetch(&cmd.version.parse()?, output).context("error while fetching python installation")?;

let version: PythonVersionRequest = match cmd.version {
Some(version) => version.parse()?,
None => {
if let Ok(pyproject) = PyProject::discover() {
pyproject.venv_python_version()?.into()
} else {
get_python_version_request_from_pyenv_pin(&std::env::current_dir()?).ok_or_else(
|| anyhow!("not sure what to fetch, please provide an explicit version"),
)?
}
}
};

fetch(&version, output).context("error while fetching python installation")?;
Ok(())
}
8 changes: 6 additions & 2 deletions rye/src/cli/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use tempfile::tempdir;
use crate::bootstrap::ensure_self_venv;
use crate::config::Config;
use crate::platform::{
get_default_author_with_fallback, get_latest_cpython_version,
get_default_author_with_fallback, get_latest_cpython_version, get_pinnable_version,
get_python_version_request_from_pyenv_pin,
};
use crate::pyproject::BuildSystem;
Expand Down Expand Up @@ -370,7 +370,11 @@ pub fn execute(cmd: Args) -> Result<(), Error> {

// write .python-version
if !cmd.no_pin && !python_version_file.is_file() {
fs::write(python_version_file, format!("{}\n", py))
// get_pinnable_version ideally doesn't fail, but if it does we fall back to
// the full version request. This has the disadvantage that we might end up
// pinning to an architecture specific version.
let to_write = get_pinnable_version(&py, false).unwrap_or_else(|| py.to_string());
fs::write(python_version_file, format!("{}\n", to_write))
.context("could not write .python-version file")?;
}

Expand Down
30 changes: 21 additions & 9 deletions rye/src/cli/shim.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::convert::Infallible;
use std::env;
use std::ffi::{OsStr, OsString};
Expand Down Expand Up @@ -227,19 +228,25 @@ fn get_shim_target(
let config = Config::current();
let mut remove1 = false;

let version_request = if let Some(rest) = args
let (version_request, implicit_request) = if let Some(rest) = args
.get(1)
.and_then(|x| x.as_os_str().to_str())
.and_then(|x| x.strip_prefix('+'))
{
remove1 = true;
PythonVersionRequest::from_str(rest)
.context("invalid python version requested from command line")?
(
PythonVersionRequest::from_str(rest)
.context("invalid python version requested from command line")?,
false,
)
} else if config.global_python() {
match get_python_version_request_from_pyenv_pin(&std::env::current_dir()?) {
Some(version_request) => version_request,
None => config.default_toolchain()?,
}
(
match get_python_version_request_from_pyenv_pin(&std::env::current_dir()?) {
Some(version_request) => version_request,
None => config.default_toolchain()?,
},
true,
)
} else {
// if neither requested explicitly, nor global-python is enabled, we fall
// back to the next shadowed target
Expand All @@ -253,10 +260,15 @@ fn get_shim_target(
};
let py = get_toolchain_python_bin(&py_ver)?;
if !py.is_file() {
let hint = if implicit_request {
Cow::Borrowed("rye fetch")
} else {
Cow::Owned(format!("rye fetch {}", py_ver))
};
bail!(
"Requested Python version ({}) is not installed. Install with `rye fetch {}`",
"Requested Python version ({}) is not installed. Install with `{}`",
py_ver,
py_ver
hint
);
}

Expand Down

0 comments on commit 95ba033

Please sign in to comment.