mirror of
https://github.com/pesde-pkg/pesde.git
synced 2025-04-05 19:30:57 +01:00
refactor(registry): ⚡ store index files as btreemaps
This commit is contained in:
parent
118174d4ba
commit
7782a7537c
5 changed files with 39 additions and 51 deletions
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "pesde-registry"
|
name = "pesde-registry"
|
||||||
version = "0.4.0"
|
version = "0.5.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -28,4 +28,3 @@ pretty_env_logger = "0.5.0"
|
||||||
sentry = "0.32.2"
|
sentry = "0.32.2"
|
||||||
sentry-log = "0.32.2"
|
sentry-log = "0.32.2"
|
||||||
sentry-actix = "0.32.2"
|
sentry-actix = "0.32.2"
|
||||||
chrono = "0.4.34"
|
|
|
@ -1,6 +1,5 @@
|
||||||
use actix_multipart::form::{bytes::Bytes, MultipartForm};
|
use actix_multipart::form::{bytes::Bytes, MultipartForm};
|
||||||
use actix_web::{web, HttpResponse, Responder};
|
use actix_web::{web, HttpResponse, Responder};
|
||||||
use chrono::Utc;
|
|
||||||
use flate2::read::GzDecoder;
|
use flate2::read::GzDecoder;
|
||||||
use log::error;
|
use log::error;
|
||||||
use reqwest::StatusCode;
|
use reqwest::StatusCode;
|
||||||
|
@ -80,7 +79,7 @@ pub async fn create_package(
|
||||||
|
|
||||||
let (scope, name) = manifest.name.parts();
|
let (scope, name) = manifest.name.parts();
|
||||||
|
|
||||||
{
|
let entry = {
|
||||||
let mut index = app_state.index.lock().unwrap();
|
let mut index = app_state.index.lock().unwrap();
|
||||||
let config = index.config()?;
|
let config = index.config()?;
|
||||||
|
|
||||||
|
@ -103,9 +102,16 @@ 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 {
|
entry
|
||||||
|
}
|
||||||
|
None => {
|
||||||
return Ok(HttpResponse::BadRequest().json(errors::ErrorResponse {
|
return Ok(HttpResponse::BadRequest().json(errors::ErrorResponse {
|
||||||
error: format!(
|
error: format!(
|
||||||
"Version {} of {} already exists",
|
"Version {} of {} already exists",
|
||||||
|
@ -113,12 +119,8 @@ pub async fn create_package(
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
index.commit_and_push(
|
|
||||||
&format!("Add version {}@{}", manifest.name, manifest.version),
|
|
||||||
&commit_signature(),
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut search_writer = app_state.search_writer.lock().unwrap();
|
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(),
|
name_field => manifest.name.to_string(),
|
||||||
schema.get_field("version").unwrap() => manifest.version.to_string(),
|
schema.get_field("version").unwrap() => manifest.version.to_string(),
|
||||||
schema.get_field("description").unwrap() => manifest.description.unwrap_or_default(),
|
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();
|
).unwrap();
|
||||||
|
|
||||||
|
@ -146,7 +148,7 @@ pub async fn create_package(
|
||||||
.s3_bucket
|
.s3_bucket
|
||||||
.put_object(
|
.put_object(
|
||||||
Some(&app_state.s3_credentials),
|
Some(&app_state.s3_credentials),
|
||||||
&*format!("{scope}-{name}-{}.tar.gz", manifest.version),
|
&format!("{scope}-{name}-{}.tar.gz", manifest.version),
|
||||||
)
|
)
|
||||||
.sign(S3_EXPIRY);
|
.sign(S3_EXPIRY);
|
||||||
|
|
||||||
|
@ -173,16 +175,13 @@ pub async fn get_package_version(
|
||||||
Some(package) => {
|
Some(package) => {
|
||||||
if version == "latest" {
|
if version == "latest" {
|
||||||
version = package
|
version = package
|
||||||
.iter()
|
.last()
|
||||||
.max_by(|a, b| a.version.cmp(&b.version))
|
|
||||||
.map(|v| v.version.to_string())
|
.map(|v| v.version.to_string())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
} else {
|
} else if !package.iter().any(|v| v.version.to_string() == version) {
|
||||||
if !package.iter().any(|v| v.version.to_string() == version) {
|
|
||||||
return Ok(HttpResponse::NotFound().finish());
|
return Ok(HttpResponse::NotFound().finish());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
None => return Ok(HttpResponse::NotFound().finish()),
|
None => return Ok(HttpResponse::NotFound().finish()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +190,7 @@ pub async fn get_package_version(
|
||||||
.s3_bucket
|
.s3_bucket
|
||||||
.get_object(
|
.get_object(
|
||||||
Some(&app_state.s3_credentials),
|
Some(&app_state.s3_credentials),
|
||||||
&*format!("{scope}-{name}-{version}.tar.gz"),
|
&format!("{scope}-{name}-{version}.tar.gz"),
|
||||||
)
|
)
|
||||||
.sign(S3_EXPIRY);
|
.sign(S3_EXPIRY);
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,11 @@ pub async fn search_packages(
|
||||||
let query = query.query.as_deref().unwrap_or_default().trim();
|
let query = query.query.as_deref().unwrap_or_default().trim();
|
||||||
|
|
||||||
let query_parser =
|
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() {
|
let query = if query.is_empty() {
|
||||||
Box::new(AllQuery)
|
Box::new(AllQuery)
|
||||||
} else {
|
} else {
|
||||||
query_parser.parse_query(&query)?
|
query_parser.parse_query(query)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let top_docs: Vec<(DateTime, DocAddress)> = searcher
|
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 retrieved_doc = searcher.doc(doc_address).unwrap();
|
||||||
let name: PackageName = retrieved_doc
|
let name: PackageName = retrieved_doc
|
||||||
.get_first(name)
|
.get_first(name)
|
||||||
.unwrap()
|
.and_then(|v| v.as_text())
|
||||||
.as_text()
|
.and_then(|v| v.parse().ok())
|
||||||
.unwrap()
|
|
||||||
.parse()
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let version: Version = retrieved_doc
|
let version: Version = retrieved_doc
|
||||||
.get_first(version)
|
.get_first(version)
|
||||||
.unwrap()
|
.and_then(|v| v.as_text())
|
||||||
.as_text()
|
.and_then(|v| v.parse().ok())
|
||||||
.unwrap()
|
|
||||||
.parse()
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let entry = index
|
let entry = index
|
||||||
.package(&name)
|
.package(&name)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap()
|
.and_then(|v| v.into_iter().find(|v| v.version == version))
|
||||||
.into_iter()
|
|
||||||
.find(|v| v.version == version)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
json!({
|
json!({
|
||||||
|
|
|
@ -57,13 +57,13 @@ impl ResponseError for Errors {
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Errors::UserYaml(err) => HttpResponse::BadRequest().json(ErrorResponse {
|
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 {
|
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 {
|
Errors::QueryParser(err) => HttpResponse::BadRequest().json(ErrorResponse {
|
||||||
error: format!("Error parsing query: {}", err.to_string()),
|
error: format!("Error parsing query: {err}"),
|
||||||
}),
|
}),
|
||||||
_ => HttpResponse::InternalServerError().finish(),
|
_ => HttpResponse::InternalServerError().finish(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,11 +141,11 @@ fn search_index(index: &GitIndex) -> (IndexReader, IndexWriter) {
|
||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
let path = entry.path();
|
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;
|
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() {
|
for entry in read_dir(&path).unwrap() {
|
||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
|
@ -155,16 +155,12 @@ fn search_index(index: &GitIndex) -> (IndexReader, IndexWriter) {
|
||||||
continue;
|
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 package_name = PackageName::new(scope, package).unwrap();
|
||||||
let entries: IndexFile =
|
let entries: IndexFile =
|
||||||
serde_yaml::from_slice(&std::fs::read(&path).unwrap()).unwrap();
|
serde_yaml::from_slice(&std::fs::read(&path).unwrap()).unwrap();
|
||||||
let entry = entries
|
let entry = entries.last().unwrap().clone();
|
||||||
.iter()
|
|
||||||
.max_by(|a, b| a.version.cmp(&b.version))
|
|
||||||
.unwrap()
|
|
||||||
.clone();
|
|
||||||
|
|
||||||
search_writer
|
search_writer
|
||||||
.add_document(doc!(
|
.add_document(doc!(
|
||||||
|
|
Loading…
Add table
Reference in a new issue