Adding upstream version 3.10.8.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
37e9b6d587
commit
03bfe4079e
356 changed files with 28857 additions and 0 deletions
20
f3/ci.go
Normal file
20
f3/ci.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// Copyright twenty-panda <twenty-panda@posteo.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
type CI struct {
|
||||
Common
|
||||
}
|
||||
|
||||
func (o CI) Equal(other CI) bool {
|
||||
return o.Common.Equal(other.Common)
|
||||
}
|
||||
|
||||
func (o *CI) Clone() Interface {
|
||||
clone := &CI{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
35
f3/comment.go
Normal file
35
f3/comment.go
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import "time"
|
||||
|
||||
type Comment struct {
|
||||
Common
|
||||
PosterID *Reference `json:"poster_id"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
func (o *Comment) GetReferences() References {
|
||||
references := o.Common.GetReferences()
|
||||
if !o.PosterID.IsNil() {
|
||||
references = append(references, o.PosterID)
|
||||
}
|
||||
return references
|
||||
}
|
||||
|
||||
func (o Comment) Equal(other Comment) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
nilOrEqual(o.PosterID, other.PosterID) &&
|
||||
o.Content == other.Content
|
||||
}
|
||||
|
||||
func (o *Comment) Clone() Interface {
|
||||
clone := &Comment{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
37
f3/equal.go
Normal file
37
f3/equal.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Copyright limiting-factor <limiting-factor@posteo.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type equalConstraint[T any] interface {
|
||||
Equal(T) bool
|
||||
*T
|
||||
}
|
||||
|
||||
func nilOrEqual[P any, T equalConstraint[P]](a, b T) bool {
|
||||
return (a == nil && b == nil) ||
|
||||
(a != nil && b != nil && a.Equal(*b))
|
||||
}
|
||||
|
||||
func arrayEqual[P any, T equalConstraint[P]](a, b []T) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < len(a); i++ {
|
||||
if !nilOrEqual(a[i], b[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func nilOrEqualTimeToDate(a, b *time.Time) bool {
|
||||
return (a == nil && b == nil) ||
|
||||
(a != nil && b != nil && a.Format(time.DateOnly) == b.Format(time.DateOnly))
|
||||
}
|
53
f3/equal_test.go
Normal file
53
f3/equal_test.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
// Copyright limiting-factor <limiting-factor@posteo.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type s struct {
|
||||
v int
|
||||
}
|
||||
|
||||
func (o s) Equal(other s) bool {
|
||||
return o.v == other.v
|
||||
}
|
||||
|
||||
func TestNilOrEqual(t *testing.T) {
|
||||
s1 := &s{1}
|
||||
s2 := &s{1}
|
||||
s3 := &s{2}
|
||||
assert.True(t, nilOrEqual[s](nil, nil))
|
||||
assert.False(t, nilOrEqual(s1, nil))
|
||||
assert.False(t, nilOrEqual(nil, s2))
|
||||
assert.True(t, nilOrEqual(s1, s2))
|
||||
assert.False(t, nilOrEqual(s1, s3))
|
||||
}
|
||||
|
||||
func TestArrayEqual(t *testing.T) {
|
||||
s1 := []*s{{1}, {2}}
|
||||
s2 := []*s{{1}, {2}}
|
||||
s3 := []*s{{1}, {2}, {3}}
|
||||
assert.True(t, arrayEqual(s1, s2))
|
||||
assert.False(t, arrayEqual(s1, s3))
|
||||
}
|
||||
|
||||
func TestNilOrEqualTimeToDate(t *testing.T) {
|
||||
t1, err := time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
|
||||
require.NoError(t, err)
|
||||
t2, err := time.Parse(time.RFC3339, "2006-01-02T00:01:00Z")
|
||||
require.NoError(t, err)
|
||||
t3, err := time.Parse(time.RFC3339, "2026-01-02T11:01:00Z")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, nilOrEqualTimeToDate(nil, nil))
|
||||
assert.False(t, nilOrEqualTimeToDate(&t1, nil))
|
||||
assert.False(t, nilOrEqualTimeToDate(nil, &t2))
|
||||
assert.True(t, nilOrEqualTimeToDate(&t1, &t2))
|
||||
assert.False(t, nilOrEqualTimeToDate(&t1, &t3))
|
||||
}
|
109
f3/file_format.go
Normal file
109
f3/file_format.go
Normal file
|
@ -0,0 +1,109 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/santhosh-tekuri/jsonschema/v6"
|
||||
)
|
||||
|
||||
// Load project data from file, with optional validation
|
||||
func Load(filename string, data any, validation bool) error {
|
||||
bs, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if validation {
|
||||
err := validate(bs, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return unmarshal(bs, data)
|
||||
}
|
||||
|
||||
func Store(filename string, data any) error {
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
bs, err := json.MarshalIndent(data, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := f.Write(bs); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := f.Write([]byte("\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func unmarshal(bs []byte, data any) error {
|
||||
return json.Unmarshal(bs, data)
|
||||
}
|
||||
|
||||
func getSchema(filename string) (*jsonschema.Schema, error) {
|
||||
c := jsonschema.NewCompiler()
|
||||
return c.Compile(filename)
|
||||
}
|
||||
|
||||
func validate(bs []byte, datatype any) error {
|
||||
var v any
|
||||
err := unmarshal(bs, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var schemaFilename string
|
||||
switch datatype := datatype.(type) {
|
||||
case *User:
|
||||
schemaFilename = "schemas/user.json"
|
||||
case *Organization:
|
||||
schemaFilename = "schemas/organization.json"
|
||||
case *Project:
|
||||
schemaFilename = "schemas/project.json"
|
||||
case *Topic:
|
||||
schemaFilename = "schemas/topic.json"
|
||||
case *Issue:
|
||||
schemaFilename = "schemas/issue.json"
|
||||
case *PullRequest:
|
||||
schemaFilename = "schemas/pullrequest.json"
|
||||
case *Label:
|
||||
schemaFilename = "schemas/label.json"
|
||||
case *Milestone:
|
||||
schemaFilename = "schemas/milestone.json"
|
||||
case *Release:
|
||||
schemaFilename = "schemas/release.json"
|
||||
case *ReleaseAsset:
|
||||
schemaFilename = "schemas/releaseasset.json"
|
||||
case *Comment:
|
||||
schemaFilename = "schemas/comment.json"
|
||||
case *Reaction:
|
||||
schemaFilename = "schemas/reaction.json"
|
||||
case *Repository:
|
||||
schemaFilename = "schemas/repository.json"
|
||||
case *Review:
|
||||
schemaFilename = "schemas/review.json"
|
||||
case *ReviewComment:
|
||||
schemaFilename = "schemas/reviewcomment.json"
|
||||
case *CI:
|
||||
schemaFilename = "schemas/ci.json"
|
||||
default:
|
||||
return fmt.Errorf("file_format:validate: %T does not have a schema that could be used for validation", datatype)
|
||||
}
|
||||
|
||||
sch, err := getSchema(schemaFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return sch.Validate(v)
|
||||
}
|
166
f3/file_format_test.go
Normal file
166
f3/file_format_test.go
Normal file
|
@ -0,0 +1,166 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/santhosh-tekuri/jsonschema/v6"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestStoreLoad(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
type S struct {
|
||||
A int
|
||||
B string
|
||||
}
|
||||
original := S{A: 1, B: "B"}
|
||||
p := filepath.Join(tmpDir, "s.json")
|
||||
assert.NoError(t, Store(p, original))
|
||||
var loaded S
|
||||
assert.NoError(t, Load(p, &loaded, false))
|
||||
assert.EqualValues(t, original, loaded)
|
||||
}
|
||||
|
||||
func TestF3_CI(t *testing.T) {
|
||||
var ci CI
|
||||
err := Load("file_format_testdata/ci/good.json", &ci, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/ci/bad.json", &ci, true)
|
||||
assert.ErrorContains(t, err, "'/index': value must be one of")
|
||||
}
|
||||
|
||||
func TestF3_User(t *testing.T) {
|
||||
var user User
|
||||
err := Load("file_format_testdata/user/good.json", &user, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/user/bad.json", &user, true)
|
||||
assert.ErrorContains(t, err, "missing properties 'index'")
|
||||
}
|
||||
|
||||
func TestF3_Organization(t *testing.T) {
|
||||
var organization Organization
|
||||
err := Load("file_format_testdata/organization/good.json", &organization, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/organization/bad.json", &organization, true)
|
||||
assert.ErrorContains(t, err, "missing properties 'index'")
|
||||
}
|
||||
|
||||
func TestF3_Project(t *testing.T) {
|
||||
var project Project
|
||||
err := Load("file_format_testdata/project/good.json", &project, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/project/bad.json", &project, true)
|
||||
assert.ErrorContains(t, err, "'/stars': got string, want number")
|
||||
}
|
||||
|
||||
func TestF3_Issue(t *testing.T) {
|
||||
var issue Issue
|
||||
err := Load("file_format_testdata/issue/good.json", &issue, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/issue/bad.json", &issue, true)
|
||||
assert.ErrorContains(t, err, "missing property 'index'")
|
||||
}
|
||||
|
||||
func TestF3_PullRequest(t *testing.T) {
|
||||
var pullRequest PullRequest
|
||||
err := Load("file_format_testdata/pullrequest/good.json", &pullRequest, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/pullrequest/bad.json", &pullRequest, true)
|
||||
assert.ErrorContains(t, err, "missing properties 'index'")
|
||||
}
|
||||
|
||||
func TestF3_Release(t *testing.T) {
|
||||
var release Release
|
||||
err := Load("file_format_testdata/release/good.json", &release, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/release/bad.json", &release, true)
|
||||
assert.ErrorContains(t, err, "missing properties 'index'")
|
||||
}
|
||||
|
||||
func TestF3_ReleaseAsset(t *testing.T) {
|
||||
var releaseAsset ReleaseAsset
|
||||
err := Load("file_format_testdata/releaseasset/good.json", &releaseAsset, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/releaseasset/bad.json", &releaseAsset, true)
|
||||
assert.ErrorContains(t, err, "missing properties 'index'")
|
||||
}
|
||||
|
||||
func TestF3_Comment(t *testing.T) {
|
||||
var comment Comment
|
||||
err := Load("file_format_testdata/comment/good.json", &comment, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/comment/bad.json", &comment, true)
|
||||
assert.ErrorContains(t, err, "'/created': 'AAAAAAAAA' is not valid date-time")
|
||||
}
|
||||
|
||||
func TestF3_Label(t *testing.T) {
|
||||
var label Label
|
||||
err := Load("file_format_testdata/label/good.json", &label, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/label/bad.json", &label, true)
|
||||
assert.ErrorContains(t, err, "'/exclusive': got string, want boolean")
|
||||
}
|
||||
|
||||
func TestF3_Milestone(t *testing.T) {
|
||||
var milestone Milestone
|
||||
err := Load("file_format_testdata/milestone/good.json", &milestone, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/milestone/bad.json", &milestone, true)
|
||||
assert.ErrorContains(t, err, "missing properties 'index'")
|
||||
}
|
||||
|
||||
func TestF3_Review(t *testing.T) {
|
||||
var review Review
|
||||
err := Load("file_format_testdata/review/good.json", &review, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/review/bad.json", &review, true)
|
||||
assert.ErrorContains(t, err, "missing properties 'index'")
|
||||
}
|
||||
|
||||
func TestF3_Reaction(t *testing.T) {
|
||||
var reaction Reaction
|
||||
err := Load("file_format_testdata/reaction/good.json", &reaction, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/reaction/bad.json", &reaction, true)
|
||||
assert.ErrorContains(t, err, "missing properties 'index'")
|
||||
}
|
||||
|
||||
func TestF3_Repository(t *testing.T) {
|
||||
var repository Repository
|
||||
err := Load("file_format_testdata/repository/good.json", &repository, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/repository/bad.json", &repository, true)
|
||||
assert.ErrorContains(t, err, "missing property 'name'")
|
||||
}
|
||||
|
||||
func TestF3_ReviewComment(t *testing.T) {
|
||||
var reviewComment ReviewComment
|
||||
err := Load("file_format_testdata/reviewcomment/good.json", &reviewComment, true)
|
||||
assert.NoError(t, err)
|
||||
err = Load("file_format_testdata/reviewcomment/bad.json", &reviewComment, true)
|
||||
assert.ErrorContains(t, err, "missing properties 'index'")
|
||||
}
|
||||
|
||||
func TestF3_Topic(t *testing.T) {
|
||||
var topic Topic
|
||||
err := Load("file_format_testdata/topic.json", &topic, true)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestF3_ValidationFail(t *testing.T) {
|
||||
var issue Issue
|
||||
err := Load("file_format_testdata/issue/bad.json", &issue, true)
|
||||
if _, ok := err.(*jsonschema.ValidationError); ok {
|
||||
errors := strings.Split(err.(*jsonschema.ValidationError).GoString(), "\n")
|
||||
assert.Contains(t, errors[1], "missing property")
|
||||
} else {
|
||||
t.Fatalf("got: type %T with value %s, want: *jsonschema.ValidationError", err, err)
|
||||
}
|
||||
}
|
3
f3/file_format_testdata/ci/bad.json
Normal file
3
f3/file_format_testdata/ci/bad.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"index": "Unknown"
|
||||
}
|
3
f3/file_format_testdata/ci/good.json
Normal file
3
f3/file_format_testdata/ci/good.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"index": "Forgejo Actions"
|
||||
}
|
7
f3/file_format_testdata/comment/bad.json
Normal file
7
f3/file_format_testdata/comment/bad.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"index": "5",
|
||||
"poster_id": "1",
|
||||
"created": "AAAAAAAAA",
|
||||
"updated": "1986-04-12T23:20:50.52Z",
|
||||
"content": "comment_content_5"
|
||||
}
|
14
f3/file_format_testdata/comment/good.json
Normal file
14
f3/file_format_testdata/comment/good.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"index": "5",
|
||||
"poster_id": "/user/1",
|
||||
"created": "1985-04-12T23:20:50.52Z",
|
||||
"updated": "1986-04-12T23:20:50.52Z",
|
||||
"content": "comment_content_5",
|
||||
"reactions": [
|
||||
{
|
||||
"index": "8",
|
||||
"user_id": "/user/23",
|
||||
"content": "laugh"
|
||||
}
|
||||
]
|
||||
}
|
20
f3/file_format_testdata/issue/bad.json
Normal file
20
f3/file_format_testdata/issue/bad.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"poster_id": "/forge/users/1",
|
||||
"title": "title_a",
|
||||
"content": "content_a",
|
||||
"milestone": "../../milestones/23",
|
||||
"state": "closed",
|
||||
"is_locked": false,
|
||||
"created": "1985-04-12T23:20:50.52Z",
|
||||
"updated": "1986-04-12T23:20:50.52Z",
|
||||
"closed": null,
|
||||
"due": "1986-04-12",
|
||||
"labels": [
|
||||
"../../labels/435"
|
||||
],
|
||||
"reactions": null,
|
||||
"assignees": [
|
||||
"/forge/users/1",
|
||||
"/forge/users/2"
|
||||
]
|
||||
}
|
21
f3/file_format_testdata/issue/good.json
Normal file
21
f3/file_format_testdata/issue/good.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"index": "1",
|
||||
"poster_id": "/forge/users/1",
|
||||
"title": "title_a",
|
||||
"content": "content_a",
|
||||
"milestone": "../../milestones/23",
|
||||
"state": "closed",
|
||||
"is_locked": false,
|
||||
"created": "1985-04-12T23:20:50.52Z",
|
||||
"updated": "1986-04-12T23:20:50.52Z",
|
||||
"closed": "1986-04-12T23:20:50.52Z",
|
||||
"due": "1986-04-12",
|
||||
"labels": [
|
||||
"../../labels/435"
|
||||
],
|
||||
"reactions": [],
|
||||
"assignees": [
|
||||
"/forge/users/1",
|
||||
"/forge/users/2"
|
||||
]
|
||||
}
|
7
f3/file_format_testdata/label/bad.json
Normal file
7
f3/file_format_testdata/label/bad.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"index": "1",
|
||||
"name": "label1",
|
||||
"description": "label1 description",
|
||||
"color": "ffffff",
|
||||
"exclusive": "CCCCCCCC"
|
||||
}
|
7
f3/file_format_testdata/label/good.json
Normal file
7
f3/file_format_testdata/label/good.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"index": "1",
|
||||
"name": "label1",
|
||||
"description": "label1 description",
|
||||
"color": "ffffff",
|
||||
"exclusive": false
|
||||
}
|
2
f3/file_format_testdata/milestone/bad.json
Normal file
2
f3/file_format_testdata/milestone/bad.json
Normal file
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
10
f3/file_format_testdata/milestone/good.json
Normal file
10
f3/file_format_testdata/milestone/good.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"index": "1",
|
||||
"title": "title_a",
|
||||
"description": "description_a",
|
||||
"deadline": "1988-04-12T23:20:50.52Z",
|
||||
"created": "1985-04-12T23:20:50.52Z",
|
||||
"updated": "1986-04-12T23:20:50.52Z",
|
||||
"closed": "1987-04-12T23:20:50.52Z",
|
||||
"state": "closed"
|
||||
}
|
2
f3/file_format_testdata/organization/bad.json
Normal file
2
f3/file_format_testdata/organization/bad.json
Normal file
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
5
f3/file_format_testdata/organization/good.json
Normal file
5
f3/file_format_testdata/organization/good.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"index": "9",
|
||||
"name": "orgunique",
|
||||
"full_name": "Org Unique"
|
||||
}
|
28
f3/file_format_testdata/project/bad.json
Normal file
28
f3/file_format_testdata/project/bad.json
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"index": "1",
|
||||
"name": "projectname",
|
||||
"is_private": false,
|
||||
"is_mirror": false,
|
||||
"description": "project description",
|
||||
"default_branch": "main",
|
||||
"repositories": [
|
||||
{
|
||||
"name": "vcs",
|
||||
"vcs": "hg"
|
||||
},
|
||||
{
|
||||
"name": "vcs.wiki"
|
||||
}
|
||||
],
|
||||
"archived": true,
|
||||
"archived_at": "1987-04-12T23:20:50.52Z",
|
||||
"created": "1985-04-12T23:20:50.52Z",
|
||||
"updated": "1986-04-12T23:20:50.52Z",
|
||||
"url": "https://example.com",
|
||||
"stars": "BBBBBB",
|
||||
"has_ci": true,
|
||||
"has_issues": true,
|
||||
"has_packages": true,
|
||||
"has_pull_requests": true,
|
||||
"has_wiki": true
|
||||
}
|
28
f3/file_format_testdata/project/good.json
Normal file
28
f3/file_format_testdata/project/good.json
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"index": "1",
|
||||
"name": "projectname",
|
||||
"is_private": false,
|
||||
"is_mirror": false,
|
||||
"description": "project description",
|
||||
"default_branch": "main",
|
||||
"repositories": [
|
||||
{
|
||||
"name": "vcs",
|
||||
"vcs": "hg"
|
||||
},
|
||||
{
|
||||
"name": "vcs.wiki"
|
||||
}
|
||||
],
|
||||
"archived": true,
|
||||
"archived_at": "1987-04-12T23:20:50.52Z",
|
||||
"created": "1985-04-12T23:20:50.52Z",
|
||||
"updated": "1986-04-12T23:20:50.52Z",
|
||||
"url": "https://example.com",
|
||||
"stars": 20,
|
||||
"has_ci": true,
|
||||
"has_issues": true,
|
||||
"has_packages": true,
|
||||
"has_pull_requests": true,
|
||||
"has_wiki": true
|
||||
}
|
2
f3/file_format_testdata/pullrequest/bad.json
Normal file
2
f3/file_format_testdata/pullrequest/bad.json
Normal file
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
32
f3/file_format_testdata/pullrequest/good.json
Normal file
32
f3/file_format_testdata/pullrequest/good.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"index": "1",
|
||||
"poster_id": "/forgejo/users/1",
|
||||
"title": "title_a",
|
||||
"content": "content_a",
|
||||
"milestone": "../../milestones/5",
|
||||
"state": "closed",
|
||||
"is_locked": false,
|
||||
"created": "1985-04-12T23:20:50.52Z",
|
||||
"updated": "1986-04-12T23:20:50.52Z",
|
||||
"closed": "1986-04-12T23:20:50.52Z",
|
||||
"labels": [
|
||||
"../../labels/435"
|
||||
],
|
||||
"reactions": [],
|
||||
"assignees": [],
|
||||
"merged": false,
|
||||
"merged_time": "1986-04-12T23:20:50.52Z",
|
||||
"merged_commit_sha": "shashasha",
|
||||
"head": {
|
||||
"clone_url": "head_clone_url",
|
||||
"ref": "head_branch",
|
||||
"sha": "head_sha",
|
||||
"repository": "/forge/user/1/projects/2/repositories/vcs"
|
||||
},
|
||||
"base": {
|
||||
"clone_url": "base_clone_url",
|
||||
"ref": "base_branch",
|
||||
"sha": "base _sha",
|
||||
"repository": "/forge/user/3/projects/4/repositories/vcs"
|
||||
}
|
||||
}
|
2
f3/file_format_testdata/reaction/bad.json
Normal file
2
f3/file_format_testdata/reaction/bad.json
Normal file
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
5
f3/file_format_testdata/reaction/good.json
Normal file
5
f3/file_format_testdata/reaction/good.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"index": "8",
|
||||
"user_id": "/forge/users/912",
|
||||
"content": "laugh"
|
||||
}
|
2
f3/file_format_testdata/release/bad.json
Normal file
2
f3/file_format_testdata/release/bad.json
Normal file
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
11
f3/file_format_testdata/release/good.json
Normal file
11
f3/file_format_testdata/release/good.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"index": "123",
|
||||
"tag_name": "v12",
|
||||
"target_commitish": "stable",
|
||||
"name": "v12 name",
|
||||
"body": "v12 body",
|
||||
"draft": false,
|
||||
"prerelease": false,
|
||||
"publisher_id": "/forgejo/user/1",
|
||||
"created": "1985-04-12T23:20:50.52Z"
|
||||
}
|
2
f3/file_format_testdata/releaseasset/bad.json
Normal file
2
f3/file_format_testdata/releaseasset/bad.json
Normal file
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
11
f3/file_format_testdata/releaseasset/good.json
Normal file
11
f3/file_format_testdata/releaseasset/good.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"index": "5",
|
||||
"name": "asset_5",
|
||||
"content_type": "application/zip",
|
||||
"size": 50,
|
||||
"download_count": 10,
|
||||
"download_url": "http://example.com/something",
|
||||
"created": "1985-04-12T23:20:50.52Z",
|
||||
"updated": "1986-04-12T23:20:50.52Z",
|
||||
"sha256": "4c5b2f412017de78124ae3a063d08e76566eea0cba6deb2533fb176d816a54fc"
|
||||
}
|
2
f3/file_format_testdata/repository/bad.json
Normal file
2
f3/file_format_testdata/repository/bad.json
Normal file
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
4
f3/file_format_testdata/repository/good.json
Normal file
4
f3/file_format_testdata/repository/good.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "vcs.wiki",
|
||||
"vcs": "fossil"
|
||||
}
|
3
f3/file_format_testdata/review/bad.json
Normal file
3
f3/file_format_testdata/review/bad.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
}
|
||||
|
12
f3/file_format_testdata/review/good.json
Normal file
12
f3/file_format_testdata/review/good.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"index": "1",
|
||||
"reviewer_id": "/forge/user/50",
|
||||
"official": false,
|
||||
"commit_id": "shashashasha",
|
||||
"content": "cover review comment",
|
||||
"created_at": "1985-04-12T23:20:50.52Z",
|
||||
"state": "PENDING",
|
||||
"dissmissed": false,
|
||||
"stale": false
|
||||
}
|
||||
|
2
f3/file_format_testdata/reviewcomment/bad.json
Normal file
2
f3/file_format_testdata/reviewcomment/bad.json
Normal file
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
14
f3/file_format_testdata/reviewcomment/good.json
Normal file
14
f3/file_format_testdata/reviewcomment/good.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"index": "100",
|
||||
"content": "review comment",
|
||||
"tree_path": "dir/file1.txt",
|
||||
"diff_hunk": "@@hunkhunk",
|
||||
"line": 1,
|
||||
"lines_count": 1,
|
||||
"commit_id": "shashashasha",
|
||||
"poster_id": "/forge/users/10",
|
||||
"reactions": [],
|
||||
"created_at": "1985-04-12T23:20:50.52Z",
|
||||
"updated_at": "1985-04-12T23:20:50.52Z",
|
||||
"resolver": "/forge/users/10"
|
||||
}
|
4
f3/file_format_testdata/topic.json
Normal file
4
f3/file_format_testdata/topic.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"index": "1",
|
||||
"name": "category1"
|
||||
}
|
2
f3/file_format_testdata/user/bad.json
Normal file
2
f3/file_format_testdata/user/bad.json
Normal file
|
@ -0,0 +1,2 @@
|
|||
{
|
||||
}
|
8
f3/file_format_testdata/user/good.json
Normal file
8
f3/file_format_testdata/user/good.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"index": "7",
|
||||
"name": "User Name One",
|
||||
"email": "user1@example.com",
|
||||
"username": "user1",
|
||||
"password": "gloxKainlo",
|
||||
"admin": false
|
||||
}
|
20
f3/forge.go
Normal file
20
f3/forge.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
type Forge struct {
|
||||
Common
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
func (o Forge) Equal(other Forge) bool {
|
||||
return o.Common.Equal(other.Common)
|
||||
}
|
||||
|
||||
func (o *Forge) Clone() Interface {
|
||||
clone := &Forge{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
99
f3/formatbase.go
Normal file
99
f3/formatbase.go
Normal file
|
@ -0,0 +1,99 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"code.forgejo.org/f3/gof3/v3/util"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
GetID() string
|
||||
GetName() string
|
||||
SetID(id string)
|
||||
IsNil() bool
|
||||
GetReferences() References
|
||||
ToReference() *Reference
|
||||
Clone() Interface
|
||||
}
|
||||
|
||||
type ReferenceInterface interface {
|
||||
Get() string
|
||||
Set(reference string)
|
||||
GetIDAsString() string
|
||||
GetIDAsInt() int64
|
||||
}
|
||||
|
||||
type Reference struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
func (r *Reference) Get() string {
|
||||
return r.ID
|
||||
}
|
||||
|
||||
func (r *Reference) Set(reference string) {
|
||||
r.ID = reference
|
||||
}
|
||||
|
||||
func (r *Reference) GetIDAsInt() int64 {
|
||||
return util.ParseInt(r.GetIDAsString())
|
||||
}
|
||||
|
||||
func (r *Reference) GetIDAsString() string {
|
||||
s := strings.Split(r.ID, "/")
|
||||
return s[len(s)-1]
|
||||
}
|
||||
|
||||
type References []ReferenceInterface
|
||||
|
||||
func (r *Reference) UnmarshalJSON(b []byte) error {
|
||||
return json.Unmarshal(b, &r.ID)
|
||||
}
|
||||
|
||||
func (r Reference) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(r.ID)
|
||||
}
|
||||
|
||||
func (r *Reference) GetID() string { return r.ID }
|
||||
func (r *Reference) SetID(id string) { r.ID = id }
|
||||
func (r *Reference) IsNil() bool { return r == nil || r.ID == "0" || r.ID == "" }
|
||||
func (r Reference) Equal(other Reference) bool { return r.ID == other.ID }
|
||||
|
||||
func NewReferences() References {
|
||||
return make([]ReferenceInterface, 0, 1)
|
||||
}
|
||||
|
||||
func NewReference(id string) *Reference {
|
||||
r := &Reference{}
|
||||
r.SetID(id)
|
||||
return r
|
||||
}
|
||||
|
||||
type Common struct {
|
||||
Index Reference `json:"index"`
|
||||
}
|
||||
|
||||
func (c *Common) GetID() string { return c.Index.GetID() }
|
||||
func (c *Common) GetName() string { return c.GetID() }
|
||||
func (c *Common) SetID(id string) { c.Index.SetID(id) }
|
||||
func (c *Common) IsNil() bool { return c == nil || c.Index.IsNil() }
|
||||
func (c *Common) GetReferences() References { return NewReferences() }
|
||||
func (c *Common) ToReference() *Reference { return &c.Index }
|
||||
func (c Common) Equal(other Common) bool { return true }
|
||||
|
||||
var Nil = &Common{}
|
||||
|
||||
func NewCommon(id string) Common {
|
||||
return Common{Index: *NewReference(id)}
|
||||
}
|
||||
|
||||
func (c *Common) Clone() Interface {
|
||||
clone := &Common{}
|
||||
*clone = *c
|
||||
return clone
|
||||
}
|
57
f3/formatbase_test.go
Normal file
57
f3/formatbase_test.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Copyright limiting-factor <limiting-factor@posteo.com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestF3Reference(t *testing.T) {
|
||||
ref := "reference"
|
||||
r := NewReference(ref)
|
||||
assert.Equal(t, ref, r.GetID())
|
||||
otherRef := "other"
|
||||
r.SetID(otherRef)
|
||||
assert.Equal(t, otherRef, r.GetID())
|
||||
r.Set(otherRef)
|
||||
assert.Equal(t, otherRef, r.Get())
|
||||
assert.True(t, r.Equal(*r))
|
||||
|
||||
m, err := r.MarshalJSON()
|
||||
require.NoError(t, err)
|
||||
u := NewReference("???")
|
||||
require.NoError(t, u.UnmarshalJSON(m))
|
||||
assert.True(t, r.Equal(*u))
|
||||
|
||||
assert.False(t, r.IsNil())
|
||||
r.SetID("")
|
||||
assert.True(t, r.IsNil())
|
||||
r.SetID("0")
|
||||
assert.True(t, r.IsNil())
|
||||
|
||||
var nilRef *Reference
|
||||
assert.True(t, nilRef.IsNil())
|
||||
}
|
||||
|
||||
func TestF3Common(t *testing.T) {
|
||||
id := "ID"
|
||||
c := NewCommon(id)
|
||||
assert.Equal(t, id, c.GetID())
|
||||
assert.Equal(t, id, c.GetName())
|
||||
otherID := "otherID"
|
||||
c.SetID(otherID)
|
||||
assert.Equal(t, otherID, c.GetID())
|
||||
|
||||
assert.False(t, c.IsNil())
|
||||
c.SetID("")
|
||||
assert.True(t, c.IsNil())
|
||||
c.SetID("0")
|
||||
assert.True(t, c.IsNil())
|
||||
|
||||
var nilCommon *Common
|
||||
assert.True(t, nilCommon.IsNil())
|
||||
}
|
58
f3/issue.go
Normal file
58
f3/issue.go
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
IssueStateOpen = "open"
|
||||
IssueStateClosed = "closed"
|
||||
)
|
||||
|
||||
type Issue struct {
|
||||
Common
|
||||
PosterID *Reference `json:"poster_id"`
|
||||
Assignees []*Reference `json:"assignees"`
|
||||
Labels []*Reference `json:"labels"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Milestone *Reference `json:"milestone"`
|
||||
State string `json:"state"` // open, closed
|
||||
IsLocked bool `json:"is_locked"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
Closed *time.Time `json:"closed"`
|
||||
}
|
||||
|
||||
func (o *Issue) GetReferences() References {
|
||||
references := o.Common.GetReferences()
|
||||
for _, assignee := range o.Assignees {
|
||||
references = append(references, assignee)
|
||||
}
|
||||
for _, label := range o.Labels {
|
||||
references = append(references, label)
|
||||
}
|
||||
if !o.Milestone.IsNil() {
|
||||
references = append(references, o.Milestone)
|
||||
}
|
||||
return append(references, o.PosterID)
|
||||
}
|
||||
|
||||
func (o Issue) Equal(other Issue) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
nilOrEqual(o.PosterID, other.PosterID) &&
|
||||
arrayEqual(o.Assignees, other.Assignees) &&
|
||||
arrayEqual(o.Labels, other.Labels) &&
|
||||
o.Title == other.Title &&
|
||||
nilOrEqual(o.Milestone, other.Milestone) &&
|
||||
o.State == other.State &&
|
||||
o.IsLocked == other.IsLocked
|
||||
}
|
||||
|
||||
func (o *Issue) Clone() Interface {
|
||||
clone := &Issue{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
25
f3/label.go
Normal file
25
f3/label.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
type Label struct {
|
||||
Common
|
||||
Name string `json:"name"`
|
||||
Color string `json:"color"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
func (o Label) Equal(other Label) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
o.Name == other.Name &&
|
||||
o.Color == other.Color &&
|
||||
o.Description == other.Description
|
||||
}
|
||||
|
||||
func (o *Label) Clone() Interface {
|
||||
clone := &Label{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
37
f3/milestone.go
Normal file
37
f3/milestone.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
MilestoneStateOpen = "open"
|
||||
MilestoneStateClosed = "closed"
|
||||
)
|
||||
|
||||
type Milestone struct {
|
||||
Common
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Deadline *time.Time `json:"deadline"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated *time.Time `json:"updated"`
|
||||
Closed *time.Time `json:"closed"`
|
||||
State string `json:"state"` // open, closed
|
||||
}
|
||||
|
||||
func (o Milestone) Equal(other Milestone) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
o.Title == other.Title &&
|
||||
o.Description == other.Description &&
|
||||
nilOrEqualTimeToDate(o.Deadline, other.Deadline) &&
|
||||
o.State == other.State
|
||||
}
|
||||
|
||||
func (o *Milestone) Clone() Interface {
|
||||
clone := &Milestone{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
81
f3/new.go
Normal file
81
f3/new.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func New(name string) Interface {
|
||||
common := NewCommon(name)
|
||||
switch name {
|
||||
case "<root>":
|
||||
return &common
|
||||
case ResourceAsset:
|
||||
return &ReleaseAsset{}
|
||||
case ResourceAssets:
|
||||
return &common
|
||||
case ResourceComment:
|
||||
return &Comment{}
|
||||
case ResourceComments:
|
||||
return &common
|
||||
case ResourceIssue:
|
||||
return &Issue{}
|
||||
case ResourceIssues:
|
||||
return &common
|
||||
case ResourceLabel:
|
||||
return &Label{}
|
||||
case ResourceLabels:
|
||||
return &common
|
||||
case ResourceMilestone:
|
||||
return &Milestone{}
|
||||
case ResourceMilestones:
|
||||
return &common
|
||||
case ResourceOrganization:
|
||||
return &Organization{}
|
||||
case ResourceOrganizations:
|
||||
return &common
|
||||
case ResourceProject:
|
||||
return &Project{}
|
||||
case ResourceProjects:
|
||||
return &common
|
||||
case ResourcePullRequest:
|
||||
return &PullRequest{}
|
||||
case ResourcePullRequests:
|
||||
return &common
|
||||
case ResourceReaction:
|
||||
return &Reaction{}
|
||||
case ResourceReactions:
|
||||
return &common
|
||||
case ResourceRelease:
|
||||
return &Release{}
|
||||
case ResourceReleases:
|
||||
return &common
|
||||
case ResourceRepository:
|
||||
return &Repository{}
|
||||
case ResourceRepositories:
|
||||
return &common
|
||||
case ResourceReview:
|
||||
return &Review{}
|
||||
case ResourceReviews:
|
||||
return &common
|
||||
case ResourceReviewComment:
|
||||
return &ReviewComment{}
|
||||
case ResourceReviewComments:
|
||||
return &common
|
||||
case ResourceTopic:
|
||||
return &Topic{}
|
||||
case ResourceTopics:
|
||||
return &common
|
||||
case ResourceUser:
|
||||
return &User{}
|
||||
case ResourceUsers:
|
||||
return &common
|
||||
case ResourceForge:
|
||||
return &Forge{}
|
||||
default:
|
||||
panic(fmt.Errorf("unknown %s", name))
|
||||
}
|
||||
}
|
27
f3/organization.go
Normal file
27
f3/organization.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
type Organization struct {
|
||||
Common
|
||||
FullName string `json:"full_name"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (o Organization) Equal(other Organization) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
o.FullName == other.FullName &&
|
||||
o.Name == other.Name
|
||||
}
|
||||
|
||||
func (o *Organization) GetName() string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
func (o *Organization) Clone() Interface {
|
||||
clone := &Organization{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
50
f3/project.go
Normal file
50
f3/project.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
type Project struct {
|
||||
Common
|
||||
Name string `json:"name"`
|
||||
IsPrivate bool `json:"is_private"`
|
||||
IsMirror bool `json:"is_mirror"`
|
||||
Description string `json:"description"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Forked *Reference `json:"forked"`
|
||||
HasWiki bool `json:"has_wiki"`
|
||||
Topics []*Reference `json:"topics"`
|
||||
}
|
||||
|
||||
func (o Project) Project(other Project) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
o.Name == other.Name &&
|
||||
o.IsPrivate == other.IsPrivate &&
|
||||
o.IsMirror == other.IsMirror &&
|
||||
o.Description == other.Description &&
|
||||
o.DefaultBranch == other.DefaultBranch &&
|
||||
nilOrEqual(o.Forked, other.Forked) &&
|
||||
o.HasWiki == other.HasWiki &&
|
||||
arrayEqual(o.Topics, other.Topics)
|
||||
}
|
||||
|
||||
func (o *Project) GetName() string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
func (o *Project) GetReferences() References {
|
||||
references := o.Common.GetReferences()
|
||||
if !o.Forked.IsNil() {
|
||||
references = append(references, o.Forked)
|
||||
}
|
||||
for _, topic := range o.Topics {
|
||||
references = append(references, topic)
|
||||
}
|
||||
return references
|
||||
}
|
||||
|
||||
func (o *Project) Clone() Interface {
|
||||
clone := &Project{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
72
f3/pullrequest.go
Normal file
72
f3/pullrequest.go
Normal file
|
@ -0,0 +1,72 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PullRequestFetchFunc func(ctx context.Context, url, ref string)
|
||||
|
||||
const (
|
||||
PullRequestStateOpen = "open"
|
||||
PullRequestStateClosed = "closed"
|
||||
)
|
||||
|
||||
type PullRequest struct {
|
||||
Common
|
||||
PosterID *Reference `json:"poster_id"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Milestone *Reference `json:"milestone"`
|
||||
State string `json:"state"` // open, closed
|
||||
IsLocked bool `json:"is_locked"`
|
||||
Created time.Time `json:"created"`
|
||||
Updated time.Time `json:"updated"`
|
||||
Closed *time.Time `json:"closed"`
|
||||
Merged bool `json:"merged"`
|
||||
MergedTime *time.Time `json:"merged_time"`
|
||||
MergeCommitSHA string `json:"merged_commit_sha"`
|
||||
Head PullRequestBranch `json:"head"`
|
||||
Base PullRequestBranch `json:"base"`
|
||||
|
||||
FetchFunc PullRequestFetchFunc `json:"-"`
|
||||
}
|
||||
|
||||
func (o PullRequest) Equal(other PullRequest) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
nilOrEqual(o.PosterID, other.PosterID) &&
|
||||
o.Title == other.Title &&
|
||||
o.Content == other.Content &&
|
||||
nilOrEqual(o.Milestone, other.Milestone) &&
|
||||
o.State == other.State &&
|
||||
o.IsLocked == other.IsLocked &&
|
||||
o.Merged == other.Merged &&
|
||||
nilOrEqual(o.MergedTime, other.MergedTime) &&
|
||||
o.MergeCommitSHA == other.MergeCommitSHA &&
|
||||
o.Head.Equal(other.Head) &&
|
||||
o.Base.Equal(other.Base)
|
||||
}
|
||||
|
||||
func (o *PullRequest) GetReferences() References {
|
||||
references := o.Common.GetReferences()
|
||||
if !o.Milestone.IsNil() {
|
||||
references = append(references, o.Milestone)
|
||||
}
|
||||
references = append(references, o.Base.GetReferences()...)
|
||||
references = append(references, o.Head.GetReferences()...)
|
||||
return append(references, o.PosterID)
|
||||
}
|
||||
|
||||
func (o *PullRequest) IsForkPullRequest() bool {
|
||||
return o.Head.Repository != o.Base.Repository
|
||||
}
|
||||
|
||||
func (o *PullRequest) Clone() Interface {
|
||||
clone := &PullRequest{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
20
f3/pullrequestbranch.go
Normal file
20
f3/pullrequestbranch.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
type PullRequestBranch struct {
|
||||
Ref string `json:"ref"`
|
||||
SHA string `json:"sha"`
|
||||
Repository *Reference `json:"repository"`
|
||||
}
|
||||
|
||||
func (o PullRequestBranch) Equal(other PullRequestBranch) bool {
|
||||
return o.Ref == other.Ref &&
|
||||
o.SHA == other.SHA
|
||||
}
|
||||
|
||||
func (o *PullRequestBranch) GetReferences() References {
|
||||
return References{o.Repository}
|
||||
}
|
31
f3/reaction.go
Normal file
31
f3/reaction.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
type Reaction struct {
|
||||
Common
|
||||
UserID *Reference `json:"user_id"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
func (o Reaction) Equal(other Reaction) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
nilOrEqual(o.UserID, other.UserID) &&
|
||||
o.Content == other.Content
|
||||
}
|
||||
|
||||
func (o *Reaction) GetReferences() References {
|
||||
references := o.Common.GetReferences()
|
||||
if !o.UserID.IsNil() {
|
||||
references = append(references, o.UserID)
|
||||
}
|
||||
return references
|
||||
}
|
||||
|
||||
func (o *Reaction) Clone() Interface {
|
||||
clone := &Reaction{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
48
f3/release.go
Normal file
48
f3/release.go
Normal file
|
@ -0,0 +1,48 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Release struct {
|
||||
Common
|
||||
TagName string `json:"tag_name"`
|
||||
TargetCommitish string `json:"target_commitish"`
|
||||
Name string `json:"name"`
|
||||
Body string `json:"body"`
|
||||
Draft bool `json:"draft"`
|
||||
Prerelease bool `json:"prerelease"`
|
||||
PublisherID *Reference `json:"publisher_id"`
|
||||
Assets []*ReleaseAsset `json:"assets"`
|
||||
Created time.Time `json:"created"`
|
||||
}
|
||||
|
||||
func (o Release) Equal(other Release) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
o.TagName == other.TagName &&
|
||||
o.TargetCommitish == other.TargetCommitish &&
|
||||
o.Name == other.Name &&
|
||||
o.Body == other.Body &&
|
||||
o.Draft == other.Draft &&
|
||||
o.Prerelease == other.Prerelease &&
|
||||
nilOrEqual(o.PublisherID, other.PublisherID) &&
|
||||
arrayEqual(o.Assets, other.Assets)
|
||||
}
|
||||
|
||||
func (o *Release) GetReferences() References {
|
||||
references := o.Common.GetReferences()
|
||||
if !o.PublisherID.IsNil() {
|
||||
references = append(references, o.PublisherID)
|
||||
}
|
||||
return references
|
||||
}
|
||||
|
||||
func (o *Release) Clone() Interface {
|
||||
clone := &Release{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
38
f3/releaseasset.go
Normal file
38
f3/releaseasset.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DownloadFuncType func() io.ReadCloser
|
||||
|
||||
type ReleaseAsset struct {
|
||||
Common
|
||||
Name string `json:"name"`
|
||||
ContentType string `json:"content_type"`
|
||||
Size int64 `json:"size"`
|
||||
DownloadCount int64 `json:"download_count"`
|
||||
Created time.Time `json:"created"`
|
||||
SHA256 string `json:"sha256"`
|
||||
DownloadURL string `json:"download_url"`
|
||||
DownloadFunc DownloadFuncType `json:"-"`
|
||||
}
|
||||
|
||||
func (o ReleaseAsset) Equal(other ReleaseAsset) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
o.Name == other.Name &&
|
||||
o.ContentType == other.ContentType &&
|
||||
o.Size == other.Size &&
|
||||
o.SHA256 == other.SHA256
|
||||
}
|
||||
|
||||
func (o *ReleaseAsset) Clone() Interface {
|
||||
clone := &ReleaseAsset{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
45
f3/repository.go
Normal file
45
f3/repository.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const (
|
||||
RepositoryNameDefault = "vcs"
|
||||
RepositoryNameWiki = "vcs.wiki"
|
||||
)
|
||||
|
||||
var nameToID = map[string]int64{
|
||||
RepositoryNameDefault: 1,
|
||||
RepositoryNameWiki: 2,
|
||||
}
|
||||
|
||||
// var RepositoryNames = []string{RepositoryNameDefault, RepositoryNameWiki}
|
||||
|
||||
var RepositoryNames = []string{RepositoryNameDefault}
|
||||
|
||||
type Repository struct {
|
||||
Common
|
||||
|
||||
Name string
|
||||
FetchFunc func(ctx context.Context, destination string, internalRefs []string) `json:"-"`
|
||||
}
|
||||
|
||||
func (o Repository) Equal(other Repository) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
o.Name == other.Name
|
||||
}
|
||||
|
||||
func (o *Repository) Clone() Interface {
|
||||
clone := &Repository{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
||||
|
||||
func RepositoryDirname(name string) string {
|
||||
return "git" + name
|
||||
}
|
39
f3/resources.go
Normal file
39
f3/resources.go
Normal file
|
@ -0,0 +1,39 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
const (
|
||||
ResourceAsset = "asset"
|
||||
ResourceAssets = "assets"
|
||||
ResourceComment = "comment"
|
||||
ResourceComments = "comments"
|
||||
ResourceIssue = "issue"
|
||||
ResourceIssues = "issues"
|
||||
ResourceLabel = "label"
|
||||
ResourceLabels = "labels"
|
||||
ResourceMilestone = "milestone"
|
||||
ResourceMilestones = "milestones"
|
||||
ResourceOrganization = "organization"
|
||||
ResourceOrganizations = "organizations"
|
||||
ResourceProject = "project"
|
||||
ResourceProjects = "projects"
|
||||
ResourcePullRequest = "pull_request"
|
||||
ResourcePullRequests = "pull_requests"
|
||||
ResourceReaction = "reaction"
|
||||
ResourceReactions = "reactions"
|
||||
ResourceRelease = "release"
|
||||
ResourceReleases = "releases"
|
||||
ResourceRepository = "repository"
|
||||
ResourceRepositories = "repositories"
|
||||
ResourceReview = "review"
|
||||
ResourceReviews = "reviews"
|
||||
ResourceReviewComment = "reviewcomment"
|
||||
ResourceReviewComments = "reviewcomments"
|
||||
ResourceTopic = "topic"
|
||||
ResourceTopics = "topics"
|
||||
ResourceUser = "user"
|
||||
ResourceUsers = "users"
|
||||
ResourceForge = "forge"
|
||||
)
|
48
f3/review.go
Normal file
48
f3/review.go
Normal file
|
@ -0,0 +1,48 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
ReviewStatePending = "PENDING"
|
||||
ReviewStateApproved = "APPROVED"
|
||||
ReviewStateChangesRequested = "CHANGES_REQUESTED"
|
||||
ReviewStateCommented = "COMMENTED"
|
||||
ReviewStateRequestReview = "REQUEST_REVIEW"
|
||||
ReviewStateUnknown = ""
|
||||
)
|
||||
|
||||
type Review struct {
|
||||
Common
|
||||
ReviewerID *Reference `json:"reviewer_id"`
|
||||
Official bool `json:"official"`
|
||||
CommitID string `json:"commit_id"`
|
||||
Content string `json:"content"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
func (o Review) Equal(other Review) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
nilOrEqual(o.ReviewerID, other.ReviewerID) &&
|
||||
o.CommitID == other.CommitID &&
|
||||
o.Content == other.Content &&
|
||||
o.State == other.State
|
||||
}
|
||||
|
||||
func (o *Review) GetReferences() References {
|
||||
references := o.Common.GetReferences()
|
||||
if !o.ReviewerID.IsNil() {
|
||||
references = append(references, o.ReviewerID)
|
||||
}
|
||||
return references
|
||||
}
|
||||
|
||||
func (o *Review) Clone() Interface {
|
||||
clone := &Review{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
46
f3/reviewcomment.go
Normal file
46
f3/reviewcomment.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type ReviewComment struct {
|
||||
Common
|
||||
Content string `json:"content"`
|
||||
TreePath string `json:"tree_path"`
|
||||
DiffHunk string `json:"diff_hunk"`
|
||||
Line int `json:"line"`
|
||||
LinesCount int `json:"lines_count"`
|
||||
CommitID string `json:"commit_id"`
|
||||
PosterID *Reference `json:"poster_id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (o ReviewComment) Equal(other ReviewComment) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
o.Content == other.Content &&
|
||||
o.TreePath == other.TreePath &&
|
||||
o.Line == other.Line &&
|
||||
o.LinesCount == other.LinesCount &&
|
||||
o.CommitID == other.CommitID &&
|
||||
nilOrEqual(o.PosterID, other.PosterID)
|
||||
}
|
||||
|
||||
func (o *ReviewComment) GetReferences() References {
|
||||
references := o.Common.GetReferences()
|
||||
if !o.PosterID.IsNil() {
|
||||
references = append(references, o.PosterID)
|
||||
}
|
||||
return references
|
||||
}
|
||||
|
||||
func (o *ReviewComment) Clone() Interface {
|
||||
clone := &ReviewComment{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
42
f3/schemas/ci.json
Normal file
42
f3/schemas/ci.json
Normal file
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"title": "CI",
|
||||
"description": "The Continuous Integration supported by the project. The configuration files are found in the repository itself, under a path that depends on the CI system.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "The type of continuous integration",
|
||||
"enum": [
|
||||
"Apache Gump",
|
||||
"Azure DevOps Server",
|
||||
"Bamboo",
|
||||
"Buddy",
|
||||
"Buildbot",
|
||||
"BuildMaster",
|
||||
"CircleCI",
|
||||
"Drone",
|
||||
"Forgejo Actions",
|
||||
"Gitea Actions",
|
||||
"GitHub Actions",
|
||||
"GitLab",
|
||||
"GoCD",
|
||||
"Jenkins",
|
||||
"OpenMake",
|
||||
"Semaphore",
|
||||
"TeamCity",
|
||||
"tekton",
|
||||
"Travis CI",
|
||||
"Vexor",
|
||||
"Woodpecker CI"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/ci.json",
|
||||
"$$target": "ci.json"
|
||||
}
|
49
f3/schemas/comment.json
Normal file
49
f3/schemas/comment.json
Normal file
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"title": "Comment",
|
||||
"description": "Comment associated to a commentable object (i.e. issue, review, etc.). Forge users add a comment to an object to create a non-threaded conversation.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier of the comment.",
|
||||
"type": "string"
|
||||
},
|
||||
"poster_id": {
|
||||
"description": "Unique identifier of the comment author.",
|
||||
"type": "string"
|
||||
},
|
||||
"created": {
|
||||
"description": "Creation time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"updated": {
|
||||
"description": "Last update time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"content": {
|
||||
"description": "Markdown content of the comment.",
|
||||
"type": "string"
|
||||
},
|
||||
"reactions": {
|
||||
"description": "List of reactions.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "reaction.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"poster_id",
|
||||
"created",
|
||||
"updated",
|
||||
"content"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/comment.json",
|
||||
"$$target": "comment.json"
|
||||
}
|
22
f3/schemas/index.rst
Normal file
22
f3/schemas/index.rst
Normal file
|
@ -0,0 +1,22 @@
|
|||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
.. jsonschema:: ci.json
|
||||
.. jsonschema:: comment.json
|
||||
.. jsonschema:: issue.json
|
||||
.. jsonschema:: label.json
|
||||
.. jsonschema:: milestone.json
|
||||
.. jsonschema:: object.json
|
||||
.. jsonschema:: organization.json
|
||||
.. jsonschema:: project.json
|
||||
.. jsonschema:: pullrequest.json
|
||||
.. jsonschema:: pullrequestbranch.json
|
||||
.. jsonschema:: reaction.json
|
||||
.. jsonschema:: release.json
|
||||
.. jsonschema:: releaseasset.json
|
||||
.. jsonschema:: repository.json
|
||||
.. jsonschema:: review.json
|
||||
.. jsonschema:: reviewcomment.json
|
||||
.. jsonschema:: topic.json
|
||||
.. jsonschema:: user.json
|
||||
|
96
f3/schemas/issue.json
Normal file
96
f3/schemas/issue.json
Normal file
|
@ -0,0 +1,96 @@
|
|||
{
|
||||
"title": "Issue",
|
||||
"description": "An issue within an issue tracking system, relative to a project.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier of the issue.",
|
||||
"type": "string"
|
||||
},
|
||||
"poster_id": {
|
||||
"description": "Unique identifier of the user who authored the issue.",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "Short description displayed as the title.",
|
||||
"type": "string"
|
||||
},
|
||||
"content": {
|
||||
"description": "Description of the issue.",
|
||||
"type": "string"
|
||||
},
|
||||
"milestone": {
|
||||
"description": "Unique identifier of the milestone.",
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"description": "An issue is 'closed' when it is resolved, 'open' otherwise. Issues that do not relate to a topic that needs to be resolved, such as an open conversation, may never be closed.",
|
||||
"enum": [
|
||||
"closed",
|
||||
"open"
|
||||
]
|
||||
},
|
||||
"is_locked": {
|
||||
"description": "A locked issue can only be modified by privileged users. It is commonly used for moderation purposes when comments associated with the issue are too heated.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"created": {
|
||||
"description": "Creation time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"updated": {
|
||||
"description": "Last update time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"closed": {
|
||||
"description": "The last time 'state' changed to 'closed'.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"due": {
|
||||
"description": "Due date.",
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"labels": {
|
||||
"description": "List of label unique identifiers.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"reactions": {
|
||||
"description": "List of reactions.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "reaction.json"
|
||||
}
|
||||
},
|
||||
"assignees": {
|
||||
"description": "List of assignees.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Name of a user assigned to the issue.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"poster_id",
|
||||
"title",
|
||||
"content",
|
||||
"state",
|
||||
"is_locked",
|
||||
"created",
|
||||
"updated"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/issue.json",
|
||||
"$$target": "issue.json"
|
||||
}
|
37
f3/schemas/label.json
Normal file
37
f3/schemas/label.json
Normal file
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"title": "Label",
|
||||
"description": "Label associated to an issue.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Name of the label, unique within the repository.",
|
||||
"type": "string"
|
||||
},
|
||||
"color": {
|
||||
"description": "Color code of the label in RGB notation 'xxx' or 'xxxxxx'.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Long description.",
|
||||
"type": "string"
|
||||
},
|
||||
"exclusive": {
|
||||
"description": "There can only be one label with the prefix found before the first slash (/).",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"name"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/label.json",
|
||||
"$$target": "label.json"
|
||||
}
|
62
f3/schemas/milestone.json
Normal file
62
f3/schemas/milestone.json
Normal file
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"title": "Milestone",
|
||||
"description": "Milestone relative to a project, for the purpose of grouping objects due to a given date (issues, etc.).",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier.",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "Short description.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Long description.",
|
||||
"type": "string"
|
||||
},
|
||||
"deadline": {
|
||||
"description": "Deadline after which the milestone is overdue.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"created": {
|
||||
"description": "Creation time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"updated": {
|
||||
"description": "Last update time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"closed": {
|
||||
"description": "The last time 'state' changed to 'closed'.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"state": {
|
||||
"description": "A 'closed' milestone will not see any activity in the future, otherwise it is 'open'.",
|
||||
"enum": [
|
||||
"closed",
|
||||
"open"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"title",
|
||||
"description",
|
||||
"deadline",
|
||||
"created",
|
||||
"updated",
|
||||
"closed",
|
||||
"state"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/milestone.json",
|
||||
"$$target": "milestone.json"
|
||||
}
|
35
f3/schemas/object.json
Normal file
35
f3/schemas/object.json
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"title": "Object",
|
||||
"description": "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.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier.",
|
||||
"type": "string"
|
||||
},
|
||||
"mime": {
|
||||
"description": "Mime type of the object.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Human readable file name.",
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"description": "Description.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"mime",
|
||||
"name",
|
||||
"description"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/object.json",
|
||||
"$$target": "object.json"
|
||||
}
|
29
f3/schemas/organization.json
Normal file
29
f3/schemas/organization.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"title": "Organization",
|
||||
"description": "A forge organization.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier of the organization.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Unique name of the organization.",
|
||||
"type": "string"
|
||||
},
|
||||
"full_name": {
|
||||
"description": "Readable name of the organization.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"name"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/organization.json",
|
||||
"$$target": "organization.json"
|
||||
}
|
117
f3/schemas/project.json
Normal file
117
f3/schemas/project.json
Normal file
|
@ -0,0 +1,117 @@
|
|||
{
|
||||
"title": "Project",
|
||||
"description": "A software project contains a code repository, an issue tracker, etc.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier of the project.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Name of the project, relative to the owner.",
|
||||
"type": "string"
|
||||
},
|
||||
"is_private": {
|
||||
"description": "True if the visibility of the project is not public.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"is_mirror": {
|
||||
"description": "True if it is a mirror of a project residing on another forge.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"description": {
|
||||
"description": "Long description of the project.",
|
||||
"type": "string"
|
||||
},
|
||||
"default_branch": {
|
||||
"description": "Name of the default branch in the code repository.",
|
||||
"type": "string"
|
||||
},
|
||||
"repositories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "repository.json"
|
||||
}
|
||||
},
|
||||
"forked": {
|
||||
"description": "Unique identifier of the project from which this one was forked.",
|
||||
"type": "string"
|
||||
},
|
||||
"ci": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "ci.json"
|
||||
}
|
||||
},
|
||||
"archived": {
|
||||
"description": "True if archived and read only.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"archived_at": {
|
||||
"description": "Time of archival.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"created": {
|
||||
"description": "Creation time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"updated": {
|
||||
"description": "Last update time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"url": {
|
||||
"description": "URL associated with the project, for instance the project home page.",
|
||||
"type": "string"
|
||||
},
|
||||
"stars": {
|
||||
"description": "Number of stars.",
|
||||
"type": "number"
|
||||
},
|
||||
"has_ci": {
|
||||
"description": "True if CI is enabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"has_issues": {
|
||||
"description": "True if the issue tracker is enabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"has_packages": {
|
||||
"description": "True if the software packages are enabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"has_kanban": {
|
||||
"description": "True if the kanban is enabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"has_pull_requests": {
|
||||
"description": "True if pull requests are enabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"has_releases": {
|
||||
"description": "True if releases are enabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"has_wiki": {
|
||||
"description": "True if the wiki is enabled.",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"name",
|
||||
"is_private",
|
||||
"is_mirror",
|
||||
"description",
|
||||
"default_branch",
|
||||
"repositories"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/project.json",
|
||||
"$$target": "project.json"
|
||||
}
|
134
f3/schemas/pullrequest.json
Normal file
134
f3/schemas/pullrequest.json
Normal file
|
@ -0,0 +1,134 @@
|
|||
{
|
||||
"title": "Pull request",
|
||||
"description": "A pull requests to merge a commit from a 'head' that may be another branch in the same repository or a branch in a forked repository.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier of the pull request.",
|
||||
"type": "string"
|
||||
},
|
||||
"poster_id": {
|
||||
"description": "Unique identifier of the user who authored the pull request.",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "Short description displayed as the title.",
|
||||
"type": "string"
|
||||
},
|
||||
"content": {
|
||||
"description": "Long description.",
|
||||
"type": "string"
|
||||
},
|
||||
"milestone": {
|
||||
"description": "Unique identifier of the milestone.",
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"description": "A 'closed' pull request will not see any activity in the future, otherwise it is 'open'.",
|
||||
"enum": [
|
||||
"closed",
|
||||
"open"
|
||||
]
|
||||
},
|
||||
"is_locked": {
|
||||
"description": "A locked pull request can only be modified by privileged users.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"created": {
|
||||
"description": "Creation time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"updated": {
|
||||
"description": "Last update time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"closed": {
|
||||
"description": "The last time 'state' changed to 'closed'.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"labels": {
|
||||
"description": "List of labels unique identifiers.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"reactions": {
|
||||
"description": "List of reactions.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "reaction.json"
|
||||
}
|
||||
},
|
||||
"assignees": {
|
||||
"description": "List of assignees.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Name of a user assigned to the issue.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"merged": {
|
||||
"description": "True if the pull request was merged.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"merged_time": {
|
||||
"description": "The time when the pull request was merged.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"merged_commit_sha": {
|
||||
"description": "The SHA of the merge commit.",
|
||||
"type": "string"
|
||||
},
|
||||
"head": {
|
||||
"description": "The changes proposed in the pull request.",
|
||||
"type": "object",
|
||||
"items": {
|
||||
"$ref": "pullrequestbranch.json"
|
||||
}
|
||||
},
|
||||
"base": {
|
||||
"description": "The branch where the pull request changes in the head are to be merged.",
|
||||
"type": "object",
|
||||
"items": {
|
||||
"$ref": "pullrequestbranch.json"
|
||||
}
|
||||
},
|
||||
"merged_by": {
|
||||
"description": "Unique identifier of the user who merged the pull request.",
|
||||
"type": "string"
|
||||
},
|
||||
"due": {
|
||||
"description": "Due date.",
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"allow_edit": {
|
||||
"description": "True when the author of the pull request allows pushing new commits to its branch.",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"poster_id",
|
||||
"title",
|
||||
"content",
|
||||
"state",
|
||||
"is_locked",
|
||||
"created",
|
||||
"updated",
|
||||
"merged",
|
||||
"head",
|
||||
"base"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/pullrequest.json",
|
||||
"$$target": "pullrequest.json"
|
||||
}
|
30
f3/schemas/pullrequestbranch.json
Normal file
30
f3/schemas/pullrequestbranch.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"title": "Pull request reference to a commit",
|
||||
"description": "The location of a commit and the repository where it can be found.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"ref": {
|
||||
"description": "Repository reference of the commit (branch, tag, etc.).",
|
||||
"type": "string"
|
||||
},
|
||||
"sha": {
|
||||
"description": "SHA of the commit.",
|
||||
"type": "string"
|
||||
},
|
||||
"repository": {
|
||||
"description": "Unique identifier of the repository.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"ref",
|
||||
"sha",
|
||||
"repository"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/pullrequestbranch.json",
|
||||
"$$target": "pullrequestbranch.json"
|
||||
}
|
30
f3/schemas/reaction.json
Normal file
30
f3/schemas/reaction.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"title": "Reaction",
|
||||
"description": "Reaction associated to a comment that is displayed as a single emoji.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier of the reaction.",
|
||||
"type": "string"
|
||||
},
|
||||
"user_id": {
|
||||
"description": "Unique identifier of the user who authored the reaction.",
|
||||
"type": "string"
|
||||
},
|
||||
"content": {
|
||||
"description": "Representation of the reaction. The rendering of the reaction depends on the forge displaying it.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"user_id",
|
||||
"content"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/reaction.json",
|
||||
"$$target": "reaction.json"
|
||||
}
|
60
f3/schemas/release.json
Normal file
60
f3/schemas/release.json
Normal file
|
@ -0,0 +1,60 @@
|
|||
{
|
||||
"title": "Release",
|
||||
"description": "A release is associated with a tag in a repository and contains of a set of files (release assets).",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier of the release.",
|
||||
"type": "string"
|
||||
},
|
||||
"tag_name": {
|
||||
"description": "Tag name of the release.",
|
||||
"type": "string"
|
||||
},
|
||||
"target_commitish": {
|
||||
"description": "Specifies the commitish value that determines where the tag is created from. Can be any branch or commit SHA. Unused if the tag already exists.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "The name of the release.",
|
||||
"type": "string"
|
||||
},
|
||||
"body": {
|
||||
"description": "Text describing the contents of the release, usually the release notes.",
|
||||
"type": "string"
|
||||
},
|
||||
"draft": {
|
||||
"description": "True if the release is a draft.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"prerelease": {
|
||||
"description": "True if the release is a pre-release.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"publisher_id": {
|
||||
"description": "Unique identifier of the user who authored the release.",
|
||||
"type": "string"
|
||||
},
|
||||
"created": {
|
||||
"description": "Creation time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"tag_name",
|
||||
"name",
|
||||
"body",
|
||||
"draft",
|
||||
"prerelease",
|
||||
"publisher_id",
|
||||
"created"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/release.json",
|
||||
"$$target": "release.json"
|
||||
}
|
61
f3/schemas/releaseasset.json
Normal file
61
f3/schemas/releaseasset.json
Normal file
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"title": "Release asset",
|
||||
"description": "A file associated with a release. The content of the file is opaque.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier of the release asset.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "The name of the release asset.",
|
||||
"type": "string"
|
||||
},
|
||||
"content_type": {
|
||||
"description": "The content type of the release asset (application/zip, etc.).",
|
||||
"type": "string"
|
||||
},
|
||||
"size": {
|
||||
"description": "Size in bytes of the release asset.",
|
||||
"type": "number"
|
||||
},
|
||||
"download_count": {
|
||||
"description": "The number of times the release asset was downloaded.",
|
||||
"type": "number"
|
||||
},
|
||||
"download_url": {
|
||||
"description": "The URL from which the release asset can be downloaded.",
|
||||
"type": "string"
|
||||
},
|
||||
"created": {
|
||||
"description": "Creation time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"updated": {
|
||||
"description": "Last update time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"sha256": {
|
||||
"description": "SHA256 of the cnotent of the asset.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"name",
|
||||
"content_type",
|
||||
"size",
|
||||
"download_count",
|
||||
"created",
|
||||
"updated",
|
||||
"sha256"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/releaseasset.json",
|
||||
"$$target": "releaseasset.json"
|
||||
}
|
31
f3/schemas/repository.json
Normal file
31
f3/schemas/repository.json
Normal file
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"title": "Repository",
|
||||
"description": "VCS repository relative to a project. The actual content of the repository is found in the sibling 'repository' directory.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Unique name of the repository relative to the project (e.g. vcs or vcs.wiki).",
|
||||
"type": "string"
|
||||
},
|
||||
"vcs": {
|
||||
"description": "The type of the repository, defaults to 'git'",
|
||||
"enum": [
|
||||
"git",
|
||||
"hg",
|
||||
"bazaar",
|
||||
"darcs",
|
||||
"fossil",
|
||||
"svn"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/repository.json",
|
||||
"$$target": "repository.json"
|
||||
}
|
63
f3/schemas/review.json
Normal file
63
f3/schemas/review.json
Normal file
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"title": "Review",
|
||||
"description": "A set of review comments on a pull/merge request.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier of the review.",
|
||||
"type": "string"
|
||||
},
|
||||
"reviewer_id": {
|
||||
"description": "Unique identifier of review author.",
|
||||
"type": "string"
|
||||
},
|
||||
"official": {
|
||||
"description": "True if a positive review counts to reach the required threshold.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"commit_id": {
|
||||
"description": "SHA of the commit targeted by the review.",
|
||||
"type": "string"
|
||||
},
|
||||
"content": {
|
||||
"description": "Cover message of the review.",
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"description": "Creation time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"state": {
|
||||
"description": "State of the review.",
|
||||
"enum": [
|
||||
"PENDING",
|
||||
"APPROVED",
|
||||
"CHANGES_REQUESTED",
|
||||
"COMMENTED"
|
||||
]
|
||||
},
|
||||
"dissmissed": {
|
||||
"description": "True if the review was dismissed.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"stale": {
|
||||
"description": "True if the review is stale because the pull request content changed after it was published.",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"reviewer_id",
|
||||
"commit_id",
|
||||
"content",
|
||||
"created_at",
|
||||
"state"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/review.json",
|
||||
"$$target": "review.json"
|
||||
}
|
77
f3/schemas/reviewcomment.json
Normal file
77
f3/schemas/reviewcomment.json
Normal file
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"title": "Review comment",
|
||||
"description": "A comment in the context of a review.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier of the review comment.",
|
||||
"type": "string"
|
||||
},
|
||||
"content": {
|
||||
"description": "The text of the review comment.",
|
||||
"type": "string"
|
||||
},
|
||||
"tree_path": {
|
||||
"description": "The relative path to the file commented on.",
|
||||
"type": "string"
|
||||
},
|
||||
"diff_hunk": {
|
||||
"description": "The hunk commented on.",
|
||||
"type": "string"
|
||||
},
|
||||
"line": {
|
||||
"description": "The line number of the comment relative to the tree_path.",
|
||||
"type": "number"
|
||||
},
|
||||
"lines_count": {
|
||||
"description": "The range of lines that are commented on. If absent it defaults to one and is a single line comment. If specified it must be a positive number. If line is N and lines_count is C, the range of lines commented on is ]N-C,N]. In other words, the range starts lines_count before line, which is the last of the range",
|
||||
"type": "number"
|
||||
},
|
||||
"commit_id": {
|
||||
"description": "The SHA of the tree_path commented on.",
|
||||
"type": "string"
|
||||
},
|
||||
"poster_id": {
|
||||
"description": "Unique identifier of the user who authored the comment.",
|
||||
"type": "string"
|
||||
},
|
||||
"reactions": {
|
||||
"description": "List of reactions.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "reaction.json"
|
||||
}
|
||||
},
|
||||
"created_at": {
|
||||
"description": "Creation time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"updated_at": {
|
||||
"description": "Last update time.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"resolver": {
|
||||
"description": "Unique identifier of the user who resolved the comment.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"content",
|
||||
"tree_path",
|
||||
"diff_hunk",
|
||||
"line",
|
||||
"commit_id",
|
||||
"poster_id",
|
||||
"created_at",
|
||||
"updated_at"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/reviewcomment.json",
|
||||
"$$target": "reviewcomment.json"
|
||||
}
|
25
f3/schemas/topic.json
Normal file
25
f3/schemas/topic.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"title": "Topic",
|
||||
"description": "A category associated with a project. There can be multiple topics/categories for a given project.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "The name of the category the project belongs to.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"name"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/topic.json",
|
||||
"$$target": "topic.json"
|
||||
}
|
42
f3/schemas/user.json
Normal file
42
f3/schemas/user.json
Normal file
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"title": "User",
|
||||
"description": "A forge user.",
|
||||
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"index": {
|
||||
"description": "Unique identifier of the user.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "User readable name of the user.",
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"description": "Mail of the user.",
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"description": "Unique name of the user.",
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"description": "Password of the user.",
|
||||
"type": "string"
|
||||
},
|
||||
"admin": {
|
||||
"description": "True if the user has administrative permissions on the forge.",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"index",
|
||||
"name",
|
||||
"username"
|
||||
],
|
||||
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$id": "https://code.forgejo.org/f3/f3-schemas/src/branch/main/user.json",
|
||||
"$$target": "user.json"
|
||||
}
|
21
f3/topic.go
Normal file
21
f3/topic.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
type Topic struct {
|
||||
Common
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (o Topic) Equal(other Topic) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
o.Name == other.Name
|
||||
}
|
||||
|
||||
func (o *Topic) Clone() Interface {
|
||||
clone := &Topic{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
32
f3/user.go
Normal file
32
f3/user.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package f3
|
||||
|
||||
type User struct {
|
||||
Common
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
UserName string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
IsAdmin bool `json:"admin"`
|
||||
}
|
||||
|
||||
func (o User) Equal(other User) bool {
|
||||
return o.Common.Equal(other.Common) &&
|
||||
o.Name == other.Name &&
|
||||
o.Email == other.Email &&
|
||||
o.UserName == other.UserName &&
|
||||
o.IsAdmin == other.IsAdmin
|
||||
}
|
||||
|
||||
func (o *User) GetName() string {
|
||||
return o.UserName
|
||||
}
|
||||
|
||||
func (o *User) Clone() Interface {
|
||||
clone := &User{}
|
||||
*clone = *o
|
||||
return clone
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue