|
1 | 1 | /* |
2 | | - * From: https://github.com/opencontainers/runtime-spec/blob/643c1429d905bba70fe977bae274f367ad101e73/schema/validate.go |
| 2 | + * Original code from: https://github.com/opencontainers/runtime-spec/blob/643c1429d905bba70fe977bae274f367ad101e73/schema/validate.go |
3 | 3 | * Changes: |
4 | 4 | * - Output errors to stderr |
| 5 | + * - Refactored to use package-internal validation library |
5 | 6 | * |
6 | 7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
7 | 8 | * you may not use this file except in compliance with the License. |
|
19 | 20 | package main |
20 | 21 |
|
21 | 22 | import ( |
| 23 | + "flag" |
22 | 24 | "fmt" |
23 | 25 | "io/ioutil" |
24 | 26 | "os" |
25 | | - "path/filepath" |
26 | | - "strings" |
27 | 27 |
|
28 | | - "github.com/xeipuuv/gojsonschema" |
| 28 | + "github.com/container-orchestrated-devices/container-device-interface/schema" |
29 | 29 | ) |
30 | 30 |
|
31 | 31 | const usage = `Validate is used to check document with specified schema. |
32 | 32 | You can use validate in following ways: |
33 | 33 |
|
34 | 34 | 1.specify document file as an argument |
35 | | - validate <schema.json> <document.json> |
| 35 | + validate --schema <schema.json> <document.json> |
36 | 36 |
|
37 | 37 | 2.pass document content through a pipe |
38 | | - cat <document.json> | validate <schema.json> |
| 38 | + cat <document.json> | validate --schema <schema.json> |
39 | 39 |
|
40 | 40 | 3.input document content manually, ended with ctrl+d(or your self-defined EOF keys) |
41 | | - validate <schema.json> |
| 41 | + validate --schema <schema.json> |
42 | 42 | [INPUT DOCUMENT CONTENT HERE] |
43 | 43 | ` |
44 | 44 |
|
45 | 45 | func main() { |
46 | | - nargs := len(os.Args[1:]) |
47 | | - if nargs == 0 || nargs > 2 { |
48 | | - fmt.Printf("ERROR: invalid arguments number\n\n%s\n", usage) |
49 | | - os.Exit(1) |
| 46 | + var ( |
| 47 | + schemaFile string |
| 48 | + docFile string |
| 49 | + docData []byte |
| 50 | + err error |
| 51 | + exitCode int |
| 52 | + ) |
| 53 | + |
| 54 | + flag.Usage = func() { |
| 55 | + fmt.Fprintf(flag.CommandLine.Output(), "%s\n", usage) |
| 56 | + fmt.Fprintf(flag.CommandLine.Output(), "Usage of %s:\n", os.Args[0]) |
| 57 | + flag.PrintDefaults() |
50 | 58 | } |
51 | 59 |
|
52 | | - if os.Args[1] == "help" || |
53 | | - os.Args[1] == "--help" || |
54 | | - os.Args[1] == "-h" { |
55 | | - fmt.Printf("%s\n", usage) |
56 | | - os.Exit(1) |
57 | | - } |
| 60 | + flag.StringVar(&schemaFile, "schema", "builtin", "JSON Schema to validate against") |
| 61 | + flag.Parse() |
58 | 62 |
|
59 | | - schemaPath := os.Args[1] |
60 | | - if !strings.Contains(schemaPath, "://") { |
61 | | - var err error |
62 | | - schemaPath, err = formatFilePath(schemaPath) |
| 63 | + if schemaFile != "" { |
| 64 | + scm, err := schema.Load(schemaFile) |
63 | 65 | if err != nil { |
64 | | - fmt.Printf("ERROR: invalid schema-file path: %s\n", err) |
| 66 | + fmt.Fprintf(os.Stderr, "failed to load schema %s: %v\n", schemaFile, err) |
65 | 67 | os.Exit(1) |
66 | 68 | } |
67 | | - schemaPath = "file://" + schemaPath |
68 | | - } |
69 | | - |
70 | | - schemaLoader := gojsonschema.NewReferenceLoader(schemaPath) |
71 | | - |
72 | | - var documentLoader gojsonschema.JSONLoader |
73 | | - |
74 | | - if nargs > 1 { |
75 | | - documentPath, err := formatFilePath(os.Args[2]) |
76 | | - if err != nil { |
77 | | - fmt.Printf("ERROR: invalid document-file path: %s\n", err) |
78 | | - os.Exit(1) |
79 | | - } |
80 | | - documentLoader = gojsonschema.NewReferenceLoader("file://" + documentPath) |
| 69 | + schema.Set(scm) |
| 70 | + fmt.Printf("Validating against JSON schema %s...\n", schemaFile) |
81 | 71 | } else { |
82 | | - documentBytes, err := ioutil.ReadAll(os.Stdin) |
83 | | - if err != nil { |
84 | | - fmt.Println(err) |
85 | | - os.Exit(1) |
86 | | - } |
87 | | - documentString := string(documentBytes) |
88 | | - documentLoader = gojsonschema.NewStringLoader(documentString) |
| 72 | + fmt.Printf("Validating against builtin JSON schema...\n") |
89 | 73 | } |
90 | 74 |
|
91 | | - result, err := gojsonschema.Validate(schemaLoader, documentLoader) |
92 | | - if err != nil { |
93 | | - fmt.Println(err) |
94 | | - os.Exit(1) |
| 75 | + docs := flag.Args() |
| 76 | + if len(docs) == 0 { |
| 77 | + docs = []string{"-"} |
95 | 78 | } |
96 | 79 |
|
97 | | - if result.Valid() { |
98 | | - fmt.Printf("The document is valid\n") |
99 | | - } else { |
100 | | - fmt.Fprintf(os.Stderr, "The document is not valid. see errors :\n") |
101 | | - for _, desc := range result.Errors() { |
102 | | - fmt.Fprintf(os.Stderr, "- %s\n", desc) |
| 80 | + for _, docFile = range docs { |
| 81 | + if docFile == "" || docFile == "-" { |
| 82 | + docFile = "<stdin>" |
| 83 | + docData, err = ioutil.ReadAll(os.Stdin) |
| 84 | + if err != nil { |
| 85 | + fmt.Fprintf(os.Stderr, "failed to read document data from stdin: %v\n", err) |
| 86 | + os.Exit(1) |
| 87 | + } |
| 88 | + err = schema.ValidateData(docData) |
| 89 | + } else { |
| 90 | + err = schema.ValidateFile(docFile) |
103 | 91 | } |
104 | | - os.Exit(1) |
105 | | - } |
106 | | -} |
107 | 92 |
|
108 | | -func formatFilePath(path string) (string, error) { |
109 | | - if _, err := os.Stat(path); err != nil { |
110 | | - return "", err |
| 93 | + if err != nil { |
| 94 | + fmt.Fprintf(os.Stderr, "%s: validation failed:\n %v\n", docFile, err) |
| 95 | + exitCode = 1 |
| 96 | + } else { |
| 97 | + fmt.Printf("%s: document is valid.\n", docFile) |
| 98 | + } |
111 | 99 | } |
112 | 100 |
|
113 | | - absPath, err := filepath.Abs(path) |
114 | | - if err != nil { |
115 | | - return "", err |
116 | | - } |
117 | | - return absPath, nil |
| 101 | + os.Exit(exitCode) |
118 | 102 | } |
0 commit comments