mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 10:58:28 +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"))]
|
||||
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.
|
||||
///
|
||||
/// 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.
|
||||
#[derive(Debug)]
|
||||
pub struct RequirementsTxtExport<'lock>(LockGraph<'lock>);
|
||||
pub struct RequirementsTxtExport<'lock> {
|
||||
graph: LockGraph<'lock>,
|
||||
hashes: bool,
|
||||
}
|
||||
|
||||
impl<'lock> RequirementsTxtExport<'lock> {
|
||||
pub fn from_lock(
|
||||
|
@ -32,6 +35,7 @@ impl<'lock> RequirementsTxtExport<'lock> {
|
|||
root_name: &PackageName,
|
||||
extras: &ExtrasSpecification,
|
||||
dev: &[GroupName],
|
||||
hashes: bool,
|
||||
) -> Result<Self, LockError> {
|
||||
let size_guess = lock.packages.len();
|
||||
let mut petgraph = LockGraph::with_capacity(size_guess, size_guess);
|
||||
|
@ -114,7 +118,7 @@ impl<'lock> RequirementsTxtExport<'lock> {
|
|||
|
||||
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 {
|
||||
// Collect all packages.
|
||||
let mut nodes = self
|
||||
.0
|
||||
.graph
|
||||
.raw_nodes()
|
||||
.iter()
|
||||
.map(|node| &node.weight)
|
||||
|
@ -197,12 +201,14 @@ impl std::fmt::Display for RequirementsTxtExport<'_> {
|
|||
write!(f, " ; {contents}")?;
|
||||
}
|
||||
|
||||
let hashes = package.hashes();
|
||||
if !hashes.is_empty() {
|
||||
for hash in &hashes {
|
||||
writeln!(f, " \\")?;
|
||||
write!(f, " --hash=")?;
|
||||
write!(f, "{hash}")?;
|
||||
if self.hashes {
|
||||
let hashes = package.hashes();
|
||||
if !hashes.is_empty() {
|
||||
for hash in &hashes {
|
||||
writeln!(f, " \\")?;
|
||||
write!(f, " --hash=")?;
|
||||
write!(f, "{hash}")?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ use crate::settings::ResolverSettings;
|
|||
pub(crate) async fn export(
|
||||
format: ExportFormat,
|
||||
package: Option<PackageName>,
|
||||
hashes: bool,
|
||||
extras: ExtrasSpecification,
|
||||
dev: bool,
|
||||
locked: bool,
|
||||
|
@ -112,8 +113,13 @@ pub(crate) async fn export(
|
|||
// Generate the export.
|
||||
match format {
|
||||
ExportFormat::RequirementsTxt => {
|
||||
let export =
|
||||
RequirementsTxtExport::from_lock(&lock, project.project_name(), &extras, &dev)?;
|
||||
let export = RequirementsTxtExport::from_lock(
|
||||
&lock,
|
||||
project.project_name(),
|
||||
&extras,
|
||||
&dev,
|
||||
hashes,
|
||||
)?;
|
||||
anstream::println!(
|
||||
"{}",
|
||||
"# This file was autogenerated via `uv export`.".green()
|
||||
|
|
|
@ -1273,6 +1273,7 @@ async fn run_project(
|
|||
commands::export(
|
||||
args.format,
|
||||
args.package,
|
||||
args.hashes,
|
||||
args.extras,
|
||||
args.dev,
|
||||
args.locked,
|
||||
|
|
|
@ -944,6 +944,7 @@ pub(crate) struct ExportSettings {
|
|||
pub(crate) package: Option<PackageName>,
|
||||
pub(crate) extras: ExtrasSpecification,
|
||||
pub(crate) dev: bool,
|
||||
pub(crate) hashes: bool,
|
||||
pub(crate) locked: bool,
|
||||
pub(crate) frozen: bool,
|
||||
pub(crate) python: Option<String>,
|
||||
|
@ -963,6 +964,8 @@ impl ExportSettings {
|
|||
no_all_extras,
|
||||
dev,
|
||||
no_dev,
|
||||
hashes,
|
||||
no_hashes,
|
||||
locked,
|
||||
frozen,
|
||||
resolver,
|
||||
|
@ -979,6 +982,7 @@ impl ExportSettings {
|
|||
extra.unwrap_or_default(),
|
||||
),
|
||||
dev: flag(dev, no_dev).unwrap_or(true),
|
||||
hashes: flag(hashes, no_hashes).unwrap_or(true),
|
||||
locked,
|
||||
frozen,
|
||||
python,
|
||||
|
|
|
@ -632,3 +632,41 @@ fn dev() -> Result<()> {
|
|||
|
||||
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-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-progress</code></dt><dd><p>Hide all progress outputs.</p>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue