feat(registry): package versions endpoint

This commit is contained in:
daimond113 2024-03-10 19:02:33 +01:00
parent d20fb4aee3
commit f2758c6351
No known key found for this signature in database
GPG key ID: 3A8ECE51328B513C
3 changed files with 54 additions and 5 deletions

View file

@ -1,6 +1,6 @@
[package]
name = "pesde-registry"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
[dependencies]

View file

@ -1,6 +1,7 @@
use actix_multipart::form::{bytes::Bytes, MultipartForm};
use actix_web::{web, HttpResponse, Responder};
use flate2::read::GzDecoder;
use log::error;
use reqwest::StatusCode;
use rusty_s3::S3Action;
use tantivy::{doc, Term};
@ -159,15 +160,28 @@ pub async fn get_package_version(
app_state: web::Data<AppState>,
path: web::Path<(String, String, String)>,
) -> Result<impl Responder, errors::Errors> {
let (scope, name, version) = path.into_inner();
let (scope, name, mut version) = path.into_inner();
let package_name = PackageName::new(&scope, &name)?;
{
let index = app_state.index.lock().unwrap();
if !index.package(&package_name)?.is_some() {
return Ok(HttpResponse::NotFound().finish());
match index.package(&package_name)? {
Some(package) => {
if version == "latest" {
version = package
.iter()
.max_by(|a, b| a.version.cmp(&b.version))
.map(|v| v.version.to_string())
.unwrap();
} else {
if !package.iter().any(|v| v.version.to_string() == version) {
return Ok(HttpResponse::NotFound().finish());
}
}
}
None => return Ok(HttpResponse::NotFound().finish()),
}
}
@ -190,7 +204,11 @@ pub async fn get_package_version(
Err(e) => {
if let Some(status) = e.status() {
if status == StatusCode::NOT_FOUND {
return Ok(HttpResponse::NotFound().finish());
error!(
"package {}@{} not found in S3, but found in index",
package_name, version
);
return Ok(HttpResponse::InternalServerError().finish());
}
}
@ -200,3 +218,28 @@ pub async fn get_package_version(
Ok(HttpResponse::Ok().body(response.bytes().await?))
}
pub async fn get_package_versions(
app_state: web::Data<AppState>,
path: web::Path<(String, String)>,
) -> Result<impl Responder, errors::Errors> {
let (scope, name) = path.into_inner();
let package_name = PackageName::new(&scope, &name)?;
{
let index = app_state.index.lock().unwrap();
match index.package(&package_name)? {
Some(package) => {
let versions = package
.iter()
.map(|v| v.version.to_string())
.collect::<Vec<String>>();
Ok(HttpResponse::Ok().json(versions))
}
None => Ok(HttpResponse::NotFound().finish()),
}
}
}

View file

@ -292,6 +292,12 @@ fn main() -> std::io::Result<()> {
.to(endpoints::search::search_packages)
.wrap(Governor::new(&generic_governor_config)),
)
.route(
"/packages/{scope}/{name}/versions",
web::get()
.to(endpoints::packages::get_package_versions)
.wrap(Governor::new(&generic_governor_config)),
)
.route(
"/packages/{scope}/{name}/{version}",
web::get()