mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-22 20:45:25 +00:00
Add editable install support to pip-install (#675)
Per the title: adds support for `-e` installs to `puffin pip-install`. There were some challenges here around threading the editable installs to the right places. Namely, we want to build _once_, then reuse the editable installs from the resolution. At present, we were losing the `editable: true` flag on the `Dist` that came back through the resolution, so it required some changes to the resolver. Closes https://github.com/astral-sh/puffin/issues/672.
This commit is contained in:
parent
8c6463d220
commit
0bb2c92246
17 changed files with 436 additions and 132 deletions
|
|
@ -10,7 +10,7 @@ use pubgrub::type_aliases::SelectedDependencies;
|
|||
use rustc_hash::FxHashMap;
|
||||
use url::Url;
|
||||
|
||||
use distribution_types::{Dist, DistributionId, Identifier, LocalEditable, Metadata, PackageId};
|
||||
use distribution_types::{Dist, LocalEditable, Metadata, PackageId};
|
||||
use pep440_rs::Version;
|
||||
use pep508_rs::{Requirement, VerbatimUrl};
|
||||
use puffin_normalize::{ExtraName, PackageName};
|
||||
|
|
@ -28,7 +28,7 @@ pub struct ResolutionGraph {
|
|||
/// The underlying graph.
|
||||
petgraph: petgraph::graph::Graph<Dist, Range<PubGrubVersion>, petgraph::Directed>,
|
||||
/// The set of editable requirements in this resolution.
|
||||
editables: FxHashMap<DistributionId, (LocalEditable, Metadata21)>,
|
||||
editables: FxHashMap<PackageName, (LocalEditable, Metadata21)>,
|
||||
/// Any diagnostics that were encountered while building the graph.
|
||||
diagnostics: Vec<Diagnostic>,
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ impl ResolutionGraph {
|
|||
distributions: &OnceMap<PackageId, Metadata21>,
|
||||
redirects: &OnceMap<Url, Url>,
|
||||
state: &State<PubGrubPackage, Range<PubGrubVersion>, PubGrubPriority>,
|
||||
editables: FxHashMap<DistributionId, (LocalEditable, Metadata21)>,
|
||||
editables: FxHashMap<PackageName, (LocalEditable, Metadata21)>,
|
||||
) -> Result<Self, ResolveError> {
|
||||
// TODO(charlie): petgraph is a really heavy and unnecessary dependency here. We should
|
||||
// write our own graph, given that our requirements are so simple.
|
||||
|
|
@ -66,11 +66,15 @@ impl ResolutionGraph {
|
|||
inverse.insert(package_name, index);
|
||||
}
|
||||
PubGrubPackage::Package(package_name, None, Some(url)) => {
|
||||
let url = redirects.get(url).map_or_else(
|
||||
|| url.clone(),
|
||||
|url| VerbatimUrl::unknown(url.value().clone()),
|
||||
);
|
||||
let pinned_package = Dist::from_url(package_name.clone(), url)?;
|
||||
let pinned_package = if let Some((editable, _)) = editables.get(package_name) {
|
||||
Dist::from_editable(package_name.clone(), editable.clone())?
|
||||
} else {
|
||||
let url = redirects.get(url).map_or_else(
|
||||
|| url.clone(),
|
||||
|url| VerbatimUrl::unknown(url.value().clone()),
|
||||
);
|
||||
Dist::from_url(package_name.clone(), url)?
|
||||
};
|
||||
|
||||
let index = petgraph.add_node(pinned_package);
|
||||
inverse.insert(package_name, index);
|
||||
|
|
@ -173,13 +177,6 @@ impl ResolutionGraph {
|
|||
|
||||
/// Return the set of [`Requirement`]s that this graph represents.
|
||||
pub fn requirements(&self) -> Vec<Requirement> {
|
||||
// Collect and sort all packages.
|
||||
let mut nodes = self
|
||||
.petgraph
|
||||
.node_indices()
|
||||
.map(|node| (node, &self.petgraph[node]))
|
||||
.collect::<Vec<_>>();
|
||||
nodes.sort_unstable_by_key(|(_, package)| package.name());
|
||||
self.petgraph
|
||||
.node_indices()
|
||||
.map(|node| &self.petgraph[node])
|
||||
|
|
@ -199,14 +196,6 @@ impl ResolutionGraph {
|
|||
) -> &petgraph::graph::Graph<Dist, Range<PubGrubVersion>, petgraph::Directed> {
|
||||
&self.petgraph
|
||||
}
|
||||
|
||||
/// Return the set of editable requirements in this resolution.
|
||||
///
|
||||
/// The editable requirements themselves are unchanged, but their dependencies were added to the general
|
||||
/// list of dependencies.
|
||||
pub fn editables(&self) -> &FxHashMap<DistributionId, (LocalEditable, Metadata21)> {
|
||||
&self.editables
|
||||
}
|
||||
}
|
||||
|
||||
/// Write the graph in the `{name}=={version}` format of requirements.txt that pip uses.
|
||||
|
|
@ -222,9 +211,8 @@ impl std::fmt::Display for ResolutionGraph {
|
|||
|
||||
// Print out the dependency graph.
|
||||
for (index, package) in nodes {
|
||||
if let Some((editable_requirement, _)) = self.editables.get(&package.distribution_id())
|
||||
{
|
||||
writeln!(f, "-e {editable_requirement}")?;
|
||||
if let Some((editable, _)) = self.editables.get(package.name()) {
|
||||
writeln!(f, "-e {editable}")?;
|
||||
} else {
|
||||
writeln!(f, "{package}")?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ use url::Url;
|
|||
|
||||
use distribution_filename::WheelFilename;
|
||||
use distribution_types::{
|
||||
BuiltDist, Dist, DistributionId, Identifier, LocalEditable, Metadata, PackageId, SourceDist,
|
||||
VersionOrUrl,
|
||||
BuiltDist, Dist, LocalEditable, Metadata, PackageId, SourceDist, VersionOrUrl,
|
||||
};
|
||||
use pep508_rs::{MarkerEnvironment, Requirement};
|
||||
use platform_tags::Tags;
|
||||
|
|
@ -157,7 +156,7 @@ pub struct Resolver<'a, Provider: ResolverProvider> {
|
|||
markers: &'a MarkerEnvironment,
|
||||
selector: CandidateSelector,
|
||||
index: Arc<Index>,
|
||||
editables: FxHashMap<DistributionId, (LocalEditable, Metadata21)>,
|
||||
editables: FxHashMap<PackageName, (LocalEditable, Metadata21)>,
|
||||
reporter: Option<Arc<dyn Reporter>>,
|
||||
provider: Provider,
|
||||
}
|
||||
|
|
@ -204,15 +203,17 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
|
|||
// Determine all the editable requirements.
|
||||
let mut editables = FxHashMap::default();
|
||||
for (editable_requirement, metadata) in &manifest.editables {
|
||||
let dist = Dist::from_url(metadata.name.clone(), editable_requirement.url().clone())
|
||||
// Convert the editable requirement into a distribution.
|
||||
let dist = Dist::from_editable(metadata.name.clone(), editable_requirement.clone())
|
||||
.expect("This is a valid distribution");
|
||||
|
||||
// Mock editable responses.
|
||||
index.distributions.register(&dist.package_id());
|
||||
index
|
||||
.distributions
|
||||
.done(dist.package_id(), metadata.clone());
|
||||
editables.insert(
|
||||
dist.distribution_id(),
|
||||
dist.name().clone(),
|
||||
(editable_requirement.clone(), metadata.clone()),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue