Skip to content

Commit bb2bebe

Browse files
committed
models/dependency: Move add_dependencies() function into to publish controller
1 parent 5e899a7 commit bb2bebe

File tree

3 files changed

+84
-87
lines changed

3 files changed

+84
-87
lines changed

src/controllers/krate/publish.rs

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,30 @@ use swirl::Job;
66

77
use crate::controllers::cargo_prelude::*;
88
use crate::git;
9-
use crate::models::dependency;
109
use crate::models::{
11-
insert_version_owner_action, Badge, Category, Keyword, NewCrate, NewVersion, Rights,
12-
VersionAction,
10+
insert_version_owner_action, Badge, Category, Crate, DependencyKind, Keyword, NewCrate,
11+
NewVersion, Rights, VersionAction,
1312
};
1413

1514
use crate::render;
15+
use crate::schema::*;
16+
use crate::util::errors::{cargo_err, AppResult};
1617
use crate::util::{read_fill, read_le_u32, Maximums};
17-
use crate::views::{EncodableCrate, EncodableCrateUpload, GoodCrate, PublishWarnings};
18+
use crate::views::{
19+
EncodableCrate, EncodableCrateDependency, EncodableCrateUpload, GoodCrate, PublishWarnings,
20+
};
1821

1922
pub const MISSING_RIGHTS_ERROR_MESSAGE: &str =
2023
"this crate exists but you don't seem to be an owner. \
2124
If you believe this is a mistake, perhaps you need \
2225
to accept an invitation to be an owner before \
2326
publishing.";
2427

28+
pub const WILDCARD_ERROR_MESSAGE: &str = "wildcard (`*`) dependency constraints are not allowed \
29+
on crates.io. See https://doc.rust-lang.org/cargo/faq.html#can-\
30+
libraries-use--as-a-version-for-their-dependencies for more \
31+
information";
32+
2533
/// Handles the `PUT /crates/new` route.
2634
/// Used by `cargo publish` to publish a new crate or to publish a new version of an
2735
/// existing crate.
@@ -163,7 +171,7 @@ pub fn publish(req: &mut dyn RequestExt) -> EndpointResult {
163171
)?;
164172

165173
// Link this new version to all dependencies
166-
let git_deps = dependency::add_dependencies(&conn, &new_crate.deps, version.id)?;
174+
let git_deps = add_dependencies(&conn, &new_crate.deps, version.id)?;
167175

168176
// Update all keywords for this crate
169177
Keyword::update_crate(&conn, &krate, &keywords)?;
@@ -277,6 +285,76 @@ pub fn missing_metadata_error_message(missing: &[&str]) -> String {
277285
)
278286
}
279287

288+
pub fn add_dependencies(
289+
conn: &PgConnection,
290+
deps: &[EncodableCrateDependency],
291+
target_version_id: i32,
292+
) -> AppResult<Vec<git::Dependency>> {
293+
use self::dependencies::dsl::*;
294+
use diesel::insert_into;
295+
296+
let git_and_new_dependencies = deps
297+
.iter()
298+
.map(|dep| {
299+
if let Some(registry) = &dep.registry {
300+
if !registry.is_empty() {
301+
return Err(cargo_err(&format_args!("Dependency `{}` is hosted on another registry. Cross-registry dependencies are not permitted on crates.io.", &*dep.name)));
302+
}
303+
}
304+
305+
// Match only identical names to ensure the index always references the original crate name
306+
let krate:Crate = Crate::by_exact_name(&dep.name)
307+
.first(&*conn)
308+
.map_err(|_| cargo_err(&format_args!("no known crate named `{}`", &*dep.name)))?;
309+
if semver::VersionReq::parse(&dep.version_req.0) == semver::VersionReq::parse("*") {
310+
return Err(cargo_err(WILDCARD_ERROR_MESSAGE));
311+
}
312+
313+
// If this dependency has an explicit name in `Cargo.toml` that
314+
// means that the `name` we have listed is actually the package name
315+
// that we're depending on. The `name` listed in the index is the
316+
// Cargo.toml-written-name which is what cargo uses for
317+
// `--extern foo=...`
318+
let (name, package) = match &dep.explicit_name_in_toml {
319+
Some(explicit) => (explicit.to_string(), Some(dep.name.to_string())),
320+
None => (dep.name.to_string(), None),
321+
};
322+
323+
Ok((
324+
git::Dependency {
325+
name,
326+
req: dep.version_req.to_string(),
327+
features: dep.features.iter().map(|s| s.0.to_string()).collect(),
328+
optional: dep.optional,
329+
default_features: dep.default_features,
330+
target: dep.target.clone(),
331+
kind: dep.kind.or(Some(DependencyKind::Normal)),
332+
package,
333+
},
334+
(
335+
version_id.eq(target_version_id),
336+
crate_id.eq(krate.id),
337+
req.eq(dep.version_req.to_string()),
338+
dep.kind.map(|k| kind.eq(k as i32)),
339+
optional.eq(dep.optional),
340+
default_features.eq(dep.default_features),
341+
features.eq(&dep.features),
342+
target.eq(dep.target.as_deref()),
343+
),
344+
))
345+
})
346+
.collect::<Result<Vec<_>, _>>()?;
347+
348+
let (git_deps, new_dependencies): (Vec<_>, Vec<_>) =
349+
git_and_new_dependencies.into_iter().unzip();
350+
351+
insert_into(dependencies)
352+
.values(&new_dependencies)
353+
.execute(conn)?;
354+
355+
Ok(git_deps)
356+
}
357+
280358
#[cfg(test)]
281359
mod tests {
282360
use super::missing_metadata_error_message;

src/models/dependency.rs

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,9 @@
11
use diesel::deserialize::{self, FromSql};
22
use diesel::pg::Pg;
3-
use diesel::prelude::*;
43
use diesel::sql_types::Integer;
54

6-
use crate::git;
7-
use crate::util::errors::{cargo_err, AppResult};
8-
95
use crate::models::{Crate, Version};
106
use crate::schema::*;
11-
use crate::views::EncodableCrateDependency;
12-
13-
pub const WILDCARD_ERROR_MESSAGE: &str = "wildcard (`*`) dependency constraints are not allowed \
14-
on crates.io. See https://doc.rust-lang.org/cargo/faq.html#can-\
15-
libraries-use--as-a-version-for-their-dependencies for more \
16-
information";
177

188
#[derive(Identifiable, Associations, Debug, Queryable, QueryableByName)]
199
#[belongs_to(Version)]
@@ -62,73 +52,3 @@ impl FromSql<Integer, Pg> for DependencyKind {
6252
}
6353
}
6454
}
65-
66-
pub fn add_dependencies(
67-
conn: &PgConnection,
68-
deps: &[EncodableCrateDependency],
69-
target_version_id: i32,
70-
) -> AppResult<Vec<git::Dependency>> {
71-
use self::dependencies::dsl::*;
72-
use diesel::insert_into;
73-
74-
let git_and_new_dependencies = deps
75-
.iter()
76-
.map(|dep| {
77-
if let Some(registry) = &dep.registry {
78-
if !registry.is_empty() {
79-
return Err(cargo_err(&format_args!("Dependency `{}` is hosted on another registry. Cross-registry dependencies are not permitted on crates.io.", &*dep.name)));
80-
}
81-
}
82-
83-
// Match only identical names to ensure the index always references the original crate name
84-
let krate:Crate = Crate::by_exact_name(&dep.name)
85-
.first(&*conn)
86-
.map_err(|_| cargo_err(&format_args!("no known crate named `{}`", &*dep.name)))?;
87-
if semver::VersionReq::parse(&dep.version_req.0) == semver::VersionReq::parse("*") {
88-
return Err(cargo_err(WILDCARD_ERROR_MESSAGE));
89-
}
90-
91-
// If this dependency has an explicit name in `Cargo.toml` that
92-
// means that the `name` we have listed is actually the package name
93-
// that we're depending on. The `name` listed in the index is the
94-
// Cargo.toml-written-name which is what cargo uses for
95-
// `--extern foo=...`
96-
let (name, package) = match &dep.explicit_name_in_toml {
97-
Some(explicit) => (explicit.to_string(), Some(dep.name.to_string())),
98-
None => (dep.name.to_string(), None),
99-
};
100-
101-
Ok((
102-
git::Dependency {
103-
name,
104-
req: dep.version_req.to_string(),
105-
features: dep.features.iter().map(|s| s.0.to_string()).collect(),
106-
optional: dep.optional,
107-
default_features: dep.default_features,
108-
target: dep.target.clone(),
109-
kind: dep.kind.or(Some(DependencyKind::Normal)),
110-
package,
111-
},
112-
(
113-
version_id.eq(target_version_id),
114-
crate_id.eq(krate.id),
115-
req.eq(dep.version_req.to_string()),
116-
dep.kind.map(|k| kind.eq(k as i32)),
117-
optional.eq(dep.optional),
118-
default_features.eq(dep.default_features),
119-
features.eq(&dep.features),
120-
target.eq(dep.target.as_deref()),
121-
),
122-
))
123-
})
124-
.collect::<Result<Vec<_>, _>>()?;
125-
126-
let (git_deps, new_dependencies): (Vec<_>, Vec<_>) =
127-
git_and_new_dependencies.into_iter().unzip();
128-
129-
insert_into(dependencies)
130-
.values(&new_dependencies)
131-
.execute(conn)?;
132-
133-
Ok(git_deps)
134-
}

src/tests/krate/publish.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ use crate::builders::{CrateBuilder, DependencyBuilder, PublishBuilder};
22
use crate::new_category;
33
use crate::util::{RequestHelper, TestApp};
44
use cargo_registry::controllers::krate::publish::{
5-
missing_metadata_error_message, MISSING_RIGHTS_ERROR_MESSAGE,
5+
missing_metadata_error_message, MISSING_RIGHTS_ERROR_MESSAGE, WILDCARD_ERROR_MESSAGE,
66
};
7-
use cargo_registry::models::dependency::WILDCARD_ERROR_MESSAGE;
87
use cargo_registry::models::krate::MAX_NAME_LENGTH;
98
use cargo_registry::schema::{api_tokens, emails, versions_published_by};
109
use cargo_registry::views::GoodCrate;

0 commit comments

Comments
 (0)