...
1 package main
2
3 import (
4 "fmt"
5 "io"
6 "os"
7 "path/filepath"
8 "strings"
9
10 "github.com/xeipuuv/gojsonschema"
11 )
12
13 const usage = `Validate is used to check document with specified schema.
14 You can use validate in following ways:
15
16 1.specify document file as an argument
17 validate <schema.json> <document.json>
18
19 2.pass document content through a pipe
20 cat <document.json> | validate <schema.json>
21
22 3.input document content manually, ended with ctrl+d(or your self-defined EOF keys)
23 validate <schema.json>
24 [INPUT DOCUMENT CONTENT HERE]
25 `
26
27 func main() {
28 nargs := len(os.Args[1:])
29 if nargs == 0 || nargs > 2 {
30 fmt.Printf("ERROR: invalid arguments number\n\n%s\n", usage)
31 os.Exit(1)
32 }
33
34 if os.Args[1] == "help" ||
35 os.Args[1] == "--help" ||
36 os.Args[1] == "-h" {
37 fmt.Printf("%s\n", usage)
38 os.Exit(1)
39 }
40
41 schemaPath := os.Args[1]
42 if !strings.Contains(schemaPath, "://") {
43 var err error
44 schemaPath, err = formatFilePath(schemaPath)
45 if err != nil {
46 fmt.Printf("ERROR: invalid schema-file path: %s\n", err)
47 os.Exit(1)
48 }
49 schemaPath = "file://" + schemaPath
50 }
51
52 schemaLoader := gojsonschema.NewReferenceLoader(schemaPath)
53
54 var documentLoader gojsonschema.JSONLoader
55
56 if nargs > 1 {
57 documentPath, err := formatFilePath(os.Args[2])
58 if err != nil {
59 fmt.Printf("ERROR: invalid document-file path: %s\n", err)
60 os.Exit(1)
61 }
62 documentLoader = gojsonschema.NewReferenceLoader("file://" + documentPath)
63 } else {
64 documentBytes, err := io.ReadAll(os.Stdin)
65 if err != nil {
66 fmt.Println(err)
67 os.Exit(1)
68 }
69 documentString := string(documentBytes)
70 documentLoader = gojsonschema.NewStringLoader(documentString)
71 }
72
73 result, err := gojsonschema.Validate(schemaLoader, documentLoader)
74 if err != nil {
75 fmt.Println(err)
76 os.Exit(1)
77 }
78
79 if result.Valid() {
80 fmt.Printf("The document is valid\n")
81 } else {
82 fmt.Printf("The document is not valid. see errors :\n")
83 for _, desc := range result.Errors() {
84 fmt.Printf("- %s\n", desc)
85 }
86 os.Exit(1)
87 }
88 }
89
90 func formatFilePath(path string) (string, error) {
91 if _, err := os.Stat(path); err != nil {
92 return "", err
93 }
94
95 absPath, err := filepath.Abs(path)
96 if err != nil {
97 return "", err
98 }
99 return absPath, nil
100 }
101
View as plain text