WIP: catchup with F3 schema v1.0 #1
15 changed files with 1490 additions and 40 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "f3-schemas"]
|
||||||
|
path = f3-schemas
|
||||||
|
url = https://lab.forgefriends.org/friendlyforgeformat/f3-schemas
|
|
@ -1,12 +1,18 @@
|
||||||
pipeline:
|
steps:
|
||||||
backend:
|
test:
|
||||||
image: rust
|
image: rust
|
||||||
commands:
|
commands:
|
||||||
- apt update && apt-get -y --no-install-recommends install tar gpg curl wget git
|
|
||||||
- rustup component add rustfmt
|
- rustup component add rustfmt
|
||||||
- rustup component add clippy
|
- rustup component add clippy
|
||||||
- make lint
|
- make lint
|
||||||
- make test
|
- make test
|
||||||
- make doc
|
- make doc
|
||||||
|
publish:
|
||||||
|
image: python
|
||||||
|
when:
|
||||||
|
event: [push, tag, deployment]
|
||||||
|
branch: master
|
||||||
|
commands:
|
||||||
|
- apt update && apt-get -y --no-install-recommends install tar gpg curl wget git
|
||||||
- make ci-deploy
|
- make ci-deploy
|
||||||
secrets: [ GITEA_WRITE_DEPLOY_KEY, LIBREPAGES_DEPLOY_SECRET ]
|
secrets: [ GITEA_WRITE_DEPLOY_KEY, LIBREPAGES_DEPLOY_SECRET ]
|
||||||
|
|
1315
Cargo.lock
generated
1315
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -14,3 +14,6 @@ authors = ["realaravinth <realaravinth@batsense.net>"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0.152", features = ["derive"] }
|
serde = { version = "1.0.152", features = ["derive"] }
|
||||||
serde_json = "1.0.91"
|
serde_json = "1.0.91"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
jsonschema = "0.17.1"
|
||||||
|
|
1
f3-schemas
Submodule
1
f3-schemas
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 12240cef49703c2e62ba5a6b4a4f98b3053ba365
|
|
@ -22,16 +22,16 @@ use crate::Reaction;
|
||||||
|
|
||||||
/// Comments associated to an issue or a pull/merge request within the repository of a forge
|
/// Comments associated to an issue or a pull/merge request within the repository of a forge
|
||||||
/// (Gitea, GitLab, etc.)
|
/// (Gitea, GitLab, etc.)
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, Serialize, Deserialize, Eq, PartialEq)]
|
||||||
pub struct Comment {
|
pub struct Comment {
|
||||||
/// Unique identifier of the issue or pull/merge request containing the comment
|
/// Unique identifier of the issue or pull/merge request containing the comment
|
||||||
pub issue_index: usize,
|
pub issue_index: usize,
|
||||||
|
|
||||||
/// Unique identifier of the comment
|
/// Unique identifier of the comment
|
||||||
pub index: usize,
|
pub index: String,
|
||||||
|
|
||||||
/// Unique identifier of the user who authored the comment
|
/// Unique identifier of the user who authored the comment
|
||||||
pub poster_id: usize,
|
pub poster_id: String,
|
||||||
|
|
||||||
// TODO: add validation for format "date-time"
|
// TODO: add validation for format "date-time"
|
||||||
/// Creating time
|
/// Creating time
|
||||||
|
|
|
@ -23,10 +23,10 @@ use crate::{OpenCloseState, Reaction};
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
||||||
pub struct Issue {
|
pub struct Issue {
|
||||||
/// Unique identifier, relative to the repository
|
/// Unique identifier, relative to the repository
|
||||||
pub index: usize,
|
pub index: String,
|
||||||
|
|
||||||
/// Unique identifier of the user who authored the issue.
|
/// Unique identifier of the user who authored the issue.
|
||||||
pub poster_id: usize,
|
pub poster_id: String,
|
||||||
|
|
||||||
/// Short description displayed as the title.
|
/// Short description displayed as the title.
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
@ -40,10 +40,10 @@ pub struct Issue {
|
||||||
/// "reference". However, "reference" will automatically be renamed to "ref" while serializing
|
/// "reference". However, "reference" will automatically be renamed to "ref" while serializing
|
||||||
/// and vice versa
|
/// and vice versa
|
||||||
#[serde(rename(serialize = "ref", deserialize = "ref"))]
|
#[serde(rename(serialize = "ref", deserialize = "ref"))]
|
||||||
pub reference: Option<String>,
|
pub reference: String,
|
||||||
|
|
||||||
/// Name of the milestone
|
/// Name of the milestone
|
||||||
pub milestone: Option<String>,
|
pub milestone: String,
|
||||||
|
|
||||||
/// state of the issue
|
/// state of the issue
|
||||||
pub state: OpenCloseState,
|
pub state: OpenCloseState,
|
||||||
|
|
|
@ -22,7 +22,7 @@ use serde::{Deserialize, Serialize};
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
||||||
pub struct Label {
|
pub struct Label {
|
||||||
/// Unique identifier of the label
|
/// Unique identifier of the label
|
||||||
pub index: usize,
|
pub index: String,
|
||||||
|
|
||||||
/// Name of the label, unique within the repository
|
/// Name of the label, unique within the repository
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
@ -31,5 +31,5 @@ pub struct Label {
|
||||||
pub color: String,
|
pub color: String,
|
||||||
|
|
||||||
/// Long, multi-line description
|
/// Long, multi-line description
|
||||||
pub description: Option<String>,
|
pub description: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ pub mod identities;
|
||||||
pub mod issue;
|
pub mod issue;
|
||||||
pub mod label;
|
pub mod label;
|
||||||
pub mod milestone;
|
pub mod milestone;
|
||||||
|
pub mod object;
|
||||||
|
pub mod organization;
|
||||||
pub mod project;
|
pub mod project;
|
||||||
pub mod pullrequest;
|
pub mod pullrequest;
|
||||||
pub mod reaction;
|
pub mod reaction;
|
||||||
|
@ -39,6 +41,8 @@ pub use identities::Identities;
|
||||||
pub use issue::Issue;
|
pub use issue::Issue;
|
||||||
pub use label::Label;
|
pub use label::Label;
|
||||||
pub use milestone::Milestone;
|
pub use milestone::Milestone;
|
||||||
|
pub use object::Object;
|
||||||
|
pub use organization::Organization;
|
||||||
pub use project::Project;
|
pub use project::Project;
|
||||||
pub use pullrequest::PullRequest;
|
pub use pullrequest::PullRequest;
|
||||||
pub use reaction::Reaction;
|
pub use reaction::Reaction;
|
||||||
|
|
34
src/object.rs
Normal file
34
src/object.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
//! Meta information and reference to an opaque content such as an image. The unique identifier is the SHA-256 of the content of the object.
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Meta information and reference to an opaque content such as an image. The unique identifier is the SHA-256 of the content of the object.
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
||||||
|
pub struct Object {
|
||||||
|
/// Unique identifier
|
||||||
|
pub index: String,
|
||||||
|
|
||||||
|
/// Human readable file name.
|
||||||
|
pub name: String,
|
||||||
|
|
||||||
|
/// Mime type of the object.
|
||||||
|
pub mime: String,
|
||||||
|
|
||||||
|
/// Description
|
||||||
|
pub description: String,
|
||||||
|
}
|
28
src/organization.rs
Normal file
28
src/organization.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
//! An organization that contains projects.
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// An organization that contains projects.
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
||||||
|
pub struct Organization {
|
||||||
|
/// Unique identifier of the organization
|
||||||
|
pub index: String,
|
||||||
|
|
||||||
|
/// User readable name of the organization."
|
||||||
|
pub name: String,
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ use crate::Repository;
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
||||||
pub struct Project {
|
pub struct Project {
|
||||||
/// Unique identifier of the project
|
/// Unique identifier of the project
|
||||||
pub index: usize,
|
pub index: String,
|
||||||
|
|
||||||
/// Name of the project, relative to the owner
|
/// Name of the project, relative to the owner
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
|
@ -23,10 +23,10 @@ use crate::{OpenCloseState, Reaction};
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
||||||
pub struct PullRequest {
|
pub struct PullRequest {
|
||||||
/// Unique identifier, relative to the repository
|
/// Unique identifier, relative to the repository
|
||||||
pub index: usize,
|
pub index: String,
|
||||||
|
|
||||||
/// Unique identifier of the user who authored the pull request.
|
/// Unique identifier of the user who authored the pull request.
|
||||||
pub poster_id: usize,
|
pub poster_id: String,
|
||||||
|
|
||||||
/// Short description displayed as the title.
|
/// Short description displayed as the title.
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
@ -35,7 +35,7 @@ pub struct PullRequest {
|
||||||
pub content: String,
|
pub content: String,
|
||||||
|
|
||||||
/// Name of the milestone
|
/// Name of the milestone
|
||||||
pub milestone: Option<String>,
|
pub milestone: String,
|
||||||
|
|
||||||
/// state of the pull request
|
/// state of the pull request
|
||||||
pub state: OpenCloseState,
|
pub state: OpenCloseState,
|
||||||
|
|
|
@ -21,7 +21,7 @@ use serde::{Deserialize, Serialize};
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Default, Eq, PartialEq)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
/// Unique identifier of the user
|
/// Unique identifier of the user
|
||||||
pub index: usize,
|
pub index: String,
|
||||||
|
|
||||||
/// User readable name of the user
|
/// User readable name of the user
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
@ -30,7 +30,7 @@ pub struct User {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
|
|
||||||
/// Mail of the user
|
/// Mail of the user
|
||||||
pub email: Option<String>,
|
pub email: String,
|
||||||
|
|
||||||
/// Password of the user
|
/// Password of the user
|
||||||
pub password: String,
|
pub password: String,
|
||||||
|
|
100
tests/basic.rs
Normal file
100
tests/basic.rs
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use jsonschema::JSONSchema;
|
||||||
|
use serde::Serialize;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
fn util<T: Serialize>(instance: &T, schema_path: &Path) {
|
||||||
|
let instance = json!(instance);
|
||||||
|
let schema_str = fs::read_to_string(schema_path).unwrap();
|
||||||
|
let schema = serde_json::from_str(&schema_str).unwrap();
|
||||||
|
let compiled = JSONSchema::compile(&schema).expect("A valid schema");
|
||||||
|
let result = compiled.validate(&instance);
|
||||||
|
if let Err(errors) = result {
|
||||||
|
for error in errors {
|
||||||
|
println!("Validation error: {}", error);
|
||||||
|
println!("Instance path: {}", error.instance_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert!(compiled.is_valid(&instance));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_comment() {
|
||||||
|
let schema_path = Path::new("./f3-schemas/comment.json");
|
||||||
|
let instance = f3_rs::Comment {
|
||||||
|
created: "1963-06-19T08:30:06.283185Z".into(),
|
||||||
|
updated: "1963-06-19T08:30:06.283185Z".into(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
util(&instance, schema_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_issue() {
|
||||||
|
let schema_path = Path::new("./f3-schemas/issue.json");
|
||||||
|
let instance = f3_rs::Issue {
|
||||||
|
created: "1963-06-19T08:30:06.283185Z".into(),
|
||||||
|
updated: "1963-06-19T08:30:06.283185Z".into(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
util(&instance, schema_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_user() {
|
||||||
|
let schema_path = Path::new("./f3-schemas/user.json");
|
||||||
|
let instance = f3_rs::User {
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
util(&instance, schema_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pr() {
|
||||||
|
let schema_path = Path::new("./f3-schemas/pullrequest.json");
|
||||||
|
let instance = f3_rs::PullRequest {
|
||||||
|
created: "1963-06-19T08:30:06.283185Z".into(),
|
||||||
|
updated: "1963-06-19T08:30:06.283185Z".into(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
util(&instance, schema_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_identities() {
|
||||||
|
let schema_path = Path::new("./f3-schemas/identities.json");
|
||||||
|
let instance = f3_rs::Identities::default();
|
||||||
|
util(&instance, schema_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_label() {
|
||||||
|
let schema_path = Path::new("./f3-schemas/label.json");
|
||||||
|
let instance = f3_rs::Label::default();
|
||||||
|
util(&instance, schema_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_object() {
|
||||||
|
let schema_path = Path::new("./f3-schemas/object.json");
|
||||||
|
let instance = f3_rs::Object::default();
|
||||||
|
util(&instance, schema_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_organization() {
|
||||||
|
let schema_path = Path::new("./f3-schemas/organization.json");
|
||||||
|
let instance = f3_rs::Organization::default();
|
||||||
|
util(&instance, schema_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_project() {
|
||||||
|
let schema_path = Path::new("./f3-schemas/project.json");
|
||||||
|
let instance = f3_rs::Project {
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
util(&instance, schema_path);
|
||||||
|
}
|
Loading…
Reference in a new issue