109 lines
2.4 KiB
Go
109 lines
2.4 KiB
Go
// 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)
|
|
}
|