mirror of https://github.com/astral-sh/uv
Issue 11632 - Add sources override
This commit is contained in:
parent
e799a088a5
commit
520f42ea31
|
|
@ -20,7 +20,7 @@ use uv_resolver::{
|
||||||
PrereleaseMode, ResolutionMode,
|
PrereleaseMode, ResolutionMode,
|
||||||
};
|
};
|
||||||
use uv_torch::TorchMode;
|
use uv_torch::TorchMode;
|
||||||
use uv_workspace::pyproject::ExtraBuildDependencies;
|
use uv_workspace::pyproject::{ExtraBuildDependencies, ToolUvSources};
|
||||||
use uv_workspace::pyproject_mut::AddBoundsKind;
|
use uv_workspace::pyproject_mut::AddBoundsKind;
|
||||||
|
|
||||||
use crate::{FilesystemOptions, Options, PipOptions};
|
use crate::{FilesystemOptions, Options, PipOptions};
|
||||||
|
|
@ -294,3 +294,23 @@ impl Combine for Option<ExtraBuildVariables> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Combine for ToolUvSources {
|
||||||
|
fn combine(self, other: Self) -> Self {
|
||||||
|
// Merge sources from other into self, with self taking precedence
|
||||||
|
let mut combined = self.into_inner();
|
||||||
|
for (package, sources) in other.into_inner() {
|
||||||
|
combined.entry(package).or_insert(sources);
|
||||||
|
}
|
||||||
|
combined.into_iter().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Combine for Option<ToolUvSources> {
|
||||||
|
fn combine(self, other: Self) -> Self {
|
||||||
|
match (self, other) {
|
||||||
|
(Some(a), Some(b)) => Some(a.combine(b)),
|
||||||
|
(a, b) => a.or(b),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ fn validate_uv_toml(path: &Path, options: &Options) -> Result<(), Error> {
|
||||||
required_environments,
|
required_environments,
|
||||||
conflicts,
|
conflicts,
|
||||||
workspace,
|
workspace,
|
||||||
sources,
|
sources: _,
|
||||||
dev_dependencies,
|
dev_dependencies,
|
||||||
default_groups,
|
default_groups,
|
||||||
dependency_groups,
|
dependency_groups,
|
||||||
|
|
@ -236,9 +236,6 @@ fn validate_uv_toml(path: &Path, options: &Options) -> Result<(), Error> {
|
||||||
if workspace.is_some() {
|
if workspace.is_some() {
|
||||||
return Err(Error::PyprojectOnlyField(path.to_path_buf(), "workspace"));
|
return Err(Error::PyprojectOnlyField(path.to_path_buf(), "workspace"));
|
||||||
}
|
}
|
||||||
if sources.is_some() {
|
|
||||||
return Err(Error::PyprojectOnlyField(path.to_path_buf(), "sources"));
|
|
||||||
}
|
|
||||||
if dev_dependencies.is_some() {
|
if dev_dependencies.is_some() {
|
||||||
return Err(Error::PyprojectOnlyField(
|
return Err(Error::PyprojectOnlyField(
|
||||||
path.to_path_buf(),
|
path.to_path_buf(),
|
||||||
|
|
|
||||||
|
|
@ -139,8 +139,11 @@ pub struct Options {
|
||||||
#[cfg_attr(feature = "schemars", schemars(skip))]
|
#[cfg_attr(feature = "schemars", schemars(skip))]
|
||||||
pub workspace: Option<serde::de::IgnoredAny>,
|
pub workspace: Option<serde::de::IgnoredAny>,
|
||||||
|
|
||||||
|
// NOTE: Unlike other fields above, `sources` is allowed in both `pyproject.toml`
|
||||||
|
// and `uv.toml` files to support local development overrides without modifying
|
||||||
|
// the committed configuration.
|
||||||
#[cfg_attr(feature = "schemars", schemars(skip))]
|
#[cfg_attr(feature = "schemars", schemars(skip))]
|
||||||
pub sources: Option<serde::de::IgnoredAny>,
|
pub sources: Option<uv_workspace::pyproject::ToolUvSources>,
|
||||||
|
|
||||||
#[cfg_attr(feature = "schemars", schemars(skip))]
|
#[cfg_attr(feature = "schemars", schemars(skip))]
|
||||||
pub dev_dependencies: Option<serde::de::IgnoredAny>,
|
pub dev_dependencies: Option<serde::de::IgnoredAny>,
|
||||||
|
|
@ -2117,12 +2120,15 @@ pub struct OptionsWire {
|
||||||
environments: Option<SupportedEnvironments>,
|
environments: Option<SupportedEnvironments>,
|
||||||
required_environments: Option<SupportedEnvironments>,
|
required_environments: Option<SupportedEnvironments>,
|
||||||
|
|
||||||
// NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
|
// NOTE: These fields should be kept in-sync with `ToolUv` in
|
||||||
// `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
|
// `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
|
||||||
// They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
|
// They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
|
||||||
conflicts: Option<serde::de::IgnoredAny>,
|
conflicts: Option<serde::de::IgnoredAny>,
|
||||||
workspace: Option<serde::de::IgnoredAny>,
|
workspace: Option<serde::de::IgnoredAny>,
|
||||||
sources: Option<serde::de::IgnoredAny>,
|
// NOTE: Unlike other fields above, `sources` is allowed in both `pyproject.toml`
|
||||||
|
// and `uv.toml` files to support local development overrides without modifying
|
||||||
|
// the committed configuration.
|
||||||
|
sources: Option<uv_workspace::pyproject::ToolUvSources>,
|
||||||
managed: Option<serde::de::IgnoredAny>,
|
managed: Option<serde::de::IgnoredAny>,
|
||||||
r#package: Option<serde::de::IgnoredAny>,
|
r#package: Option<serde::de::IgnoredAny>,
|
||||||
default_groups: Option<serde::de::IgnoredAny>,
|
default_groups: Option<serde::de::IgnoredAny>,
|
||||||
|
|
|
||||||
|
|
@ -731,6 +731,12 @@ impl<'de> serde::de::Deserialize<'de> for ToolUvSources {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromIterator<(PackageName, Sources)> for ToolUvSources {
|
||||||
|
fn from_iter<T: IntoIterator<Item = (PackageName, Sources)>>(iter: T) -> Self {
|
||||||
|
Self(iter.into_iter().collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(test, derive(Serialize))]
|
#[cfg_attr(test, derive(Serialize))]
|
||||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,14 @@ configuration tables, the project-level value will be used, and the user-level v
|
||||||
ignored. If an array is present in both tables, the arrays will be concatenated, with the
|
ignored. If an array is present in both tables, the arrays will be concatenated, with the
|
||||||
project-level settings appearing earlier in the merged array.
|
project-level settings appearing earlier in the merged array.
|
||||||
|
|
||||||
|
!!! tip "Local development overrides"
|
||||||
|
|
||||||
|
The `[sources]` table can be defined in both `uv.toml` and `pyproject.toml`. When both are
|
||||||
|
present, sources from `uv.toml` override those from `pyproject.toml` on a per-package basis.
|
||||||
|
This enables local development workflows where different team members have dependencies at
|
||||||
|
different filesystem locations. See [Dependency sources](projects/dependencies.md#local-development-overrides-with-uvtoml)
|
||||||
|
for more details.
|
||||||
|
|
||||||
Settings provided via environment variables take precedence over persistent configuration, and
|
Settings provided via environment variables take precedence over persistent configuration, and
|
||||||
settings provided via the command line take precedence over both.
|
settings provided via the command line take precedence over both.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -216,6 +216,34 @@ dependencies = ["foo"]
|
||||||
foo = { path = "./packages/foo" }
|
foo = { path = "./packages/foo" }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Local development overrides with `uv.toml`
|
||||||
|
|
||||||
|
Sources can also be defined in a `uv.toml` file to enable local development overrides without
|
||||||
|
modifying the committed `pyproject.toml`. This is useful when:
|
||||||
|
|
||||||
|
- Different developers have dependencies at different local paths
|
||||||
|
- You want to temporarily override a dependency without committing the change
|
||||||
|
- You want to use version control ignore patterns (e.g., `.gitignore`) to exclude local configuration
|
||||||
|
|
||||||
|
```toml title="uv.toml"
|
||||||
|
[sources]
|
||||||
|
httpx = { path = "../httpx", editable = true }
|
||||||
|
my-package = { git = "https://github.com/me/my-package", branch = "dev" }
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
When both `uv.toml` and `pyproject.toml` define sources for the same package, the `uv.toml`
|
||||||
|
definition takes precedence. This allows local overrides without modifying the project
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
Add `uv.toml` to your `.gitignore` to maintain local-only development configurations without
|
||||||
|
affecting other team members.
|
||||||
|
|
||||||
|
### Supported source types
|
||||||
|
|
||||||
The following dependency sources are supported by uv:
|
The following dependency sources are supported by uv:
|
||||||
|
|
||||||
- [Index](#index): A package resolved from a specific package index.
|
- [Index](#index): A package resolved from a specific package index.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue