Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5e3c810
feat(docker): set default `UV_TOOL_BIN_DIR` on docker images (#13391)
samypr100 Jun 21, 2025
62f222f
Require `--global` for removal of the global Python pin (#14169)
zanieb Jun 26, 2025
c0d2579
Bump `--python-platform linux` to `manylinux_2_28` (#14300)
charliermarsh Jun 27, 2025
3479082
Default to `--workspace` when adding subdirectories (#14529)
charliermarsh Jul 11, 2025
ee4c9bf
Support conflicting editable settings across groups (#14197)
charliermarsh Jul 11, 2025
9584b0b
Tear miette out of the `uv venv` command (#14546)
zanieb Jul 11, 2025
da9f6f5
Add missing validations for disallowed `uv.toml` fields (#14322)
Gankra Jul 11, 2025
9a23a66
Use an ephemeral environment for `uv run --with` invocations (#14447)
charliermarsh Jul 14, 2025
eb88e0f
make `--check` outdated a non-error status 1 (#14167)
Gankra Jul 14, 2025
a9d16b6
Remove `uv version` fallback (#14161)
Gankra Jul 16, 2025
c3fe503
`uv init`: Make `uv_build` the default build backend (from `hatchling…
konstin Jul 16, 2025
f9979ae
Stabilize addition of Python versions to the Windows registry (#14625)
zanieb Jul 16, 2025
ddafdb3
Require `uv venv --clear` before removing an existing directory (#14309)
jtfmumm Jul 16, 2025
118cfba
Validate that discovered interpreters meet the Python preference (#7934)
zanieb Jul 16, 2025
2113a4d
Build `path` sources without build systems by default (#14413)
jtfmumm Jul 16, 2025
7a070d3
Stabilize addition of Python executables to the bin (#14626)
zanieb Jul 17, 2025
108a816
Build and install workspace members that are dependencies by default …
zanieb Jul 17, 2025
ef3c133
Add missing trailing newline to outdated error (#14689)
konstin Jul 17, 2025
0ca19c3
Fix rendering of `uv venv --clear` hint in bash (#14691)
zanieb Jul 17, 2025
5d097d4
Add release notes and bump version for 0.8.0 (#14690)
zanieb Jul 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ jobs:
cat <<EOF > Dockerfile
FROM ${BASE_IMAGE}
COPY --from=${{ env.UV_GHCR_IMAGE }}:latest /uv /uvx /usr/local/bin/
ENV UV_TOOL_BIN_DIR="/usr/local/bin"
ENTRYPOINT []
CMD ["/usr/local/bin/uv"]
EOF
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ jobs:

- name: "Create a virtual environment (uv)"
run: |
./uv venv -p 3.13t --managed-python
./uv venv -c -p 3.13t --managed-python

- name: "Check version (uv)"
run: |
Expand Down Expand Up @@ -1087,7 +1087,7 @@ jobs:

- name: "Create a virtual environment (uv)"
run: |
./uv venv -p 3.13 --managed-python
./uv venv -c -p 3.13 --managed-python

- name: "Check version (uv)"
run: |
Expand Down Expand Up @@ -1132,7 +1132,7 @@ jobs:

- name: "Create a virtual environment (uv)"
run: |
./uv venv -p 3.13 --managed-python
./uv venv -c -p 3.13 --managed-python

- name: "Check version (uv)"
run: |
Expand Down Expand Up @@ -1758,14 +1758,14 @@ jobs:
./uv run --no-project python -c "from built_by_uv import greet; print(greet())"

# Test both `build_wheel` and `build_sdist` through uv
./uv venv -v
./uv venv -c -v
./uv build -v --force-pep517 scripts/packages/built-by-uv --find-links crates/uv-build/dist --offline
./uv pip install -v scripts/packages/built-by-uv/dist/*.tar.gz --find-links crates/uv-build/dist --offline --no-deps
./uv run --no-project python -c "from built_by_uv import greet; print(greet())"

# Test both `build_wheel` and `build_sdist` through the official `build`
rm -rf scripts/packages/built-by-uv/dist/
./uv venv -v
./uv venv -c -v
./uv pip install build
# Add the uv binary to PATH for `build` to find
PATH="$(pwd):$PATH" UV_OFFLINE=1 UV_FIND_LINKS=crates/uv-build/dist ./uv run --no-project python -m build -v --installer uv scripts/packages/built-by-uv
Expand Down
197 changes: 173 additions & 24 deletions CHANGELOG.md

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/uv-build-backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ mod tests {
// Check that the source dist is reproducible across platforms.
assert_snapshot!(
format!("{:x}", sha2::Sha256::digest(fs_err::read(&source_dist_path).unwrap())),
@"dab46bcc4d66960a11cfdc19604512a8e1a3241a67536f7e962166760e9c575c"
@"9a7f7181c5e69ac14e411a2500fed153a1e6ea41cd5da6f24f226c4cddacf6b7"
);
// Check both the files we report and the actual files
assert_snapshot!(format_file_list(build.source_dist_list_files, src.path()), @r"
Expand Down
14 changes: 7 additions & 7 deletions crates/uv-build-backend/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl PyProjectToml {
///
/// ```toml
/// [build-system]
/// requires = ["uv_build>=0.4.15,<5"]
/// requires = ["uv_build>=0.4.15,<0.5"]
/// build-backend = "uv_build"
/// ```
pub fn check_build_system(&self, uv_version: &str) -> Vec<String> {
Expand Down Expand Up @@ -826,7 +826,7 @@ mod tests {
{payload}

[build-system]
requires = ["uv_build>=0.4.15,<5"]
requires = ["uv_build>=0.4.15,<0.5"]
build-backend = "uv_build"
"#
}
Expand Down Expand Up @@ -909,7 +909,7 @@ mod tests {
foo-bar = "foo:bar"

[build-system]
requires = ["uv_build>=0.4.15,<5"]
requires = ["uv_build>=0.4.15,<0.5"]
build-backend = "uv_build"
"#
};
Expand Down Expand Up @@ -1036,7 +1036,7 @@ mod tests {
foo-bar = "foo:bar"

[build-system]
requires = ["uv_build>=0.4.15,<5"]
requires = ["uv_build>=0.4.15,<0.5"]
build-backend = "uv_build"
"#
};
Expand Down Expand Up @@ -1104,7 +1104,7 @@ mod tests {
let contents = extend_project("");
let pyproject_toml = PyProjectToml::parse(&contents).unwrap();
assert_snapshot!(
pyproject_toml.check_build_system("1.0.0+test").join("\n"),
pyproject_toml.check_build_system("0.4.15+test").join("\n"),
@""
);
}
Expand Down Expand Up @@ -1135,7 +1135,7 @@ mod tests {
version = "0.1.0"

[build-system]
requires = ["uv_build>=0.4.15,<5", "wheel"]
requires = ["uv_build>=0.4.15,<0.5", "wheel"]
build-backend = "uv_build"
"#};
let pyproject_toml = PyProjectToml::parse(contents).unwrap();
Expand Down Expand Up @@ -1171,7 +1171,7 @@ mod tests {
version = "0.1.0"

[build-system]
requires = ["uv_build>=0.4.15,<5"]
requires = ["uv_build>=0.4.15,<0.5"]
build-backend = "setuptools"
"#};
let pyproject_toml = PyProjectToml::parse(contents).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion crates/uv-build-frontend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ impl SourceBuild {
interpreter.clone(),
uv_virtualenv::Prompt::None,
false,
false,
uv_virtualenv::OnExisting::Remove,
false,
false,
false,
Expand Down
2 changes: 1 addition & 1 deletion crates/uv-build/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "uv-build"
version = "0.7.22"
version = "0.8.0"
edition.workspace = true
rust-version.workspace = true
homepage.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/uv-build/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "uv-build"
version = "0.7.22"
version = "0.8.0"
description = "The uv build backend"
authors = [{ name = "Astral Software Inc.", email = "[email protected]" }]
requires-python = ">=3.8"
Expand Down
9 changes: 0 additions & 9 deletions crates/uv-cli/src/compat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,6 @@ enum Resolver {
/// These represent a subset of the `virtualenv` interface that uv supports by default.
#[derive(Args)]
pub struct VenvCompatArgs {
#[clap(long, hide = true)]
clear: bool,

#[clap(long, hide = true)]
no_seed: bool,

Expand All @@ -289,12 +286,6 @@ impl CompatArgs for VenvCompatArgs {
/// behavior. If an argument is passed that does _not_ match uv's behavior, this method will
/// return an error.
fn validate(&self) -> Result<()> {
if self.clear {
warn_user!(
"virtualenv's `--clear` has no effect (uv always clears the virtual environment)"
);
}

if self.no_seed {
warn_user!(
"virtualenv's `--no-seed` has no effect (uv omits seed packages by default)"
Expand Down
35 changes: 25 additions & 10 deletions crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2615,16 +2615,23 @@ pub struct VenvArgs {
#[arg(long, value_parser = clap::builder::BoolishValueParser::new(), env = EnvVars::UV_VENV_SEED)]
pub seed: bool,

/// Remove any existing files or directories at the target path.
///
/// By default, `uv venv` will exit with an error if the given path is non-empty. The
/// `--clear` option will instead clear a non-empty path before creating a new virtual
/// environment.
#[clap(long, short, overrides_with = "allow_existing", value_parser = clap::builder::BoolishValueParser::new(), env = EnvVars::UV_VENV_CLEAR)]
pub clear: bool,

/// Preserve any existing files or directories at the target path.
///
/// By default, `uv venv` will remove an existing virtual environment at the given path, and
/// exit with an error if the path is non-empty but _not_ a virtual environment. The
/// By default, `uv venv` will exit with an error if the given path is non-empty. The
/// `--allow-existing` option will instead write to the given path, regardless of its contents,
/// and without clearing it beforehand.
///
/// WARNING: This option can lead to unexpected behavior if the existing virtual environment and
/// the newly-created virtual environment are linked to different Python interpreters.
#[clap(long)]
#[clap(long, overrides_with = "clear")]
pub allow_existing: bool,

/// The path to the virtual environment to create.
Expand Down Expand Up @@ -3726,10 +3733,19 @@ pub struct AddArgs {

/// Add the dependency as a workspace member.
///
/// When used with a path dependency, the package will be added to the workspace's `members`
/// list in the root `pyproject.toml` file.
#[arg(long)]
/// By default, uv will add path dependencies that are within the workspace directory
/// as workspace members. When used with a path dependency, the package will be added
/// to the workspace's `members` list in the root `pyproject.toml` file.
#[arg(long, overrides_with = "no_workspace")]
pub workspace: bool,

/// Don't add the dependency as a workspace member.
///
/// By default, when adding a dependency that's a local path and is within the workspace
/// directory, uv will add it as a workspace member; pass `--no-workspace` to add the package
/// as direct path dependency instead.
#[arg(long, overrides_with = "workspace")]
pub no_workspace: bool,
}

#[derive(Args)]
Expand Down Expand Up @@ -4794,10 +4810,9 @@ pub enum PythonCommand {
/// Python versions are installed into the uv Python directory, which can be retrieved with `uv
/// python dir`.
///
/// A `python` executable is not made globally available, managed Python versions are only used
/// in uv commands or in active virtual environments. There is experimental support for adding
/// Python executables to a directory on the path — use the `--preview` flag to enable this
/// behavior and `uv python dir --bin` to retrieve the target directory.
/// By default, Python executables are added to a directory on the path with a minor version
/// suffix, e.g., `python3.13`. To install `python3` and `python`, use the `--default` flag. Use
/// `uv python dir --bin` to see the target directory.
///
/// Multiple Python versions may be requested.
///
Expand Down
8 changes: 4 additions & 4 deletions crates/uv-configuration/src/target_triple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub enum TargetTriple {
#[serde(rename = "i686-pc-windows-msvc")]
I686PcWindowsMsvc,

/// An x86 Linux target. Equivalent to `x86_64-manylinux_2_17`.
/// An x86 Linux target. Equivalent to `x86_64-manylinux_2_28`.
#[cfg_attr(feature = "clap", value(name = "x86_64-unknown-linux-gnu"))]
#[serde(rename = "x86_64-unknown-linux-gnu")]
#[serde(alias = "x8664-unknown-linux-gnu")]
Expand All @@ -56,7 +56,7 @@ pub enum TargetTriple {
#[serde(alias = "x8664-apple-darwin")]
X8664AppleDarwin,

/// An ARM64 Linux target. Equivalent to `aarch64-manylinux_2_17`.
/// An ARM64 Linux target. Equivalent to `aarch64-manylinux_2_28`.
#[cfg_attr(feature = "clap", value(name = "aarch64-unknown-linux-gnu"))]
#[serde(rename = "aarch64-unknown-linux-gnu")]
Aarch64UnknownLinuxGnu,
Expand Down Expand Up @@ -240,7 +240,7 @@ impl TargetTriple {
Self::Linux | Self::X8664UnknownLinuxGnu => Platform::new(
Os::Manylinux {
major: 2,
minor: 17,
minor: 28,
},
Arch::X86_64,
),
Expand All @@ -262,7 +262,7 @@ impl TargetTriple {
Self::Aarch64UnknownLinuxGnu => Platform::new(
Os::Manylinux {
major: 2,
minor: 17,
minor: 28,
},
Arch::Aarch64,
),
Expand Down
35 changes: 34 additions & 1 deletion crates/uv-console/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ use std::{cmp::Ordering, iter};
/// This is a slimmed-down version of `dialoguer::Confirm`, with the post-confirmation report
/// enabled.
pub fn confirm(message: &str, term: &Term, default: bool) -> std::io::Result<bool> {
confirm_inner(message, None, term, default)
}

/// Prompt the user for confirmation in the given [`Term`], with a hint.
pub fn confirm_with_hint(
message: &str,
hint: &str,
term: &Term,
default: bool,
) -> std::io::Result<bool> {
confirm_inner(message, Some(hint), term, default)
}

fn confirm_inner(
message: &str,
hint: Option<&str>,
term: &Term,
default: bool,
) -> std::io::Result<bool> {
let prompt = format!(
"{} {} {} {} {}",
style("?".to_string()).for_stderr().yellow(),
Expand All @@ -18,6 +37,13 @@ pub fn confirm(message: &str, term: &Term, default: bool) -> std::io::Result<boo
);

term.write_str(&prompt)?;
if let Some(hint) = hint {
term.write_str(&format!(
"\n\n{}{} {hint}",
style("hint").for_stderr().bold().cyan(),
style(":").for_stderr().bold()
))?;
}
term.hide_cursor()?;
term.flush()?;

Expand Down Expand Up @@ -56,7 +82,14 @@ pub fn confirm(message: &str, term: &Term, default: bool) -> std::io::Result<boo
.cyan(),
);

term.clear_line()?;
if hint.is_some() {
term.clear_last_lines(2)?;
// It's not clear why we need to clear to the end of the screen here, but it fixes lingering
// display of the hint on `bash` (the issue did not reproduce on `zsh`).
term.clear_to_end_of_screen()?;
} else {
term.clear_line()?;
}
term.write_line(&report)?;
term.show_cursor()?;
term.flush()?;
Expand Down
Loading
Loading