Skip to content

Commit 0ec7f68

Browse files
committed
Allow path + registry dependencies
Closes rust-lang#4843
1 parent 7fa132c commit 0ec7f68

File tree

4 files changed

+51
-16
lines changed

4 files changed

+51
-16
lines changed

src/cargo/core/dependency.rs

+11
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub struct Dependency {
2222
struct Inner {
2323
name: String,
2424
source_id: SourceId,
25+
registry_id: Option<SourceId>,
2526
req: VersionReq,
2627
specified_req: bool,
2728
kind: Kind,
@@ -172,6 +173,7 @@ impl Dependency {
172173
inner: Rc::new(Inner {
173174
name: name.to_string(),
174175
source_id: source_id.clone(),
176+
registry_id: None,
175177
req: VersionReq::any(),
176178
kind: Kind::Normal,
177179
only_match_name: true,
@@ -196,6 +198,15 @@ impl Dependency {
196198
&self.inner.source_id
197199
}
198200

201+
pub fn registry_id(&self) -> Option<&SourceId> {
202+
self.inner.registry_id.as_ref()
203+
}
204+
205+
pub fn set_registry_id(&mut self, registry_id: &SourceId) -> &mut Dependency {
206+
Rc::make_mut(&mut self.inner).registry_id = Some(registry_id.clone());
207+
self
208+
}
209+
199210
pub fn kind(&self) -> Kind {
200211
self.inner.kind
201212
}

src/cargo/ops/registry.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,17 @@ fn transmit(config: &Config,
130130

131131
// If the dependency is from a different registry, then include the
132132
// registry in the dependency.
133-
let dep_registry = if dep.source_id() != registry_id {
134-
Some(dep.source_id().url().to_string())
133+
let dep_registry_id = match dep.registry_id() {
134+
Some(id) => id,
135+
None => bail!("dependency missing registry ID"),
136+
};
137+
let dep_registry = if dep_registry_id != registry_id {
138+
Some(dep_registry_id.url().to_string())
135139
} else {
136140
None
137141
};
138142

139-
NewCrateDependency {
143+
Ok(NewCrateDependency {
140144
optional: dep.is_optional(),
141145
default_features: dep.uses_default_features(),
142146
name: dep.name().to_string(),
@@ -149,8 +153,8 @@ fn transmit(config: &Config,
149153
Kind::Development => "dev",
150154
}.to_string(),
151155
registry: dep_registry,
152-
}
153-
}).collect::<Vec<NewCrateDependency>>();
156+
})
157+
}).collect::<CargoResult<Vec<NewCrateDependency>>>()?;
154158
let manifest = pkg.manifest();
155159
let ManifestMetadata {
156160
ref authors, ref description, ref homepage, ref documentation,

src/cargo/util/toml/mod.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -925,11 +925,17 @@ impl TomlDependency {
925925
}
926926
}
927927

928+
let registry_id = match details.registry {
929+
Some(ref registry) => {
930+
cx.features.require(Feature::alternative_registries())?;
931+
SourceId::alt_registry(cx.config, registry)?
932+
}
933+
None => SourceId::crates_io(cx.config)?
934+
};
935+
928936
let new_source_id = match (details.git.as_ref(), details.path.as_ref(), details.registry.as_ref()) {
929937
(Some(_), _, Some(_)) => bail!("dependency ({}) specification is ambiguous. \
930938
Only one of `git` or `registry` is allowed.", name),
931-
(_, Some(_), Some(_)) => bail!("dependency ({}) specification is ambiguous. \
932-
Only one of `path` or `registry` is allowed.", name),
933939
(Some(git), maybe_path, _) => {
934940
if maybe_path.is_some() {
935941
let msg = format!("dependency ({}) specification is ambiguous. \
@@ -975,10 +981,7 @@ impl TomlDependency {
975981
cx.source_id.clone()
976982
}
977983
},
978-
(None, None, Some(registry)) => {
979-
cx.features.require(Feature::alternative_registries())?;
980-
SourceId::alt_registry(cx.config, registry)?
981-
}
984+
(None, None, Some(registry)) => SourceId::alt_registry(cx.config, registry)?,
982985
(None, None, None) => SourceId::crates_io(cx.config)?,
983986
};
984987

@@ -995,7 +998,8 @@ impl TomlDependency {
995998
.or(details.default_features2)
996999
.unwrap_or(true))
9971000
.set_optional(details.optional.unwrap_or(false))
998-
.set_platform(cx.platform.clone());
1001+
.set_platform(cx.platform.clone())
1002+
.set_registry_id(&registry_id);
9991003
if let Some(kind) = kind {
10001004
dep.set_kind(kind);
10011005
}

tests/alt-registry.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ fn depend_on_alt_registry_depends_on_crates_io() {
180180
}
181181

182182
#[test]
183-
fn registry_incompatible_with_path() {
183+
fn registry_and_path_dep_works() {
184+
registry::init();
185+
184186
let p = project("foo")
185187
.file("Cargo.toml", r#"
186188
cargo-features = ["alternative-registries"]
@@ -191,19 +193,33 @@ fn registry_incompatible_with_path() {
191193
authors = []
192194
193195
[dependencies.bar]
194-
path = ""
196+
path = "bar"
195197
registry = "alternative"
196198
"#)
197199
.file("src/main.rs", "fn main() {}")
200+
.file("bar/Cargo.toml", r#"
201+
[project]
202+
name = "bar"
203+
version = "0.0.1"
204+
authors = []
205+
"#)
206+
.file("bar/src/lib.rs", "")
198207
.build();
199208

200209
assert_that(p.cargo("build").masquerade_as_nightly_cargo(),
201-
execs().with_status(101)
202-
.with_stderr_contains(" dependency (bar) specification is ambiguous. Only one of `path` or `registry` is allowed."));
210+
execs().with_status(0)
211+
.with_stderr(&format!("\
212+
[COMPILING] bar v0.0.1 ({dir}/bar)
213+
[COMPILING] foo v0.0.1 ({dir})
214+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] secs
215+
",
216+
dir = p.url())));
203217
}
204218

205219
#[test]
206220
fn registry_incompatible_with_git() {
221+
registry::init();
222+
207223
let p = project("foo")
208224
.file("Cargo.toml", r#"
209225
cargo-features = ["alternative-registries"]

0 commit comments

Comments
 (0)