mirror of
https://github.com/astral-sh/uv.git
synced 2025-09-26 20:19:08 +00:00
Add --require-hashes
and --verify-hashes
to uv build
(#7094)
This commit is contained in:
parent
80f51cee06
commit
5b89734c85
6 changed files with 235 additions and 45 deletions
|
@ -1988,6 +1988,46 @@ pub struct BuildArgs {
|
||||||
#[arg(long, short, env = "UV_BUILD_CONSTRAINT", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
|
#[arg(long, short, env = "UV_BUILD_CONSTRAINT", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
|
||||||
pub build_constraint: Vec<Maybe<PathBuf>>,
|
pub build_constraint: Vec<Maybe<PathBuf>>,
|
||||||
|
|
||||||
|
/// Require a matching hash for each build requirement.
|
||||||
|
///
|
||||||
|
/// Hash-checking mode is all or nothing. If enabled, _all_ build requirements must be provided
|
||||||
|
/// with a corresponding hash or set of hashes via the `--build-constraints` argument.
|
||||||
|
/// Additionally, if enabled, _all_ requirements must either be pinned to exact versions
|
||||||
|
/// (e.g., `==1.0.0`), or be specified via direct URL.
|
||||||
|
///
|
||||||
|
/// Hash-checking mode introduces a number of additional constraints:
|
||||||
|
///
|
||||||
|
/// - Git dependencies are not supported.
|
||||||
|
/// - Editable installs are not supported.
|
||||||
|
/// - Local dependencies are not supported, unless they point to a specific wheel (`.whl`) or
|
||||||
|
/// source archive (`.zip`, `.tar.gz`), as opposed to a directory.
|
||||||
|
#[arg(
|
||||||
|
long,
|
||||||
|
env = "UV_REQUIRE_HASHES",
|
||||||
|
value_parser = clap::builder::BoolishValueParser::new(),
|
||||||
|
overrides_with("no_require_hashes"),
|
||||||
|
)]
|
||||||
|
pub require_hashes: bool,
|
||||||
|
|
||||||
|
#[arg(long, overrides_with("require_hashes"), hide = true)]
|
||||||
|
pub no_require_hashes: bool,
|
||||||
|
|
||||||
|
/// Validate any hashes provided in the build constraints file.
|
||||||
|
///
|
||||||
|
/// Unlike `--require-hashes`, `--verify-hashes` does not require that all requirements have
|
||||||
|
/// hashes; instead, it will limit itself to verifying the hashes of those requirements that do
|
||||||
|
/// include them.
|
||||||
|
#[arg(
|
||||||
|
long,
|
||||||
|
env = "UV_VERIFY_HASHES",
|
||||||
|
value_parser = clap::builder::BoolishValueParser::new(),
|
||||||
|
overrides_with("no_verify_hashes"),
|
||||||
|
)]
|
||||||
|
pub verify_hashes: bool,
|
||||||
|
|
||||||
|
#[arg(long, overrides_with("verify_hashes"), hide = true)]
|
||||||
|
pub no_verify_hashes: bool,
|
||||||
|
|
||||||
/// The Python interpreter to use for the build environment.
|
/// The Python interpreter to use for the build environment.
|
||||||
///
|
///
|
||||||
/// By default, builds are executed in isolated virtual environments. The
|
/// By default, builds are executed in isolated virtual environments. The
|
||||||
|
|
|
@ -35,6 +35,7 @@ pub(crate) async fn build(
|
||||||
sdist: bool,
|
sdist: bool,
|
||||||
wheel: bool,
|
wheel: bool,
|
||||||
build_constraints: Vec<RequirementsSource>,
|
build_constraints: Vec<RequirementsSource>,
|
||||||
|
hash_checking: Option<HashCheckingMode>,
|
||||||
python: Option<String>,
|
python: Option<String>,
|
||||||
settings: ResolverSettings,
|
settings: ResolverSettings,
|
||||||
no_config: bool,
|
no_config: bool,
|
||||||
|
@ -53,6 +54,7 @@ pub(crate) async fn build(
|
||||||
sdist,
|
sdist,
|
||||||
wheel,
|
wheel,
|
||||||
&build_constraints,
|
&build_constraints,
|
||||||
|
hash_checking,
|
||||||
python.as_deref(),
|
python.as_deref(),
|
||||||
settings.as_ref(),
|
settings.as_ref(),
|
||||||
no_config,
|
no_config,
|
||||||
|
@ -93,6 +95,7 @@ async fn build_impl(
|
||||||
sdist: bool,
|
sdist: bool,
|
||||||
wheel: bool,
|
wheel: bool,
|
||||||
build_constraints: &[RequirementsSource],
|
build_constraints: &[RequirementsSource],
|
||||||
|
hash_checking: Option<HashCheckingMode>,
|
||||||
python_request: Option<&str>,
|
python_request: Option<&str>,
|
||||||
settings: ResolverSettingsRef<'_>,
|
settings: ResolverSettingsRef<'_>,
|
||||||
no_config: bool,
|
no_config: bool,
|
||||||
|
@ -235,16 +238,19 @@ async fn build_impl(
|
||||||
operations::read_constraints(build_constraints, &client_builder).await?;
|
operations::read_constraints(build_constraints, &client_builder).await?;
|
||||||
|
|
||||||
// Collect the set of required hashes.
|
// Collect the set of required hashes.
|
||||||
// Enforce (but never require) the build constraints, if `--require-hashes` or `--verify-hashes`
|
let hasher = if let Some(hash_checking) = hash_checking {
|
||||||
// is provided. _Requiring_ hashes would be too strict, and would break with pip.
|
HashStrategy::from_requirements(
|
||||||
let build_hasher = HashStrategy::from_requirements(
|
std::iter::empty(),
|
||||||
std::iter::empty(),
|
build_constraints
|
||||||
build_constraints
|
.iter()
|
||||||
.iter()
|
.map(|entry| (&entry.requirement, entry.hashes.as_slice())),
|
||||||
.map(|entry| (&entry.requirement, entry.hashes.as_slice())),
|
Some(&interpreter.resolver_markers()),
|
||||||
Some(&interpreter.resolver_markers()),
|
hash_checking,
|
||||||
HashCheckingMode::Verify,
|
)?
|
||||||
)?;
|
} else {
|
||||||
|
HashStrategy::None
|
||||||
|
};
|
||||||
|
|
||||||
let build_constraints = Constraints::from_requirements(
|
let build_constraints = Constraints::from_requirements(
|
||||||
build_constraints
|
build_constraints
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -279,7 +285,7 @@ async fn build_impl(
|
||||||
let flat_index = {
|
let flat_index = {
|
||||||
let client = FlatIndexClient::new(&client, cache);
|
let client = FlatIndexClient::new(&client, cache);
|
||||||
let entries = client.fetch(index_locations.flat_index()).await?;
|
let entries = client.fetch(index_locations.flat_index()).await?;
|
||||||
FlatIndex::from_entries(entries, None, &build_hasher, build_options)
|
FlatIndex::from_entries(entries, None, &hasher, build_options)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize any shared state.
|
// Initialize any shared state.
|
||||||
|
@ -301,7 +307,7 @@ async fn build_impl(
|
||||||
build_isolation,
|
build_isolation,
|
||||||
link_mode,
|
link_mode,
|
||||||
build_options,
|
build_options,
|
||||||
&build_hasher,
|
&hasher,
|
||||||
exclude_newer,
|
exclude_newer,
|
||||||
sources,
|
sources,
|
||||||
concurrency,
|
concurrency,
|
||||||
|
|
|
@ -684,6 +684,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
|
||||||
args.sdist,
|
args.sdist,
|
||||||
args.wheel,
|
args.wheel,
|
||||||
build_constraints,
|
build_constraints,
|
||||||
|
args.hash_checking,
|
||||||
args.python,
|
args.python,
|
||||||
args.settings,
|
args.settings,
|
||||||
cli.no_config,
|
cli.no_config,
|
||||||
|
|
|
@ -1630,6 +1630,7 @@ pub(crate) struct BuildSettings {
|
||||||
pub(crate) sdist: bool,
|
pub(crate) sdist: bool,
|
||||||
pub(crate) wheel: bool,
|
pub(crate) wheel: bool,
|
||||||
pub(crate) build_constraint: Vec<PathBuf>,
|
pub(crate) build_constraint: Vec<PathBuf>,
|
||||||
|
pub(crate) hash_checking: Option<HashCheckingMode>,
|
||||||
pub(crate) python: Option<String>,
|
pub(crate) python: Option<String>,
|
||||||
pub(crate) refresh: Refresh,
|
pub(crate) refresh: Refresh,
|
||||||
pub(crate) settings: ResolverSettings,
|
pub(crate) settings: ResolverSettings,
|
||||||
|
@ -1645,6 +1646,10 @@ impl BuildSettings {
|
||||||
sdist,
|
sdist,
|
||||||
wheel,
|
wheel,
|
||||||
build_constraint,
|
build_constraint,
|
||||||
|
require_hashes,
|
||||||
|
no_require_hashes,
|
||||||
|
verify_hashes,
|
||||||
|
no_verify_hashes,
|
||||||
python,
|
python,
|
||||||
build,
|
build,
|
||||||
refresh,
|
refresh,
|
||||||
|
@ -1661,6 +1666,10 @@ impl BuildSettings {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(Maybe::into_option)
|
.filter_map(Maybe::into_option)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
hash_checking: HashCheckingMode::from_args(
|
||||||
|
flag(require_hashes, no_require_hashes).unwrap_or_default(),
|
||||||
|
flag(verify_hashes, no_verify_hashes).unwrap_or_default(),
|
||||||
|
),
|
||||||
python,
|
python,
|
||||||
refresh: Refresh::from(refresh),
|
refresh: Refresh::from(refresh),
|
||||||
settings: ResolverSettings::combine(resolver_options(resolver, build), filesystem),
|
settings: ResolverSettings::combine(resolver_options(resolver, build), filesystem),
|
||||||
|
|
|
@ -1240,42 +1240,10 @@ fn sha() -> Result<()> {
|
||||||
project.child("src").child("__init__.py").touch()?;
|
project.child("src").child("__init__.py").touch()?;
|
||||||
project.child("README").touch()?;
|
project.child("README").touch()?;
|
||||||
|
|
||||||
// Reject an incorrect hash.
|
// Ignore an incorrect hash, if `--require-hashes` is not provided.
|
||||||
let constraints = project.child("constraints.txt");
|
let constraints = project.child("constraints.txt");
|
||||||
constraints.write_str("setuptools==68.2.2 --hash=sha256:a248cb506794bececcddeddb1678bc722f9cfcacf02f98f7c0af6b9ed893caf2")?;
|
constraints.write_str("setuptools==68.2.2 --hash=sha256:a248cb506794bececcddeddb1678bc722f9cfcacf02f98f7c0af6b9ed893caf2")?;
|
||||||
|
|
||||||
uv_snapshot!(&filters, context.build().arg("--build-constraint").arg("constraints.txt").current_dir(&project), @r###"
|
|
||||||
success: false
|
|
||||||
exit_code: 2
|
|
||||||
----- stdout -----
|
|
||||||
|
|
||||||
----- stderr -----
|
|
||||||
Building source distribution...
|
|
||||||
error: Failed to install requirements from `build-system.requires` (install)
|
|
||||||
Caused by: Failed to prepare distributions
|
|
||||||
Caused by: Failed to fetch wheel: setuptools==68.2.2
|
|
||||||
Caused by: Hash mismatch for `setuptools==68.2.2`
|
|
||||||
|
|
||||||
Expected:
|
|
||||||
sha256:a248cb506794bececcddeddb1678bc722f9cfcacf02f98f7c0af6b9ed893caf2
|
|
||||||
|
|
||||||
Computed:
|
|
||||||
sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
|
|
||||||
"###);
|
|
||||||
|
|
||||||
project
|
|
||||||
.child("dist")
|
|
||||||
.child("project-0.1.0.tar.gz")
|
|
||||||
.assert(predicate::path::missing());
|
|
||||||
project
|
|
||||||
.child("dist")
|
|
||||||
.child("project-0.1.0-py3-none-any.whl")
|
|
||||||
.assert(predicate::path::missing());
|
|
||||||
|
|
||||||
// Accept a correct hash.
|
|
||||||
let constraints = project.child("constraints.txt");
|
|
||||||
constraints.write_str("setuptools==68.2.2 --hash=sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a")?;
|
|
||||||
|
|
||||||
uv_snapshot!(&filters, context.build().arg("--build-constraint").arg("constraints.txt").current_dir(&project), @r###"
|
uv_snapshot!(&filters, context.build().arg("--build-constraint").arg("constraints.txt").current_dir(&project), @r###"
|
||||||
success: true
|
success: true
|
||||||
exit_code: 0
|
exit_code: 0
|
||||||
|
@ -1357,6 +1325,156 @@ fn sha() -> Result<()> {
|
||||||
Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
|
Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
|
project
|
||||||
|
.child("dist")
|
||||||
|
.child("project-0.1.0.tar.gz")
|
||||||
|
.assert(predicate::path::is_file());
|
||||||
|
project
|
||||||
|
.child("dist")
|
||||||
|
.child("project-0.1.0-py3-none-any.whl")
|
||||||
|
.assert(predicate::path::is_file());
|
||||||
|
|
||||||
|
fs_err::remove_dir_all(project.child("dist"))?;
|
||||||
|
|
||||||
|
// Reject an incorrect hash.
|
||||||
|
uv_snapshot!(&filters, context.build().arg("--build-constraint").arg("constraints.txt").arg("--require-hashes").current_dir(&project), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Building source distribution...
|
||||||
|
error: Failed to install requirements from `build-system.requires` (install)
|
||||||
|
Caused by: Failed to prepare distributions
|
||||||
|
Caused by: Failed to fetch wheel: setuptools==68.2.2
|
||||||
|
Caused by: Hash mismatch for `setuptools==68.2.2`
|
||||||
|
|
||||||
|
Expected:
|
||||||
|
sha256:a248cb506794bececcddeddb1678bc722f9cfcacf02f98f7c0af6b9ed893caf2
|
||||||
|
|
||||||
|
Computed:
|
||||||
|
sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
|
||||||
|
"###);
|
||||||
|
|
||||||
|
project
|
||||||
|
.child("dist")
|
||||||
|
.child("project-0.1.0.tar.gz")
|
||||||
|
.assert(predicate::path::missing());
|
||||||
|
project
|
||||||
|
.child("dist")
|
||||||
|
.child("project-0.1.0-py3-none-any.whl")
|
||||||
|
.assert(predicate::path::missing());
|
||||||
|
|
||||||
|
fs_err::remove_dir_all(project.child("dist"))?;
|
||||||
|
|
||||||
|
// Reject a missing hash.
|
||||||
|
let constraints = project.child("constraints.txt");
|
||||||
|
constraints.write_str("setuptools==68.2.2")?;
|
||||||
|
|
||||||
|
uv_snapshot!(&filters, context.build().arg("--build-constraint").arg("constraints.txt").arg("--require-hashes").current_dir(&project), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Building source distribution...
|
||||||
|
error: Failed to install requirements from `build-system.requires` (resolve)
|
||||||
|
Caused by: No solution found when resolving: setuptools>=42
|
||||||
|
Caused by: In `--require-hashes` mode, all requirements must be pinned upfront with `==`, but found: `setuptools`
|
||||||
|
"###);
|
||||||
|
|
||||||
|
project
|
||||||
|
.child("dist")
|
||||||
|
.child("project-0.1.0.tar.gz")
|
||||||
|
.assert(predicate::path::missing());
|
||||||
|
project
|
||||||
|
.child("dist")
|
||||||
|
.child("project-0.1.0-py3-none-any.whl")
|
||||||
|
.assert(predicate::path::missing());
|
||||||
|
|
||||||
|
// Accept a correct hash.
|
||||||
|
let constraints = project.child("constraints.txt");
|
||||||
|
constraints.write_str("setuptools==68.2.2 --hash=sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a")?;
|
||||||
|
|
||||||
|
uv_snapshot!(&filters, context.build().arg("--build-constraint").arg("constraints.txt").current_dir(&project), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Building source distribution...
|
||||||
|
running egg_info
|
||||||
|
writing src/project.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/project.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/project.egg-info/requires.txt
|
||||||
|
writing top-level names to src/project.egg-info/top_level.txt
|
||||||
|
reading manifest file 'src/project.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/project.egg-info/SOURCES.txt'
|
||||||
|
running sdist
|
||||||
|
running egg_info
|
||||||
|
writing src/project.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/project.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/project.egg-info/requires.txt
|
||||||
|
writing top-level names to src/project.egg-info/top_level.txt
|
||||||
|
reading manifest file 'src/project.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/project.egg-info/SOURCES.txt'
|
||||||
|
running check
|
||||||
|
creating project-0.1.0
|
||||||
|
creating project-0.1.0/src
|
||||||
|
creating project-0.1.0/src/project.egg-info
|
||||||
|
copying files to project-0.1.0...
|
||||||
|
copying README -> project-0.1.0
|
||||||
|
copying pyproject.toml -> project-0.1.0
|
||||||
|
copying src/__init__.py -> project-0.1.0/src
|
||||||
|
copying src/project.egg-info/PKG-INFO -> project-0.1.0/src/project.egg-info
|
||||||
|
copying src/project.egg-info/SOURCES.txt -> project-0.1.0/src/project.egg-info
|
||||||
|
copying src/project.egg-info/dependency_links.txt -> project-0.1.0/src/project.egg-info
|
||||||
|
copying src/project.egg-info/requires.txt -> project-0.1.0/src/project.egg-info
|
||||||
|
copying src/project.egg-info/top_level.txt -> project-0.1.0/src/project.egg-info
|
||||||
|
Writing project-0.1.0/setup.cfg
|
||||||
|
Creating tar archive
|
||||||
|
removing 'project-0.1.0' (and everything under it)
|
||||||
|
Building wheel from source distribution...
|
||||||
|
running egg_info
|
||||||
|
writing src/project.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/project.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/project.egg-info/requires.txt
|
||||||
|
writing top-level names to src/project.egg-info/top_level.txt
|
||||||
|
reading manifest file 'src/project.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/project.egg-info/SOURCES.txt'
|
||||||
|
running bdist_wheel
|
||||||
|
running build
|
||||||
|
running build_py
|
||||||
|
creating build
|
||||||
|
creating build/lib
|
||||||
|
copying src/__init__.py -> build/lib
|
||||||
|
running egg_info
|
||||||
|
writing src/project.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/project.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/project.egg-info/requires.txt
|
||||||
|
writing top-level names to src/project.egg-info/top_level.txt
|
||||||
|
reading manifest file 'src/project.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/project.egg-info/SOURCES.txt'
|
||||||
|
installing to build/bdist.linux-x86_64/wheel
|
||||||
|
running install
|
||||||
|
running install_lib
|
||||||
|
creating build/bdist.linux-x86_64
|
||||||
|
creating build/bdist.linux-x86_64/wheel
|
||||||
|
copying build/lib/__init__.py -> build/bdist.linux-x86_64/wheel
|
||||||
|
running install_egg_info
|
||||||
|
Copying src/project.egg-info to build/bdist.linux-x86_64/wheel/project-0.1.0-py3.8.egg-info
|
||||||
|
running install_scripts
|
||||||
|
creating build/bdist.linux-x86_64/wheel/project-0.1.0.dist-info/WHEEL
|
||||||
|
creating '[TEMP_DIR]/project/dist/[TMP]/wheel' to it
|
||||||
|
adding '__init__.py'
|
||||||
|
adding 'project-0.1.0.dist-info/METADATA'
|
||||||
|
adding 'project-0.1.0.dist-info/WHEEL'
|
||||||
|
adding 'project-0.1.0.dist-info/top_level.txt'
|
||||||
|
adding 'project-0.1.0.dist-info/RECORD'
|
||||||
|
removing build/bdist.linux-x86_64/wheel
|
||||||
|
Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
|
||||||
|
"###);
|
||||||
|
|
||||||
project
|
project
|
||||||
.child("dist")
|
.child("dist")
|
||||||
.child("project-0.1.0.tar.gz")
|
.child("project-0.1.0.tar.gz")
|
||||||
|
|
|
@ -6434,6 +6434,17 @@ uv build [OPTIONS] [SRC]
|
||||||
|
|
||||||
</dd><dt><code>--refresh-package</code> <i>refresh-package</i></dt><dd><p>Refresh cached data for a specific package</p>
|
</dd><dt><code>--refresh-package</code> <i>refresh-package</i></dt><dd><p>Refresh cached data for a specific package</p>
|
||||||
|
|
||||||
|
</dd><dt><code>--require-hashes</code></dt><dd><p>Require a matching hash for each build requirement.</p>
|
||||||
|
|
||||||
|
<p>Hash-checking mode is all or nothing. If enabled, <em>all</em> build requirements must be provided with a corresponding hash or set of hashes via the <code>--build-constraints</code> argument. Additionally, if enabled, <em>all</em> requirements must either be pinned to exact versions (e.g., <code>==1.0.0</code>), or be specified via direct URL.</p>
|
||||||
|
|
||||||
|
<p>Hash-checking mode introduces a number of additional constraints:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Git dependencies are not supported. - Editable installs are not supported. - Local dependencies are not supported, unless they point to a specific wheel (<code>.whl</code>) or source archive (<code>.zip</code>, <code>.tar.gz</code>), as opposed to a directory.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>May also be set with the <code>UV_REQUIRE_HASHES</code> environment variable.</p>
|
||||||
</dd><dt><code>--resolution</code> <i>resolution</i></dt><dd><p>The strategy to use when selecting between the different compatible versions for a given package requirement.</p>
|
</dd><dt><code>--resolution</code> <i>resolution</i></dt><dd><p>The strategy to use when selecting between the different compatible versions for a given package requirement.</p>
|
||||||
|
|
||||||
<p>By default, uv will use the latest compatible version of each package (<code>highest</code>).</p>
|
<p>By default, uv will use the latest compatible version of each package (<code>highest</code>).</p>
|
||||||
|
@ -6458,6 +6469,11 @@ uv build [OPTIONS] [SRC]
|
||||||
|
|
||||||
<p>You can configure fine-grained logging using the <code>RUST_LOG</code> environment variable. (<https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives>)</p>
|
<p>You can configure fine-grained logging using the <code>RUST_LOG</code> environment variable. (<https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives>)</p>
|
||||||
|
|
||||||
|
</dd><dt><code>--verify-hashes</code></dt><dd><p>Validate any hashes provided in the build constraints file.</p>
|
||||||
|
|
||||||
|
<p>Unlike <code>--require-hashes</code>, <code>--verify-hashes</code> does not require that all requirements have hashes; instead, it will limit itself to verifying the hashes of those requirements that do include them.</p>
|
||||||
|
|
||||||
|
<p>May also be set with the <code>UV_VERIFY_HASHES</code> environment variable.</p>
|
||||||
</dd><dt><code>--version</code>, <code>-V</code></dt><dd><p>Display the uv version</p>
|
</dd><dt><code>--version</code>, <code>-V</code></dt><dd><p>Display the uv version</p>
|
||||||
|
|
||||||
</dd><dt><code>--wheel</code></dt><dd><p>Build a binary distribution ("wheel") from the given directory</p>
|
</dd><dt><code>--wheel</code></dt><dd><p>Build a binary distribution ("wheel") from the given directory</p>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue