uv/crates
Charlie Marsh 2652caa3e3
Add support for URL dependencies (#251)
## Summary

This PR adds support for resolving and installing dependencies via
direct URLs, like:

```
werkzeug @ 960bb4017c/Werkzeug-2.0.0-py3-none-any.whl
```

These are fairly common (e.g., with `torch`), but you most often see
them as Git dependencies.

Broadly, structs like `RemoteDistribution` and friends are now enums
that can represent either registry-based dependencies or URL-based
dependencies:

```rust
/// A built distribution (wheel) that exists as a remote file (e.g., on `PyPI`).
#[derive(Debug, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum RemoteDistribution {
    /// The distribution exists in a registry, like `PyPI`.
    Registry(PackageName, Version, File),
    /// The distribution exists at an arbitrary URL.
    Url(PackageName, Url),
}
```

In the resolver, we now allow packages to take on an extra, optional
`Url` field:

```rust
#[derive(Debug, Clone, Eq, Derivative)]
#[derivative(PartialEq, Hash)]
pub enum PubGrubPackage {
    Root,
    Package(
        PackageName,
        Option<DistInfoName>,
        #[derivative(PartialEq = "ignore")]
        #[derivative(PartialOrd = "ignore")]
        #[derivative(Hash = "ignore")]
        Option<Url>,
    ),
}
```

However, for the purpose of version satisfaction, we ignore the URL.
This allows for the URL dependency to satisfy the transitive request in
cases like:

```
flask==3.0.0
werkzeug @ 254c3e9b5f/werkzeug-3.0.1-py3-none-any.whl
```

There are a couple limitations in the current approach:

- The caching for remote URLs is done separately in the resolver vs. the
installer. I decided not to sweat this too much... We need to figure out
caching holistically.
- We don't support any sort of time-based cache for remote URLs -- they
just exist forever. This will be a problem for URL dependencies, where
we need some way to evict and refresh them. But I've deferred it for
now.
- I think I need to redo how this is modeled in the resolver, because
right now, we don't detect a variety of invalid cases, e.g., providing
two different URLs for a dependency, asking for a URL dependency and a
_different version_ of the same dependency in the list of first-party
dependencies, etc.
- (We don't yet support VCS dependencies.)
2023-11-01 09:21:44 -04:00
..
distribution-filename Add support for URL dependencies (#251) 2023-11-01 09:21:44 -04:00
gourgeist Fix musl compilation (#234) 2023-10-30 18:10:17 +01:00
install-wheel-rs Upgrade crates and remove unused dependencies (#256) 2023-10-31 13:16:58 -04:00
pep440-rs Add support for pre-release versions (#216) 2023-10-29 14:31:55 -04:00
pep508-rs Build source distributions in the resolver (#138) 2023-10-25 20:05:13 +00:00
platform-host Fix musl compilation (#234) 2023-10-30 18:10:17 +01:00
platform-tags Store all distributions rather than compatible wheels (#114) 2023-10-17 17:09:31 -04:00
puffin-build Implement mixed PEP 517 and setup.py build 2023-10-30 19:11:52 +01:00
puffin-cli Add support for URL dependencies (#251) 2023-11-01 09:21:44 -04:00
puffin-client Move PyPI-oriented types out of puffin-client crate (#255) 2023-10-31 17:10:23 +00:00
puffin-dev Add script to check the top 8k pypi packages (#198) 2023-10-26 12:03:59 +00:00
puffin-dispatch Move distribution abstraction in shared crate (#258) 2023-10-31 15:30:06 -04:00
puffin-distribution Add support for URL dependencies (#251) 2023-11-01 09:21:44 -04:00
puffin-installer Add support for URL dependencies (#251) 2023-11-01 09:21:44 -04:00
puffin-interpreter Fail gracefully when invalid markers are stored (#230) 2023-10-30 04:02:51 +00:00
puffin-package Remove implicit clone from ExtraName and document requirement in PackageName (#262) 2023-10-31 15:24:27 -05:00
puffin-resolver Add support for URL dependencies (#251) 2023-11-01 09:21:44 -04:00
puffin-traits Add script to check the top 8k pypi packages (#198) 2023-10-26 12:03:59 +00:00
puffin-workspace Add a puffin remove command (#120) 2023-10-18 18:50:08 +00:00
README.md Add source distribution filename abstraction (#154) 2023-10-20 17:45:57 +02:00

Crates

pep440-rs

Utilities for interacting with Python version numbers and specifiers.

pep508-rs

Utilities for interacting with PEP 508 dependency specifiers.

platform-host

Functionality for detecting the current platform (operating system, architecture, etc.).

platform-tags

Functionality for parsing and inferring Python platform tags as per PEP 425.

puffin-cli

Command-line interface for the Puffin package manager.

puffin-client

Client for interacting with PyPI-compatible HTTP APIs.

puffin-installer

Functionality for installing Python packages into a virtual environment.

puffin-interpreter

Functionality for detecting and leveraging the current Python interpreter.

puffin-package

Types and functionality for working with Python packages, e.g., parsing wheel files.

puffin-resolver

Functionality for resolving Python packages and their dependencies.

distribution-filename

Functionality for parsing wheel filenames as per PEP 427.