summaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'server/src')
-rw-r--r--server/src/api_model.rs12
-rw-r--r--server/src/db_utils.rs10
-rw-r--r--server/src/main.rs70
-rw-r--r--server/src/tests.rs12
4 files changed, 72 insertions, 32 deletions
diff --git a/server/src/api_model.rs b/server/src/api_model.rs
index b08ad5c..1b0d7b2 100644
--- a/server/src/api_model.rs
+++ b/server/src/api_model.rs
@@ -62,6 +62,10 @@ pub struct Review {
pub state: ReviewState,
#[schema(example = 37.5)]
pub progress: f32,
+ #[schema(example = "r/user/TASK-123456")]
+ pub branch: String,
+ #[schema(example = false)]
+ pub archived: bool,
}
#[derive(Serialize, ToSchema)]
@@ -115,6 +119,10 @@ pub struct Project {
pub title: String,
#[schema(example = "Example project")]
pub description: String,
+ #[schema(example = "ssh://git.example.org/srv/git/")]
+ pub remote: String,
+ #[schema(example = "main")]
+ pub main_branch: String,
pub users: Vec<ProjectUserEntry>,
}
@@ -124,6 +132,10 @@ pub struct ProjectData<'r> {
pub title: Option<&'r str>,
#[schema(example = "Example project")]
pub description: Option<&'r str>,
+ #[schema(example = "ssh://git.example.org/srv/git/")]
+ pub remote: Option<&'r str>,
+ #[schema(example = "main")]
+ pub main_branch: Option<&'r str>,
}
#[derive(Deserialize, Serialize, ToSchema)]
diff --git a/server/src/db_utils.rs b/server/src/db_utils.rs
index e74fd68..b7e1fd5 100644
--- a/server/src/db_utils.rs
+++ b/server/src/db_utils.rs
@@ -92,6 +92,16 @@ where
self
}
+ pub fn ok(&self) -> bool {
+ self.sanity_check();
+
+ return !self
+ .names
+ .as_ref()
+ .expect("BUG: names taken already")
+ .is_empty();
+ }
+
pub fn build(&mut self) -> (String, <DB as HasArguments<'args>>::Arguments) {
self.sanity_check();
diff --git a/server/src/main.rs b/server/src/main.rs
index 596eb5b..88546cb 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -153,7 +153,7 @@ async fn get_project(
.unwrap();
let project = sqlx::query!(
- "SELECT id,title,description FROM projects WHERE id=?",
+ "SELECT id,title,description,remote,main_branch FROM projects WHERE id=?",
projectid
)
.fetch_one(&mut ***db)
@@ -161,6 +161,8 @@ async fn get_project(
id: r.id,
title: r.title,
description: r.description,
+ remote: r.remote,
+ main_branch: r.main_branch,
users,
})
.map_err(|_| NotFound("No such project"))
@@ -189,7 +191,7 @@ async fn project(
#[utoipa::path(
responses(
- (status = 200, description = "Project updated", body = api_model::Project),
+ (status = 200, description = "Project created", body = api_model::Project),
),
security(
("session" = []),
@@ -207,9 +209,11 @@ async fn project_new(
let mut tx = db.begin().await.unwrap();
projectid = sqlx::query!(
- "INSERT INTO projects (title, description) VALUES (?, ?)",
+ "INSERT INTO projects (title, description, remote, main_branch) VALUES (?, ?, ?, ?)",
data.title.unwrap_or("Unnamed"),
- data.description.unwrap_or("")
+ data.description.unwrap_or(""),
+ data.remote.unwrap_or(""),
+ data.main_branch.unwrap_or("main"),
)
.execute(&mut *tx)
.map_ok(|r| r.last_insert_id())
@@ -274,21 +278,24 @@ async fn project_update(
) -> Result<&'static str, Custom<&'static str>> {
project_check_maintainer(&mut db, session, projectid).await?;
- if data.title.is_none() && data.description.is_none() {
- // Nothing to update. Treat as "success".
- } else {
- let mut update_builder: db_utils::UpdateBuilder<sqlx::MySql> =
- db_utils::UpdateBuilder::new();
- update_builder.table("projects");
+ let mut update_builder: db_utils::UpdateBuilder<sqlx::MySql> = db_utils::UpdateBuilder::new();
+ update_builder.table("projects");
- if let Some(title) = &data.title {
- update_builder.set("title", title);
- }
- if let Some(description) = &data.description {
- update_builder.set("description", description);
- }
- update_builder.and_where("id", "=", projectid);
+ if let Some(title) = &data.title {
+ update_builder.set("title", title);
+ }
+ if let Some(description) = &data.description {
+ update_builder.set("description", description);
+ }
+ if let Some(remote) = &data.remote {
+ update_builder.set("remote", remote);
+ }
+ if let Some(main_branch) = &data.main_branch {
+ update_builder.set("main_branch", main_branch);
+ }
+ update_builder.and_where("id", "=", projectid);
+ if update_builder.ok() {
let (query, args) = update_builder.build();
let mut query_builder: sqlx::QueryBuilder<sqlx::MySql> =
@@ -360,22 +367,19 @@ async fn project_user_update(
project_check_maintainer(&mut db, session, projectid).await?;
}
- if data.default_role.is_none() && data.maintainer.is_none() {
- // Nothing to update. Treat as "success".
- } else {
- let mut update_builder: db_utils::UpdateBuilder<sqlx::MySql> =
- db_utils::UpdateBuilder::new();
- update_builder.table("project_users");
+ let mut update_builder: db_utils::UpdateBuilder<sqlx::MySql> = db_utils::UpdateBuilder::new();
+ update_builder.table("project_users");
- if let Some(default_role) = &data.default_role {
- update_builder.set("default_role", u8::from(*default_role));
- }
- if let Some(maintainer) = &data.maintainer {
- update_builder.set("maintainer", maintainer);
- }
- update_builder.and_where("project", "=", projectid);
- update_builder.and_where("user", "=", userid);
+ if let Some(default_role) = &data.default_role {
+ update_builder.set("default_role", u8::from(*default_role));
+ }
+ if let Some(maintainer) = &data.maintainer {
+ update_builder.set("maintainer", maintainer);
+ }
+ update_builder.and_where("project", "=", projectid);
+ update_builder.and_where("user", "=", userid);
+ if update_builder.ok() {
let (query, args) = update_builder.build();
let mut query_builder: sqlx::QueryBuilder<sqlx::MySql> =
@@ -497,7 +501,7 @@ async fn review(
let mut projectid = 0;
let mut review = sqlx::query!(
- "SELECT reviews.id AS id,project,title,description,state,progress,users.id AS user_id,users.username AS username,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE reviews.id=?",
+ "SELECT reviews.id AS id,project,title,description,state,progress,branch,archived,users.id AS user_id,users.username AS username,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE reviews.id=?",
reviewid)
.fetch_one(&mut **db)
.map_ok(|r| {
@@ -516,6 +520,8 @@ async fn review(
users: Vec::new(),
state: api_model::ReviewState::try_from(r.state).unwrap(),
progress: r.progress,
+ branch: r.branch,
+ archived: r.archived != 0,
}
})
.map_err(|_| NotFound("No such review"))
diff --git a/server/src/tests.rs b/server/src/tests.rs
index a658c33..ca7217b 100644
--- a/server/src/tests.rs
+++ b/server/src/tests.rs
@@ -184,6 +184,8 @@ async fn new_project(client: &Client) -> api_model::Project {
.json(&api_model::ProjectData {
title: Some("foo"),
description: Some("bar"),
+ remote: Some("fum"),
+ main_branch: Some("zod"),
}),
)
.await
@@ -281,6 +283,8 @@ async fn test_project_new() {
assert_eq!(project.title, "foo");
assert_eq!(project.description, "bar");
+ assert_eq!(project.remote, "fum");
+ assert_eq!(project.main_branch, "zod");
assert_eq!(project.users.len(), 1);
let user = project.users.get(0).unwrap();
assert_eq!(user.user.username, "user");
@@ -309,6 +313,8 @@ async fn test_project_update() {
&api_model::ProjectData {
title: Some("foo"),
description: None,
+ remote: Some("fum"),
+ main_branch: None,
},
))
.await;
@@ -320,6 +326,8 @@ async fn test_project_update() {
.json(&api_model::ProjectData {
title: None,
description: Some("bar"),
+ remote: None,
+ main_branch: Some("zod"),
})
.header(&FAKE_IP)
.dispatch()
@@ -329,6 +337,8 @@ async fn test_project_update() {
let updated_project = get_project_from(client.get(project_url)).await;
assert_eq!(updated_project.title, project.title);
assert_eq!(updated_project.description, "bar");
+ assert_eq!(updated_project.remote, project.remote);
+ assert_eq!(updated_project.main_branch, "zod");
}
#[rocket::async_test]
@@ -453,6 +463,8 @@ async fn test_project_check_maintainer() {
.json(&api_model::ProjectData {
title: None,
description: Some("fool"),
+ remote: None,
+ main_branch: None,
})
.header(&FAKE_IP)
.dispatch()