mirror of
https://github.com/astral-sh/uv.git
synced 2025-09-26 12:09:12 +00:00
Add --no-hashes
to uv export
(#6954)
## Summary Closes https://github.com/astral-sh/uv/issues/6944.
This commit is contained in:
parent
ad82b94856
commit
ccdf2d793b
7 changed files with 76 additions and 11 deletions
|
@ -2802,6 +2802,14 @@ pub struct ExportArgs {
|
||||||
#[arg(long, overrides_with("dev"))]
|
#[arg(long, overrides_with("dev"))]
|
||||||
pub no_dev: bool,
|
pub no_dev: bool,
|
||||||
|
|
||||||
|
/// Include hashes for all dependencies.
|
||||||
|
#[arg(long, overrides_with("no_hashes"), hide = true)]
|
||||||
|
pub hashes: bool,
|
||||||
|
|
||||||
|
/// Omit hashes in the generated output.
|
||||||
|
#[arg(long, overrides_with("hashes"))]
|
||||||
|
pub no_hashes: bool,
|
||||||
|
|
||||||
/// Assert that the `uv.lock` will remain unchanged.
|
/// Assert that the `uv.lock` will remain unchanged.
|
||||||
///
|
///
|
||||||
/// Requires that the lockfile is up-to-date. If the lockfile is missing or
|
/// Requires that the lockfile is up-to-date. If the lockfile is missing or
|
||||||
|
|
|
@ -24,7 +24,10 @@ type LockGraph<'lock> = Graph<Node<'lock>, Edge, Directed>;
|
||||||
|
|
||||||
/// An export of a [`Lock`] that renders in `requirements.txt` format.
|
/// An export of a [`Lock`] that renders in `requirements.txt` format.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RequirementsTxtExport<'lock>(LockGraph<'lock>);
|
pub struct RequirementsTxtExport<'lock> {
|
||||||
|
graph: LockGraph<'lock>,
|
||||||
|
hashes: bool,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'lock> RequirementsTxtExport<'lock> {
|
impl<'lock> RequirementsTxtExport<'lock> {
|
||||||
pub fn from_lock(
|
pub fn from_lock(
|
||||||
|
@ -32,6 +35,7 @@ impl<'lock> RequirementsTxtExport<'lock> {
|
||||||
root_name: &PackageName,
|
root_name: &PackageName,
|
||||||
extras: &ExtrasSpecification,
|
extras: &ExtrasSpecification,
|
||||||
dev: &[GroupName],
|
dev: &[GroupName],
|
||||||
|
hashes: bool,
|
||||||
) -> Result<Self, LockError> {
|
) -> Result<Self, LockError> {
|
||||||
let size_guess = lock.packages.len();
|
let size_guess = lock.packages.len();
|
||||||
let mut petgraph = LockGraph::with_capacity(size_guess, size_guess);
|
let mut petgraph = LockGraph::with_capacity(size_guess, size_guess);
|
||||||
|
@ -114,7 +118,7 @@ impl<'lock> RequirementsTxtExport<'lock> {
|
||||||
|
|
||||||
let graph = propagate_markers(petgraph);
|
let graph = propagate_markers(petgraph);
|
||||||
|
|
||||||
Ok(Self(graph))
|
Ok(Self { graph, hashes })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +126,7 @@ impl std::fmt::Display for RequirementsTxtExport<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
// Collect all packages.
|
// Collect all packages.
|
||||||
let mut nodes = self
|
let mut nodes = self
|
||||||
.0
|
.graph
|
||||||
.raw_nodes()
|
.raw_nodes()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|node| &node.weight)
|
.map(|node| &node.weight)
|
||||||
|
@ -197,6 +201,7 @@ impl std::fmt::Display for RequirementsTxtExport<'_> {
|
||||||
write!(f, " ; {contents}")?;
|
write!(f, " ; {contents}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.hashes {
|
||||||
let hashes = package.hashes();
|
let hashes = package.hashes();
|
||||||
if !hashes.is_empty() {
|
if !hashes.is_empty() {
|
||||||
for hash in &hashes {
|
for hash in &hashes {
|
||||||
|
@ -205,6 +210,7 @@ impl std::fmt::Display for RequirementsTxtExport<'_> {
|
||||||
write!(f, "{hash}")?;
|
write!(f, "{hash}")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ use crate::settings::ResolverSettings;
|
||||||
pub(crate) async fn export(
|
pub(crate) async fn export(
|
||||||
format: ExportFormat,
|
format: ExportFormat,
|
||||||
package: Option<PackageName>,
|
package: Option<PackageName>,
|
||||||
|
hashes: bool,
|
||||||
extras: ExtrasSpecification,
|
extras: ExtrasSpecification,
|
||||||
dev: bool,
|
dev: bool,
|
||||||
locked: bool,
|
locked: bool,
|
||||||
|
@ -112,8 +113,13 @@ pub(crate) async fn export(
|
||||||
// Generate the export.
|
// Generate the export.
|
||||||
match format {
|
match format {
|
||||||
ExportFormat::RequirementsTxt => {
|
ExportFormat::RequirementsTxt => {
|
||||||
let export =
|
let export = RequirementsTxtExport::from_lock(
|
||||||
RequirementsTxtExport::from_lock(&lock, project.project_name(), &extras, &dev)?;
|
&lock,
|
||||||
|
project.project_name(),
|
||||||
|
&extras,
|
||||||
|
&dev,
|
||||||
|
hashes,
|
||||||
|
)?;
|
||||||
anstream::println!(
|
anstream::println!(
|
||||||
"{}",
|
"{}",
|
||||||
"# This file was autogenerated via `uv export`.".green()
|
"# This file was autogenerated via `uv export`.".green()
|
||||||
|
|
|
@ -1273,6 +1273,7 @@ async fn run_project(
|
||||||
commands::export(
|
commands::export(
|
||||||
args.format,
|
args.format,
|
||||||
args.package,
|
args.package,
|
||||||
|
args.hashes,
|
||||||
args.extras,
|
args.extras,
|
||||||
args.dev,
|
args.dev,
|
||||||
args.locked,
|
args.locked,
|
||||||
|
|
|
@ -944,6 +944,7 @@ pub(crate) struct ExportSettings {
|
||||||
pub(crate) package: Option<PackageName>,
|
pub(crate) package: Option<PackageName>,
|
||||||
pub(crate) extras: ExtrasSpecification,
|
pub(crate) extras: ExtrasSpecification,
|
||||||
pub(crate) dev: bool,
|
pub(crate) dev: bool,
|
||||||
|
pub(crate) hashes: bool,
|
||||||
pub(crate) locked: bool,
|
pub(crate) locked: bool,
|
||||||
pub(crate) frozen: bool,
|
pub(crate) frozen: bool,
|
||||||
pub(crate) python: Option<String>,
|
pub(crate) python: Option<String>,
|
||||||
|
@ -963,6 +964,8 @@ impl ExportSettings {
|
||||||
no_all_extras,
|
no_all_extras,
|
||||||
dev,
|
dev,
|
||||||
no_dev,
|
no_dev,
|
||||||
|
hashes,
|
||||||
|
no_hashes,
|
||||||
locked,
|
locked,
|
||||||
frozen,
|
frozen,
|
||||||
resolver,
|
resolver,
|
||||||
|
@ -979,6 +982,7 @@ impl ExportSettings {
|
||||||
extra.unwrap_or_default(),
|
extra.unwrap_or_default(),
|
||||||
),
|
),
|
||||||
dev: flag(dev, no_dev).unwrap_or(true),
|
dev: flag(dev, no_dev).unwrap_or(true),
|
||||||
|
hashes: flag(hashes, no_hashes).unwrap_or(true),
|
||||||
locked,
|
locked,
|
||||||
frozen,
|
frozen,
|
||||||
python,
|
python,
|
||||||
|
|
|
@ -632,3 +632,41 @@ fn dev() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_hashes() -> 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("--no-hashes"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
# This file was autogenerated via `uv export`.
|
||||||
|
-e .
|
||||||
|
anyio==3.7.0
|
||||||
|
idna==3.6
|
||||||
|
sniffio==1.3.1
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 4 packages in [TIME]
|
||||||
|
"###);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -1738,6 +1738,8 @@ uv export [OPTIONS]
|
||||||
|
|
||||||
</dd><dt><code>--no-dev</code></dt><dd><p>Omit development dependencies</p>
|
</dd><dt><code>--no-dev</code></dt><dd><p>Omit development dependencies</p>
|
||||||
|
|
||||||
|
</dd><dt><code>--no-hashes</code></dt><dd><p>Omit hashes in the generated output</p>
|
||||||
|
|
||||||
</dd><dt><code>--no-index</code></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
|
</dd><dt><code>--no-index</code></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
|
||||||
|
|
||||||
</dd><dt><code>--no-progress</code></dt><dd><p>Hide all progress outputs.</p>
|
</dd><dt><code>--no-progress</code></dt><dd><p>Hide all progress outputs.</p>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue