gitech

Форк
0
/
file_format.go 
110 строк · 2.1 Кб
1
// Copyright 2022 The Gitea Authors. All rights reserved.
2
// SPDX-License-Identifier: MIT
3

4
package migration
5

6
import (
7
	"fmt"
8
	"os"
9
	"strings"
10
	"time"
11

12
	"code.gitea.io/gitea/modules/json"
13
	"code.gitea.io/gitea/modules/log"
14

15
	"github.com/santhosh-tekuri/jsonschema/v5"
16
	"gopkg.in/yaml.v3"
17
)
18

19
// Load project data from file, with optional validation
20
func Load(filename string, data any, validation bool) error {
21
	isJSON := strings.HasSuffix(filename, ".json")
22

23
	bs, err := os.ReadFile(filename)
24
	if err != nil {
25
		return err
26
	}
27

28
	if validation {
29
		err := validate(bs, data, isJSON)
30
		if err != nil {
31
			return err
32
		}
33
	}
34
	return unmarshal(bs, data, isJSON)
35
}
36

37
func unmarshal(bs []byte, data any, isJSON bool) error {
38
	if isJSON {
39
		return json.Unmarshal(bs, data)
40
	}
41
	return yaml.Unmarshal(bs, data)
42
}
43

44
func getSchema(filename string) (*jsonschema.Schema, error) {
45
	c := jsonschema.NewCompiler()
46
	c.LoadURL = openSchema
47
	return c.Compile(filename)
48
}
49

50
func validate(bs []byte, datatype any, isJSON bool) error {
51
	var v any
52
	err := unmarshal(bs, &v, isJSON)
53
	if err != nil {
54
		return err
55
	}
56
	if !isJSON {
57
		v, err = toStringKeys(v)
58
		if err != nil {
59
			return err
60
		}
61
	}
62

63
	var schemaFilename string
64
	switch datatype := datatype.(type) {
65
	case *[]*Issue:
66
		schemaFilename = "issue.json"
67
	case *[]*Milestone:
68
		schemaFilename = "milestone.json"
69
	default:
70
		return fmt.Errorf("file_format:validate: %T has not a validation implemented", datatype)
71
	}
72

73
	sch, err := getSchema(schemaFilename)
74
	if err != nil {
75
		return err
76
	}
77
	err = sch.Validate(v)
78
	if err != nil {
79
		log.Error("migration validation with %s failed:\n%#v", schemaFilename, err)
80
	}
81
	return err
82
}
83

84
func toStringKeys(val any) (any, error) {
85
	var err error
86
	switch val := val.(type) {
87
	case map[string]any:
88
		m := make(map[string]any)
89
		for k, v := range val {
90
			m[k], err = toStringKeys(v)
91
			if err != nil {
92
				return nil, err
93
			}
94
		}
95
		return m, nil
96
	case []any:
97
		l := make([]any, len(val))
98
		for i, v := range val {
99
			l[i], err = toStringKeys(v)
100
			if err != nil {
101
				return nil, err
102
			}
103
		}
104
		return l, nil
105
	case time.Time:
106
		return val.Format(time.RFC3339), nil
107
	default:
108
		return val, nil
109
	}
110
}
111

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.