Rename gourgeist to uv-virtualenv (#2118)

As agreed on Discord!
This commit is contained in:
Charlie Marsh 2024-03-01 14:02:40 -05:00 committed by GitHub
parent b818199403
commit 59c7a10c4b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 65 additions and 184 deletions

56
Cargo.lock generated
View file

@ -1276,29 +1276,6 @@ dependencies = [
"scroll",
]
[[package]]
name = "gourgeist"
version = "0.0.4"
dependencies = [
"anstream",
"cachedir",
"camino",
"clap",
"directories",
"fs-err",
"platform-host",
"serde",
"serde_json",
"tempfile",
"thiserror",
"tracing",
"tracing-subscriber",
"uv-cache",
"uv-fs",
"uv-interpreter",
"which",
]
[[package]]
name = "h2"
version = "0.3.24"
@ -4152,7 +4129,6 @@ dependencies = [
"flate2",
"fs-err",
"futures",
"gourgeist",
"indexmap 2.2.3",
"indicatif",
"indoc",
@ -4199,6 +4175,7 @@ dependencies = [
"uv-normalize",
"uv-resolver",
"uv-traits",
"uv-virtualenv",
"uv-warnings",
"which",
]
@ -4218,7 +4195,6 @@ dependencies = [
"anyhow",
"distribution-types",
"fs-err",
"gourgeist",
"indoc",
"insta",
"itertools 0.12.1",
@ -4240,6 +4216,7 @@ dependencies = [
"uv-fs",
"uv-interpreter",
"uv-traits",
"uv-virtualenv",
]
[[package]]
@ -4322,7 +4299,6 @@ dependencies = [
"distribution-types",
"fs-err",
"futures",
"gourgeist",
"indicatif",
"install-wheel-rs",
"itertools 0.12.1",
@ -4358,6 +4334,7 @@ dependencies = [
"uv-normalize",
"uv-resolver",
"uv-traits",
"uv-virtualenv",
"which",
]
@ -4369,7 +4346,6 @@ dependencies = [
"distribution-types",
"fs-err",
"futures",
"gourgeist",
"itertools 0.12.1",
"pep508_rs",
"platform-host",
@ -4387,6 +4363,7 @@ dependencies = [
"uv-interpreter",
"uv-resolver",
"uv-traits",
"uv-virtualenv",
]
[[package]]
@ -4575,7 +4552,6 @@ dependencies = [
"either",
"fs-err",
"futures",
"gourgeist",
"indexmap 2.2.3",
"insta",
"install-wheel-rs",
@ -4609,6 +4585,7 @@ dependencies = [
"uv-interpreter",
"uv-normalize",
"uv-traits",
"uv-virtualenv",
"uv-warnings",
"zip",
]
@ -4630,6 +4607,29 @@ dependencies = [
"uv-normalize",
]
[[package]]
name = "uv-virtualenv"
version = "0.0.4"
dependencies = [
"anstream",
"cachedir",
"camino",
"clap",
"directories",
"fs-err",
"platform-host",
"serde",
"serde_json",
"tempfile",
"thiserror",
"tracing",
"tracing-subscriber",
"uv-cache",
"uv-fs",
"uv-interpreter",
"which",
]
[[package]]
name = "uv-warnings"
version = "0.0.1"

View file

@ -18,10 +18,6 @@ metadata.
Abstractions for representing built distributions (wheels) and source distributions (sdists), and
the sources from which they can be downloaded.
## [gourgeist](./gourgeist)
A `venv` replacement to create virtual environments in Rust.
## [install-wheel-rs](./install-wheel-rs)
Install built distributions (wheels) into a virtual environment.]
@ -117,6 +113,10 @@ Shared traits for uv, to avoid circular dependencies.
General-purpose type definitions for types used in PyPI-compatible APIs.
## [uv-virtualenv](./uv-virtualenv)
A `venv` replacement to create virtual environments in Rust.
## [uv-warnings](./uv-warnings)
User-facing warnings for uv.

View file

@ -1,33 +0,0 @@
# Gourgeist
Gourgeist is a rust library to create python virtual environments. It also has a CLI.
It currently supports only unix (linux/mac), windows support is missing.
## Rust
```rust
use camino::Utf8PathBuf;
use gourgeist::{create_venv, get_interpreter_info, parse_python_cli};
let location = cli.path.unwrap_or(Utf8PathBuf::from(".venv"));
let python = parse_python_cli(cli.python)?;
let data = get_interpreter_info(&python)?;
create_venv(&location, &python, &data, cli.bare)?;
```
## CLI
Use `python` as base for a virtualenv `.venv`:
```bash
gourgeist
```
Or use custom defaults:
```bash
gourgeist -p 3.11 my_env
```
## Jessie's gourgeist
![Jessie's gourgeist, a pokemon with a jack o'lantern as body](static/gourgeist.png)

View file

@ -1,14 +0,0 @@
#!/usr/bin/env bash
set -e
cd "$(git rev-parse --show-toplevel)"
virtualenv --version
cargo build --profile profiling --bin gourgeist --features cli
hyperfine --warmup 1 --shell none --prepare "rm -rf target/venv-benchmark" \
"target/profiling/gourgeist -p 3.11 target/venv-benchmark" \
"virtualenv -p 3.11 --no-seed target/venv-benchmark"

View file

@ -1,27 +0,0 @@
#!/usr/bin/env bash
set -e
virtualenv_command() {
virtualenv -p 3.11 compare_venv # --no-pip --no-setuptools --no-wheel
}
rust_command() {
cargo run -- -p 3.11 compare_venv # --bare
}
rm -rf compare_venv
virtualenv_command
rm compare_venv/.gitignore
git -C compare_venv init
git -C compare_venv add -A
git -C compare_venv commit -q -m "Initial commit"
rm -r compare_venv/* # This skips the hidden .git
mkdir -p target
mv compare_venv target/compare_venv2
rust_command
rm compare_venv/.gitignore
cp -r compare_venv/* target/compare_venv2
rm -r compare_venv
mv target/compare_venv2 compare_venv
git -C compare_venv/ status

View file

@ -1,12 +0,0 @@
import sys
def main():
print(sys.executable)
print(sys.version)
print(sys.base_prefix)
print(sys.prefix)
if __name__ == "__main__":
main()

View file

@ -1,8 +0,0 @@
{
"styles": {
"theme": "axo_light"
},
"build": {
"path_prefix": "gourgeist"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 MiB

View file

@ -1,28 +0,0 @@
from pathlib import Path
from subprocess import check_output, check_call
def main():
project_root = Path(__file__).parent
venv_name = ".venv-rs"
venv_python = f"{venv_name}/bin/python"
venv_pip = f"{venv_name}/bin/pip"
command = f". {venv_name}/bin/activate && which python"
output = check_output(["bash"], input=command, text=True).strip()
assert output == str(project_root.joinpath(venv_python)), output
command = f". {venv_name}/bin/activate && wheel help"
output = check_output(["bash"], input=command, text=True).strip()
assert output.startswith("usage:"), output
output = check_output([venv_python, "imasnake.py"], text=True).strip().splitlines()
assert output[0] == str(project_root.joinpath(venv_python)), output
assert not output[2].startswith(str(project_root)), output
assert output[3] == str(project_root.joinpath(venv_name)), output
check_call([venv_pip, "install", "tqdm"])
if __name__ == "__main__":
main()

View file

@ -15,14 +15,14 @@ workspace = true
[dependencies]
distribution-types = { path = "../distribution-types" }
gourgeist = { path = "../gourgeist" }
pep508_rs = { path = "../pep508-rs" }
platform-host = { path = "../platform-host" }
pypi-types = { path = "../pypi-types" }
uv-extract = { path = "../uv-extract" }
uv-fs = { path = "../uv-fs" }
uv-interpreter = { path = "../uv-interpreter" }
uv-traits = { path = "../uv-traits", features = ["serde"] }
pypi-types = { path = "../pypi-types" }
uv-virtualenv = { path = "../uv-virtualenv" }
anyhow = { workspace = true }
fs-err = { workspace = true }

View file

@ -75,7 +75,7 @@ pub enum Error {
#[error("Source distribution not found at: {0}")]
NotFound(PathBuf),
#[error("Failed to create temporary virtualenv")]
Gourgeist(#[from] gourgeist::Error),
Virtualenv(#[from] uv_virtualenv::Error),
#[error("Failed to run {0}")]
CommandFailed(PathBuf, #[source] io::Error),
#[error("{message}:\n--- stdout:\n{stdout}\n--- stderr:\n{stderr}\n---")]
@ -398,10 +398,10 @@ impl SourceBuild {
let pep517_backend = Self::get_pep517_backend(setup_py, &source_tree, &default_backend)
.map_err(|err| *err)?;
let venv = gourgeist::create_venv(
let venv = uv_virtualenv::create_venv(
&temp_dir.path().join(".venv"),
interpreter.clone(),
gourgeist::Prompt::None,
uv_virtualenv::Prompt::None,
false,
Vec::new(),
)?;

View file

@ -18,12 +18,12 @@ workspace = true
[dependencies]
distribution-filename = { path = "../distribution-filename" }
distribution-types = { path = "../distribution-types" }
gourgeist = { path = "../gourgeist" }
install-wheel-rs = { path = "../install-wheel-rs" }
pep440_rs = { path = "../pep440-rs" }
pep508_rs = { path = "../pep508-rs" }
platform-host = { path = "../platform-host" }
platform-tags = { path = "../platform-tags" }
pypi-types = { path = "../pypi-types" }
uv-build = { path = "../uv-build" }
uv-cache = { path = "../uv-cache", features = ["clap"] }
uv-client = { path = "../uv-client" }
@ -33,8 +33,8 @@ 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" }
uv-traits = { path = "../uv-traits" }
uv-virtualenv = { path = "../uv-virtualenv" }
# 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.

View file

@ -15,10 +15,10 @@ workspace = true
[dependencies]
distribution-types = { path = "../distribution-types" }
gourgeist = { path = "../gourgeist" }
pep508_rs = { path = "../pep508-rs" }
platform-host = { path = "../platform-host" }
platform-tags = { path = "../platform-tags" }
pypi-types = { path = "../pypi-types" }
uv-build = { path = "../uv-build" }
uv-cache = { path = "../uv-cache" }
uv-client = { path = "../uv-client" }
@ -27,13 +27,13 @@ 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" }
rustc-hash = { workspace = true }
uv-virtualenv = { path = "../uv-virtualenv" }
anyhow = { workspace = true }
fs-err = { workspace = true }
futures = { workspace = true }
itertools = { workspace = true }
rustc-hash = { workspace = true }
tempfile = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }

View file

@ -22,6 +22,7 @@ pep440_rs = { path = "../pep440-rs", features = ["pubgrub"] }
pep508_rs = { path = "../pep508-rs" }
platform-host = { path = "../platform-host" }
platform-tags = { path = "../platform-tags" }
pypi-types = { path = "../pypi-types" }
uv-cache = { path = "../uv-cache" }
uv-client = { path = "../uv-client" }
uv-distribution = { path = "../uv-distribution" }
@ -30,7 +31,6 @@ uv-interpreter = { path = "../uv-interpreter" }
uv-normalize = { path = "../uv-normalize" }
uv-traits = { path = "../uv-traits" }
uv-warnings = { path = "../uv-warnings" }
pypi-types = { path = "../pypi-types" }
anstream = { workspace = true }
anyhow = { workspace = true }
@ -62,7 +62,7 @@ url = { workspace = true }
zip = { workspace = true }
[dev-dependencies]
gourgeist = { path = "../gourgeist" }
uv-virtualenv = { path = "../uv-virtualenv" }
uv-interpreter = { path = "../uv-interpreter" }
once_cell = { version = "1.19.0" }

View file

@ -1,5 +1,5 @@
[package]
name = "gourgeist"
name = "uv-virtualenv"
version = "0.0.4"
publish = false
description = "virtualenv creation implemented in rust"
@ -14,7 +14,7 @@ authors = { workspace = true }
license = { workspace = true }
[[bin]]
name = "gourgeist"
name = "uv-virtualenv"
required-features = ["cli"]
[lints]

View file

@ -0,0 +1,3 @@
# uv-virtualenv
`uv-virtualenv` is a rust library to create Python virtual environments. It also has a CLI.

View file

@ -11,10 +11,10 @@ use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{fmt, EnvFilter};
use gourgeist::{create_bare_venv, Prompt};
use platform_host::Platform;
use uv_cache::Cache;
use uv_interpreter::{find_default_python, find_requested_python};
use uv_virtualenv::{create_bare_venv, Prompt};
#[derive(Parser, Debug)]
struct Cli {
@ -27,14 +27,14 @@ struct Cli {
system_site_packages: bool,
}
fn run() -> Result<(), gourgeist::Error> {
fn run() -> Result<(), uv_virtualenv::Error> {
let cli = Cli::parse();
let location = cli.path.unwrap_or(Utf8PathBuf::from(".venv"));
let platform = Platform::current()?;
let cache = if let Some(project_dirs) = ProjectDirs::from("", "", "gourgeist") {
let cache = if let Some(project_dirs) = ProjectDirs::from("", "", "uv-virtualenv") {
Cache::from_path(project_dirs.cache_dir())?
} else {
Cache::from_path(".gourgeist_cache")?
Cache::from_path(".cache")?
};
let interpreter = if let Some(python_request) = &cli.python {
find_requested_python(python_request, &platform, &cache)?.ok_or(

View file

@ -16,12 +16,13 @@ workspace = true
[dependencies]
distribution-filename = { path = "../distribution-filename" }
distribution-types = { path = "../distribution-types" }
gourgeist = { path = "../gourgeist" }
install-wheel-rs = { path = "../install-wheel-rs", features = ["clap"], default-features = false }
pep440_rs = { path = "../pep440-rs" }
pep508_rs = { path = "../pep508-rs" }
platform-host = { path = "../platform-host" }
platform-tags = { path = "../platform-tags" }
pypi-types = { path = "../pypi-types" }
requirements-txt = { path = "../requirements-txt" }
uv-build = { path = "../uv-build" }
uv-cache = { path = "../uv-cache", features = ["clap"] }
uv-client = { path = "../uv-client" }
@ -33,9 +34,8 @@ uv-interpreter = { path = "../uv-interpreter" }
uv-normalize = { path = "../uv-normalize" }
uv-resolver = { path = "../uv-resolver", features = ["clap"] }
uv-traits = { path = "../uv-traits" }
uv-virtualenv = { path = "../uv-virtualenv" }
uv-warnings = { path = "../uv-warnings" }
pypi-types = { path = "../pypi-types" }
requirements-txt = { path = "../requirements-txt" }
anstream = { workspace = true }
anyhow = { workspace = true }

View file

@ -12,7 +12,6 @@ use owo_colors::OwoColorize;
use thiserror::Error;
use distribution_types::{DistributionMetadata, IndexLocations, Name};
use gourgeist::Prompt;
use pep508_rs::Requirement;
use platform_host::Platform;
use uv_cache::Cache;
@ -33,7 +32,7 @@ pub(crate) async fn venv(
path: &Path,
python_request: Option<&str>,
index_locations: &IndexLocations,
prompt: Prompt,
prompt: uv_virtualenv::Prompt,
system_site_packages: bool,
connectivity: Connectivity,
seed: bool,
@ -67,7 +66,7 @@ pub(crate) async fn venv(
enum VenvError {
#[error("Failed to create virtualenv")]
#[diagnostic(code(uv::venv::creation))]
Creation(#[source] gourgeist::Error),
Creation(#[source] uv_virtualenv::Error),
#[error("Failed to install seed packages")]
#[diagnostic(code(uv::venv::seed))]
@ -88,7 +87,7 @@ async fn venv_impl(
path: &Path,
python_request: Option<&str>,
index_locations: &IndexLocations,
prompt: Prompt,
prompt: uv_virtualenv::Prompt,
system_site_packages: bool,
connectivity: Connectivity,
seed: bool,
@ -126,8 +125,9 @@ async fn venv_impl(
let extra_cfg = vec![("uv".to_string(), env!("CARGO_PKG_VERSION").to_string())];
// Create the virtual environment.
let venv = gourgeist::create_venv(path, interpreter, prompt, system_site_packages, extra_cfg)
.map_err(VenvError::Creation)?;
let venv =
uv_virtualenv::create_venv(path, interpreter, prompt, system_site_packages, extra_cfg)
.map_err(VenvError::Creation)?;
// Install seed packages.
if seed {

View file

@ -1397,7 +1397,7 @@ async fn run() -> Result<ExitStatus> {
&args.name,
args.python.as_deref(),
&index_locations,
gourgeist::Prompt::from_args(prompt),
uv_virtualenv::Prompt::from_args(prompt),
args.system_site_packages,
if args.offline {
Connectivity::Offline

View file

@ -1,6 +1,6 @@
exclude = [
"crates/gourgeist/src/activator/activate_this.py",
"crates/gourgeist/src/_virtualenv.py"
"crates/uv-virtualenv/src/activator/activate_this.py",
"crates/uv-virtualenv/src/_virtualenv.py"
]
[lint.per-file-ignores]
"__init__.py" = ["F403", "F405"]