feat: add environment variable to disable writing installer metadata files (#8877)

## Summary

This change introduces the `UV_NO_INSTALLER_METADATA` environment
variable
as a way to opt out of the extra installer metadata files that `uv` is
creating.

This is important to achieve reproducible builds in distribution
packaging, allowing to replace usage of
[installer](https://pypi.org/project/installer) with `uv pip install`.

At the time of writing these files are:
- `uv_cache.json`
    Contains timestamps which are non-reproducible.
    These hashes also leak in to the `RECORD` file.

- `direct_url.json`
    Contains the path to the installed wheel.
While not non-reproducible it's not required for distribution packaging.

- `INSTALLER`
Again, not non-reproducible, but of no value in distribution packaging.

## Test Plan

Automated test added.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
This commit is contained in:
adisbladis 2024-12-04 01:29:33 +00:00 committed by GitHub
parent ae033e2d3b
commit 28d4ef35f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 162 additions and 13 deletions

View File

@ -256,6 +256,10 @@ pub struct GlobalArgs {
#[arg(global = true, long, env = EnvVars::UV_NO_PROGRESS, value_parser = clap::builder::BoolishValueParser::new())]
pub no_progress: bool,
/// Skip writing `uv` installer metadata files (e.g., `INSTALLER`, `REQUESTED`, and `direct_url.json`) to site-packages `.dist-info` directories.
#[arg(global = true, long, hide = true, env = EnvVars::UV_NO_INSTALLER_METADATA, value_parser = clap::builder::BoolishValueParser::new())]
pub no_installer_metadata: bool,
/// Change to the given directory prior to running the command.
///
/// Relative paths are resolved with the given directory as the base.

View File

@ -7,8 +7,8 @@ use std::time::SystemTime;
use crate::script::{scripts_from_ini, Script};
use crate::wheel::{
extra_dist_info, install_data, parse_wheel_file, read_record_file, write_script_entrypoints,
LibKind,
install_data, parse_wheel_file, read_record_file, write_installer_metadata,
write_script_entrypoints, LibKind,
};
use crate::{Error, Layout};
use fs_err as fs;
@ -43,6 +43,7 @@ pub fn install_wheel(
direct_url: Option<&DirectUrl>,
cache_info: Option<&CacheInfo>,
installer: Option<&str>,
installer_metadata: bool,
link_mode: LinkMode,
locks: &Locks,
) -> Result<(), Error> {
@ -140,16 +141,18 @@ pub fn install_wheel(
trace!(?name, "No data");
}
trace!(?name, "Writing extra metadata");
extra_dist_info(
site_packages,
&dist_info_prefix,
true,
direct_url,
cache_info,
installer,
&mut record,
)?;
if installer_metadata {
trace!(?name, "Writing installer metadata");
write_installer_metadata(
site_packages,
&dist_info_prefix,
true,
direct_url,
cache_info,
installer,
&mut record,
)?;
}
trace!(?name, "Writing record");
let mut record_writer = csv::WriterBuilder::new()

View File

@ -612,7 +612,7 @@ pub(crate) fn write_file_recorded(
}
/// Adds `INSTALLER`, `REQUESTED` and `direct_url.json` to the .dist-info dir
pub(crate) fn extra_dist_info(
pub(crate) fn write_installer_metadata(
site_packages: &Path,
dist_info_prefix: &str,
requested: bool,

View File

@ -17,6 +17,7 @@ pub struct Installer<'a> {
cache: Option<&'a Cache>,
reporter: Option<Box<dyn Reporter>>,
installer_name: Option<String>,
installer_metadata: bool,
}
impl<'a> Installer<'a> {
@ -28,6 +29,7 @@ impl<'a> Installer<'a> {
cache: None,
reporter: None,
installer_name: Some("uv".to_string()),
installer_metadata: true,
}
}
@ -64,6 +66,15 @@ impl<'a> Installer<'a> {
}
}
/// Set the whether to link Uv specific files in dist-info
#[must_use]
pub fn with_installer_metadata(self, installer_metadata: bool) -> Self {
Self {
installer_metadata,
..self
}
}
/// Install a set of wheels into a Python virtual environment.
#[instrument(skip_all, fields(num_wheels = %wheels.len()))]
pub async fn install(self, wheels: Vec<CachedDist>) -> Result<Vec<CachedDist>> {
@ -73,6 +84,7 @@ impl<'a> Installer<'a> {
link_mode,
reporter,
installer_name,
installer_metadata,
} = self;
if cache.is_some_and(Cache::is_temporary) {
@ -97,6 +109,7 @@ impl<'a> Installer<'a> {
link_mode,
reporter,
relocatable,
installer_metadata,
);
// This may fail if the main task was cancelled.
@ -126,6 +139,7 @@ impl<'a> Installer<'a> {
self.link_mode,
self.reporter,
self.venv.relocatable(),
self.installer_metadata,
)
}
}
@ -139,6 +153,7 @@ fn install(
link_mode: LinkMode,
reporter: Option<Box<dyn Reporter>>,
relocatable: bool,
installer_metadata: bool,
) -> Result<Vec<CachedDist>> {
// Initialize the threadpool with the user settings.
LazyLock::force(&RAYON_INITIALIZE);
@ -161,6 +176,7 @@ fn install(
Some(wheel.cache_info())
},
installer_name.as_deref(),
installer_metadata,
link_mode,
&locks,
)

View File

@ -553,4 +553,7 @@ impl EnvVars {
/// Avoid modifying the `PATH` environment variable when installing uv using the standalone
/// installer and `self update` feature.
pub const INSTALLER_NO_MODIFY_PATH: &'static str = "INSTALLER_NO_MODIFY_PATH";
/// Skip writing `uv` installer metadata files (e.g., `INSTALLER`, `REQUESTED`, and `direct_url.json`) to site-packages `.dist-info` directories.
pub const UV_NO_INSTALLER_METADATA: &'static str = "UV_NO_INSTALLER_METADATA";
}

View File

@ -61,6 +61,7 @@ pub(crate) async fn pip_install(
link_mode: LinkMode,
compile: bool,
hash_checking: Option<HashCheckingMode>,
installer_metadata: bool,
connectivity: Connectivity,
config_settings: &ConfigSettings,
no_build_isolation: bool,
@ -449,6 +450,7 @@ pub(crate) async fn pip_install(
&cache,
&environment,
Box::new(DefaultInstallLogger),
installer_metadata,
dry_run,
printer,
)

View File

@ -397,6 +397,7 @@ pub(crate) async fn install(
cache: &Cache,
venv: &PythonEnvironment,
logger: Box<dyn InstallLogger>,
installer_metadata: bool,
dry_run: bool,
printer: Printer,
) -> Result<Changelog, Error> {
@ -546,6 +547,7 @@ pub(crate) async fn install(
installs = uv_installer::Installer::new(venv)
.with_link_mode(link_mode)
.with_cache(cache)
.with_installer_metadata(installer_metadata)
.with_reporter(InstallReporter::from(printer).with_length(installs.len() as u64))
// This technically can block the runtime, but we are on the main thread and
// have no other running tasks at this point, so this lets us avoid spawning a blocking

View File

@ -51,6 +51,7 @@ pub(crate) async fn pip_sync(
dependency_metadata: DependencyMetadata,
keyring_provider: KeyringProviderType,
allow_empty_requirements: bool,
installer_metadata: bool,
connectivity: Connectivity,
config_settings: &ConfigSettings,
no_build_isolation: bool,
@ -394,6 +395,7 @@ pub(crate) async fn pip_sync(
&cache,
&environment,
Box::new(DefaultInstallLogger),
installer_metadata,
dry_run,
printer,
)

View File

@ -77,6 +77,7 @@ pub(crate) async fn add(
script: Option<PathBuf>,
python_preference: PythonPreference,
python_downloads: PythonDownloads,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -673,6 +674,7 @@ pub(crate) async fn add(
raw_sources,
settings.as_ref(),
bounds,
installer_metadata,
connectivity,
concurrency,
native_tls,
@ -715,6 +717,7 @@ async fn lock_and_sync(
raw_sources: bool,
settings: ResolverInstallerSettingsRef<'_>,
bounds: LowerBound,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -918,6 +921,7 @@ async fn lock_and_sync(
Modifications::Sufficient,
settings.into(),
Box::new(DefaultInstallLogger),
installer_metadata,
connectivity,
concurrency,
native_tls,

View File

@ -34,6 +34,7 @@ impl CachedEnvironment {
state: &SharedState,
resolve: Box<dyn ResolveLogger>,
install: Box<dyn InstallLogger>,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -117,6 +118,7 @@ impl CachedEnvironment {
settings.as_ref().into(),
state,
install,
installer_metadata,
connectivity,
concurrency,
native_tls,

View File

@ -1211,6 +1211,7 @@ pub(crate) async fn sync_environment(
settings: InstallerSettingsRef<'_>,
state: &SharedState,
logger: Box<dyn InstallLogger>,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -1326,6 +1327,7 @@ pub(crate) async fn sync_environment(
cache,
&venv,
logger,
installer_metadata,
dry_run,
printer,
)
@ -1361,6 +1363,7 @@ pub(crate) async fn update_environment(
state: &SharedState,
resolve: Box<dyn ResolveLogger>,
install: Box<dyn InstallLogger>,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -1562,6 +1565,7 @@ pub(crate) async fn update_environment(
cache,
&venv,
install,
installer_metadata,
dry_run,
printer,
)

View File

@ -46,6 +46,7 @@ pub(crate) async fn remove(
script: Option<Pep723Script>,
python_preference: PythonPreference,
python_downloads: PythonDownloads,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -277,6 +278,7 @@ pub(crate) async fn remove(
Modifications::Exact,
settings.as_ref().into(),
Box::new(DefaultInstallLogger),
installer_metadata,
connectivity,
concurrency,
native_tls,

View File

@ -77,6 +77,7 @@ pub(crate) async fn run(
settings: ResolverInstallerSettings,
python_preference: PythonPreference,
python_downloads: PythonDownloads,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -333,6 +334,7 @@ pub(crate) async fn run(
} else {
Box::new(SummaryInstallLogger)
},
installer_metadata,
connectivity,
concurrency,
native_tls,
@ -733,6 +735,7 @@ pub(crate) async fn run(
} else {
Box::new(SummaryInstallLogger)
},
installer_metadata,
connectivity,
concurrency,
native_tls,
@ -883,6 +886,7 @@ pub(crate) async fn run(
} else {
Box::new(SummaryInstallLogger)
},
installer_metadata,
connectivity,
concurrency,
native_tls,

View File

@ -59,6 +59,7 @@ pub(crate) async fn sync(
python_preference: PythonPreference,
python_downloads: PythonDownloads,
settings: ResolverInstallerSettings,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -223,6 +224,7 @@ pub(crate) async fn sync(
modifications,
settings.as_ref().into(),
Box::new(DefaultInstallLogger),
installer_metadata,
connectivity,
concurrency,
native_tls,
@ -256,6 +258,7 @@ pub(super) async fn do_sync(
modifications: Modifications,
settings: InstallerSettingsRef<'_>,
logger: Box<dyn InstallLogger>,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -446,6 +449,7 @@ pub(super) async fn do_sync(
cache,
venv,
logger,
installer_metadata,
dry_run,
printer,
)

View File

@ -39,6 +39,7 @@ use crate::printer::Printer;
use crate::settings::ResolverInstallerSettings;
/// Install a tool.
#[allow(clippy::fn_params_excessive_bools)]
pub(crate) async fn install(
package: String,
editable: bool,
@ -53,6 +54,7 @@ pub(crate) async fn install(
settings: ResolverInstallerSettings,
python_preference: PythonPreference,
python_downloads: PythonDownloads,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -413,6 +415,7 @@ pub(crate) async fn install(
&state,
Box::new(DefaultResolveLogger),
Box::new(DefaultInstallLogger),
installer_metadata,
connectivity,
concurrency,
native_tls,
@ -480,6 +483,7 @@ pub(crate) async fn install(
settings.as_ref().into(),
&state,
Box::new(DefaultInstallLogger),
installer_metadata,
connectivity,
concurrency,
native_tls,

View File

@ -64,6 +64,7 @@ impl Display for ToolRunCommand {
}
/// Run a command.
#[allow(clippy::fn_params_excessive_bools)]
pub(crate) async fn run(
command: Option<ExternalCommand>,
from: Option<String>,
@ -76,6 +77,7 @@ pub(crate) async fn run(
isolated: bool,
python_preference: PythonPreference,
python_downloads: PythonDownloads,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -119,6 +121,7 @@ pub(crate) async fn run(
isolated,
python_preference,
python_downloads,
installer_metadata,
connectivity,
concurrency,
native_tls,
@ -425,6 +428,7 @@ fn warn_executable_not_provided_by_package(
///
/// If the target tool is already installed in a compatible environment, returns that
/// [`PythonEnvironment`]. Otherwise, gets or creates a [`CachedEnvironment`].
#[allow(clippy::fn_params_excessive_bools)]
async fn get_or_create_environment(
target: &Target<'_>,
with: &[RequirementsSource],
@ -435,6 +439,7 @@ async fn get_or_create_environment(
isolated: bool,
python_preference: PythonPreference,
python_downloads: PythonDownloads,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -626,6 +631,7 @@ async fn get_or_create_environment(
} else {
Box::new(SummaryInstallLogger)
},
installer_metadata,
connectivity,
concurrency,
native_tls,

View File

@ -42,6 +42,7 @@ pub(crate) async fn upgrade(
filesystem: ResolverInstallerOptions,
python_preference: PythonPreference,
python_downloads: PythonDownloads,
installer_metadata: bool,
concurrency: Concurrency,
native_tls: bool,
allow_insecure_host: &[TrustedHost],
@ -123,6 +124,7 @@ pub(crate) async fn upgrade(
&args,
cache,
&filesystem,
installer_metadata,
connectivity,
concurrency,
native_tls,
@ -212,6 +214,7 @@ async fn upgrade_tool(
args: &ResolverInstallerOptions,
cache: &Cache,
filesystem: &ResolverInstallerOptions,
installer_metadata: bool,
connectivity: Connectivity,
concurrency: Concurrency,
native_tls: bool,
@ -309,6 +312,7 @@ async fn upgrade_tool(
settings.as_ref().into(),
&state,
Box::new(DefaultInstallLogger),
installer_metadata,
connectivity,
concurrency,
native_tls,
@ -333,6 +337,7 @@ async fn upgrade_tool(
&state,
Box::new(SummaryResolveLogger),
Box::new(UpgradeInstallLogger::new(name.clone())),
installer_metadata,
connectivity,
concurrency,
native_tls,

View File

@ -422,6 +422,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
args.settings.dependency_metadata,
args.settings.keyring_provider,
args.settings.allow_empty_requirements,
globals.installer_metadata,
globals.connectivity,
&args.settings.config_setting,
args.settings.no_build_isolation,
@ -510,6 +511,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
args.settings.link_mode,
args.settings.compile_bytecode,
args.settings.hash_checking,
globals.installer_metadata,
globals.connectivity,
&args.settings.config_setting,
args.settings.no_build_isolation,
@ -916,6 +918,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
args.isolated,
globals.python_preference,
globals.python_downloads,
globals.installer_metadata,
globals.connectivity,
globals.concurrency,
globals.native_tls,
@ -979,6 +982,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
args.settings,
globals.python_preference,
globals.python_downloads,
globals.installer_metadata,
globals.connectivity,
globals.concurrency,
globals.native_tls,
@ -1025,6 +1029,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
args.filesystem,
globals.python_preference,
globals.python_downloads,
globals.installer_metadata,
globals.concurrency,
globals.native_tls,
&globals.allow_insecure_host,
@ -1359,6 +1364,7 @@ async fn run_project(
args.settings,
globals.python_preference,
globals.python_downloads,
globals.installer_metadata,
globals.connectivity,
globals.concurrency,
globals.native_tls,
@ -1398,6 +1404,7 @@ async fn run_project(
globals.python_preference,
globals.python_downloads,
args.settings,
globals.installer_metadata,
globals.connectivity,
globals.concurrency,
globals.native_tls,
@ -1483,6 +1490,7 @@ async fn run_project(
args.script,
globals.python_preference,
globals.python_downloads,
globals.installer_metadata,
globals.connectivity,
globals.concurrency,
globals.native_tls,
@ -1526,6 +1534,7 @@ async fn run_project(
script,
globals.python_preference,
globals.python_downloads,
globals.installer_metadata,
globals.connectivity,
globals.concurrency,
globals.native_tls,

View File

@ -63,6 +63,7 @@ pub(crate) struct GlobalSettings {
pub(crate) python_preference: PythonPreference,
pub(crate) python_downloads: PythonDownloads,
pub(crate) no_progress: bool,
pub(crate) installer_metadata: bool,
}
impl GlobalSettings {
@ -150,6 +151,7 @@ impl GlobalSettings {
.combine(workspace.and_then(|workspace| workspace.globals.python_downloads))
.unwrap_or_default(),
no_progress: args.no_progress,
installer_metadata: !args.no_installer_metadata,
}
}
}

View File

@ -7423,3 +7423,35 @@ fn resolve_derivation_chain() -> Result<()> {
Ok(())
}
/// Ensure that `UV_NO_INSTALLER_METADATA` env var is respected.
#[test]
fn respect_no_installer_metadata_env_var() {
let context = TestContext::new("3.12");
// Install urllib3.
uv_snapshot!(context.pip_install()
.arg("urllib3==2.2.1")
.arg("--strict")
.env(EnvVars::UV_NO_INSTALLER_METADATA, "1"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 1 package in [TIME]
Prepared 1 package in [TIME]
Installed 1 package in [TIME]
+ urllib3==2.2.1
"###
);
context.assert_command("import urllib3").success();
// Assert INSTALLER file was _not_ created.
let installer_file = context
.site_packages()
.join("urllib3-2.2.3.dist-info")
.join("INSTALLER");
assert!(!installer_file.exists());
}

View File

@ -60,6 +60,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -213,6 +214,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -367,6 +369,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -553,6 +556,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -708,6 +712,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -843,6 +848,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -1021,6 +1027,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -1204,6 +1211,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -1440,6 +1448,7 @@ fn resolve_find_links() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -1617,6 +1626,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -1758,6 +1768,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -1939,6 +1950,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -2144,6 +2156,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -2275,6 +2288,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -2406,6 +2420,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -2539,6 +2554,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -2691,6 +2707,7 @@ fn resolve_tool() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -2854,6 +2871,7 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -3013,6 +3031,7 @@ fn resolve_both() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -3289,6 +3308,7 @@ fn resolve_config_file() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -3543,6 +3563,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -3677,6 +3698,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -3830,6 +3852,7 @@ fn allow_insecure_host() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -3975,6 +3998,7 @@ fn index_priority() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -4158,6 +4182,7 @@ fn index_priority() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -4347,6 +4372,7 @@ fn index_priority() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -4531,6 +4557,7 @@ fn index_priority() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -4722,6 +4749,7 @@ fn index_priority() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -4906,6 +4934,7 @@ fn index_priority() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -5103,6 +5132,7 @@ fn verify_hashes() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -5228,6 +5258,7 @@ fn verify_hashes() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -5351,6 +5382,7 @@ fn verify_hashes() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -5476,6 +5508,7 @@ fn verify_hashes() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -5599,6 +5632,7 @@ fn verify_hashes() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,
@ -5723,6 +5757,7 @@ fn verify_hashes() -> anyhow::Result<()> {
python_preference: Managed,
python_downloads: Automatic,
no_progress: false,
installer_metadata: true,
}
CacheSettings {
no_cache: false,

View File

@ -179,6 +179,10 @@ directories.
Ignore `.env` files when executing `uv run` commands.
### `UV_NO_INSTALLER_METADATA`
Skip writing `uv` installer metadata files (e.g., `INSTALLER`, `REQUESTED`, and `direct_url.json`) to site-packages `.dist-info` directories.
### `UV_NO_PROGRESS`
Equivalent to the `--no-progress` command-line argument. Disables all progress output. For