Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added --extra-requirement to rye install #326

Merged
merged 1 commit into from
Jun 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ that were not yet released.

_Unreleased_

- `rye install` now lets you install dependencies into the tool's virtualenv
during installation that are undeclared via the new `--extra-requirement`
option. #326

- Improved handling of relative path installations by setting `PROJECT_PATH`
the same way as PDM does. #321

Expand Down
17 changes: 17 additions & 0 deletions docs/guide/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,23 @@ are placed in `~/.rye/shims`.
The `install` command now considers custom sources configured
in the `config.toml` file. For more information see [Dependency Sources](sources.md).

## Extra Requirements

Some tools do not declare all of their dependencies since they might be optional.
In some cases these can be declared by passing extra features to the installer:

```bash
rye install black --features colorama
```

If dependencies are not at all specified, then they can be provided with `--extra-requirement`.
This is particularly sometimes necessary if the tool uses `pkg_resources` (part of
`setuptools`) but forgets to declare that dependency:

```bash
rye install gradio --extra-requirement setuptools
```

## Listing Tools

If you want to see which tools are installed, you can use `rye tools list`:
Expand Down
55 changes: 39 additions & 16 deletions rye/src/cli/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ pub struct Args {
/// Include scripts from a given dependency.
#[arg(long)]
include_dep: Vec<String>,
/// Additional dependencies to install that are not declared by the main package.
#[arg(long)]
extra_requirement: Vec<String>,
/// Optionally the Python version to use.
#[arg(short, long)]
python: Option<String>,
Expand All @@ -35,27 +38,19 @@ pub struct Args {

pub fn execute(mut cmd: Args) -> Result<(), Error> {
let output = CommandOutput::from_quiet_and_verbose(cmd.quiet, cmd.verbose);
let mut extra_requirements = Vec::new();

let mut requirement = match resolve_local_requirement(Path::new(&cmd.requirement), output)? {
Some(req) => req,
None => cmd.requirement.parse::<Requirement>().with_context(|| {
if cmd.requirement.contains("://") {
format!(
"failed to parse requirement '{}'. It looks like a URL, maybe \
you wanted to use --url or --git",
cmd.requirement
)
} else {
format!("failed to parse requirement '{}'", cmd.requirement)
}
})?,
};

// main requirement
let mut requirement = handle_requirement(&cmd.requirement, output, true)?;
// installations here always use absolute paths for local references
// because we do not have a rye workspace to work with.
cmd.req_extras.force_absolute();
cmd.req_extras.apply_to_requirement(&mut requirement)?;

for req in cmd.extra_requirement {
extra_requirements.push(handle_requirement(&req, output, false)?);
}

let py_ver: PythonVersionRequest = match cmd.python {
Some(ref py) => py.parse()?,
None => PythonVersionRequest {
Expand All @@ -67,6 +62,34 @@ pub fn execute(mut cmd: Args) -> Result<(), Error> {
},
};

install(requirement, &py_ver, cmd.force, &cmd.include_dep, output)?;
install(
requirement,
&py_ver,
cmd.force,
&cmd.include_dep,
&extra_requirements,
output,
)?;
Ok(())
}

fn handle_requirement(
req: &str,
output: CommandOutput,
local_hint: bool,
) -> Result<Requirement, Error> {
Ok(match resolve_local_requirement(Path::new(req), output)? {
Some(req) => req,
None => req.parse::<Requirement>().with_context(|| {
if local_hint && req.contains("://") {
format!(
"failed to parse requirement '{}'. It looks like a URL, maybe \
you wanted to use --url or --git",
req
)
} else {
format!("failed to parse requirement '{}'", req)
}
})?,
})
}
5 changes: 5 additions & 0 deletions rye/src/installer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ pub fn install(
py_ver: &PythonVersionRequest,
force: bool,
include_deps: &[String],
extra_requirements: &[Requirement],
output: CommandOutput,
) -> Result<(), Error> {
let config = Config::current();
Expand Down Expand Up @@ -121,6 +122,10 @@ pub fn install(
cmd.arg("importlib-metadata==6.6.0");
}

for extra in extra_requirements {
cmd.arg(extra.to_string());
}

let status = cmd.status()?;
if !status.success() {
uninstall_helper(&target_venv_path, &shim_dir)?;
Expand Down