Rename to uv (#1302)

First, replace all usages in files in-place. I used my editor for this.
If someone wants to add a one-liner that'd be fun.

Then, update directory and file names:

```
# Run twice for nested directories
find . -type d -print0 | xargs -0 rename s/puffin/uv/g
find . -type d -print0 | xargs -0 rename s/puffin/uv/g

# Update files
find . -type f -print0 | xargs -0 rename s/puffin/uv/g
```

Then add all the files again

```
# Add all the files again
git add crates
git add python/uv

# This one needs a force-add
git add -f crates/uv-trampoline
```
This commit is contained in:
Zanie Blue 2024-02-15 11:19:46 -06:00 committed by GitHub
parent 328b116d5d
commit 2586f655bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
229 changed files with 1796 additions and 1818 deletions

View file

@ -1,4 +1,4 @@
# Build Puffin on all platforms.
# Build uv on all platforms.
#
# Generates both wheels (for PyPI) and archived binaries (for GitHub releases).
#
@ -24,8 +24,8 @@ concurrency:
cancel-in-progress: true
env:
PACKAGE_NAME: puffin_alpha
MODULE_NAME: puffin
PACKAGE_NAME: uv
MODULE_NAME: uv
PYTHON_VERSION: "3.11"
CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10
@ -43,7 +43,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: echo "# Puffin" > README.md
run: echo "# uv" > README.md
- name: "Build sdist"
uses: PyO3/maturin-action@v1
with:
@ -71,7 +71,7 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
- name: "Prep README.md"
run: echo "# Puffin" > README.md
run: echo "# uv" > README.md
- name: "Build wheels - x86_64"
uses: PyO3/maturin-action@v1
with:
@ -85,11 +85,11 @@ jobs:
- name: "Archive binary"
run: |
TARGET=x86_64-apple-darwin
ARCHIVE_NAME=puffin-$TARGET
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp target/$TARGET/release/puffin $ARCHIVE_NAME/puffin
cp target/$TARGET/release/uv $ARCHIVE_NAME/uv
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
@ -111,7 +111,7 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
- name: "Prep README.md"
run: echo "# Puffin" > README.md
run: echo "# uv" > README.md
- name: "Build wheels - universal2"
uses: PyO3/maturin-action@v1
with:
@ -129,11 +129,11 @@ jobs:
- name: "Archive binary"
run: |
TARGET=aarch64-apple-darwin
ARCHIVE_NAME=puffin-$TARGET
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp target/$TARGET/release/puffin $ARCHIVE_NAME/puffin
cp target/$TARGET/release/uv $ARCHIVE_NAME/uv
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
@ -162,7 +162,7 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
architecture: ${{ matrix.platform.arch }}
- name: "Prep README.md"
run: echo "# Puffin" > README.md
run: echo "# uv" > README.md
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@ -183,8 +183,8 @@ jobs:
- name: "Archive binary"
shell: bash
run: |
ARCHIVE_FILE=puffin-${{ matrix.platform.target }}.zip
7z a $ARCHIVE_FILE ./target/${{ matrix.platform.target }}/release/puffin.exe
ARCHIVE_FILE=uv-${{ matrix.platform.target }}.zip
7z a $ARCHIVE_FILE ./target/${{ matrix.platform.target }}/release/uv.exe
sha256sum $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@v3
@ -210,7 +210,7 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
- name: "Prep README.md"
run: echo "# Puffin" > README.md
run: echo "# uv" > README.md
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@ -249,11 +249,11 @@ jobs:
set -euo pipefail
TARGET=${{ matrix.target }}
ARCHIVE_NAME=puffin-$TARGET
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp target/$TARGET/release/puffin $ARCHIVE_NAME/puffin
cp target/$TARGET/release/uv $ARCHIVE_NAME/uv
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
@ -285,7 +285,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: echo "# Puffin" > README.md
run: echo "# uv" > README.md
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@ -318,11 +318,11 @@ jobs:
set -euo pipefail
TARGET=${{ matrix.platform.target }}
ARCHIVE_NAME=puffin-$TARGET
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp target/$TARGET/release/puffin $ARCHIVE_NAME/puffin
cp target/$TARGET/release/uv $ARCHIVE_NAME/uv
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
@ -334,7 +334,7 @@ jobs:
*.sha256
# Like `linux-arm`, but use `--no-default-features --features flate2/rust_backend` when
# building Puffin.
# building uv.
linux-s390x:
runs-on: ubuntu-latest
strategy:
@ -351,7 +351,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: echo "# Puffin" > README.md
run: echo "# uv" > README.md
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@ -384,11 +384,11 @@ jobs:
set -euo pipefail
TARGET=${{ matrix.platform.target }}
ARCHIVE_NAME=puffin-$TARGET
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp target/$TARGET/release/puffin $ARCHIVE_NAME/puffin
cp target/$TARGET/release/uv $ARCHIVE_NAME/uv
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
@ -399,9 +399,8 @@ jobs:
*.tar.gz
*.sha256
# Like `linux-arm`, but use `--no-default-features --features flate2/rust_backend` when
# building Puffin, and install the `gcc-powerpc64-linux-gnu` package.
# building uv, and install the `gcc-powerpc64-linux-gnu` package.
linux-powerpc:
runs-on: ubuntu-latest
strategy:
@ -420,7 +419,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: echo "# Puffin" > README.md
run: echo "# uv" > README.md
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@ -460,11 +459,11 @@ jobs:
set -euo pipefail
TARGET=${{ matrix.platform.target }}
ARCHIVE_NAME=puffin-$TARGET
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp target/$TARGET/release/puffin $ARCHIVE_NAME/puffin
cp target/$TARGET/release/uv $ARCHIVE_NAME/uv
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
@ -491,7 +490,7 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
- name: "Prep README.md"
run: echo "# Puffin" > README.md
run: echo "# uv" > README.md
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@ -520,11 +519,11 @@ jobs:
set -euo pipefail
TARGET=${{ matrix.target }}
ARCHIVE_NAME=puffin-$TARGET
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp target/$TARGET/release/puffin $ARCHIVE_NAME/puffin
cp target/$TARGET/release/uv $ARCHIVE_NAME/uv
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
@ -554,7 +553,7 @@ jobs:
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: echo "# Puffin" > README.md
run: echo "# uv" > README.md
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
@ -585,11 +584,11 @@ jobs:
set -euo pipefail
TARGET=${{ matrix.platform.target }}
ARCHIVE_NAME=puffin-$TARGET
ARCHIVE_NAME=uv-$TARGET
ARCHIVE_FILE=$ARCHIVE_NAME.tar.gz
mkdir -p $ARCHIVE_NAME
cp target/$TARGET/release/puffin $ARCHIVE_NAME/puffin
cp target/$TARGET/release/uv $ARCHIVE_NAME/uv
tar czvf $ARCHIVE_FILE $ARCHIVE_NAME
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"

View file

@ -19,7 +19,7 @@ on:
jobs:
docker-publish:
name: Build Docker image (ghcr.io/astral-sh/puffin)
name: Build Docker image (ghcr.io/astral-sh/uv)
runs-on: ubuntu-latest
environment:
name: release
@ -40,7 +40,7 @@ jobs:
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/astral-sh/puffin
images: ghcr.io/astral-sh/uv
- name: Check tag consistency
if: ${{ inputs.plan != '' && !fromJson(inputs.plan).announcement_tag_is_implicit }}
@ -64,5 +64,5 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
push: ${{ inputs.plan != '' && !fromJson(inputs.plan).announcement_tag_is_implicit }}
tags: ghcr.io/astral-sh/puffin:latest,ghcr.io/astral-sh/puffin:${{ (inputs.plan != '' && fromJson(inputs.plan).announcement_tag) || 'dry-run' }}
tags: ghcr.io/astral-sh/uv:latest,ghcr.io/astral-sh/uv:${{ (inputs.plan != '' && fromJson(inputs.plan).announcement_tag) || 'dry-run' }}
labels: ${{ steps.meta.outputs.labels }}

View file

@ -90,17 +90,17 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: "Install Rust toolchain"
working-directory: crates/puffin-trampoline
working-directory: crates/uv-trampoline
run: |
rustup target add x86_64-pc-windows-msvc
rustup component add clippy rust-src --toolchain nightly-2024-01-23-x86_64-pc-windows-msvc
- uses: rui314/setup-mold@v1
- uses: Swatinem/rust-cache@v2
with:
workspaces: "crates/puffin-trampoline"
workspaces: "crates/uv-trampoline"
- name: "Clippy"
working-directory: crates/puffin-trampoline
working-directory: crates/uv-trampoline
run: cargo clippy --all-features --locked -- -D warnings
- name: "Build"
working-directory: crates/puffin-trampoline
working-directory: crates/uv-trampoline
run: cargo build --release -Z build-std=core,panic_abort,alloc -Z build-std-features=compiler-builtins-mem --target x86_64-pc-windows-msvc

View file

@ -1,18 +1,18 @@
# Benchmarks
All benchmarks were computed on macOS using Python 3.12.0 (for non-Puffin tools), and come with a few
All benchmarks were computed on macOS using Python 3.12.0 (for non-uv tools), and come with a few
important caveats:
- Benchmark performance may vary dramatically across different operating systems and filesystems.
In particular, Puffin uses different installation strategies based on the underlying filesystem's
capabilities. (For example, Puffin uses reflinking on macOS, and hardlinking on Linux.)
In particular, uv uses different installation strategies based on the underlying filesystem's
capabilities. (For example, uv uses reflinking on macOS, and hardlinking on Linux.)
- Benchmark performance may vary dramatically depending on the set of packages being installed.
For example, a resolution that requires building a single intensive source distribution may appear
very similar across tools, since the bottleneck is tool-agnostic.
- Unlike Poetry, both Puffin and pip-tools do _not_ generate multi-platform lockfiles. As such,
- Unlike Poetry, both uv and pip-tools do _not_ generate multi-platform lockfiles. As such,
Poetry is (by design) doing significantly more work than other tools in the resolution benchmarks.
Poetry is included for completeness, as many projects may not _need_ a multi-platform lockfile.
However, it's critical to understand that benchmarking Puffin's resolution time against Poetry is
However, it's critical to understand that benchmarking uv's resolution time against Poetry is
an unfair comparison. (Benchmarking installation, however, _is_ a fair comparison.)
This document benchmarks against Trio's `docs-requirements.in`, as a representative example of a
@ -22,7 +22,7 @@ In each case, a smaller bar (i.e., lower) is better.
## Warm Installation
Benchmarking package installation (e.g., `puffin pip sync`) with a warm cache. This is equivalent
Benchmarking package installation (e.g., `uv pip sync`) with a warm cache. This is equivalent
to removing and recreating a virtual environment, and then populating it with dependencies that
you've installed previously on the same machine.
@ -30,15 +30,15 @@ you've installed previously on the same machine.
## Cold Installation
Benchmarking package installation (e.g., `puffin pip sync`) with a cold cache. This is equivalent
to running `puffin pip sync` on a new machine or in CI (assuming that the package manager cache is
Benchmarking package installation (e.g., `uv pip sync`) with a cold cache. This is equivalent
to running `uv pip sync` on a new machine or in CI (assuming that the package manager cache is
not shared across runs).
![install-cold](https://github.com/astral-sh/ruff/assets/1309177/ed86c193-582f-4163-b369-f12ec3905c3c)
## Warm Resolution
Benchmarking dependency resolution (e.g., `puffin pip compile`) with a warm cache, but no existing
Benchmarking dependency resolution (e.g., `uv pip compile`) with a warm cache, but no existing
lockfile. This is equivalent to blowing away an existing `requirements.txt` file to regenerate it
from a `requirements.in` file.
@ -46,8 +46,8 @@ from a `requirements.in` file.
## Cold Resolution
Benchmarking dependency resolution (e.g., `puffin pip compile`) with a cold cache. This is
equivalent to running `puffin pip compile` on a new machine or in CI (assuming that the package
Benchmarking dependency resolution (e.g., `uv pip compile`) with a cold cache. This is
equivalent to running `uv pip compile` on a new machine or in CI (assuming that the package
manager cache is not shared across runs).
![resolve-cold](https://github.com/astral-sh/ruff/assets/1309177/556ac7aa-0a6a-4f94-b0d9-90b25461de7b)
@ -55,20 +55,20 @@ manager cache is not shared across runs).
## Reproduction
All benchmarks were generated using the `scripts/bench/__main__.py` script, which wraps
[`hyperfine`](https://github.com/sharkdp/hyperfine) to facilitate benchmarking Puffin
[`hyperfine`](https://github.com/sharkdp/hyperfine) to facilitate benchmarking uv
against a variety of other tools.
The benchmark script itself has a several requirements:
- A local Puffin release build (`cargo build --release`).
- A virtual environment with the script's own dependencies installed (`puffin venv && puffin pip sync scripts/bench/requirements.txt`).
- A local uv release build (`cargo build --release`).
- A virtual environment with the script's own dependencies installed (`uv venv && uv pip sync scripts/bench/requirements.txt`).
- The [`hyperfine`](https://github.com/sharkdp/hyperfine) command-line tool installed on your system.
To benchmark Puffin's resolution against pip-compile and Poetry:
To benchmark uv's resolution against pip-compile and Poetry:
```shell
python -m scripts.bench \
--puffin \
--uv \
--poetry \
--pip-compile \
--benchmark resolve-warm \
@ -76,11 +76,11 @@ python -m scripts.bench \
--json
```
To benchmark Puffin's installation against pip-sync and Poetry:
To benchmark uv's installation against pip-sync and Poetry:
```shell
python -m scripts.bench \
--puffin \
--uv \
--poetry \
--pip-sync \
--benchmark install-warm \
@ -91,10 +91,10 @@ python -m scripts.bench \
After running the benchmark script, you can generate the corresponding graph via:
```shell
cargo run -p puffin-dev render-benchmarks resolve-warm.json --title "Warm Resolution"
cargo run -p puffin-dev render-benchmarks resolve-cold.json --title "Cold Resolution"
cargo run -p puffin-dev render-benchmarks install-warm.json --title "Warm Installation"
cargo run -p puffin-dev render-benchmarks install-cold.json --title "Cold Installation"
cargo run -p uv-dev render-benchmarks resolve-warm.json --title "Warm Resolution"
cargo run -p uv-dev render-benchmarks resolve-cold.json --title "Cold Resolution"
cargo run -p uv-dev render-benchmarks install-warm.json --title "Warm Installation"
cargo run -p uv-dev render-benchmarks install-cold.json --title "Cold Installation"
```
You need to install the [Roboto Font](https://fonts.google.com/specimen/Roboto) if the labels are missing in the generated graph.

View file

@ -2,7 +2,7 @@
## Setup
[Rust](https://rustup.rs/), a C compiler, and CMake are required to build Puffin.
[Rust](https://rustup.rs/), a C compiler, and CMake are required to build uv.
### Linux
@ -35,7 +35,7 @@ You can install CMake from the [installers](https://cmake.org/download/) or with
## Testing
Testing Puffin requires multiple specific Python versions. You can install them into
Testing uv requires multiple specific Python versions. You can install them into
`<project root>/bin` via our bootstrapping script:
```shell
@ -55,10 +55,10 @@ For running tests, we recommend [nextest](https://nexte.st/).
Source distributions can run arbitrary code on build and can make unwanted modifications to your system (https://moyix.blogspot.com/2022/09/someones-been-messing-with-my-subnormals.html, https://pypi.org/project/nvidia-pyindex/), which can even occur when just resolving requirements. To prevent this, there's a Docker container you can run commands in:
```bash
docker buildx build -t puffin-builder -f builder.dockerfile --load .
docker buildx build -t uv-builder -f builder.dockerfile --load .
# Build for musl to avoid glibc errors, might not be required with your OS version
cargo build --target x86_64-unknown-linux-musl --profile profiling --features vendored-openssl
docker run --rm -it -v $(pwd):/app puffin-builder /app/target/x86_64-unknown-linux-musl/profiling/puffin-dev resolve-many --cache-dir /app/cache-docker /app/scripts/popular_packages/pypi_10k_most_dependents.txt
docker run --rm -it -v $(pwd):/app uv-builder /app/target/x86_64-unknown-linux-musl/profiling/uv-dev resolve-many --cache-dir /app/cache-docker /app/scripts/popular_packages/pypi_10k_most_dependents.txt
```
We recommend using this container if you don't trust the dependency tree of the package(s) you are trying to resolve or install.
@ -66,16 +66,16 @@ We recommend using this container if you don't trust the dependency tree of the
## Profiling
Please refer to Ruff's [Profiling Guide](https://github.com/astral-sh/ruff/blob/main/CONTRIBUTING.md#profiling-projects), it applies to Puffin, too.
Please refer to Ruff's [Profiling Guide](https://github.com/astral-sh/ruff/blob/main/CONTRIBUTING.md#profiling-projects), it applies to uv, too.
### Analysing concurrency
You can use [tracing-durations-export](https://github.com/konstin/tracing-durations-export) to visualize parallel requests and find any spots where Puffin is CPU-bound. Example usage, with `puffin` and `puffin-dev` respectively:
You can use [tracing-durations-export](https://github.com/konstin/tracing-durations-export) to visualize parallel requests and find any spots where uv is CPU-bound. Example usage, with `uv` and `uv-dev` respectively:
```bash
RUST_LOG=puffin=info TRACING_DURATIONS_FILE=target/traces/jupyter.ndjson cargo run --features tracing-durations-export --profile profiling -- pip compile scripts/requirements/jupyter.in
RUST_LOG=uv=info TRACING_DURATIONS_FILE=target/traces/jupyter.ndjson cargo run --features tracing-durations-export --profile profiling -- pip compile scripts/requirements/jupyter.in
```
```bash
RUST_LOG=puffin=info TRACING_DURATIONS_FILE=target/traces/jupyter.ndjson cargo run --features tracing-durations-export --bin puffin-dev --profile profiling -- resolve jupyter
RUST_LOG=uv=info TRACING_DURATIONS_FILE=target/traces/jupyter.ndjson cargo run --features tracing-durations-export --bin uv-dev --profile profiling -- resolve jupyter
```

1002
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -3,17 +3,17 @@ members = ["crates/*"]
exclude = [
"scripts",
# Needs nightly
"crates/puffin-trampoline"
"crates/uv-trampoline"
]
resolver = "2"
[workspace.package]
edition = "2021"
rust-version = "1.74"
homepage = "https://pypi.org/project/puffin-alpha/"
documentation = "https://pypi.org/project/puffin-alpha/"
repository = "https://github.com/astral-sh/puffin"
authors = ["Puffin"]
homepage = "https://pypi.org/project/uv/"
documentation = "https://pypi.org/project/uv/"
repository = "https://github.com/astral-sh/uv"
authors = ["uv"]
license = "MIT OR Apache-2.0"
[workspace.dependencies]

View file

@ -3,13 +3,13 @@ ENV HOME="/root"
WORKDIR $HOME
RUN apt update \
&& apt install -y --no-install-recommends \
build-essential \
curl \
python3-venv \
cmake \
&& apt clean \
&& rm -rf /var/lib/apt/lists/*
&& apt install -y --no-install-recommends \
build-essential \
curl \
python3-venv \
cmake \
&& apt clean \
&& rm -rf /var/lib/apt/lists/*
# Setup zig as cross compiling linker
RUN python3 -m venv $HOME/.venv
@ -19,10 +19,10 @@ ENV PATH="$HOME/.venv/bin:$PATH"
# Install rust
ARG TARGETPLATFORM
RUN case "$TARGETPLATFORM" in \
"linux/arm64") echo "aarch64-unknown-linux-musl" > rust_target.txt ;; \
"linux/amd64") echo "x86_64-unknown-linux-musl" > rust_target.txt ;; \
*) exit 1 ;; \
esac
"linux/arm64") echo "aarch64-unknown-linux-musl" > rust_target.txt ;; \
"linux/amd64") echo "x86_64-unknown-linux-musl" > rust_target.txt ;; \
*) exit 1 ;; \
esac
# Update rustup whenever we bump the rust version
COPY rust-toolchain.toml rust-toolchain.toml
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --target $(cat rust_target.txt) --profile minimal --default-toolchain none
@ -34,12 +34,12 @@ RUN rustup target add $(cat rust_target.txt)
COPY crates crates
COPY ./Cargo.toml Cargo.toml
COPY ./Cargo.lock Cargo.lock
RUN cargo zigbuild --bin puffin --target $(cat rust_target.txt) --release
RUN cp target/$(cat rust_target.txt)/release/puffin /puffin
RUN cargo zigbuild --bin uv --target $(cat rust_target.txt) --release
RUN cp target/$(cat rust_target.txt)/release/uv /uv
# TODO(konsti): Optimize binary size, with a version that also works when cross compiling
# RUN strip --strip-all /puffin
# RUN strip --strip-all /uv
FROM scratch
COPY --from=build /puffin /puffin
COPY --from=build /uv /uv
WORKDIR /io
ENTRYPOINT ["/puffin"]
ENTRYPOINT ["/uv"]

166
README.md
View file

@ -1,24 +1,24 @@
# Puffin
# uv
[![Puffin](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/puffin/main/assets/badge/v0.json)](https://github.com/astral-sh/puffin)
[![image](https://img.shields.io/pypi/v/puffin-alpha.svg)](https://pypi.python.org/pypi/puffin-alpha)
[![image](https://img.shields.io/pypi/l/puffin-alpha.svg)](https://pypi.python.org/pypi/puffin-alpha)
[![image](https://img.shields.io/pypi/pyversions/puffin-alpha.svg)](https://pypi.python.org/pypi/puffin-alpha)
[![Actions status](https://github.com/astral-sh/puffin/workflows/CI/badge.svg)](https://github.com/astral-sh/puffin/actions)
[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
[![image](https://img.shields.io/pypi/v/uv.svg)](https://pypi.python.org/pypi/uv)
[![image](https://img.shields.io/pypi/l/uv.svg)](https://pypi.python.org/pypi/uv)
[![image](https://img.shields.io/pypi/pyversions/uv.svg)](https://pypi.python.org/pypi/uv)
[![Actions status](https://github.com/astral-sh/uv/workflows/CI/badge.svg)](https://github.com/astral-sh/uv/actions)
[![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?logo=discord&logoColor=white)](https://discord.gg/astral-sh)
An extremely fast Python package installer and resolver, written in Rust. Designed as a drop-in
replacement for `pip` and `pip-compile`.
Puffin is backed by [Astral](https://astral.sh), the creators of [Ruff](https://github.com/astral-sh/ruff).
uv is backed by [Astral](https://astral.sh), the creators of [Ruff](https://github.com/astral-sh/ruff).
## Highlights
- ⚖️ Drop-in replacement for common `pip`, `pip-tools`, and `virtualenv` commands.
- ⚡️ [10-100x faster](https://github.com/astral-sh/puffin/blob/main/BENCHMARKS.md) than `pip`
- ⚡️ [10-100x faster](https://github.com/astral-sh/uv/blob/main/BENCHMARKS.md) than `pip`
and `pip-tools` (`pip-compile` and `pip-sync`).
- 💾 Disk-space efficient, with a global cache for dependency deduplication.
- 🐍 Installable via `curl`, `pip`, `pipx`, etc. Puffin is a static binary that can be installed
- 🐍 Installable via `curl`, `pip`, `pipx`, etc. uv is a static binary that can be installed
without Rust or Python.
- 🧪 Tested at-scale against the top 10,000 PyPI packages.
- 🖥️ Support for macOS, Linux, and Windows.
@ -31,85 +31,85 @@ Puffin is backed by [Astral](https://astral.sh), the creators of [Ruff](https://
## Getting Started
Install Puffin with our standalone installers, or from [PyPI](https://pypi.org/project/puffin/):
Install uv with our standalone installers, or from [PyPI](https://pypi.org/project/uv/):
```shell
# On macOS and Linux.
curl -LsSf https://astral.sh/puffin/install.sh | sh
curl -LsSf https://astral.sh/uv/install.sh | sh
# On Windows.
irm https://astral.sh/puffin/install.ps1 | iex
irm https://astral.sh/uv/install.ps1 | iex
# With pip.
pip install puffin
pip install uv
# With pipx.
pipx install puffin
pipx install uv
```
To create a virtual environment:
```shell
puffin venv # Create a virtual environment at .venv.
uv venv # Create a virtual environment at .venv.
```
To install a package into the virtual environment:
```shell
puffin pip install flask # Install Flask.
puffin pip install -r requirements.txt # Install from a requirements.txt file.
puffin pip install -e . # Install the current project in editable mode.
uv pip install flask # Install Flask.
uv pip install -r requirements.txt # Install from a requirements.txt file.
uv pip install -e . # Install the current project in editable mode.
```
To generate a set of locked dependencies from an input file:
```shell
puffin pip compile pyproject.toml -o requirements.txt # Read a pyproject.toml file.
puffin pip compile requirements.in -o requirements.txt # Read a requirements.in file.
uv pip compile pyproject.toml -o requirements.txt # Read a pyproject.toml file.
uv pip compile requirements.in -o requirements.txt # Read a requirements.in file.
```
To sync a set of locked dependencies with the virtual environment:
```shell
puffin pip sync requirements.txt # Install from a requirements.txt file.
uv pip sync requirements.txt # Install from a requirements.txt file.
```
Puffin's `pip-install` and `pip-compile` commands supports many of the same command-line arguments
uv's `pip-install` and `pip-compile` commands supports many of the same command-line arguments
as existing tools, including `-r requirements.txt`, `-c constraints.txt`, `-e .` (for editable
installs), `--index-url`, and more.
## Limitations
Puffin does not support the entire `pip` feature set. Namely, Puffin does not (and does not plan to)
uv does not support the entire `pip` feature set. Namely, uv does not (and does not plan to)
support the following `pip` features:
- `.egg` dependencies
- Editable installs for Git and direct URL dependencies (editable installs _are_ supported for local
dependencies)
On the other hand, Puffin plans to (but does not currently) support:
On the other hand, uv plans to (but does not currently) support:
- [Hash-checking mode](https://github.com/astral-sh/puffin/issues/474)
- [URL requirements without package names](https://github.com/astral-sh/puffin/issues/313)
- [Hash-checking mode](https://github.com/astral-sh/uv/issues/474)
- [URL requirements without package names](https://github.com/astral-sh/uv/issues/313)
(e.g., `https://...` instead of `package @ https://...`)
Like `pip-compile`, Puffin generates a platform-specific `requirements.txt` file (unlike, e.g.,
Like `pip-compile`, uv generates a platform-specific `requirements.txt` file (unlike, e.g.,
`poetry` and `pdm`, which generate platform-agnostic `poetry.lock` and `pdm.lock` files). As such,
Puffin's `requirements.txt` files may not be portable across platforms and Python versions.
uv's `requirements.txt` files may not be portable across platforms and Python versions.
## Roadmap
Puffin is an extremely fast Python package resolver and installer, designed as a drop-in
uv is an extremely fast Python package resolver and installer, designed as a drop-in
replacement for `pip`, `pip-tools` (`pip-compile` and `pip-sync`), and `virtualenv`.
Puffin represents an intermediary goal in our pursuit of a ["Cargo for Python"](https://blog.rust-lang.org/2016/05/05/cargo-pillars.html#pillars-of-cargo):
uv represents an intermediary goal in our pursuit of a ["Cargo for Python"](https://blog.rust-lang.org/2016/05/05/cargo-pillars.html#pillars-of-cargo):
a comprehensive project and package manager that is extremely fast, reliable, and easy to use.
Think: a single binary that bootstraps your Python installation and gives you everything you need to
be productive with Python, bundling not only `pip`, `pip-tools`, and `virtualenv`, but also `pipx`,
`tox`, `poetry`, `pyenv`, `ruff`, and more.
Our goal is to evolve Puffin into such a tool.
Our goal is to evolve uv into such a tool.
In the meantime, though, the narrower `pip-tools` scope allows us to solve the low-level problems
involved in building such a tool (like package installation) while shipping something immediately
@ -119,20 +119,20 @@ useful with minimal barrier to adoption.
### Python discovery
Puffin itself does not depend on Python, but it does need to locate a Python environment to (1)
uv itself does not depend on Python, but it does need to locate a Python environment to (1)
install dependencies into the environment and (2) build source distributions.
When running `pip sync` or `pip install`, Puffin will search for a virtual environment in the
When running `pip sync` or `pip install`, uv will search for a virtual environment in the
following order:
- An activated virtual environment based on the `VIRTUAL_ENV` environment variable.
- An activated Conda environment based on the `CONDA_PREFIX` environment variable.
- A virtual environment at `.venv` in the current directory, or in the nearest parent directory.
If no virtual environment is found, Puffin will prompt the user to create one in the current
directory via `puffin venv`.
If no virtual environment is found, uv will prompt the user to create one in the current
directory via `uv venv`.
When running `pip compile`, Puffin does not _require_ a virtual environment and will search for a
When running `pip compile`, uv does not _require_ a virtual environment and will search for a
Python interpreter in the following order:
- An activated virtual environment based on the `VIRTUAL_ENV` environment variable.
@ -140,51 +140,51 @@ Python interpreter in the following order:
- A virtual environment at `.venv` in the current directory, or in the nearest parent directory.
- The Python interpreter available as `python3` on macOS and Linux, or `python.exe` on Windows.
If a `--python-version` is provided to `pip compile` (e.g., `--python-version=3.7`), Puffin will
If a `--python-version` is provided to `pip compile` (e.g., `--python-version=3.7`), uv will
search for a Python interpreter matching that version in the following order:
- An activated virtual environment based on the `VIRTUAL_ENV` environment variable.
- An activated Conda environment based on the `CONDA_PREFIX` environment variable.
- A virtual environment at `.venv` in the current directory, or in the nearest parent directory.
- The Python interpreter available as, e.g., `python3.7` on macOS and Linux. On Windows, Puffin
- The Python interpreter available as, e.g., `python3.7` on macOS and Linux. On Windows, uv
will use the same mechanism as `py --list-paths` to discover all available Python interpreters,
and will select the first interpreter matching the requested version.
- The Python interpreter available as `python3` on macOS and Linux, or `python.exe` on Windows.
Since Puffin has no dependency on Python, it can even install into virtual environments other than
its own. For example, setting `VIRTUAL_ENV=/path/to/venv` will cause Puffin to install into
`/path/to/venv`, no matter where Puffin is installed.
Since uv has no dependency on Python, it can even install into virtual environments other than
its own. For example, setting `VIRTUAL_ENV=/path/to/venv` will cause uv to install into
`/path/to/venv`, no matter where uv is installed.
### Dependency caching
Puffin uses aggressive caching to avoid re-downloading (and re-building dependencies) that have
uv uses aggressive caching to avoid re-downloading (and re-building dependencies) that have
already been accessed in prior runs.
The specifics of Puffin's caching semantics vary based on the nature of the dependency:
The specifics of uv's caching semantics vary based on the nature of the dependency:
- **For registry dependencies** (like those downloaded from PyPI), Puffin respects HTTP caching headers.
- **For direct URL dependencies**, Puffin respects HTTP caching headers, and also caches based on
- **For registry dependencies** (like those downloaded from PyPI), uv respects HTTP caching headers.
- **For direct URL dependencies**, uv respects HTTP caching headers, and also caches based on
the URL itself.
- **For Git dependencies**, Puffin caches based on the fully-resolved Git commit hash. As such,
`puffin pip compile` will pin Git dependencies to a specific commit hash when writing the resolved
- **For Git dependencies**, uv caches based on the fully-resolved Git commit hash. As such,
`uv pip compile` will pin Git dependencies to a specific commit hash when writing the resolved
dependency set.
- **For local dependencies**, Puffin caches based on the last-modified time of the `setup.py` or
- **For local dependencies**, uv caches based on the last-modified time of the `setup.py` or
`pyproject.toml` file.
If you're running into caching issues, Puffin includes a few escape hatches:
If you're running into caching issues, uv includes a few escape hatches:
- To force Puffin to revalidate cached data for all dependencies, run `puffin pip install --refresh ...`.
- To force Puffin to revalidate cached data for a specific dependency, run, e.g., `puffin pip install --refresh-package flask ...`.
- To force Puffin to ignore existing installed versions, run `puffin pip install --reinstall ...`.
- To clear the global cache entirely, run `puffin clean`.
- To force uv to revalidate cached data for all dependencies, run `uv pip install --refresh ...`.
- To force uv to revalidate cached data for a specific dependency, run, e.g., `uv pip install --refresh-package flask ...`.
- To force uv to ignore existing installed versions, run `uv pip install --reinstall ...`.
- To clear the global cache entirely, run `uv clean`.
### Resolution strategy
By default, Puffin follows the standard Python dependency resolution strategy of preferring the
latest compatible version of each package. For example, `puffin pip install flask>=2.0.0` will
By default, uv follows the standard Python dependency resolution strategy of preferring the
latest compatible version of each package. For example, `uv pip install flask>=2.0.0` will
install the latest version of Flask (at time of writing: `3.0.0`).
However, Puffin's resolution strategy be configured to prefer the _lowest_ compatible version of
However, uv's resolution strategy be configured to prefer the _lowest_ compatible version of
each package (`--resolution=lowest`), or even the lowest compatible version of any _direct_
dependencies (`--resolution=lowest-direct`), both of which can be useful for library authors looking
to test their packages against the oldest supported versions of their dependencies.
@ -195,11 +195,11 @@ For example, given the following `requirements.in` file:
flask>=2.0.0
```
Running `puffin pip compile requirements.in` would produce the following `requirements.txt` file:
Running `uv pip compile requirements.in` would produce the following `requirements.txt` file:
```text
# This file was autogenerated by Puffin v0.0.1 via the following command:
# puffin pip compile requirements.in
# This file was autogenerated by uv v0.0.1 via the following command:
# uv pip compile requirements.in
blinker==1.7.0
# via flask
click==8.1.7
@ -217,11 +217,11 @@ werkzeug==3.0.1
# via flask
```
However, `puffin pip compile --resolution=lowest requirements.in` would instead produce:
However, `uv pip compile --resolution=lowest requirements.in` would instead produce:
```text
# This file was autogenerated by Puffin v0.0.1 via the following command:
# puffin pip compile requirements.in --resolution=lowest
# This file was autogenerated by uv v0.0.1 via the following command:
# uv pip compile requirements.in --resolution=lowest
click==7.1.2
# via flask
flask==2.0.0
@ -237,13 +237,13 @@ werkzeug==2.0.0
### Pre-release handling
By default, Puffin will accept pre-release versions during dependency resolution in two cases:
By default, uv will accept pre-release versions during dependency resolution in two cases:
1. If the package is a direct dependency, and its version markers include a pre-release specifier
(e.g., `flask>=2.0.0rc1`).
1. If _all_ published versions of a package are pre-releases.
If dependency resolution fails due to a transitive pre-release, Puffin will prompt the user to
If dependency resolution fails due to a transitive pre-release, uv will prompt the user to
re-run with `--prerelease=allow`, to allow pre-releases for all dependencies.
Alternatively, you can add the transitive dependency to your `requirements.in` file with
@ -251,7 +251,7 @@ pre-release specifier (e.g., `flask>=2.0.0rc1`) to opt in to pre-release support
dependency.
Pre-releases are [notoriously difficult](https://pubgrub-rs-guide.netlify.app/limitations/prerelease_versions)
to model, and are a frequent source of bugs in other packaging tools. Puffin's pre-release handling
to model, and are a frequent source of bugs in other packaging tools. uv's pre-release handling
is _intentionally_ limited and _intentionally_ requires user intervention to opt in to pre-releases
to ensure correctness, though pre-release handling will be revisited in future releases.
@ -260,7 +260,7 @@ to ensure correctness, though pre-release handling will be revisited in future r
Historically, `pip` has supported "constraints" (`-c constraints.txt`), which allows users to
narrow the set of acceptable versions for a given package.
Puffin supports constraints, but also takes this concept further by allowing users to _override_ the
uv supports constraints, but also takes this concept further by allowing users to _override_ the
acceptable versions of a package across the dependency tree via overrides (`-o overrides.txt`).
In short, overrides allow the user to lie to the resolver by overriding the declared dependencies
@ -278,28 +278,28 @@ hatch for erroneous upper version bounds.
### Multi-version resolution
Puffin's `pip-compile` command produces a resolution that's known to be compatible with the
current platform and Python version. Unlike Poetry, PDM, and other package managers, Puffin does
uv's `pip-compile` command produces a resolution that's known to be compatible with the
current platform and Python version. Unlike Poetry, PDM, and other package managers, uv does
not yet produce a machine-agnostic lockfile.
However, Puffin _does_ support resolving for alternate Python versions via the `--python-version`
command line argument. For example, if you're running Puffin on Python 3.9, but want to resolve for
Python 3.8, you can run `puffin pip compile --python-version=3.8 requirements.in` to produce a
However, uv _does_ support resolving for alternate Python versions via the `--python-version`
command line argument. For example, if you're running uv on Python 3.9, but want to resolve for
Python 3.8, you can run `uv pip compile --python-version=3.8 requirements.in` to produce a
Python 3.8-compatible resolution.
## Platform support
Puffin has Tier 1 support for the following platforms:
uv has Tier 1 support for the following platforms:
- macOS (Apple Silicon)
- macOS (x86_64)
- Linux (x86_64)
- Windows (x86_64)
Puffin is continuously built, tested, and developed against its Tier 1 platforms. Inspired by the
uv is continuously built, tested, and developed against its Tier 1 platforms. Inspired by the
Rust project, Tier 1 can be thought of as ["guaranteed to work"](https://doc.rust-lang.org/beta/rustc/platform-support.html).
Puffin has Tier 2 support (["guaranteed to build"](https://doc.rust-lang.org/beta/rustc/platform-support.html)) for the following platforms:
uv has Tier 2 support (["guaranteed to build"](https://doc.rust-lang.org/beta/rustc/platform-support.html)) for the following platforms:
- Linux (PPC64)
- Linux (PPC64LE)
@ -308,24 +308,24 @@ Puffin has Tier 2 support (["guaranteed to build"](https://doc.rust-lang.org/bet
- Linux (i686)
- Linux (s390x)
Puffin ships pre-built wheels to [PyPI](https://pypi.org/project/puffin-alpha/) for its Tier 1 and
uv ships pre-built wheels to [PyPI](https://pypi.org/project/uv/) for its Tier 1 and
Tier 2 platforms. However, while Tier 2 platforms are continuously built, they are not continuously
tested or developed against, and so stability may vary in practice.
Beyond the Tier 1 and Tier 2 platforms, Puffin is known to build on i686 Windows, and known _not_
Beyond the Tier 1 and Tier 2 platforms, uv is known to build on i686 Windows, and known _not_
to build on aarch64 Windows, but does not consider either platform to be supported at this time.
Puffin supports and is tested against Python 3.8, 3.9, 3.10, 3.11, and 3.12.
uv supports and is tested against Python 3.8, 3.9, 3.10, 3.11, and 3.12.
## Acknowledgements
Puffin's dependency resolver uses [PubGrub](https://github.com/pubgrub-rs/pubgrub) under the hood.
uv's dependency resolver uses [PubGrub](https://github.com/pubgrub-rs/pubgrub) under the hood.
We're grateful to the PubGrub maintainers, especially [Jacob Finkelman](https://github.com/Eh2406),
for their support.
Puffin's Git implementation is based on [Cargo](https://github.com/rust-lang/cargo).
uv's Git implementation is based on [Cargo](https://github.com/rust-lang/cargo).
Some of Puffin's optimizations are inspired by the great work we've seen in
Some of uv's optimizations are inspired by the great work we've seen in
[pnpm](https://pnpm.io/), [Orogene](https://github.com/orogene/orogene), and
[Bun](https://github.com/oven-sh/bun). We've also learned a lot from Nathaniel
J. Smith's [Posy](https://github.com/njsmith/posy) and adapted its [trampoline](https://github.com/njsmith/posy/tree/main/src/trampolines/windows-trampolines/posy-trampoline)
@ -333,7 +333,7 @@ for Windows support.
## License
Puffin is licensed under either of
uv is licensed under either of
- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
@ -341,11 +341,11 @@ Puffin is licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in Puffin by you, as defined in the Apache-2.0 license, shall be
for inclusion in uv by you, as defined in the Apache-2.0 license, shall be
dually licensed as above, without any additional terms or conditions.
<div align="center">
<a target="_blank" href="https://astral.sh" style="background:none">
<img src="https://raw.githubusercontent.com/astral-sh/puffin/main/assets/svg/Astral.svg">
<img src="https://raw.githubusercontent.com/astral-sh/uv/main/assets/svg/Astral.svg">
</a>
</div>

View file

@ -1,6 +1,6 @@
{
"label": "",
"message": "Puffin",
"message": "uv",
"logoSvg": "<svg width=\"510\" height=\"622\" viewBox=\"0 0 510 622\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M206.701 0C200.964 0 196.314 4.64131 196.314 10.3667V41.4667C196.314 47.192 191.663 51.8333 185.927 51.8333H156.843C151.107 51.8333 146.456 56.4746 146.456 62.2V145.133C146.456 150.859 141.806 155.5 136.069 155.5H106.986C101.249 155.5 96.5988 160.141 96.5988 165.867V222.883C96.5988 228.609 91.9484 233.25 86.2118 233.25H57.1283C51.3917 233.25 46.7413 237.891 46.7413 243.617V300.633C46.7413 306.359 42.0909 311 36.3544 311H10.387C4.6504 311 0 315.641 0 321.367V352.467C0 358.192 4.6504 362.833 10.387 362.833H145.418C151.154 362.833 155.804 367.475 155.804 373.2V430.217C155.804 435.942 151.154 440.583 145.418 440.583H116.334C110.597 440.583 105.947 445.225 105.947 450.95V507.967C105.947 513.692 101.297 518.333 95.5601 518.333H66.4766C60.74 518.333 56.0896 522.975 56.0896 528.7V611.633C56.0896 617.359 60.74 622 66.4766 622H149.572C155.309 622 159.959 617.359 159.959 611.633V570.167H201.507C207.244 570.167 211.894 565.525 211.894 559.8V528.7C211.894 522.975 216.544 518.333 222.281 518.333H251.365C257.101 518.333 261.752 513.692 261.752 507.967V476.867C261.752 471.141 266.402 466.5 272.138 466.5H301.222C306.959 466.5 311.609 461.859 311.609 456.133V425.033C311.609 419.308 316.259 414.667 321.996 414.667H351.079C356.816 414.667 361.466 410.025 361.466 404.3V373.2C361.466 367.475 366.117 362.833 371.853 362.833H400.937C406.673 362.833 411.324 358.192 411.324 352.467V321.367C411.324 315.641 415.974 311 421.711 311H450.794C456.531 311 461.181 306.359 461.181 300.633V217.7C461.181 211.975 456.531 207.333 450.794 207.333H420.672C414.936 207.333 410.285 202.692 410.285 196.967V165.867C410.285 160.141 414.936 155.5 420.672 155.5H449.756C455.492 155.5 460.143 150.859 460.143 145.133V114.033C460.143 108.308 464.793 103.667 470.53 103.667H499.613C505.35 103.667 510 99.0253 510 93.3V10.3667C510 4.64132 505.35 0 499.613 0H206.701ZM168.269 440.583C162.532 440.583 157.882 445.225 157.882 450.95V507.967C157.882 513.692 153.231 518.333 147.495 518.333H118.411C112.675 518.333 108.024 522.975 108.024 528.7V559.8C108.024 565.525 112.675 570.167 118.411 570.167H159.959V528.7C159.959 522.975 164.61 518.333 170.346 518.333H199.43C205.166 518.333 209.817 513.692 209.817 507.967V476.867C209.817 471.141 214.467 466.5 220.204 466.5H249.287C255.024 466.5 259.674 461.859 259.674 456.133V425.033C259.674 419.308 264.325 414.667 270.061 414.667H299.145C304.881 414.667 309.532 410.025 309.532 404.3V373.2C309.532 367.475 314.182 362.833 319.919 362.833H349.002C354.739 362.833 359.389 358.192 359.389 352.467V321.367C359.389 315.641 364.039 311 369.776 311H398.859C404.596 311 409.246 306.359 409.246 300.633V269.533C409.246 263.808 404.596 259.167 398.859 259.167H318.88C313.143 259.167 308.493 254.525 308.493 248.8V217.7C308.493 211.975 313.143 207.333 318.88 207.333H347.963C353.7 207.333 358.35 202.692 358.35 196.967V165.867C358.35 160.141 363.001 155.5 368.737 155.5H397.821C403.557 155.5 408.208 150.859 408.208 145.133V114.033C408.208 108.308 412.858 103.667 418.595 103.667H447.678C453.415 103.667 458.065 99.0253 458.065 93.3V62.2C458.065 56.4746 453.415 51.8333 447.678 51.8333H208.778C203.041 51.8333 198.391 56.4746 198.391 62.2V145.133C198.391 150.859 193.741 155.5 188.004 155.5H158.921C153.184 155.5 148.534 160.141 148.534 165.867V222.883C148.534 228.609 143.883 233.25 138.147 233.25H109.063C103.327 233.25 98.6762 237.891 98.6762 243.617V300.633C98.6762 306.359 103.327 311 109.063 311H197.352C203.089 311 207.739 315.641 207.739 321.367V430.217C207.739 435.942 203.089 440.583 197.352 440.583H168.269Z\" fill=\"#D7FF64\"/></svg>",
"logoWidth": 10,
"labelColor": "grey",

View file

@ -2,7 +2,7 @@
## [bench](./bench)
Functionality for benchmarking Puffin.
Functionality for benchmarking uv.
## [cache-key](./cache-key)
@ -47,79 +47,79 @@ Functionality for detecting the current platform (operating system, architecture
Functionality for parsing and inferring Python platform tags as per [PEP 425](https://peps.python.org/pep-0425/).
## [puffin](./puffin)
## [uv](./uv)
Command-line interface for the Puffin package manager.
Command-line interface for the uv package manager.
## [puffin-build](./puffin-build)
## [uv-build](./uv-build)
A [PEP 517](https://www.python.org/dev/peps/pep-0517/)-compatible build frontend for Puffin.
A [PEP 517](https://www.python.org/dev/peps/pep-0517/)-compatible build frontend for uv.
## [puffin-cache](./puffin-cache)
## [uv-cache](./uv-cache)
Functionality for caching Python packages and associated metadata.
## [puffin-client](./puffin-client)
## [uv-client](./uv-client)
Client for interacting with PyPI-compatible HTTP APIs.
## [puffin-dev](./puffin-dev)
## [uv-dev](./uv-dev)
Development utilities for Puffin.
Development utilities for uv.
## [puffin-dispatch](./puffin-dispatch)
## [uv-dispatch](./uv-dispatch)
A centralized `struct` for resolving and building source distributions in isolated environments.
Implements the traits defined in `puffin-traits`.
Implements the traits defined in `uv-traits`.
## [puffin-distribution](./puffin-distribution)
## [uv-distribution](./uv-distribution)
Client for interacting with built distributions (wheels) and source distributions (sdists).
Capable of fetching metadata, distribution contents, etc.
## [puffin-extract](./puffin-extract)
## [uv-extract](./uv-extract)
Utilities for extracting files from archives.
## [puffin-fs](./puffin-fs)
## [uv-fs](./uv-fs)
Utilities for interacting with the filesystem.
## [puffin-git](./puffin-git)
## [uv-git](./uv-git)
Functionality for interacting with Git repositories.
## [puffin-installer](./puffin-installer)
## [uv-installer](./uv-installer)
Functionality for installing Python packages into a virtual environment.
## [puffin-interpreter](./puffin-interpreter)
## [uv-interpreter](./uv-interpreter)
Functionality for detecting and leveraging the current Python interpreter.
## [puffin-normalize](./puffin-normalize)
## [uv-normalize](./uv-normalize)
Normalize package and extra names as per Python specifications.
## [puffin-package](./puffin-package)
## [uv-package](./uv-package)
Types and functionality for working with Python packages, e.g., parsing wheel files.
## [puffin-resolver](./puffin-resolver)
## [uv-resolver](./uv-resolver)
Functionality for resolving Python packages and their dependencies.
## [puffin-traits](./puffin-traits)
## [uv-traits](./uv-traits)
Shared traits for Puffin, to avoid circular dependencies.
Shared traits for uv, to avoid circular dependencies.
## [pypi-types](./pypi-types)
General-purpose type definitions for types used in PyPI-compatible APIs.
## [puffin-warnings](./puffin-warnings)
## [uv-warnings](./uv-warnings)
User-facing warnings for Puffin.
User-facing warnings for uv.
## [requirements-txt](./requirements-txt)

View file

@ -1,7 +1,7 @@
[package]
name = "bench"
version = "0.0.0"
description = "Puffin Micro-benchmarks"
description = "uv Micro-benchmarks"
publish = false
authors = { workspace = true }
edition = { workspace = true }

View file

@ -18,7 +18,7 @@ rkyv = ["dep:rkyv", "pep440_rs/rkyv"]
[dependencies]
pep440_rs = { path = "../pep440-rs" }
platform-tags = { path = "../platform-tags" }
puffin-normalize = { path = "../puffin-normalize" }
uv-normalize = { path = "../uv-normalize" }
rkyv = { workspace = true, features = ["strict", "validation"], optional = true }
serde = { workspace = true, optional = true }

View file

@ -1,7 +1,7 @@
use pep440_rs::Version;
use puffin_normalize::PackageName;
use std::fmt::{Display, Formatter};
use std::str::FromStr;
use uv_normalize::PackageName;
pub use source_dist::{SourceDistExtension, SourceDistFilename, SourceDistFilenameError};
pub use wheel::{WheelFilename, WheelFilenameError};

View file

@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use thiserror::Error;
use pep440_rs::{Version, VersionParseError};
use puffin_normalize::{InvalidNameError, PackageName};
use uv_normalize::{InvalidNameError, PackageName};
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@ -196,7 +196,7 @@ enum SourceDistFilenameErrorKind {
mod tests {
use std::str::FromStr;
use puffin_normalize::PackageName;
use uv_normalize::PackageName;
use crate::SourceDistFilename;

View file

@ -8,7 +8,7 @@ use url::Url;
use pep440_rs::{Version, VersionParseError};
use platform_tags::{TagCompatibility, Tags};
use puffin_normalize::{InvalidNameError, PackageName};
use uv_normalize::{InvalidNameError, PackageName};
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(

View file

@ -18,9 +18,9 @@ distribution-filename = { path = "../distribution-filename", features = ["serde"
pep440_rs = { path = "../pep440-rs" }
pep508_rs = { path = "../pep508-rs" }
platform-tags = { path = "../platform-tags" }
puffin-fs = { path = "../puffin-fs" }
puffin-git = { path = "../puffin-git", features = ["vendored-openssl"] }
puffin-normalize = { path = "../puffin-normalize" }
uv-fs = { path = "../uv-fs" }
uv-git = { path = "../uv-git", features = ["vendored-openssl"] }
uv-normalize = { path = "../uv-normalize" }
pypi-types = { path = "../pypi-types" }
anyhow = { workspace = true }

View file

@ -1,4 +1,4 @@
use puffin_normalize::PackageName;
use uv_normalize::PackageName;
use crate::cached::CachedDist;
use crate::installed::InstalledDist;

View file

@ -4,7 +4,7 @@ use anyhow::Result;
use distribution_filename::WheelFilename;
use pep508_rs::VerbatimUrl;
use puffin_normalize::PackageName;
use uv_normalize::PackageName;
use crate::direct_url::{DirectUrl, LocalFileUrl};
use crate::{

View file

@ -3,7 +3,7 @@ use std::path::PathBuf;
use anyhow::{Context, Error, Result};
use url::Url;
use puffin_git::{GitSha, GitUrl};
use uv_git::{GitSha, GitUrl};
#[derive(Debug)]
pub enum DirectUrl {

View file

@ -4,7 +4,7 @@ use std::path::PathBuf;
use url::Url;
use pep508_rs::VerbatimUrl;
use puffin_normalize::ExtraName;
use uv_normalize::ExtraName;
use crate::Verbatim;

View file

@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use url::Url;
use pep508_rs::split_scheme;
use puffin_fs::normalize_url_path;
use uv_fs::normalize_url_path;
static PYPI_URL: Lazy<Url> = Lazy::new(|| Url::parse("https://pypi.org/simple").unwrap());

View file

@ -6,8 +6,8 @@ use fs_err as fs;
use url::Url;
use pep440_rs::Version;
use puffin_fs::Normalized;
use puffin_normalize::PackageName;
use uv_fs::Normalized;
use uv_normalize::PackageName;
use crate::{InstalledMetadata, InstalledVersion, Name};

View file

@ -42,7 +42,7 @@ use url::Url;
use distribution_filename::{DistFilename, SourceDistFilename, WheelFilename};
use pep440_rs::Version;
use pep508_rs::VerbatimUrl;
use puffin_normalize::PackageName;
use uv_normalize::PackageName;
pub use crate::any::*;
pub use crate::cached::*;

View file

@ -1,7 +1,7 @@
use rustc_hash::FxHashMap;
use pep508_rs::Requirement;
use puffin_normalize::PackageName;
use uv_normalize::PackageName;
use crate::{BuiltDist, Dist, PathSourceDist, SourceDist};

View file

@ -3,7 +3,7 @@ use std::borrow::Cow;
use anyhow::Result;
use pep508_rs::VerbatimUrl;
use puffin_normalize::PackageName;
use uv_normalize::PackageName;
use crate::error::Error;
use crate::{

View file

@ -22,8 +22,8 @@ workspace = true
[dependencies]
platform-host = { path = "../platform-host" }
puffin-cache = { path = "../puffin-cache" }
puffin-interpreter = { path = "../puffin-interpreter" }
uv-cache = { path = "../uv-cache" }
uv-interpreter = { path = "../uv-interpreter" }
anstream = { workspace = true }
camino = { workspace = true }

View file

@ -9,7 +9,7 @@ use fs_err as fs;
use fs_err::File;
use tracing::info;
use puffin_interpreter::Interpreter;
use uv_interpreter::Interpreter;
/// The bash activate scripts with the venv dependent paths patches out
const ACTIVATE_TEMPLATES: &[(&str, &str)] = &[

View file

@ -6,7 +6,7 @@ use thiserror::Error;
pub use interpreter::parse_python_cli;
use platform_host::PlatformError;
use puffin_interpreter::{Interpreter, Virtualenv};
use uv_interpreter::{Interpreter, Virtualenv};
pub use crate::bare::create_bare_venv;

View file

@ -13,8 +13,8 @@ use tracing_subscriber::{fmt, EnvFilter};
use gourgeist::{create_bare_venv, parse_python_cli};
use platform_host::Platform;
use puffin_cache::Cache;
use puffin_interpreter::Interpreter;
use uv_cache::Cache;
use uv_interpreter::Interpreter;
#[derive(Parser, Debug)]
struct Cli {

View file

@ -23,8 +23,8 @@ name = "install_wheel_rs"
distribution-filename = { path = "../distribution-filename" }
pep440_rs = { path = "../pep440-rs" }
platform-host = { path = "../platform-host" }
puffin-normalize = { path = "../puffin-normalize" }
puffin-fs = { path = "../puffin-fs" }
uv-normalize = { path = "../uv-normalize" }
uv-fs = { path = "../uv-fs" }
pypi-types = { path = "../pypi-types" }
clap = { workspace = true, optional = true, features = ["derive", "env"] }

View file

@ -5,7 +5,7 @@ use fs2::FileExt;
use fs_err::File;
use tracing::{error, warn};
use puffin_fs::Normalized;
use uv_fs::Normalized;
const INSTALL_LOCKFILE: &str = "install-wheel-rs.lock";

View file

@ -14,11 +14,11 @@ use distribution_filename::WheelFilename;
pub use install_location::{normalize_name, InstallLocation, LockedDir};
use pep440_rs::Version;
use platform_host::{Arch, Os};
use puffin_fs::Normalized;
use puffin_normalize::PackageName;
pub use record::RecordEntry;
pub use script::Script;
pub use uninstall::{uninstall_wheel, Uninstall};
use uv_fs::Normalized;
use uv_normalize::PackageName;
pub use wheel::{
install_wheel, parse_key_value_file, read_record_file, relative_to, SHEBANG_PYTHON,
};
@ -86,7 +86,7 @@ pub enum Error {
#[error("Invalid wheel size")]
InvalidSize,
#[error("Invalid package name")]
InvalidName(#[from] puffin_normalize::InvalidNameError),
InvalidName(#[from] uv_normalize::InvalidNameError),
#[error("Invalid package version")]
InvalidVersion(#[from] pep440_rs::VersionParseError),
#[error("Wheel package name does not match filename: {0} != {1}")]

View file

@ -12,8 +12,8 @@ use tracing::{debug, instrument};
use distribution_filename::WheelFilename;
use pep440_rs::Version;
use puffin_normalize::PackageName;
use pypi_types::DirectUrl;
use uv_normalize::PackageName;
use crate::install_location::InstallLocation;
use crate::wheel::{

View file

@ -21,9 +21,9 @@ use zip::{ZipArchive, ZipWriter};
use distribution_filename::WheelFilename;
use pep440_rs::Version;
use puffin_fs::Normalized;
use puffin_normalize::PackageName;
use pypi_types::DirectUrl;
use uv_fs::Normalized;
use uv_normalize::PackageName;
use crate::install_location::{InstallLocation, LockedDir};
use crate::record::RecordEntry;
@ -35,19 +35,19 @@ pub const SHEBANG_PYTHON: &str = "#!/usr/bin/env python";
#[cfg(all(windows, target_arch = "x86_64"))]
const LAUNCHER_X86_64_GUI: &[u8] =
include_bytes!("../../puffin-trampoline/trampolines/puffin-trampoline-x86_64-gui.exe");
include_bytes!("../../uv-trampoline/trampolines/uv-trampoline-x86_64-gui.exe");
#[cfg(all(windows, target_arch = "x86_64"))]
const LAUNCHER_X86_64_CONSOLE: &[u8] =
include_bytes!("../../puffin-trampoline/trampolines/puffin-trampoline-x86_64-console.exe");
include_bytes!("../../uv-trampoline/trampolines/uv-trampoline-x86_64-console.exe");
#[cfg(all(windows, target_arch = "aarch64"))]
const LAUNCHER_AARCH64_GUI: &[u8] =
include_bytes!("../../puffin-trampoline/trampolines/puffin-trampoline-aarch64-gui.exe");
include_bytes!("../../uv-trampoline/trampolines/uv-trampoline-aarch64-gui.exe");
#[cfg(all(windows, target_arch = "aarch64"))]
const LAUNCHER_AARCH64_CONSOLE: &[u8] =
include_bytes!("../../puffin-trampoline/trampolines/puffin-trampoline-aarch64-console.exe");
include_bytes!("../../uv-trampoline/trampolines/uv-trampoline-aarch64-console.exe");
/// Wrapper script template function
///

View file

@ -18,8 +18,8 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
pep440_rs = { path = "../pep440-rs" }
puffin-fs = { path = "../puffin-fs" }
puffin-normalize = { path = "../puffin-normalize" }
uv-fs = { path = "../uv-fs" }
uv-normalize = { path = "../uv-normalize" }
derivative = { workspace = true }
once_cell = { workspace = true }

View file

@ -6,7 +6,7 @@
//! ```
//! use std::str::FromStr;
//! use pep508_rs::Requirement;
//! use puffin_normalize::ExtraName;
//! use uv_normalize::ExtraName;
//!
//! let marker = r#"requests [security,tests] >= 2.8.1, == 2.8.* ; python_version > "3.8""#;
//! let dependency_specification = Requirement::from_str(marker).unwrap();
@ -42,10 +42,10 @@ pub use marker::{
MarkerValueString, MarkerValueVersion, MarkerWarningKind, StringVersion,
};
use pep440_rs::{Version, VersionSpecifier, VersionSpecifiers};
use puffin_fs::normalize_url_path;
use uv_fs::normalize_url_path;
#[cfg(feature = "pyo3")]
use puffin_normalize::InvalidNameError;
use puffin_normalize::{ExtraName, PackageName};
use uv_normalize::InvalidNameError;
use uv_normalize::{ExtraName, PackageName};
pub use verbatim_url::{split_scheme, VerbatimUrl};
mod marker;
@ -1008,7 +1008,7 @@ mod tests {
use indoc::indoc;
use pep440_rs::{Operator, Version, VersionPattern, VersionSpecifier};
use puffin_normalize::{ExtraName, PackageName};
use uv_normalize::{ExtraName, PackageName};
use crate::marker::{
parse_markers_impl, MarkerExpression, MarkerOperator, MarkerTree, MarkerValue,

View file

@ -11,7 +11,6 @@
use crate::{Cursor, Pep508Error, Pep508ErrorSource};
use pep440_rs::{Version, VersionPattern, VersionSpecifier};
use puffin_normalize::ExtraName;
#[cfg(feature = "pyo3")]
use pyo3::{
basic::CompareOp, exceptions::PyValueError, pyclass, pymethods, PyAny, PyResult, Python,
@ -23,6 +22,7 @@ use std::fmt::{Display, Formatter};
use std::ops::Deref;
use std::str::FromStr;
use tracing::warn;
use uv_normalize::ExtraName;
/// Ways in which marker evaluation can fail
#[derive(Debug, Eq, Hash, Ord, PartialOrd, PartialEq, Clone, Copy)]
@ -731,7 +731,7 @@ impl MarkerExpression {
/// # use std::str::FromStr;
/// # use pep508_rs::{MarkerTree, Pep508Error};
/// # use pep440_rs::Version;
/// # use puffin_normalize::ExtraName;
/// # use uv_normalize::ExtraName;
///
/// # fn main() -> Result<(), Pep508Error> {
/// let marker_tree = MarkerTree::from_str(r#"("linux" in sys_platform) and extra == 'day'"#)?;

View file

@ -15,7 +15,7 @@ workspace = true
[dependencies]
pep440_rs = { path = "../pep440-rs", features = ["rkyv", "serde"] }
pep508_rs = { path = "../pep508-rs", features = ["rkyv", "serde"] }
puffin-normalize = { path = "../puffin-normalize" }
uv-normalize = { path = "../uv-normalize" }
chrono = { workspace = true, features = ["serde"] }
mailparse = { workspace = true }

View file

@ -9,7 +9,7 @@ use thiserror::Error;
use pep440_rs::{Version, VersionParseError, VersionSpecifiers, VersionSpecifiersParseError};
use pep508_rs::{Pep508Error, Requirement};
use puffin_normalize::{ExtraName, InvalidNameError, PackageName};
use uv_normalize::{ExtraName, InvalidNameError, PackageName};
use crate::lenient_requirement::LenientRequirement;
use crate::LenientVersionSpecifiers;
@ -145,7 +145,7 @@ mod tests {
use std::str::FromStr;
use pep440_rs::Version;
use puffin_normalize::PackageName;
use uv_normalize::PackageName;
use crate::Error;

View file

@ -15,8 +15,8 @@ workspace = true
[dependencies]
pep440_rs = { path = "../pep440-rs", features = ["rkyv", "serde"] }
pep508_rs = { path = "../pep508-rs", features = ["rkyv", "serde"] }
puffin-fs = { path = "../puffin-fs" }
puffin-normalize = { path = "../puffin-normalize" }
uv-fs = { path = "../uv-fs" }
uv-normalize = { path = "../uv-normalize" }
fs-err = { workspace = true }
once_cell = { workspace = true }

View file

@ -45,8 +45,8 @@ use unscanny::{Pattern, Scanner};
use url::Url;
use pep508_rs::{split_scheme, Extras, Pep508Error, Pep508ErrorSource, Requirement, VerbatimUrl};
use puffin_fs::{normalize_url_path, Normalized};
use puffin_normalize::ExtraName;
use uv_fs::{normalize_url_path, Normalized};
use uv_normalize::ExtraName;
/// We emit one of those for each requirements.txt entry
enum RequirementsTxtStatement {
@ -298,12 +298,11 @@ impl RequirementsTxt {
requirements_txt: impl AsRef<Path>,
working_dir: impl AsRef<Path>,
) -> Result<Self, RequirementsTxtFileError> {
let content = puffin_fs::read_to_string(&requirements_txt).map_err(|err| {
RequirementsTxtFileError {
let content =
uv_fs::read_to_string(&requirements_txt).map_err(|err| RequirementsTxtFileError {
file: requirements_txt.as_ref().to_path_buf(),
error: RequirementsTxtParserError::IO(err),
}
})?;
})?;
let data = Self::parse_inner(&content, working_dir.as_ref()).map_err(|err| {
RequirementsTxtFileError {
file: requirements_txt.as_ref().to_path_buf(),
@ -936,9 +935,9 @@ mod test {
use fs_err as fs;
use indoc::indoc;
use itertools::Itertools;
use puffin_fs::Normalized;
use tempfile::tempdir;
use test_case::test_case;
use uv_fs::Normalized;
use crate::{EditableRequirement, RequirementsTxt};

View file

@ -1,5 +1,5 @@
[package]
name = "puffin-build"
name = "uv-build"
version = "0.0.1"
description = "Build wheels from source distributions"
edition = { workspace = true }
@ -18,10 +18,10 @@ distribution-types = { path = "../distribution-types" }
gourgeist = { path = "../gourgeist" }
pep508_rs = { path = "../pep508-rs" }
platform-host = { path = "../platform-host" }
puffin-extract = { path = "../puffin-extract" }
puffin-fs = { path = "../puffin-fs" }
puffin-interpreter = { path = "../puffin-interpreter" }
puffin-traits = { path = "../puffin-traits" }
uv-extract = { path = "../uv-extract" }
uv-fs = { path = "../uv-fs" }
uv-interpreter = { path = "../uv-interpreter" }
uv-traits = { path = "../uv-traits" }
pypi-types = { path = "../pypi-types" }
anyhow = { workspace = true }

View file

@ -27,9 +27,9 @@ use tracing::{debug, info_span, instrument, Instrument};
use distribution_types::Resolution;
use pep508_rs::Requirement;
use puffin_fs::Normalized;
use puffin_interpreter::{Interpreter, Virtualenv};
use puffin_traits::{BuildContext, BuildKind, SetupPyStrategy, SourceBuildTrait};
use uv_fs::Normalized;
use uv_interpreter::{Interpreter, Virtualenv};
use uv_traits::{BuildContext, BuildKind, SetupPyStrategy, SourceBuildTrait};
/// e.g. `pygraphviz/graphviz_wrap.c:3020:10: fatal error: graphviz/cgraph.h: No such file or directory`
static MISSING_HEADER_RE: Lazy<Regex> = Lazy::new(|| {
@ -59,7 +59,7 @@ pub enum Error {
#[error(transparent)]
IO(#[from] io::Error),
#[error("Failed to extract archive: {0}")]
Extraction(PathBuf, #[source] puffin_extract::Error),
Extraction(PathBuf, #[source] uv_extract::Error),
#[error("Unsupported archive format (extension not recognized): {0}")]
UnsupportedArchiveType(String),
#[error("Invalid source distribution: {0}")]
@ -301,11 +301,11 @@ impl SourceBuild {
let extracted = temp_dir.path().join("extracted");
// Unzip the archive into the temporary directory.
puffin_extract::archive(source, &extracted)
uv_extract::archive(source, &extracted)
.map_err(|err| Error::Extraction(extracted.clone(), err))?;
// Extract the top-level directory from the archive.
puffin_extract::strip_component(&extracted)
uv_extract::strip_component(&extracted)
.map_err(|err| Error::Extraction(extracted.clone(), err))?
};
let source_tree = if let Some(subdir) = subdirectory {
@ -542,7 +542,7 @@ impl SourceBuild {
let wheel_dir = fs::canonicalize(wheel_dir)?;
if let Some(pep517_backend) = &self.pep517_backend {
// Prevent clashes from two puffin processes building wheels in parallel.
// Prevent clashes from two uv processes building wheels in parallel.
let tmp_dir = tempdir_in(&wheel_dir)?;
let filename = self.pep517_build(tmp_dir.path(), pep517_backend).await?;

View file

@ -1,5 +1,5 @@
[package]
name = "puffin-cache"
name = "uv-cache"
version = "0.0.1"
description = "Generate stable hash digests across versions and platforms."
edition = { workspace = true }
@ -16,8 +16,8 @@ workspace = true
[dependencies]
cache-key = { path = "../cache-key" }
distribution-types = { path = "../distribution-types" }
puffin-fs = { path = "../puffin-fs" }
puffin-normalize = { path = "../puffin-normalize" }
uv-fs = { path = "../uv-fs" }
uv-normalize = { path = "../uv-normalize" }
pypi-types = { path = "../pypi-types" }
cachedir = { workspace = true }

View file

@ -26,7 +26,7 @@ impl TryFrom<CacheArgs> for Cache {
/// 1. A temporary cache directory, if the user requested `--no-cache`.
/// 2. The specific cache directory specified by the user via `--cache-dir` or `PUFFIN_CACHE_DIR`.
/// 3. The system-appropriate cache directory.
/// 4. A `.puffin_cache` directory in the current working directory.
/// 4. A `.uv_cache` directory in the current working directory.
///
/// Returns an absolute cache dir.
fn try_from(value: CacheArgs) -> Result<Self, Self::Error> {
@ -34,10 +34,10 @@ impl TryFrom<CacheArgs> for Cache {
Cache::temp()
} else if let Some(cache_dir) = value.cache_dir {
Cache::from_path(cache_dir)
} else if let Some(project_dirs) = ProjectDirs::from("", "", "puffin") {
} else if let Some(project_dirs) = ProjectDirs::from("", "", "uv") {
Cache::from_path(project_dirs.cache_dir())
} else {
Cache::from_path(".puffin_cache")
Cache::from_path(".uv_cache")
}
}
}

View file

@ -8,8 +8,8 @@ use std::sync::Arc;
use fs_err as fs;
use tempfile::{tempdir, TempDir};
use puffin_fs::directories;
use puffin_normalize::PackageName;
use uv_fs::directories;
use uv_normalize::PackageName;
pub use crate::by_timestamp::CachedByTimestamp;
#[cfg(feature = "clap")]
@ -219,7 +219,7 @@ impl Cache {
// Create a symlink to the directory store.
fs_err::create_dir_all(path.as_ref().parent().expect("Cache entry to have parent"))?;
puffin_fs::replace_symlink(archive_entry.path(), path.as_ref())?;
uv_fs::replace_symlink(archive_entry.path(), path.as_ref())?;
Ok(archive_entry.into_path_buf())
}
@ -283,7 +283,7 @@ pub enum CacheBucket {
/// * `wheel-metadata-v0/<digest(index-url)>/foo/{foo-1.0.0-py3-none-any.msgpack, foo-1.0.0-py3-none-any.whl}`
/// * `wheel-metadata-v0/url/<digest(url)>/foo/{foo-1.0.0-py3-none-any.msgpack, foo-1.0.0-py3-none-any.whl}`
///
/// See `puffin_client::RegistryClient::wheel_metadata` for information on how wheel metadata
/// See `uv_client::RegistryClient::wheel_metadata` for information on how wheel metadata
/// is fetched.
///
/// # Example
@ -478,7 +478,7 @@ pub enum CacheBucket {
/// },
/// "base_exec_prefix": "/home/ferris/.pyenv/versions/3.12.0",
/// "base_prefix": "/home/ferris/.pyenv/versions/3.12.0",
/// "sys_executable": "/home/ferris/projects/puffin/.venv/bin/python"
/// "sys_executable": "/home/ferris/projects/uv/.venv/bin/python"
/// }
/// }
/// ```
@ -491,7 +491,7 @@ pub enum CacheBucket {
/// * `simple-v0/pypi/<package_name>.rkyv`
/// * `simple-v0/<digest(index_url)>/<package_name>.rkyv`
///
/// The response is parsed into `puffin_client::SimpleMetadata` before storage.
/// The response is parsed into `uv_client::SimpleMetadata` before storage.
Simple,
/// A cache of unzipped wheels, stored as directories. This is used internally within the cache.
/// When other buckets need to store directories, they should persist them to

View file

@ -1,5 +1,5 @@
[package]
name = "puffin-client"
name = "uv-client"
version = "0.0.1"
edition = "2021"
@ -11,9 +11,9 @@ install-wheel-rs = { path = "../install-wheel-rs" }
pep440_rs = { path = "../pep440-rs" }
pep508_rs = { path = "../pep508-rs" }
platform-tags = { path = "../platform-tags" }
puffin-cache = { path = "../puffin-cache" }
puffin-fs = { path = "../puffin-fs", features = ["tokio"] }
puffin-normalize = { path = "../puffin-normalize" }
uv-cache = { path = "../uv-cache" }
uv-fs = { path = "../uv-fs", features = ["tokio"] }
uv-normalize = { path = "../uv-normalize" }
pypi-types = { path = "../pypi-types" }
async-trait = { workspace = true }

View file

@ -8,8 +8,8 @@ use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use tracing::{debug, info_span, instrument, trace, warn, Instrument};
use puffin_cache::{CacheEntry, Freshness};
use puffin_fs::write_atomic;
use uv_cache::{CacheEntry, Freshness};
use uv_fs::write_atomic;
use crate::{
httpcache::{AfterResponse, BeforeRequest, CachePolicy, CachePolicyBuilder},

View file

@ -3,7 +3,7 @@ use async_zip::error::ZipError;
use url::Url;
use distribution_filename::{WheelFilename, WheelFilenameError};
use puffin_normalize::PackageName;
use uv_normalize::PackageName;
use crate::html;
use crate::middleware::OfflineError;

View file

@ -15,9 +15,9 @@ use distribution_types::{
};
use pep440_rs::Version;
use platform_tags::Tags;
use puffin_cache::{Cache, CacheBucket};
use puffin_normalize::PackageName;
use pypi_types::{Hashes, Yanked};
use uv_cache::{Cache, CacheBucket};
use uv_normalize::PackageName;
use crate::cached_client::{CacheControl, CachedClientError};
use crate::html::SimpleHtml;

View file

@ -160,7 +160,7 @@ impl FromIterator<CacheControlDirective> for CacheControl {
/// server before using anything in case.
///
/// This parser handles a bit more than what we actually need in
/// `puffin-client`. For example, we don't need to handle quoted values at all
/// `uv-client`. For example, we don't need to handle quoted values at all
/// since either don't use or care about values that require quoted. With that
/// said, the parser handles these because it wasn't that much extra work to do
/// so and just generally seemed like good sense. (If we didn't handle them and

View file

@ -44,7 +44,7 @@ wheel.
When a cached response exceeds the `max-age` configured on a response, then
we call that response stale. Generally speaking, we won't return responses
from the cache that are known to be stale. (This can be overridden in the
request by adding a `max-stale` cache-control directive, but nothing in Puffin
request by adding a `max-stale` cache-control directive, but nothing in uv
does this at time of writing.) When a response is stale, we don't necessarily
need to give up completely. It is at this point that we can send something
called a re-validation request.
@ -63,7 +63,7 @@ to the behavior of caching (like a new `Age` header).
# Scope
In general, the cache semantics implemented below are targeted toward Puffin's
In general, the cache semantics implemented below are targeted toward uv's
use case: a private client cache for custom data objects. This constraint
results in a modest simplification in what we need to support. That is, we
don't need to cache the entirety of the request's or response's headers (like
@ -145,7 +145,7 @@ use self::control::CacheControl;
mod control;
/// Knobs to configure Puffin's cache behavior.
/// Knobs to configure uv's cache behavior.
///
/// At time of writing, we don't expose any way of modifying these since I
/// suspect we won't ever need to. We split them out into their own type so
@ -164,7 +164,7 @@ struct CacheConfig {
impl Default for CacheConfig {
fn default() -> CacheConfig {
CacheConfig {
// The caching puffin does ought to be considered
// The caching uv does ought to be considered
// private.
shared: false,
// This is only used to heuristically guess at a freshness lifetime
@ -234,7 +234,7 @@ impl CachePolicyBuilder {
}
/// A value encapsulating the data needed to implement HTTP caching behavior
/// for Puffin.
/// for uv.
///
/// A cache policy is meant to be stored and persisted with the data being
/// cached. It is specifically meant to capture the smallest amount of
@ -242,7 +242,7 @@ impl CachePolicyBuilder {
/// and the information required to issue a re-validation request.
///
/// This does not provide a complete set of HTTP cache semantics. Notably
/// absent from this (among other things that Puffin probably doesn't care
/// absent from this (among other things that uv probably doesn't care
/// about it) are proxy cache semantics.
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[archive(check_bytes)]

View file

@ -20,9 +20,9 @@ use distribution_filename::{DistFilename, SourceDistFilename, WheelFilename};
use distribution_types::{BuiltDist, File, FileLocation, IndexUrl, IndexUrls, Name};
use install_wheel_rs::find_dist_info;
use pep440_rs::Version;
use puffin_cache::{Cache, CacheBucket, WheelCache};
use puffin_normalize::PackageName;
use pypi_types::{Metadata21, SimpleJson};
use uv_cache::{Cache, CacheBucket, WheelCache};
use uv_normalize::PackageName;
use crate::cached_client::CacheControl;
use crate::html::SimpleHtml;
@ -80,7 +80,7 @@ impl RegistryClientBuilder {
let client_raw = {
// Disallow any connections.
let client_core = ClientBuilder::new()
.user_agent("puffin")
.user_agent("uv")
.pool_max_idle_per_host(20)
.timeout(std::time::Duration::from_secs(60 * 5));
@ -501,7 +501,7 @@ impl RegistryClient {
}
}
/// It doesn't really fit into `puffin_client`, but it avoids cyclical crate dependencies.
/// It doesn't really fit into `uv_client`, but it avoids cyclical crate dependencies.
async fn read_metadata_async(
filename: &WheelFilename,
debug_source: String,
@ -705,8 +705,8 @@ pub enum Connectivity {
mod tests {
use std::str::FromStr;
use puffin_normalize::PackageName;
use pypi_types::SimpleJson;
use uv_normalize::PackageName;
use crate::{SimpleMetadata, SimpleMetadatum};

View file

@ -53,7 +53,7 @@ use crate::{Error, ErrorKind};
///
/// Note that this type makes a number of assumptions about the specific
/// serializer, deserializer and validator used. This type could be made
/// more generic, but it's not clear we need that in puffin. By making our
/// more generic, but it's not clear we need that in uv. By making our
/// choices concrete here, we make use of this type much simpler to understand.
/// Unfortunately, AG couldn't find a way of making the trait bounds simpler,
/// so if `OwnedVec` is being used in trait implementations, the traits bounds

View file

@ -5,8 +5,8 @@ use anyhow::Result;
use distribution_filename::WheelFilename;
use distribution_types::{BuiltDist, DirectUrlBuiltDist};
use pep508_rs::VerbatimUrl;
use puffin_cache::Cache;
use puffin_client::RegistryClientBuilder;
use uv_cache::Cache;
use uv_client::RegistryClientBuilder;
#[tokio::test]
async fn remote_metadata_with_and_without_cache() -> Result<()> {

View file

@ -1,5 +1,5 @@
[package]
name = "puffin-dev"
name = "uv-dev"
version = "0.0.1"
description = "Build wheels from source distributions"
publish = false
@ -24,19 +24,19 @@ pep440_rs = { path = "../pep440-rs" }
pep508_rs = { path = "../pep508-rs" }
platform-host = { path = "../platform-host" }
platform-tags = { path = "../platform-tags" }
puffin-build = { path = "../puffin-build" }
puffin-cache = { path = "../puffin-cache", features = ["clap"] }
puffin-client = { path = "../puffin-client" }
puffin-dispatch = { path = "../puffin-dispatch" }
puffin-distribution = { path = "../puffin-distribution" }
puffin-installer = { path = "../puffin-installer" }
puffin-interpreter = { path = "../puffin-interpreter" }
puffin-normalize = { path = "../puffin-normalize" }
puffin-resolver = { path = "../puffin-resolver" }
uv-build = { path = "../uv-build" }
uv-cache = { path = "../uv-cache", features = ["clap"] }
uv-client = { path = "../uv-client" }
uv-dispatch = { path = "../uv-dispatch" }
uv-distribution = { path = "../uv-distribution" }
uv-installer = { path = "../uv-installer" }
uv-interpreter = { path = "../uv-interpreter" }
uv-normalize = { path = "../uv-normalize" }
uv-resolver = { path = "../uv-resolver" }
pypi-types = { path = "../pypi-types" }
puffin-traits = { path = "../puffin-traits" }
uv-traits = { path = "../uv-traits" }
# Any dependencies that are exclusively used in `puffin-dev` should be listed as non-workspace
# Any dependencies that are exclusively used in `uv-dev` should be listed as non-workspace
# dependencies, to ensure that we're forced to think twice before including them in other crates.
anstream = { workspace = true }
anyhow = { workspace = true }

View file

@ -7,14 +7,14 @@ use fs_err as fs;
use distribution_types::IndexLocations;
use platform_host::Platform;
use puffin_build::{SourceBuild, SourceBuildContext};
use puffin_cache::{Cache, CacheArgs};
use puffin_client::{FlatIndex, RegistryClientBuilder};
use puffin_dispatch::BuildDispatch;
use puffin_installer::NoBinary;
use puffin_interpreter::Virtualenv;
use puffin_resolver::InMemoryIndex;
use puffin_traits::{BuildContext, BuildKind, InFlight, NoBuild, SetupPyStrategy};
use uv_build::{SourceBuild, SourceBuildContext};
use uv_cache::{Cache, CacheArgs};
use uv_client::{FlatIndex, RegistryClientBuilder};
use uv_dispatch::BuildDispatch;
use uv_installer::NoBinary;
use uv_interpreter::Virtualenv;
use uv_resolver::InMemoryIndex;
use uv_traits::{BuildContext, BuildKind, InFlight, NoBuild, SetupPyStrategy};
#[derive(Parser)]
pub(crate) struct BuildArgs {

View file

@ -17,15 +17,15 @@ use install_wheel_rs::linker::LinkMode;
use pep508_rs::Requirement;
use platform_host::Platform;
use platform_tags::Tags;
use puffin_cache::{Cache, CacheArgs};
use puffin_client::{FlatIndex, RegistryClient, RegistryClientBuilder};
use puffin_dispatch::BuildDispatch;
use puffin_distribution::RegistryWheelIndex;
use puffin_installer::{Downloader, NoBinary};
use puffin_interpreter::Virtualenv;
use puffin_normalize::PackageName;
use puffin_resolver::{DistFinder, InMemoryIndex};
use puffin_traits::{BuildContext, InFlight, NoBuild, SetupPyStrategy};
use uv_cache::{Cache, CacheArgs};
use uv_client::{FlatIndex, RegistryClient, RegistryClientBuilder};
use uv_dispatch::BuildDispatch;
use uv_distribution::RegistryWheelIndex;
use uv_installer::{Downloader, NoBinary};
use uv_interpreter::Virtualenv;
use uv_normalize::PackageName;
use uv_resolver::{DistFinder, InMemoryIndex};
use uv_traits::{BuildContext, InFlight, NoBuild, SetupPyStrategy};
#[derive(Parser)]
pub(crate) struct InstallManyArgs {
@ -187,7 +187,7 @@ async fn install_chunk(
}
let wheels: Vec<_> = wheels.into_iter().chain(cached).collect();
puffin_installer::Installer::new(venv)
uv_installer::Installer::new(venv)
.with_link_mode(LinkMode::default())
.install(&wheels)
.context("Failed to install")?;

View file

@ -55,11 +55,11 @@ enum Cli {
///
/// Run `scripts/popular_packages/pypi_8k_downloads.sh` once, then
/// ```bash
/// cargo run --bin puffin-dev -- resolve-many scripts/popular_packages/pypi_8k_downloads.txt
/// cargo run --bin uv-dev -- resolve-many scripts/popular_packages/pypi_8k_downloads.txt
/// ```
/// or
/// ```bash
/// cargo run --bin puffin-dev -- resolve-many scripts/popular_packages/pypi_10k_most_dependents.txt
/// cargo run --bin uv-dev -- resolve-many scripts/popular_packages/pypi_10k_most_dependents.txt
/// ```
ResolveMany(ResolveManyArgs),
InstallMany(InstallManyArgs),
@ -130,7 +130,7 @@ async fn main() -> ExitCode {
let filter_layer = EnvFilter::try_from_default_env().unwrap_or_else(|_| {
EnvFilter::builder()
// Show only the important spans
.parse("puffin_dev=info,puffin_dispatch=info")
.parse("uv_dev=info,uv_dispatch=info")
.unwrap()
});
tracing_subscriber::registry()
@ -144,7 +144,7 @@ async fn main() -> ExitCode {
let result = run().await;
debug!("Took {}ms", start.elapsed().as_millis());
if let Err(err) = result {
eprintln!("{}", "puffin-dev failed".red().bold());
eprintln!("{}", "uv-dev failed".red().bold());
for err in err.chain() {
eprintln!(" {}: {}", "Caused by".red().bold(), err);
}

View file

@ -22,8 +22,8 @@ pub(crate) fn render_benchmarks(args: &RenderBenchmarksArgs) -> Result<()> {
// Replace the command with a shorter name. (The command typically includes the benchmark name,
// but we assume we're running over a single benchmark here.)
for result in &mut results.results {
if result.command.starts_with("puffin") {
result.command = "Puffin".into();
if result.command.starts_with("uv") {
result.command = "uv".into();
} else if result.command.starts_with("pip-compile") {
result.command = "pip-compile".into();
} else if result.command.starts_with("pip-sync") {

View file

@ -12,13 +12,13 @@ use petgraph::dot::{Config as DotConfig, Dot};
use distribution_types::{FlatIndexLocation, IndexLocations, IndexUrl, Resolution};
use pep508_rs::Requirement;
use platform_host::Platform;
use puffin_cache::{Cache, CacheArgs};
use puffin_client::{FlatIndex, FlatIndexClient, RegistryClientBuilder};
use puffin_dispatch::BuildDispatch;
use puffin_installer::NoBinary;
use puffin_interpreter::Virtualenv;
use puffin_resolver::{InMemoryIndex, Manifest, Options, Resolver};
use puffin_traits::{InFlight, NoBuild, SetupPyStrategy};
use uv_cache::{Cache, CacheArgs};
use uv_client::{FlatIndex, FlatIndexClient, RegistryClientBuilder};
use uv_dispatch::BuildDispatch;
use uv_installer::NoBinary;
use uv_interpreter::Virtualenv;
use uv_resolver::{InMemoryIndex, Manifest, Options, Resolver};
use uv_traits::{InFlight, NoBuild, SetupPyStrategy};
#[derive(ValueEnum, Default, Clone)]
pub(crate) enum ResolveCliFormat {

View file

@ -14,14 +14,14 @@ use distribution_types::IndexLocations;
use pep440_rs::{Version, VersionSpecifier, VersionSpecifiers};
use pep508_rs::{Requirement, VersionOrUrl};
use platform_host::Platform;
use puffin_cache::{Cache, CacheArgs};
use puffin_client::{FlatIndex, OwnedArchive, RegistryClient, RegistryClientBuilder};
use puffin_dispatch::BuildDispatch;
use puffin_installer::NoBinary;
use puffin_interpreter::Virtualenv;
use puffin_normalize::PackageName;
use puffin_resolver::InMemoryIndex;
use puffin_traits::{BuildContext, InFlight, NoBuild, SetupPyStrategy};
use uv_cache::{Cache, CacheArgs};
use uv_client::{FlatIndex, OwnedArchive, RegistryClient, RegistryClientBuilder};
use uv_dispatch::BuildDispatch;
use uv_installer::NoBinary;
use uv_interpreter::Virtualenv;
use uv_normalize::PackageName;
use uv_resolver::InMemoryIndex;
use uv_traits::{BuildContext, InFlight, NoBuild, SetupPyStrategy};
#[derive(Parser)]
pub(crate) struct ResolveManyArgs {

View file

@ -7,8 +7,8 @@ use clap::Parser;
use distribution_filename::WheelFilename;
use distribution_types::{BuiltDist, DirectUrlBuiltDist};
use pep508_rs::VerbatimUrl;
use puffin_cache::{Cache, CacheArgs};
use puffin_client::RegistryClientBuilder;
use uv_cache::{Cache, CacheArgs};
use uv_client::RegistryClientBuilder;
#[derive(Parser)]
pub(crate) struct WheelMetadataArgs {

View file

@ -12,8 +12,8 @@ if [ ! -f sdist_building_test_data/sdist/geoextract-0.3.1.tar.gz ]; then
wget https://files.pythonhosted.org/packages/c4/00/9d9826a6e1c9139cc7183647f47f6b7acb290fa4c572140aa84a12728e60/geoextract-0.3.1.tar.gz -O sdist_building_test_data/sdist/geoextract-0.3.1.tar.gz
fi
rm -rf sdist_building_test_data/wheels
RUST_LOG=puffin_build=debug cargo run --bin puffin-dev -- build --wheels sdist_building_test_data/wheels sdist_building_test_data/sdist/tqdm-4.66.1.tar.gz
RUST_LOG=puffin_build=debug cargo run --bin puffin-dev -- build --wheels sdist_building_test_data/wheels sdist_building_test_data/sdist/geoextract-0.3.1.tar.gz
RUST_LOG=uv_build=debug cargo run --bin uv-dev -- build --wheels sdist_building_test_data/wheels sdist_building_test_data/sdist/tqdm-4.66.1.tar.gz
RUST_LOG=uv_build=debug cargo run --bin uv-dev -- build --wheels sdist_building_test_data/wheels sdist_building_test_data/sdist/geoextract-0.3.1.tar.gz
# Check that pip accepts the wheels. It would be better to do functional checks
virtualenv -p 3.8 -q --clear sdist_building_test_data/.venv

View file

@ -1,5 +1,5 @@
[package]
name = "puffin-dispatch"
name = "uv-dispatch"
version = "0.0.1"
description = "Avoid cyclic crate dependencies between resolver, installer and builder"
edition = { workspace = true }
@ -19,14 +19,14 @@ gourgeist = { path = "../gourgeist" }
pep508_rs = { path = "../pep508-rs" }
platform-host = { path = "../platform-host" }
platform-tags = { path = "../platform-tags" }
puffin-build = { path = "../puffin-build" }
puffin-cache = { path = "../puffin-cache" }
puffin-client = { path = "../puffin-client" }
puffin-distribution = { path = "../puffin-distribution" }
puffin-installer = { path = "../puffin-installer" }
puffin-interpreter = { path = "../puffin-interpreter" }
puffin-resolver = { path = "../puffin-resolver" }
puffin-traits = { path = "../puffin-traits" }
uv-build = { path = "../uv-build" }
uv-cache = { path = "../uv-cache" }
uv-client = { path = "../uv-client" }
uv-distribution = { path = "../uv-distribution" }
uv-installer = { path = "../uv-installer" }
uv-interpreter = { path = "../uv-interpreter" }
uv-resolver = { path = "../uv-resolver" }
uv-traits = { path = "../uv-traits" }
pypi-types = { path = "../pypi-types" }
anyhow = { workspace = true }

View file

@ -1,5 +1,5 @@
//! Avoid cyclic crate dependencies between [resolver][`puffin_resolver`],
//! [installer][`puffin_installer`] and [build][`puffin_build`] through [`BuildDispatch`]
//! Avoid cyclic crate dependencies between [resolver][`uv_resolver`],
//! [installer][`uv_installer`] and [build][`uv_build`] through [`BuildDispatch`]
//! implementing [`BuildContext`].
use std::future::Future;
@ -12,13 +12,13 @@ use tracing::{debug, instrument};
use distribution_types::{IndexLocations, Name, Resolution, SourceDist};
use futures::FutureExt;
use pep508_rs::Requirement;
use puffin_build::{SourceBuild, SourceBuildContext};
use puffin_cache::Cache;
use puffin_client::{FlatIndex, RegistryClient};
use puffin_installer::{Downloader, Installer, NoBinary, Plan, Planner, Reinstall, SitePackages};
use puffin_interpreter::{Interpreter, Virtualenv};
use puffin_resolver::{InMemoryIndex, Manifest, Options, Resolver};
use puffin_traits::{BuildContext, BuildKind, InFlight, NoBuild, SetupPyStrategy};
use uv_build::{SourceBuild, SourceBuildContext};
use uv_cache::Cache;
use uv_client::{FlatIndex, RegistryClient};
use uv_installer::{Downloader, Installer, NoBinary, Plan, Planner, Reinstall, SitePackages};
use uv_interpreter::{Interpreter, Virtualenv};
use uv_resolver::{InMemoryIndex, Manifest, Options, Resolver};
use uv_traits::{BuildContext, BuildKind, InFlight, NoBuild, SetupPyStrategy};
/// The main implementation of [`BuildContext`], used by the CLI, see [`BuildContext`]
/// documentation.
@ -208,7 +208,7 @@ impl<'a> BuildContext for BuildDispatch<'a> {
// Remove any unnecessary packages.
if !extraneous.is_empty() || !reinstalls.is_empty() {
for dist_info in extraneous.iter().chain(reinstalls.iter()) {
let summary = puffin_installer::uninstall(dist_info)
let summary = uv_installer::uninstall(dist_info)
.await
.context("Failed to uninstall build dependencies")?;
debug!(

View file

@ -1,5 +1,5 @@
[package]
name = "puffin-distribution"
name = "uv-distribution"
version = "0.0.1"
edition = { workspace = true }
rust-version = { workspace = true }
@ -20,13 +20,13 @@ install-wheel-rs = { path = "../install-wheel-rs" }
pep440_rs = { path = "../pep440-rs" }
pep508_rs = { path = "../pep508-rs" }
platform-tags = { path = "../platform-tags" }
puffin-cache = { path = "../puffin-cache" }
puffin-client = { path = "../puffin-client" }
puffin-extract = { path = "../puffin-extract" }
puffin-fs = { path = "../puffin-fs", features = ["tokio"] }
puffin-git = { path = "../puffin-git", features = ["vendored-openssl"] }
puffin-normalize = { path = "../puffin-normalize" }
puffin-traits = { path = "../puffin-traits" }
uv-cache = { path = "../uv-cache" }
uv-client = { path = "../uv-client" }
uv-extract = { path = "../uv-extract" }
uv-fs = { path = "../uv-fs", features = ["tokio"] }
uv-git = { path = "../uv-git", features = ["vendored-openssl"] }
uv-normalize = { path = "../uv-normalize" }
uv-traits = { path = "../uv-traits" }
pypi-types = { path = "../pypi-types" }
anyhow = { workspace = true }

View file

@ -12,12 +12,12 @@ use distribution_types::{
BuiltDist, DirectGitUrl, Dist, FileLocation, IndexLocations, LocalEditable, Name, SourceDist,
};
use platform_tags::Tags;
use puffin_cache::{Cache, CacheBucket, Timestamp, WheelCache};
use puffin_client::{CacheControl, CachedClientError, Connectivity, RegistryClient};
use puffin_fs::metadata_if_exists;
use puffin_git::GitSource;
use puffin_traits::{BuildContext, NoBinary, NoBuild};
use pypi_types::Metadata21;
use uv_cache::{Cache, CacheBucket, Timestamp, WheelCache};
use uv_client::{CacheControl, CachedClientError, Connectivity, RegistryClient};
use uv_fs::metadata_if_exists;
use uv_git::GitSource;
use uv_traits::{BuildContext, NoBinary, NoBuild};
use crate::download::{BuiltWheel, UnzippedWheel};
use crate::locks::Locks;
@ -156,7 +156,7 @@ impl<'a, Context: BuildContext + Send + Sync> DistributionDatabase<'a, Context>
// Download and unzip the wheel to a temporary directory.
let temp_dir =
tempfile::tempdir_in(self.cache.root()).map_err(Error::CacheWrite)?;
puffin_extract::stream::unzip(reader.compat(), temp_dir.path()).await?;
uv_extract::stream::unzip(reader.compat(), temp_dir.path()).await?;
// Persist the temporary directory to the directory store.
let archive = self
@ -218,7 +218,7 @@ impl<'a, Context: BuildContext + Send + Sync> DistributionDatabase<'a, Context>
// Download and unzip the wheel to a temporary directory.
let temp_dir =
tempfile::tempdir_in(self.cache.root()).map_err(Error::CacheWrite)?;
puffin_extract::stream::unzip(reader.compat(), temp_dir.path()).await?;
uv_extract::stream::unzip(reader.compat(), temp_dir.path()).await?;
// Persist the temporary directory to the directory store.
let archive = self

View file

@ -2,7 +2,7 @@ use tokio::task::JoinError;
use zip::result::ZipError;
use distribution_filename::WheelFilenameError;
use puffin_normalize::PackageName;
use uv_normalize::PackageName;
#[derive(Debug, thiserror::Error)]
pub enum Error {
@ -21,7 +21,7 @@ pub enum Error {
#[error(transparent)]
Request(#[from] reqwest::Error),
#[error(transparent)]
Client(#[from] puffin_client::Error),
Client(#[from] uv_client::Error),
// Cache writing error
#[error("Failed to read from the distribution cache")]
@ -54,7 +54,7 @@ pub enum Error {
#[error("Source distribution directory contains neither readable pyproject.toml nor setup.py")]
DirWithoutEntrypoint,
#[error("Failed to extract source distribution: {0}")]
Extract(#[from] puffin_extract::Error),
Extract(#[from] uv_extract::Error),
/// Should not occur; only seen when another task panicked.
#[error("The task executor is broken, did some other task panic?")]

View file

@ -1,7 +1,7 @@
use distribution_types::{git_reference, DirectUrlSourceDist, GitSourceDist, Name, PathSourceDist};
use platform_tags::Tags;
use puffin_cache::{ArchiveTimestamp, Cache, CacheBucket, CacheShard, WheelCache};
use puffin_fs::symlinks;
use uv_cache::{ArchiveTimestamp, Cache, CacheBucket, CacheShard, WheelCache};
use uv_fs::symlinks;
use crate::index::cached_wheel::CachedWheel;
use crate::source::{read_http_manifest, read_timestamp_manifest, MANIFEST};

View file

@ -3,7 +3,7 @@ use std::path::Path;
use distribution_filename::WheelFilename;
use distribution_types::{CachedDirectUrlDist, CachedRegistryDist};
use pep508_rs::VerbatimUrl;
use puffin_cache::CacheEntry;
use uv_cache::CacheEntry;
#[derive(Debug, Clone)]
pub struct CachedWheel {

View file

@ -7,9 +7,9 @@ use rustc_hash::FxHashMap;
use distribution_types::{CachedRegistryDist, FlatIndexLocation, IndexLocations, IndexUrl};
use pep440_rs::Version;
use platform_tags::Tags;
use puffin_cache::{Cache, CacheBucket, WheelCache};
use puffin_fs::{directories, symlinks};
use puffin_normalize::PackageName;
use uv_cache::{Cache, CacheBucket, WheelCache};
use uv_fs::{directories, symlinks};
use uv_normalize::PackageName;
use crate::index::cached_wheel::CachedWheel;
use crate::source::{read_http_manifest, MANIFEST};

View file

@ -18,7 +18,7 @@ pub trait Reporter: Send + Sync {
fn on_checkout_complete(&self, url: &Url, rev: &str, index: usize);
}
/// A facade for converting from [`Reporter`] to [`puffin_git::Reporter`].
/// A facade for converting from [`Reporter`] to [`uv_git::Reporter`].
pub(crate) struct Facade {
reporter: Arc<dyn Reporter>,
}
@ -29,7 +29,7 @@ impl From<Arc<dyn Reporter>> for Facade {
}
}
impl puffin_git::Reporter for Facade {
impl uv_git::Reporter for Facade {
fn on_checkout_start(&self, url: &Url, rev: &str) -> usize {
self.reporter.on_checkout_start(url, rev)
}

View file

@ -3,8 +3,8 @@ use std::str::FromStr;
use distribution_filename::WheelFilename;
use platform_tags::Tags;
use puffin_cache::CacheShard;
use puffin_fs::files;
use uv_cache::CacheShard;
use uv_fs::files;
/// The information about the wheel we either just built or got from the cache.
#[derive(Debug, Clone)]

View file

@ -21,16 +21,16 @@ use distribution_types::{
use install_wheel_rs::read_dist_info;
use pep508_rs::VerbatimUrl;
use platform_tags::Tags;
use puffin_cache::{
use pypi_types::Metadata21;
use uv_cache::{
ArchiveTimestamp, CacheBucket, CacheEntry, CacheShard, CachedByTimestamp, Freshness, WheelCache,
};
use puffin_client::{
use uv_client::{
CacheControl, CachedClientError, Connectivity, DataWithCachePolicy, RegistryClient,
};
use puffin_fs::{write_atomic, LockedFile};
use puffin_git::{Fetch, GitSource};
use puffin_traits::{BuildContext, BuildKind, NoBuild, SourceBuildTrait};
use pypi_types::Metadata21;
use uv_fs::{write_atomic, LockedFile};
use uv_git::{Fetch, GitSource};
use uv_traits::{BuildContext, BuildKind, NoBuild, SourceBuildTrait};
use crate::error::Error;
use crate::reporter::Facade;
@ -783,11 +783,11 @@ impl<'a, T: BuildContext> SourceDistCachedBuilder<'a, T> {
.bytes_stream()
.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))
.into_async_read();
puffin_extract::stream::archive(reader.compat(), filename, temp_dir.path()).await?;
uv_extract::stream::archive(reader.compat(), filename, temp_dir.path()).await?;
drop(span);
// Extract the top-level directory.
let extracted = puffin_extract::strip_component(temp_dir.path())?;
let extracted = uv_extract::strip_component(temp_dir.path())?;
// Persist it to the cache.
fs_err::tokio::create_dir_all(cache_path.parent().expect("Cache entry to have parent"))

View file

@ -1,6 +1,6 @@
use std::path::Path;
use puffin_extract::Error;
use uv_extract::Error;
use crate::download::BuiltWheel;
use crate::{DiskWheel, LocalWheel};
@ -12,13 +12,13 @@ pub trait Unzip {
impl Unzip for DiskWheel {
fn unzip(&self, target: &Path) -> Result<(), Error> {
puffin_extract::unzip(fs_err::File::open(&self.path)?, target)
uv_extract::unzip(fs_err::File::open(&self.path)?, target)
}
}
impl Unzip for BuiltWheel {
fn unzip(&self, target: &Path) -> Result<(), Error> {
puffin_extract::unzip(fs_err::File::open(&self.path)?, target)
uv_extract::unzip(fs_err::File::open(&self.path)?, target)
}
}

View file

@ -1,5 +1,5 @@
[package]
name = "puffin-extract"
name = "uv-extract"
version = "0.0.1"
edition = { workspace = true }
rust-version = { workspace = true }

Some files were not shown because too many files have changed in this diff Show more