mirror of https://github.com/astral-sh/uv
Reject non-PEP 751 filenames in `uv pip compile` and `uv export` (#13119)
We shouldn't let users create files that won't work in subsequent commands. Closes https://github.com/astral-sh/uv/issues/13117.
This commit is contained in:
parent
e8524ebea4
commit
3ace372158
|
|
@ -1,5 +1,6 @@
|
|||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
|
@ -33,7 +34,7 @@ use uv_python::{
|
|||
};
|
||||
use uv_requirements::upgrade::{read_pylock_toml_requirements, LockedRequirements};
|
||||
use uv_requirements::{
|
||||
upgrade::read_requirements_txt, RequirementsSource, RequirementsSpecification,
|
||||
is_pylock_toml, upgrade::read_requirements_txt, RequirementsSource, RequirementsSpecification,
|
||||
};
|
||||
use uv_resolver::{
|
||||
AnnotationStyle, DependencyMode, DisplayResolutionGraph, ExcludeNewer, FlatIndex, ForkStrategy,
|
||||
|
|
@ -133,6 +134,20 @@ pub(crate) async fn pip_compile(
|
|||
}
|
||||
});
|
||||
|
||||
// If the user is exporting to PEP 751, ensure the filename matches the specification.
|
||||
if matches!(format, ExportFormat::PylockToml) {
|
||||
if let Some(file_name) = output_file
|
||||
.and_then(Path::file_name)
|
||||
.and_then(OsStr::to_str)
|
||||
{
|
||||
if !is_pylock_toml(file_name) {
|
||||
return Err(anyhow!(
|
||||
"Expected the output filename to start with `pylock.` and end with `.toml` (e.g., `pylock.toml`, `pylock.dev.toml`); `{file_name}` won't be recognized as a `pylock.toml` file in subsequent commands",
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Respect `UV_PYTHON`
|
||||
if python.is_none() && python_version.is_none() {
|
||||
if let Ok(request) = std::env::var("UV_PYTHON") {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::env;
|
|||
use std::ffi::OsStr;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use itertools::Itertools;
|
||||
use owo_colors::OwoColorize;
|
||||
|
||||
|
|
@ -282,6 +282,21 @@ pub(crate) async fn export(
|
|||
}
|
||||
});
|
||||
|
||||
// If the user is exporting to PEP 751, ensure the filename matches the specification.
|
||||
if matches!(format, ExportFormat::PylockToml) {
|
||||
if let Some(file_name) = output_file
|
||||
.as_deref()
|
||||
.and_then(Path::file_name)
|
||||
.and_then(OsStr::to_str)
|
||||
{
|
||||
if !is_pylock_toml(file_name) {
|
||||
return Err(anyhow!(
|
||||
"Expected the output filename to start with `pylock.` and end with `.toml` (e.g., `pylock.toml`, `pylock.dev.toml`); `{file_name}` won't be recognized as a `pylock.toml` file in subsequent commands",
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the export.
|
||||
match format {
|
||||
ExportFormat::RequirementsTxt => {
|
||||
|
|
|
|||
|
|
@ -4066,3 +4066,37 @@ fn pep_751_infer_output_format() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_filename() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["anyio==3.7.0"]
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=42"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
"#,
|
||||
)?;
|
||||
|
||||
context.lock().assert().success();
|
||||
|
||||
uv_snapshot!(context.filters(), context.export().arg("--format").arg("pylock.toml").arg("-o").arg("test.toml"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 4 packages in [TIME]
|
||||
error: Expected the output filename to start with `pylock.` and end with `.toml` (e.g., `pylock.toml`, `pylock.dev.toml`); `test.toml` won't be recognized as a `pylock.toml` file in subsequent commands
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16262,6 +16262,32 @@ fn compile_invalid_output_file() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_filename() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str("iniconfig")?;
|
||||
|
||||
uv_snapshot!(context.filters(), context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("--format")
|
||||
.arg("pylock.toml")
|
||||
.arg("-o")
|
||||
.arg("test.toml"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: Expected the output filename to start with `pylock.` and end with `.toml` (e.g., `pylock.toml`, `pylock.dev.toml`); `test.toml` won't be recognized as a `pylock.toml` file in subsequent commands
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_registry_wheel() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
|
|
|||
Loading…
Reference in New Issue