mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Add --emit-build-options
flag to uv pip compile
interface (#4463)
## Summary Closes https://github.com/astral-sh/uv/issues/4420.
This commit is contained in:
parent
cba270f750
commit
f07308823e
14 changed files with 148 additions and 13 deletions
|
@ -385,3 +385,7 @@ By default, uv does not write any index URLs to the output file, while `pip-comp
|
|||
`--index-url` or `--extra-index-url` that does not match the default (PyPI). To include index URLs
|
||||
in the output file, pass the `--emit-index-url` flag to `uv pip compile`. Unlike `pip-compile`,
|
||||
uv will include all index URLs when `--emit-index-url` is passed, including the default index URL.
|
||||
|
||||
By default, uv does not write any `--no-build` or `--only-binary` options to the output file, unlike
|
||||
`pip-compile`. To include these options in the output file, pass the `--emit-build-options` flag to
|
||||
`uv pip compile`.
|
||||
|
|
|
@ -89,7 +89,7 @@ enum RequirementsTxtStatement {
|
|||
NoIndex,
|
||||
/// `--no-binary`
|
||||
NoBinary(NoBinary),
|
||||
/// `only-binary`
|
||||
/// `--only-binary`
|
||||
OnlyBinary(NoBuild),
|
||||
}
|
||||
|
||||
|
|
|
@ -577,6 +577,13 @@ pub struct PipCompileArgs {
|
|||
#[arg(long, overrides_with("emit_find_links"), hide = true)]
|
||||
pub no_emit_find_links: bool,
|
||||
|
||||
/// Include `--no-binary` and `--only-binary` entries in the generated output file.
|
||||
#[arg(long, overrides_with("no_emit_build_options"))]
|
||||
pub emit_build_options: bool,
|
||||
|
||||
#[arg(long, overrides_with("emit_build_options"), hide = true)]
|
||||
pub no_emit_build_options: bool,
|
||||
|
||||
/// Whether to emit a marker string indicating when it is known that the
|
||||
/// resulting set of pinned dependencies is valid.
|
||||
///
|
||||
|
|
|
@ -78,14 +78,14 @@ impl BuildOptions {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn no_build(&self, package_name: Option<&PackageName>) -> bool {
|
||||
pub fn no_build_requirement(&self, package_name: Option<&PackageName>) -> bool {
|
||||
match package_name {
|
||||
Some(name) => self.no_build_package(name),
|
||||
None => self.no_build_all(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn no_binary(&self, package_name: Option<&PackageName>) -> bool {
|
||||
pub fn no_binary_requirement(&self, package_name: Option<&PackageName>) -> bool {
|
||||
match package_name {
|
||||
Some(name) => self.no_binary_package(name),
|
||||
None => self.no_binary_all(),
|
||||
|
@ -99,6 +99,16 @@ impl BuildOptions {
|
|||
pub fn no_binary_all(&self) -> bool {
|
||||
matches!(self.no_binary, NoBinary::All)
|
||||
}
|
||||
|
||||
/// Return the [`NoBuild`] strategy to use.
|
||||
pub fn no_build(&self) -> &NoBuild {
|
||||
&self.no_build
|
||||
}
|
||||
|
||||
/// Return the [`NoBinary`] strategy to use.
|
||||
pub fn no_binary(&self) -> &NoBinary {
|
||||
&self.no_binary
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
|
|
|
@ -308,7 +308,7 @@ impl<'a> BuildContext for BuildDispatch<'a> {
|
|||
// unless all builds are disabled.
|
||||
if self
|
||||
.build_options
|
||||
.no_build(dist.map(distribution_types::Name::name))
|
||||
.no_build_requirement(dist.map(distribution_types::Name::name))
|
||||
// We always allow editable builds
|
||||
&& !matches!(build_kind, BuildKind::Editable)
|
||||
{
|
||||
|
|
|
@ -413,7 +413,11 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
|
|||
hashes: HashPolicy<'_>,
|
||||
) -> Result<ArchiveMetadata, Error> {
|
||||
// Optimization: Skip source dist download when we must not build them anyway.
|
||||
if self.build_context.build_options().no_build(source.name()) {
|
||||
if self
|
||||
.build_context
|
||||
.build_options()
|
||||
.no_build_requirement(source.name())
|
||||
{
|
||||
if source.is_editable() {
|
||||
debug!("Allowing build for editable source distribution: {source}");
|
||||
} else {
|
||||
|
|
|
@ -1390,7 +1390,11 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
|
|||
debug!("Building: {source}");
|
||||
|
||||
// Guard against build of source distributions when disabled.
|
||||
if self.build_context.build_options().no_build(source.name()) {
|
||||
if self
|
||||
.build_context
|
||||
.build_options()
|
||||
.no_build_requirement(source.name())
|
||||
{
|
||||
if source.is_editable() {
|
||||
debug!("Allowing build for editable source distribution: {source}");
|
||||
} else {
|
||||
|
|
|
@ -180,6 +180,7 @@ pub struct PipOptions {
|
|||
pub no_emit_package: Option<Vec<PackageName>>,
|
||||
pub emit_index_url: Option<bool>,
|
||||
pub emit_find_links: Option<bool>,
|
||||
pub emit_build_options: Option<bool>,
|
||||
pub emit_marker_expression: Option<bool>,
|
||||
pub emit_index_annotation: Option<bool>,
|
||||
pub annotation_style: Option<AnnotationStyle>,
|
||||
|
|
|
@ -21,7 +21,7 @@ use uv_cache::Cache;
|
|||
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
|
||||
use uv_configuration::{
|
||||
BuildOptions, Concurrency, ConfigSettings, Constraints, ExtrasSpecification, IndexStrategy,
|
||||
Overrides, PreviewMode, SetupPyStrategy, Upgrade,
|
||||
NoBinary, NoBuild, Overrides, PreviewMode, SetupPyStrategy, Upgrade,
|
||||
};
|
||||
use uv_configuration::{KeyringProviderType, TargetTriple};
|
||||
use uv_dispatch::BuildDispatch;
|
||||
|
@ -71,6 +71,7 @@ pub(crate) async fn pip_compile(
|
|||
custom_compile_command: Option<String>,
|
||||
include_index_url: bool,
|
||||
include_find_links: bool,
|
||||
include_build_options: bool,
|
||||
include_marker_expression: bool,
|
||||
include_index_annotation: bool,
|
||||
index_locations: IndexLocations,
|
||||
|
@ -539,18 +540,17 @@ pub(crate) async fn pip_compile(
|
|||
writeln!(writer, "{}", format!("# {relevant_markers}").green())?;
|
||||
}
|
||||
|
||||
// Write the index locations to the output channel.
|
||||
let mut wrote_index = false;
|
||||
let mut wrote_preamble = false;
|
||||
|
||||
// If necessary, include the `--index-url` and `--extra-index-url` locations.
|
||||
if include_index_url {
|
||||
if let Some(index) = index_locations.index() {
|
||||
writeln!(writer, "--index-url {}", index.verbatim())?;
|
||||
wrote_index = true;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
for extra_index in index_locations.extra_index() {
|
||||
writeln!(writer, "--extra-index-url {}", extra_index.verbatim())?;
|
||||
wrote_index = true;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -558,12 +558,42 @@ pub(crate) async fn pip_compile(
|
|||
if include_find_links {
|
||||
for flat_index in index_locations.flat_index() {
|
||||
writeln!(writer, "--find-links {flat_index}")?;
|
||||
wrote_index = true;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If necessary, include the `--no-binary` and `--only-binary` options.
|
||||
if include_build_options {
|
||||
match build_options.no_binary() {
|
||||
NoBinary::None => {}
|
||||
NoBinary::All => {
|
||||
writeln!(writer, "--no-binary :all:")?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
NoBinary::Packages(packages) => {
|
||||
for package in packages {
|
||||
writeln!(writer, "--no-binary {package}")?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
match build_options.no_build() {
|
||||
NoBuild::None => {}
|
||||
NoBuild::All => {
|
||||
writeln!(writer, "--only-binary :all:")?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
NoBuild::Packages(packages) => {
|
||||
for package in packages {
|
||||
writeln!(writer, "--only-binary {package}")?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we wrote an index, add a newline to separate it from the requirements
|
||||
if wrote_index {
|
||||
if wrote_preamble {
|
||||
writeln!(writer)?;
|
||||
}
|
||||
|
||||
|
|
|
@ -268,6 +268,7 @@ async fn run() -> Result<ExitStatus> {
|
|||
args.settings.custom_compile_command,
|
||||
args.settings.emit_index_url,
|
||||
args.settings.emit_find_links,
|
||||
args.settings.emit_build_options,
|
||||
args.settings.emit_marker_expression,
|
||||
args.settings.emit_index_annotation,
|
||||
args.settings.index_locations,
|
||||
|
|
|
@ -528,6 +528,8 @@ impl PipCompileSettings {
|
|||
no_emit_index_url,
|
||||
emit_find_links,
|
||||
no_emit_find_links,
|
||||
emit_build_options,
|
||||
no_emit_build_options,
|
||||
emit_marker_expression,
|
||||
no_emit_marker_expression,
|
||||
emit_index_annotation,
|
||||
|
@ -581,6 +583,7 @@ impl PipCompileSettings {
|
|||
no_emit_package,
|
||||
emit_index_url: flag(emit_index_url, no_emit_index_url),
|
||||
emit_find_links: flag(emit_find_links, no_emit_find_links),
|
||||
emit_build_options: flag(emit_build_options, no_emit_build_options),
|
||||
emit_marker_expression: flag(emit_marker_expression, no_emit_marker_expression),
|
||||
emit_index_annotation: flag(emit_index_annotation, no_emit_index_annotation),
|
||||
annotation_style,
|
||||
|
@ -1406,6 +1409,7 @@ pub(crate) struct PipSettings {
|
|||
pub(crate) no_emit_package: Vec<PackageName>,
|
||||
pub(crate) emit_index_url: bool,
|
||||
pub(crate) emit_find_links: bool,
|
||||
pub(crate) emit_build_options: bool,
|
||||
pub(crate) emit_marker_expression: bool,
|
||||
pub(crate) emit_index_annotation: bool,
|
||||
pub(crate) annotation_style: AnnotationStyle,
|
||||
|
@ -1460,6 +1464,7 @@ impl PipSettings {
|
|||
no_emit_package,
|
||||
emit_index_url,
|
||||
emit_find_links,
|
||||
emit_build_options,
|
||||
emit_marker_expression,
|
||||
emit_index_annotation,
|
||||
annotation_style,
|
||||
|
@ -1595,6 +1600,10 @@ impl PipSettings {
|
|||
.emit_find_links
|
||||
.combine(emit_find_links)
|
||||
.unwrap_or_default(),
|
||||
emit_build_options: args
|
||||
.emit_build_options
|
||||
.combine(emit_build_options)
|
||||
.unwrap_or_default(),
|
||||
emit_marker_expression: args
|
||||
.emit_marker_expression
|
||||
.combine(emit_marker_expression)
|
||||
|
|
|
@ -5116,6 +5116,49 @@ fn emit_find_links() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Emit the `--no-binary` and `--only-binary` options.
|
||||
#[test]
|
||||
fn emit_build_options() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
let requirements_in = context.temp_dir.child("requirements.in");
|
||||
requirements_in.write_str("black==23.10.1")?;
|
||||
|
||||
uv_snapshot!(context.compile()
|
||||
.arg("requirements.in")
|
||||
.arg("--emit-build-options")
|
||||
.arg("--only-binary")
|
||||
.arg("black")
|
||||
.arg("--no-binary")
|
||||
.arg(":all:"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in --emit-build-options --only-binary black --no-binary :all:
|
||||
--no-binary :all:
|
||||
--only-binary black
|
||||
|
||||
black==23.10.1
|
||||
# via -r requirements.in
|
||||
click==8.1.7
|
||||
# via black
|
||||
mypy-extensions==1.0.0
|
||||
# via black
|
||||
packaging==24.0
|
||||
# via black
|
||||
pathspec==0.12.1
|
||||
# via black
|
||||
platformdirs==4.2.0
|
||||
# via black
|
||||
|
||||
----- stderr -----
|
||||
Resolved 6 packages in [TIME]
|
||||
"###
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Respect the `--no-index` flag in a `requirements.txt` file.
|
||||
#[test]
|
||||
fn no_index_requirements_txt() -> Result<()> {
|
||||
|
|
|
@ -147,6 +147,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -274,6 +275,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -402,6 +404,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -562,6 +565,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -668,6 +672,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -806,6 +811,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -981,6 +987,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -1155,6 +1162,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -1302,6 +1310,7 @@ fn resolve_find_links() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -1430,6 +1439,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -1596,6 +1606,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -1745,6 +1756,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -1873,6 +1885,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -1984,6 +1997,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -2095,6 +2109,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
@ -2208,6 +2223,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
no_emit_package: [],
|
||||
emit_index_url: false,
|
||||
emit_find_links: false,
|
||||
emit_build_options: false,
|
||||
emit_marker_expression: false,
|
||||
emit_index_annotation: false,
|
||||
annotation_style: Split,
|
||||
|
|
6
uv.schema.json
generated
6
uv.schema.json
generated
|
@ -493,6 +493,12 @@
|
|||
"null"
|
||||
]
|
||||
},
|
||||
"emit-build-options": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"emit-find-links": {
|
||||
"type": [
|
||||
"boolean",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue