mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 05:15:00 +00:00
Change install
to sync
(with sync semantics) (#24)
For better separate at this stage (and following `pip-tools`), it's now `puffin sync`, and it assumes `--no-deps`.
This commit is contained in:
parent
ff8e24a621
commit
dab70a661a
7 changed files with 70 additions and 39 deletions
|
@ -13,7 +13,7 @@ cargo run -p puffin-cli -- compile requirements.in
|
|||
To install from a resolved `requirements.txt` file:
|
||||
|
||||
```shell
|
||||
cargo run -p puffin-cli -- install requirements.txt
|
||||
cargo run -p puffin-cli -- sync requirements.txt
|
||||
```
|
||||
|
||||
## Benchmarks
|
||||
|
|
|
@ -43,7 +43,14 @@ pub(crate) async fn compile(src: &Path, cache: Option<&Path>) -> Result<ExitStat
|
|||
};
|
||||
|
||||
// Resolve the dependencies.
|
||||
let resolution = puffin_resolver::resolve(&requirements, markers, &tags, &client).await?;
|
||||
let resolution = puffin_resolver::resolve(
|
||||
&requirements,
|
||||
markers,
|
||||
&tags,
|
||||
&client,
|
||||
puffin_resolver::Flags::default(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
for (name, package) in resolution.iter() {
|
||||
#[allow(clippy::print_stdout)]
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use std::process::ExitCode;
|
||||
|
||||
pub(crate) use compile::compile;
|
||||
pub(crate) use install::install;
|
||||
pub(crate) use sync::sync;
|
||||
|
||||
mod compile;
|
||||
mod install;
|
||||
mod sync;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) enum ExitStatus {
|
||||
|
|
|
@ -11,8 +11,8 @@ use puffin_platform::Platform;
|
|||
|
||||
use crate::commands::ExitStatus;
|
||||
|
||||
/// Install a set of requirements into the current Python environment.
|
||||
pub(crate) async fn install(src: &Path, cache: Option<&Path>) -> Result<ExitStatus> {
|
||||
/// Install a set of locked requirements into the current Python environment.
|
||||
pub(crate) async fn sync(src: &Path, cache: Option<&Path>) -> Result<ExitStatus> {
|
||||
// Read the `requirements.txt` from disk.
|
||||
let requirements_txt = std::fs::read_to_string(src)?;
|
||||
|
||||
|
@ -43,12 +43,23 @@ pub(crate) async fn install(src: &Path, cache: Option<&Path>) -> Result<ExitStat
|
|||
};
|
||||
|
||||
// Resolve the dependencies.
|
||||
// TODO(charlie): When installing, assume `--no-deps`.
|
||||
let resolution = puffin_resolver::resolve(&requirements, markers, &tags, &client).await?;
|
||||
let resolution = puffin_resolver::resolve(
|
||||
&requirements,
|
||||
markers,
|
||||
&tags,
|
||||
&client,
|
||||
puffin_resolver::Flags::NO_DEPS,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Install into the current environment.
|
||||
let wheels = resolution.into_files().collect::<Vec<_>>();
|
||||
puffin_installer::install(&wheels, &python, &client).await?;
|
||||
|
||||
#[allow(clippy::print_stdout)]
|
||||
{
|
||||
println!("Installed {} wheels", wheels.len());
|
||||
}
|
||||
|
||||
Ok(ExitStatus::Success)
|
||||
}
|
|
@ -22,8 +22,8 @@ struct Cli {
|
|||
enum Commands {
|
||||
/// Compile a `requirements.in` file to a `requirements.txt` file.
|
||||
Compile(CompileArgs),
|
||||
/// Install dependencies from a `requirements.txt` file.
|
||||
Install(InstallArgs),
|
||||
/// Sync dependencies from a `requirements.txt` file.
|
||||
Sync(SyncArgs),
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
|
@ -37,7 +37,7 @@ struct CompileArgs {
|
|||
}
|
||||
|
||||
#[derive(Args)]
|
||||
struct InstallArgs {
|
||||
struct SyncArgs {
|
||||
/// Path to the `requirements.txt` file to install.
|
||||
src: PathBuf,
|
||||
|
||||
|
@ -59,16 +59,16 @@ async fn main() -> ExitCode {
|
|||
commands::compile(
|
||||
&args.src,
|
||||
dirs.as_ref()
|
||||
.map(directories::ProjectDirs::cache_dir)
|
||||
.map(ProjectDirs::cache_dir)
|
||||
.filter(|_| !args.no_cache),
|
||||
)
|
||||
.await
|
||||
}
|
||||
Commands::Install(args) => {
|
||||
commands::install(
|
||||
Commands::Sync(args) => {
|
||||
commands::sync(
|
||||
&args.src,
|
||||
dirs.as_ref()
|
||||
.map(directories::ProjectDirs::cache_dir)
|
||||
.map(ProjectDirs::cache_dir)
|
||||
.filter(|_| !args.no_cache),
|
||||
)
|
||||
.await
|
||||
|
|
|
@ -19,3 +19,4 @@ futures = "0.3.28"
|
|||
anyhow = "1.0.75"
|
||||
tracing = "0.1.37"
|
||||
pep508_rs = "0.2.3"
|
||||
bitflags = "2.4.0"
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::collections::{HashMap, HashSet};
|
|||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Result;
|
||||
use bitflags::bitflags;
|
||||
use futures::future::Either;
|
||||
use futures::{StreamExt, TryFutureExt};
|
||||
use pep440_rs::Version;
|
||||
|
@ -42,12 +43,21 @@ impl PinnedPackage {
|
|||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub struct Flags: u8 {
|
||||
/// Don't install package dependencies.
|
||||
const NO_DEPS = 1 << 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve a set of requirements into a set of pinned versions.
|
||||
pub async fn resolve(
|
||||
requirements: &Requirements,
|
||||
markers: &MarkerEnvironment,
|
||||
tags: &Tags,
|
||||
client: &PypiClient,
|
||||
flags: Flags,
|
||||
) -> Result<Resolution> {
|
||||
// A channel to fetch package metadata (e.g., given `flask`, fetch all versions) and version
|
||||
// metadata (e.g., given `flask==1.0.0`, fetch the metadata for that version).
|
||||
|
@ -141,31 +151,33 @@ pub async fn resolve(
|
|||
},
|
||||
);
|
||||
|
||||
// Enqueue its dependencies.
|
||||
for dependency in metadata.requires_dist {
|
||||
if !dependency.evaluate_markers(
|
||||
markers,
|
||||
// TODO(charlie): Remove this clone.
|
||||
requirement.extras.clone().unwrap_or_default(),
|
||||
) {
|
||||
debug!("--> ignoring {dependency} due to environment mismatch");
|
||||
continue;
|
||||
if !flags.intersects(Flags::NO_DEPS) {
|
||||
// Enqueue its dependencies.
|
||||
for dependency in metadata.requires_dist {
|
||||
if !dependency.evaluate_markers(
|
||||
markers,
|
||||
// TODO(charlie): Remove this clone.
|
||||
requirement.extras.clone().unwrap_or_default(),
|
||||
) {
|
||||
debug!("--> ignoring {dependency} due to environment mismatch");
|
||||
continue;
|
||||
}
|
||||
|
||||
let normalized_name = PackageName::normalize(&dependency.name);
|
||||
|
||||
if resolution.contains_key(&normalized_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !in_flight.insert(normalized_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
debug!("--> adding transitive dependency: {}", dependency);
|
||||
|
||||
package_sink.unbounded_send(Request::Package(dependency))?;
|
||||
}
|
||||
|
||||
let normalized_name = PackageName::normalize(&dependency.name);
|
||||
|
||||
if resolution.contains_key(&normalized_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !in_flight.insert(normalized_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
debug!("--> adding transitive dependency: {}", dependency);
|
||||
|
||||
package_sink.unbounded_send(Request::Package(dependency))?;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue