refactor(registry): store index files as btreemaps

This commit is contained in:
daimond113 2024-03-16 22:34:39 +01:00
parent 118174d4ba
commit 7782a7537c
No known key found for this signature in database
GPG key ID: 3A8ECE51328B513C
5 changed files with 39 additions and 51 deletions

View file

@ -1,6 +1,6 @@
[package]
name = "pesde-registry"
version = "0.4.0"
version = "0.5.0"
edition = "2021"
[dependencies]
@ -28,4 +28,3 @@ pretty_env_logger = "0.5.0"
sentry = "0.32.2"
sentry-log = "0.32.2"
sentry-actix = "0.32.2"
chrono = "0.4.34"

View file

@ -1,6 +1,5 @@
use actix_multipart::form::{bytes::Bytes, MultipartForm};
use actix_web::{web, HttpResponse, Responder};
use chrono::Utc;
use flate2::read::GzDecoder;
use log::error;
use reqwest::StatusCode;
@ -80,7 +79,7 @@ pub async fn create_package(
let (scope, name) = manifest.name.parts();
{
let entry = {
let mut index = app_state.index.lock().unwrap();
let config = index.config()?;
@ -103,22 +102,25 @@ pub async fn create_package(
};
}
let success = index.create_package_version(&manifest, &user_id.0)?;
match index.create_package_version(&manifest, &user_id.0)? {
Some(entry) => {
index.commit_and_push(
&format!("Add version {}@{}", manifest.name, manifest.version),
&commit_signature(),
)?;
if !success {
return Ok(HttpResponse::BadRequest().json(errors::ErrorResponse {
error: format!(
"Version {} of {} already exists",
manifest.version, manifest.name
),
}));
entry
}
None => {
return Ok(HttpResponse::BadRequest().json(errors::ErrorResponse {
error: format!(
"Version {} of {} already exists",
manifest.version, manifest.name
),
}));
}
}
index.commit_and_push(
&format!("Add version {}@{}", manifest.name, manifest.version),
&commit_signature(),
)?;
}
};
{
let mut search_writer = app_state.search_writer.lock().unwrap();
@ -135,7 +137,7 @@ pub async fn create_package(
name_field => manifest.name.to_string(),
schema.get_field("version").unwrap() => manifest.version.to_string(),
schema.get_field("description").unwrap() => manifest.description.unwrap_or_default(),
schema.get_field("published_at").unwrap() => DateTime::from_timestamp_secs(Utc::now().timestamp()),
schema.get_field("published_at").unwrap() => DateTime::from_timestamp_secs(entry.published_at.timestamp())
)
).unwrap();
@ -146,7 +148,7 @@ pub async fn create_package(
.s3_bucket
.put_object(
Some(&app_state.s3_credentials),
&*format!("{scope}-{name}-{}.tar.gz", manifest.version),
&format!("{scope}-{name}-{}.tar.gz", manifest.version),
)
.sign(S3_EXPIRY);
@ -173,14 +175,11 @@ pub async fn get_package_version(
Some(package) => {
if version == "latest" {
version = package
.iter()
.max_by(|a, b| a.version.cmp(&b.version))
.last()
.map(|v| v.version.to_string())
.unwrap();
} else {
if !package.iter().any(|v| v.version.to_string() == version) {
return Ok(HttpResponse::NotFound().finish());
}
} else if !package.iter().any(|v| v.version.to_string() == version) {
return Ok(HttpResponse::NotFound().finish());
}
}
None => return Ok(HttpResponse::NotFound().finish()),
@ -191,7 +190,7 @@ pub async fn get_package_version(
.s3_bucket
.get_object(
Some(&app_state.s3_credentials),
&*format!("{scope}-{name}-{version}.tar.gz"),
&format!("{scope}-{name}-{version}.tar.gz"),
)
.sign(S3_EXPIRY);

View file

@ -27,11 +27,11 @@ pub async fn search_packages(
let query = query.query.as_deref().unwrap_or_default().trim();
let query_parser =
tantivy::query::QueryParser::for_index(&searcher.index(), vec![name, description]);
tantivy::query::QueryParser::for_index(searcher.index(), vec![name, description]);
let query = if query.is_empty() {
Box::new(AllQuery)
} else {
query_parser.parse_query(&query)?
query_parser.parse_query(query)?
};
let top_docs: Vec<(DateTime, DocAddress)> = searcher
@ -52,26 +52,20 @@ pub async fn search_packages(
let retrieved_doc = searcher.doc(doc_address).unwrap();
let name: PackageName = retrieved_doc
.get_first(name)
.unwrap()
.as_text()
.unwrap()
.parse()
.and_then(|v| v.as_text())
.and_then(|v| v.parse().ok())
.unwrap();
let version: Version = retrieved_doc
.get_first(version)
.unwrap()
.as_text()
.unwrap()
.parse()
.and_then(|v| v.as_text())
.and_then(|v| v.parse().ok())
.unwrap();
let entry = index
.package(&name)
.unwrap()
.unwrap()
.into_iter()
.find(|v| v.version == version)
.and_then(|v| v.into_iter().find(|v| v.version == version))
.unwrap();
json!({

View file

@ -57,13 +57,13 @@ impl ResponseError for Errors {
match self {
Errors::UserYaml(err) => HttpResponse::BadRequest().json(ErrorResponse {
error: format!("Error parsing YAML file: {}", err.to_string()),
error: format!("Error parsing YAML file: {err}"),
}),
Errors::PackageName(err) => HttpResponse::BadRequest().json(ErrorResponse {
error: format!("Invalid package name: {}", err.to_string()),
error: format!("Invalid package name: {err}"),
}),
Errors::QueryParser(err) => HttpResponse::BadRequest().json(ErrorResponse {
error: format!("Error parsing query: {}", err.to_string()),
error: format!("Error parsing query: {err}"),
}),
_ => HttpResponse::InternalServerError().finish(),
}

View file

@ -141,11 +141,11 @@ fn search_index(index: &GitIndex) -> (IndexReader, IndexWriter) {
let entry = entry.unwrap();
let path = entry.path();
if !path.is_dir() || path.file_name().unwrap() == ".git" {
if !path.is_dir() || path.file_name().is_some_and(|v| v == ".git") {
continue;
}
let scope = path.file_name().unwrap().to_str().unwrap();
let scope = path.file_name().and_then(|v| v.to_str()).unwrap();
for entry in read_dir(&path).unwrap() {
let entry = entry.unwrap();
@ -155,16 +155,12 @@ fn search_index(index: &GitIndex) -> (IndexReader, IndexWriter) {
continue;
}
let package = path.file_name().unwrap().to_str().unwrap();
let package = path.file_name().and_then(|v| v.to_str()).unwrap();
let package_name = PackageName::new(scope, package).unwrap();
let entries: IndexFile =
serde_yaml::from_slice(&std::fs::read(&path).unwrap()).unwrap();
let entry = entries
.iter()
.max_by(|a, b| a.version.cmp(&b.version))
.unwrap()
.clone();
let entry = entries.last().unwrap().clone();
search_writer
.add_document(doc!(