mirror of https://github.com/astral-sh/uv
Add `--no-emit-project` and friends to `uv export` (#7110)
## Summary Like `uv sync`, you can omit the current project (`--no-emit-project`), a specific package (`--no-emit-package`), or the entire workspace (`--no-emit-workspace`). Closes https://github.com/astral-sh/uv/issues/6960. Closes #6995.
This commit is contained in:
parent
d0f9016eda
commit
6ae005b0d0
|
|
@ -2970,6 +2970,29 @@ pub struct ExportArgs {
|
||||||
#[arg(long, short)]
|
#[arg(long, short)]
|
||||||
pub output_file: Option<PathBuf>,
|
pub output_file: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Do not emit the current project.
|
||||||
|
///
|
||||||
|
/// By default, the current project is included in the exported requirements file with all of its
|
||||||
|
/// dependencies. The `--no-emit-project` option allows the project to be excluded, but all of
|
||||||
|
/// its dependencies to remain included.
|
||||||
|
#[arg(long, alias = "no-install-project")]
|
||||||
|
pub no_emit_project: bool,
|
||||||
|
|
||||||
|
/// Do not emit any workspace members, including the root project.
|
||||||
|
///
|
||||||
|
/// By default, all workspace members and their dependencies are included in the exported
|
||||||
|
/// requirements file, with all of their dependencies. The `--no-emit-workspace` option allows
|
||||||
|
/// exclusion of all the workspace members while retaining their dependencies.
|
||||||
|
#[arg(long, alias = "no-install-workspace")]
|
||||||
|
pub no_emit_workspace: bool,
|
||||||
|
|
||||||
|
/// Do not emit the given package(s).
|
||||||
|
///
|
||||||
|
/// By default, all of the project's dependencies are included in the exported requirements
|
||||||
|
/// file. The `--no-install-package` option allows exclusion of specific packages.
|
||||||
|
#[arg(long, alias = "no-install-package")]
|
||||||
|
pub no_emit_package: Vec<PackageName>,
|
||||||
|
|
||||||
/// 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
|
||||||
|
|
|
||||||
|
|
@ -80,4 +80,29 @@ impl InstallOptions {
|
||||||
|
|
||||||
resolution.filter(|dist| !no_install_packages.contains(dist.name()))
|
resolution.filter(|dist| !no_install_packages.contains(dist.name()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if a package passes the install filters.
|
||||||
|
pub fn include_package(
|
||||||
|
&self,
|
||||||
|
package: &PackageName,
|
||||||
|
project_name: &PackageName,
|
||||||
|
members: &BTreeSet<PackageName>,
|
||||||
|
) -> bool {
|
||||||
|
// If `--no-install-project` is set, remove the project itself.
|
||||||
|
if self.no_install_project && package == project_name {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If `--no-install-workspace` is set, remove the project and any workspace members.
|
||||||
|
if self.no_install_workspace && members.contains(package) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If `--no-install-package` is provided, remove the requested packages.
|
||||||
|
if self.no_install_package.contains(package) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ use std::fmt::Formatter;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use petgraph::graph::NodeIndex;
|
|
||||||
use petgraph::visit::IntoNodeReferences;
|
use petgraph::visit::IntoNodeReferences;
|
||||||
use petgraph::{Directed, Graph};
|
use petgraph::{Directed, Graph};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
|
@ -13,7 +12,7 @@ use url::Url;
|
||||||
use distribution_filename::{DistExtension, SourceDistExtension};
|
use distribution_filename::{DistExtension, SourceDistExtension};
|
||||||
use pep508_rs::MarkerTree;
|
use pep508_rs::MarkerTree;
|
||||||
use pypi_types::{ParsedArchiveUrl, ParsedGitUrl};
|
use pypi_types::{ParsedArchiveUrl, ParsedGitUrl};
|
||||||
use uv_configuration::ExtrasSpecification;
|
use uv_configuration::{ExtrasSpecification, InstallOptions};
|
||||||
use uv_fs::Simplified;
|
use uv_fs::Simplified;
|
||||||
use uv_git::GitReference;
|
use uv_git::GitReference;
|
||||||
use uv_normalize::{ExtraName, GroupName, PackageName};
|
use uv_normalize::{ExtraName, GroupName, PackageName};
|
||||||
|
|
@ -24,11 +23,16 @@ use crate::{Lock, LockError};
|
||||||
|
|
||||||
type LockGraph<'lock> = Graph<&'lock Package, Edge, Directed>;
|
type LockGraph<'lock> = Graph<&'lock Package, Edge, Directed>;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
struct Node<'lock> {
|
||||||
|
package: &'lock Package,
|
||||||
|
marker: MarkerTree,
|
||||||
|
}
|
||||||
|
|
||||||
/// 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> {
|
pub struct RequirementsTxtExport<'lock> {
|
||||||
graph: LockGraph<'lock>,
|
nodes: Vec<Node<'lock>>,
|
||||||
reachability: FxHashMap<NodeIndex, MarkerTree>,
|
|
||||||
hashes: bool,
|
hashes: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,6 +43,7 @@ impl<'lock> RequirementsTxtExport<'lock> {
|
||||||
extras: &ExtrasSpecification,
|
extras: &ExtrasSpecification,
|
||||||
dev: &[GroupName],
|
dev: &[GroupName],
|
||||||
hashes: bool,
|
hashes: bool,
|
||||||
|
install_options: &'lock InstallOptions,
|
||||||
) -> 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);
|
||||||
|
|
@ -123,28 +128,33 @@ impl<'lock> RequirementsTxtExport<'lock> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let reachability = marker_reachability(&petgraph, &[]);
|
let mut reachability = marker_reachability(&petgraph, &[]);
|
||||||
|
|
||||||
Ok(Self {
|
// Collect all packages.
|
||||||
graph: petgraph,
|
let mut nodes: Vec<Node> = petgraph
|
||||||
reachability,
|
.node_references()
|
||||||
hashes,
|
.filter(|(_index, package)| {
|
||||||
})
|
install_options.include_package(&package.id.name, root_name, lock.members())
|
||||||
|
})
|
||||||
|
.map(|(index, package)| Node {
|
||||||
|
package,
|
||||||
|
marker: reachability.remove(&index).unwrap_or_default(),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
// Sort the nodes, such that unnamed URLs (editables) appear at the top.
|
||||||
|
nodes.sort_unstable_by(|a, b| {
|
||||||
|
NodeComparator::from(a.package).cmp(&NodeComparator::from(b.package))
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(Self { nodes, hashes })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for RequirementsTxtExport<'_> {
|
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.
|
|
||||||
let mut nodes = self.graph.node_references().collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Sort the nodes, such that unnamed URLs (editables) appear at the top.
|
|
||||||
nodes.sort_unstable_by(|(_, a), (_, b)| {
|
|
||||||
NodeComparator::from(**a).cmp(&NodeComparator::from(**b))
|
|
||||||
});
|
|
||||||
|
|
||||||
// Write out each package.
|
// Write out each package.
|
||||||
for (node_index, package) in nodes {
|
for Node { package, marker } in &self.nodes {
|
||||||
match &package.id.source {
|
match &package.id.source {
|
||||||
Source::Registry(_) => {
|
Source::Registry(_) => {
|
||||||
write!(f, "{}=={}", package.id.name, package.id.version)?;
|
write!(f, "{}=={}", package.id.name, package.id.version)?;
|
||||||
|
|
@ -201,7 +211,7 @@ impl std::fmt::Display for RequirementsTxtExport<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(contents) = self.reachability[&node_index].contents() {
|
if let Some(contents) = marker.contents() {
|
||||||
write!(f, " ; {contents}")?;
|
write!(f, " ; {contents}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
use uv_cache::Cache;
|
use uv_cache::Cache;
|
||||||
use uv_client::Connectivity;
|
use uv_client::Connectivity;
|
||||||
use uv_configuration::{Concurrency, ExportFormat, ExtrasSpecification};
|
use uv_configuration::{Concurrency, ExportFormat, ExtrasSpecification, InstallOptions};
|
||||||
use uv_fs::CWD;
|
use uv_fs::CWD;
|
||||||
use uv_normalize::{PackageName, DEV_DEPENDENCIES};
|
use uv_normalize::{PackageName, DEV_DEPENDENCIES};
|
||||||
use uv_python::{PythonDownloads, PythonPreference, PythonRequest};
|
use uv_python::{PythonDownloads, PythonPreference, PythonRequest};
|
||||||
|
|
@ -24,6 +24,7 @@ pub(crate) async fn export(
|
||||||
format: ExportFormat,
|
format: ExportFormat,
|
||||||
package: Option<PackageName>,
|
package: Option<PackageName>,
|
||||||
hashes: bool,
|
hashes: bool,
|
||||||
|
install_options: InstallOptions,
|
||||||
output_file: Option<PathBuf>,
|
output_file: Option<PathBuf>,
|
||||||
extras: ExtrasSpecification,
|
extras: ExtrasSpecification,
|
||||||
dev: bool,
|
dev: bool,
|
||||||
|
|
@ -125,6 +126,7 @@ pub(crate) async fn export(
|
||||||
&extras,
|
&extras,
|
||||||
&dev,
|
&dev,
|
||||||
hashes,
|
hashes,
|
||||||
|
&install_options,
|
||||||
)?;
|
)?;
|
||||||
writeln!(
|
writeln!(
|
||||||
writer,
|
writer,
|
||||||
|
|
|
||||||
|
|
@ -1323,6 +1323,7 @@ async fn run_project(
|
||||||
args.format,
|
args.format,
|
||||||
args.package,
|
args.package,
|
||||||
args.hashes,
|
args.hashes,
|
||||||
|
args.install_options,
|
||||||
args.output_file,
|
args.output_file,
|
||||||
args.extras,
|
args.extras,
|
||||||
args.dev,
|
args.dev,
|
||||||
|
|
|
||||||
|
|
@ -957,6 +957,7 @@ pub(crate) struct ExportSettings {
|
||||||
pub(crate) extras: ExtrasSpecification,
|
pub(crate) extras: ExtrasSpecification,
|
||||||
pub(crate) dev: bool,
|
pub(crate) dev: bool,
|
||||||
pub(crate) hashes: bool,
|
pub(crate) hashes: bool,
|
||||||
|
pub(crate) install_options: InstallOptions,
|
||||||
pub(crate) output_file: Option<PathBuf>,
|
pub(crate) output_file: Option<PathBuf>,
|
||||||
pub(crate) locked: bool,
|
pub(crate) locked: bool,
|
||||||
pub(crate) frozen: bool,
|
pub(crate) frozen: bool,
|
||||||
|
|
@ -980,6 +981,9 @@ impl ExportSettings {
|
||||||
hashes,
|
hashes,
|
||||||
no_hashes,
|
no_hashes,
|
||||||
output_file,
|
output_file,
|
||||||
|
no_emit_project,
|
||||||
|
no_emit_workspace,
|
||||||
|
no_emit_package,
|
||||||
locked,
|
locked,
|
||||||
frozen,
|
frozen,
|
||||||
resolver,
|
resolver,
|
||||||
|
|
@ -997,6 +1001,11 @@ impl ExportSettings {
|
||||||
),
|
),
|
||||||
dev: flag(dev, no_dev).unwrap_or(true),
|
dev: flag(dev, no_dev).unwrap_or(true),
|
||||||
hashes: flag(hashes, no_hashes).unwrap_or(true),
|
hashes: flag(hashes, no_hashes).unwrap_or(true),
|
||||||
|
install_options: InstallOptions::new(
|
||||||
|
no_emit_project,
|
||||||
|
no_emit_workspace,
|
||||||
|
no_emit_package,
|
||||||
|
),
|
||||||
output_file,
|
output_file,
|
||||||
locked,
|
locked,
|
||||||
frozen,
|
frozen,
|
||||||
|
|
|
||||||
|
|
@ -695,3 +695,131 @@ fn output_file() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_emit() -> 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", "child"]
|
||||||
|
|
||||||
|
[tool.uv.workspace]
|
||||||
|
members = ["child"]
|
||||||
|
|
||||||
|
[tool.uv.sources]
|
||||||
|
child = { workspace = true }
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=42"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let child = context.temp_dir.child("child");
|
||||||
|
child.child("pyproject.toml").write_str(
|
||||||
|
r#"
|
||||||
|
[project]
|
||||||
|
name = "child"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = ["iniconfig>=2"]
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=42"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
context.lock().assert().success();
|
||||||
|
|
||||||
|
// Exclude `anyio`.
|
||||||
|
uv_snapshot!(context.filters(), context.export().arg("--no-emit-package").arg("anyio"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
# This file was autogenerated via `uv export`.
|
||||||
|
-e .
|
||||||
|
-e child
|
||||||
|
idna==3.6 \
|
||||||
|
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
|
||||||
|
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
|
||||||
|
iniconfig==2.0.0 \
|
||||||
|
--hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
|
||||||
|
--hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
|
||||||
|
sniffio==1.3.1 \
|
||||||
|
--hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc \
|
||||||
|
--hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 6 packages in [TIME]
|
||||||
|
"###);
|
||||||
|
|
||||||
|
// Exclude `project`.
|
||||||
|
uv_snapshot!(context.filters(), context.export().arg("--no-emit-project"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
# This file was autogenerated via `uv export`.
|
||||||
|
-e child
|
||||||
|
anyio==3.7.0 \
|
||||||
|
--hash=sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce \
|
||||||
|
--hash=sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0
|
||||||
|
idna==3.6 \
|
||||||
|
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
|
||||||
|
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
|
||||||
|
iniconfig==2.0.0 \
|
||||||
|
--hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
|
||||||
|
--hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
|
||||||
|
sniffio==1.3.1 \
|
||||||
|
--hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc \
|
||||||
|
--hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 6 packages in [TIME]
|
||||||
|
"###);
|
||||||
|
|
||||||
|
// Exclude `child`.
|
||||||
|
uv_snapshot!(context.filters(), context.export().arg("--no-emit-project").arg("--package").arg("child"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
# This file was autogenerated via `uv export`.
|
||||||
|
iniconfig==2.0.0 \
|
||||||
|
--hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
|
||||||
|
--hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 6 packages in [TIME]
|
||||||
|
"###);
|
||||||
|
|
||||||
|
// Exclude the workspace.
|
||||||
|
uv_snapshot!(context.filters(), context.export().arg("--no-emit-workspace"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
# This file was autogenerated via `uv export`.
|
||||||
|
anyio==3.7.0 \
|
||||||
|
--hash=sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce \
|
||||||
|
--hash=sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0
|
||||||
|
idna==3.6 \
|
||||||
|
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
|
||||||
|
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
|
||||||
|
iniconfig==2.0.0 \
|
||||||
|
--hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
|
||||||
|
--hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
|
||||||
|
sniffio==1.3.1 \
|
||||||
|
--hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc \
|
||||||
|
--hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 6 packages in [TIME]
|
||||||
|
"###);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1857,6 +1857,18 @@ uv export [OPTIONS]
|
||||||
<p>May also be set with the <code>UV_NO_CONFIG</code> environment variable.</p>
|
<p>May also be set with the <code>UV_NO_CONFIG</code> environment variable.</p>
|
||||||
</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-emit-package</code> <i>no-emit-package</i></dt><dd><p>Do not emit the given package(s).</p>
|
||||||
|
|
||||||
|
<p>By default, all of the project’s dependencies are included in the exported requirements file. The <code>--no-install-package</code> option allows exclusion of specific packages.</p>
|
||||||
|
|
||||||
|
</dd><dt><code>--no-emit-project</code></dt><dd><p>Do not emit the current project.</p>
|
||||||
|
|
||||||
|
<p>By default, the current project is included in the exported requirements file with all of its dependencies. The <code>--no-emit-project</code> option allows the project to be excluded, but all of its dependencies to remain included.</p>
|
||||||
|
|
||||||
|
</dd><dt><code>--no-emit-workspace</code></dt><dd><p>Do not emit any workspace members, including the root project.</p>
|
||||||
|
|
||||||
|
<p>By default, all workspace members and their dependencies are included in the exported requirements file, with all of their dependencies. The <code>--no-emit-workspace</code> option allows exclusion of all the workspace members while retaining their dependencies.</p>
|
||||||
|
|
||||||
</dd><dt><code>--no-hashes</code></dt><dd><p>Omit hashes in the generated output</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>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue