diff --git a/app/components/crate-header.hbs b/app/components/crate-header.hbs index 81d8e23d504..4e0ab00d868 100644 --- a/app/components/crate-header.hbs +++ b/app/components/crate-header.hbs @@ -54,7 +54,7 @@ - {{pluralize @crate.versions.length "Version"}} + {{pluralize @crate.num_versions "Version"}} - All {{ this.model.versions.length }} + All {{ this.model.num_versions }} versions of {{ this.model.name }} since {{date-format this.model.created_at 'PPP'}} diff --git a/packages/crates-io-msw/handlers/crates/get.test.js b/packages/crates-io-msw/handlers/crates/get.test.js index 9fed9f1a89b..c3b2a51ef09 100644 --- a/packages/crates-io-msw/handlers/crates/get.test.js +++ b/packages/crates-io-msw/handlers/crates/get.test.js @@ -38,6 +38,7 @@ test('returns a crate object for known crates', async function () { max_stable_version: null, name: 'rand', newest_version: '1.0.0-beta.1', + num_versions: 1, repository: null, recent_downloads: 321, updated_at: '2017-02-24T12:34:56Z', @@ -101,6 +102,7 @@ test('works for non-canonical names', async function () { max_stable_version: null, name: 'foo-bar', newest_version: '1.0.0-beta.1', + num_versions: 1, repository: null, recent_downloads: 321, updated_at: '2017-02-24T12:34:56Z', diff --git a/packages/crates-io-msw/handlers/crates/list.test.js b/packages/crates-io-msw/handlers/crates/list.test.js index c63ba8119f8..dcafbf659a4 100644 --- a/packages/crates-io-msw/handlers/crates/list.test.js +++ b/packages/crates-io-msw/handlers/crates/list.test.js @@ -55,6 +55,7 @@ test('returns a paginated crates list', async function () { max_stable_version: '1.0.0', name: 'rand', newest_version: '2.0.0-beta.1', + num_versions: 2, repository: null, recent_downloads: 321, updated_at: '2017-02-24T12:34:56Z', diff --git a/packages/crates-io-msw/handlers/summary.test.js b/packages/crates-io-msw/handlers/summary.test.js index 806a74e6994..a918470d167 100644 --- a/packages/crates-io-msw/handlers/summary.test.js +++ b/packages/crates-io-msw/handlers/summary.test.js @@ -51,6 +51,7 @@ test('returns the data for the front page', async function () { max_stable_version: '1.0.0', name: 'crate-1', newest_version: '1.0.0', + num_versions: 1, recent_downloads: 321, repository: null, updated_at: '2017-02-24T12:34:56Z', @@ -81,6 +82,7 @@ test('returns the data for the front page', async function () { max_stable_version: '1.0.3', name: 'crate-4', newest_version: '1.0.3', + num_versions: 1, repository: null, recent_downloads: 963, updated_at: '2017-02-24T12:34:56Z', @@ -111,6 +113,7 @@ test('returns the data for the front page', async function () { max_stable_version: '1.0.10', name: 'crate-11', newest_version: '1.0.10', + num_versions: 1, repository: null, recent_downloads: 3852, updated_at: '2017-02-24T12:34:56Z', @@ -141,6 +144,7 @@ test('returns the data for the front page', async function () { max_stable_version: '1.0.19', name: 'crate-20', newest_version: '1.0.19', + num_versions: 1, repository: null, recent_downloads: 1605, updated_at: '2017-02-24T12:34:56Z', diff --git a/packages/crates-io-msw/serializers/crate.js b/packages/crates-io-msw/serializers/crate.js index d6004e5a5df..5b21db89192 100644 --- a/packages/crates-io-msw/serializers/crate.js +++ b/packages/crates-io-msw/serializers/crate.js @@ -27,6 +27,8 @@ export function serializeCrate( versionNums.find(it => !versionsByNum[it].yanked) ?? versionNums[0]; + serialized.num_versions = versions.length; + serialized.yanked = versionsByNum[serialized.default_version]?.yanked ?? false; serialized.links = { diff --git a/src/controllers/krate/metadata.rs b/src/controllers/krate/metadata.rs index d259a5fea94..9f77a9347ae 100644 --- a/src/controllers/krate/metadata.rs +++ b/src/controllers/krate/metadata.rs @@ -75,21 +75,27 @@ pub async fn find_crate( .transpose()? .unwrap_or_default(); - let (krate, downloads, default_version, yanked): (Crate, i64, Option, Option) = - Crate::by_name(&path.name) - .inner_join(crate_downloads::table) - .left_join(default_versions::table) - .left_join(versions::table.on(default_versions::version_id.eq(versions::id))) - .select(( - Crate::as_select(), - crate_downloads::downloads, - versions::num.nullable(), - versions::yanked.nullable(), - )) - .first(&mut conn) - .await - .optional()? - .ok_or_else(|| crate_not_found(&path.name))?; + let (krate, downloads, default_version, yanked, num_versions): ( + Crate, + i64, + Option, + Option, + Option, + ) = Crate::by_name(&path.name) + .inner_join(crate_downloads::table) + .left_join(default_versions::table) + .left_join(versions::table.on(default_versions::version_id.eq(versions::id))) + .select(( + Crate::as_select(), + crate_downloads::downloads, + versions::num.nullable(), + versions::yanked.nullable(), + default_versions::num_versions.nullable(), + )) + .first(&mut conn) + .await + .optional()? + .ok_or_else(|| crate_not_found(&path.name))?; let mut versions_publishers_and_audit_actions = if include.versions { let versions_and_publishers: Vec<(Version, Option)> = Version::belonging_to(&krate) @@ -183,6 +189,7 @@ pub async fn find_crate( let encodable_crate = EncodableCrate::from( krate.clone(), default_version.as_deref(), + num_versions.unwrap_or_default(), yanked, top_versions.as_ref(), ids, diff --git a/src/controllers/krate/publish.rs b/src/controllers/krate/publish.rs index 0decc4d9b6b..26f4f7a9df2 100644 --- a/src/controllers/krate/publish.rs +++ b/src/controllers/krate/publish.rs @@ -436,11 +436,12 @@ pub async fn publish(app: AppState, req: Parts, body: Body) -> AppResult)>(conn) .await .optional()?; + let num_versions = existing_default_version.as_ref().and_then(|t|t.1).unwrap_or_default(); let mut default_version = None; // Upsert the `default_value` determined by the existing `default_value` and the // published version. Note that this could potentially write an outdated version @@ -450,7 +451,7 @@ pub async fn publish(app: AppState, req: Parts, body: Body) -> AppResult AppResult(), versions::num.nullable(), versions::yanked.nullable(), + default_versions::num_versions.nullable(), ); let mut seek: Option = None; @@ -113,6 +114,7 @@ pub async fn list_crates( rank, versions::num.nullable(), versions::yanked.nullable(), + default_versions::num_versions.nullable(), )); seek = Some(Seek::Relevance); query = query.then_order_by(rank.desc()) @@ -125,6 +127,7 @@ pub async fn list_crates( 0_f32.into_sql::(), versions::num.nullable(), versions::yanked.nullable(), + default_versions::num_versions.nullable(), )); seek = Some(Seek::Query); } @@ -227,6 +230,7 @@ pub async fn list_crates( EncodableCrate::from_minimal( record.krate, record.default_version.as_deref(), + record.num_versions.unwrap_or_default(), record.yanked, Some(&max_version), record.exact_match, @@ -704,6 +708,7 @@ struct Record { rank: f32, default_version: Option, yanked: Option, + num_versions: Option, } type QuerySource = LeftJoinQuerySource< diff --git a/src/controllers/summary.rs b/src/controllers/summary.rs index 30fa196c3c1..7dd2694a92d 100644 --- a/src/controllers/summary.rs +++ b/src/controllers/summary.rs @@ -135,6 +135,8 @@ struct Record { default_version: Option, #[diesel(select_expression = versions::columns::yanked.nullable())] yanked: Option, + #[diesel(select_expression = default_versions::columns::num_versions.nullable())] + num_versions: Option, } fn encode_crates( @@ -165,6 +167,7 @@ fn encode_crates( Ok(EncodableCrate::from_minimal( record.krate, record.default_version.as_deref(), + record.num_versions.unwrap_or_default(), record.yanked, Some(&top_versions), false, diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate.snap index 0365b6ccfa3..28cb4db0450 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo_new", "newest_version": "1.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice.snap index d959bcaa0fb..501d39ee175 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "2.0.0", "name": "foo_twice", "newest_version": "2.0.0", + "num_versions": 2, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice_alt.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice_alt.snap index faf28612baf..06a5033f589 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice_alt.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_twice_alt.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "2.0.0", "name": "foo_twice", "newest_version": "0.99.0", + "num_versions": 2, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_weird_version.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_weird_version.snap index ef9e159a689..72ade9bb92e 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_weird_version.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_weird_version.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "0.0.0-pre", "name": "foo_weird", "newest_version": "0.0.0-pre", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_with_token.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_with_token.snap index 0365b6ccfa3..28cb4db0450 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_with_token.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__basics__new_krate_with_token.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo_new", "newest_version": "1.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_1.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_1.snap index d13d9369710..41b3c2f3247 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_1.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_1.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0+foo", "name": "foo", "newest_version": "1.0.0+foo", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_2.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_2.snap index b1c0ebc2b4c..c4b64395e8e 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_2.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_2.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0-beta.1", "name": "foo", "newest_version": "1.0.0-beta.1", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_3.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_3.snap index d13d9369710..41b3c2f3247 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_3.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__build_metadata__version_with_build_metadata@build_metadata_3.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0+foo", "name": "foo", "newest_version": "1.0.0+foo", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__categories__good_categories.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__categories__good_categories.snap index 165c2ab3786..26be0235fbd 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__categories__good_categories.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__categories__good_categories.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo_good_cat", "newest_version": "1.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__dependencies__dep_limit-2.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__dependencies__dep_limit-2.snap index 6c3a975825c..469fe526ce4 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__dependencies__dep_limit-2.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__dependencies__dep_limit-2.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo", "newest_version": "1.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__edition__edition_is_saved.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__edition__edition_is_saved.snap index 94b597a6f4b..7a884ebe94e 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__edition__edition_is_saved.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__edition__edition_is_saved.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo", "newest_version": "1.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__keywords__good_keywords.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__keywords__good_keywords.snap index d05f0cba378..88d74b8c9d9 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__keywords__good_keywords.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__keywords__good_keywords.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo_good_key", "newest_version": "1.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__links__crate_with_links_field.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__links__crate_with_links_field.snap index 0456f01fb9e..07e0cfe632c 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__links__crate_with_links_field.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__links__crate_with_links_field.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo", "newest_version": "1.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__boolean_readme.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__boolean_readme.snap index 7782eadcd2e..c0787b7c239 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__boolean_readme.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__boolean_readme.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo", "newest_version": "1.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__lib_and_bin_crate.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__lib_and_bin_crate.snap index 7782eadcd2e..c0787b7c239 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__lib_and_bin_crate.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__manifest__lib_and_bin_crate.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo", "newest_version": "1.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__max_size__tarball_between_default_axum_limit_and_max_upload_size.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__max_size__tarball_between_default_axum_limit_and_max_upload_size.snap index bdf0b47ea19..c2acc59eeb3 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__max_size__tarball_between_default_axum_limit_and_max_upload_size.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__max_size__tarball_between_default_axum_limit_and_max_upload_size.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.1.0", "name": "foo", "newest_version": "1.1.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_empty_readme.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_empty_readme.snap index 961fbe387de..1b92337edd3 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_empty_readme.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_empty_readme.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo_readme", "newest_version": "1.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme.snap index 961fbe387de..1b92337edd3 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo_readme", "newest_version": "1.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme_and_plus_version.snap b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme_and_plus_version.snap index b18206501b0..85f7ef58068 100644 --- a/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme_and_plus_version.snap +++ b/src/tests/krate/publish/snapshots/crates_io__tests__krate__publish__readme__new_krate_with_readme_and_plus_version.snap @@ -27,6 +27,7 @@ expression: response.json() "max_version": "1.0.0+foo", "name": "foo_readme", "newest_version": "1.0.0+foo", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__include_default_version.snap b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__include_default_version.snap index 11f3d480479..c7b079c37a4 100644 --- a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__include_default_version.snap +++ b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__include_default_version.snap @@ -28,6 +28,7 @@ expression: response.json() "max_version": "0.0.0", "name": "foo_default_version", "newest_version": "0.0.0", + "num_versions": 3, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__new_name.snap b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__new_name.snap index 026be79f9c0..991a1909f2c 100644 --- a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__new_name.snap +++ b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__new_name.snap @@ -28,6 +28,7 @@ expression: response.json() "max_version": "0.0.0", "name": "new", "newest_version": "0.0.0", + "num_versions": 1, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show.snap b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show.snap index dd145a4139f..75c2cd698be 100644 --- a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show.snap +++ b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show.snap @@ -30,6 +30,7 @@ expression: response.json() "max_version": "1.0.0", "name": "foo_show", "newest_version": "0.5.1", + "num_versions": 3, "recent_downloads": 10, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_all_yanked.snap b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_all_yanked.snap index fcd31e61706..30269ad6920 100644 --- a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_all_yanked.snap +++ b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_all_yanked.snap @@ -30,6 +30,7 @@ expression: response.json() "max_version": "0.0.0", "name": "foo_show", "newest_version": "0.0.0", + "num_versions": 2, "recent_downloads": 10, "repository": null, "updated_at": "[datetime]", diff --git a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_minimal.snap b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_minimal.snap index a040d208028..d1480ec96ef 100644 --- a/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_minimal.snap +++ b/src/tests/routes/crates/snapshots/crates_io__tests__routes__crates__read__show_minimal.snap @@ -28,6 +28,7 @@ expression: response.json() "max_version": "0.0.0", "name": "foo_show_minimal", "newest_version": "0.0.0", + "num_versions": 3, "recent_downloads": null, "repository": null, "updated_at": "[datetime]", diff --git a/src/views.rs b/src/views.rs index 72492d664d3..b7503739db0 100644 --- a/src/views.rs +++ b/src/views.rs @@ -207,6 +207,7 @@ pub struct EncodableCrate { pub downloads: i64, pub recent_downloads: Option, pub default_version: Option, + pub num_versions: i32, pub yanked: bool, // NOTE: Used by shields.io, altering `max_version` requires a PR with shields.io pub max_version: String, @@ -225,6 +226,7 @@ impl EncodableCrate { pub fn from( krate: Crate, default_version: Option<&str>, + num_versions: i32, yanked: Option, top_versions: Option<&TopVersions>, versions: Option>, @@ -297,6 +299,7 @@ impl EncodableCrate { categories: category_ids, badges: [], default_version, + num_versions, yanked, max_version, newest_version, @@ -317,9 +320,11 @@ impl EncodableCrate { } } + #[allow(clippy::too_many_arguments)] pub fn from_minimal( krate: Crate, default_version: Option<&str>, + num_versions: i32, yanked: Option, top_versions: Option<&TopVersions>, exact_match: bool, @@ -329,6 +334,7 @@ impl EncodableCrate { Self::from( krate, default_version, + num_versions, yanked, top_versions, None, @@ -823,6 +829,7 @@ mod tests { downloads: 0, recent_downloads: None, default_version: None, + num_versions: 0, yanked: false, max_version: "".to_string(), newest_version: "".to_string(),