Skip to content

Commit 498ff8c

Browse files
committed
validator: Improve error reporting, add support for multiple files
- Display clickable links to directly jump to error line - Display invalid JSON path - Dynamic error nesting - Support for validation multiple files e.g. `validator.exe .\schema.json .\bucket\*.json` or `validator.exe .\schema.json .\manifest1.json .\manifest2.json`
1 parent b24e7d8 commit 498ff8c

File tree

6 files changed

+81
-25
lines changed

6 files changed

+81
-25
lines changed

Scoop.Validator.cs

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4+
using System.Text;
45
using Newtonsoft.Json;
56
using Newtonsoft.Json.Linq;
67
using Newtonsoft.Json.Schema;
@@ -118,19 +119,44 @@ public bool Validate()
118119

119120
this.Manifest.IsValid(this.Schema, out validationErrors);
120121

121-
if (validationErrors.Count > 0)
122+
if (validationErrors.Count == 0)
122123
{
123-
foreach (ValidationError error in validationErrors)
124-
{
125-
this.Errors.Add(String.Format("{0}{1}: {2}", (this.CI ? " [*] " : ""), this.ManifestFile.Name, error.Message));
126-
foreach (ValidationError childError in error.ChildErrors)
127-
{
128-
this.Errors.Add(String.Format((this.CI ? " [^] {0}{1}" : "{0}^ {1}"), new String(' ', this.ManifestFile.Name.Length + 2), childError.Message));
129-
}
130-
}
124+
return true;
131125
}
126+
traverseErrors(validationErrors, this.CI ? 3 : 1);
132127

133128
return (this.Errors.Count == 0);
134129
}
130+
131+
public void traverseErrors(IList<ValidationError> errors, int level = 1) {
132+
if(errors == null) {
133+
return;
134+
}
135+
foreach (ValidationError error in errors)
136+
{
137+
StringBuilder sb = new StringBuilder();
138+
sb.Insert(sb.Length, " ", level * 2);
139+
sb.Insert(sb.Length, this.CI ? "[*] " : "- ");
140+
sb.AppendFormat("Error: {0}\n", error.Message);
141+
142+
sb.Insert(sb.Length, " ", level * 2);
143+
sb.Insert(sb.Length, this.CI ? " [^] " : " ");
144+
sb.AppendFormat("Line: {0}:{1}:{2}\n", this.ManifestFile.FullName, error.LineNumber, error.LinePosition);
145+
146+
sb.Insert(sb.Length, " ", level * 2);
147+
sb.Insert(sb.Length, this.CI ? " [^] " : " ");
148+
sb.AppendFormat("Path: {0}/{1}", error.SchemaId, error.ErrorType);
149+
150+
if(!this.CI) {
151+
sb.Insert(sb.Length, "\n");
152+
}
153+
154+
this.Errors.Add(sb.ToString());
155+
156+
if(error.ChildErrors != null || error.ChildErrors.Count > 0) {
157+
traverseErrors(error.ChildErrors, level + 1);
158+
}
159+
}
160+
}
135161
}
136162
}

bin/Scoop.Validator.dll

512 Bytes
Binary file not shown.

bin/checksum.sha256

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
f58c374ffcaae4e36d740d90fbf7fe70d0abb7328cd9af3a0a7b70803e994ba4 *Newtonsoft.Json.dll
22
4ca0681df3755205cfd178aaa38f7fd6818c183c4d14c77cd77f8d777282a650 *Newtonsoft.Json.Schema.dll
3-
e077a05608126d44938158da04fe2062513afedba666648ed185d3e25b50436e *Scoop.Validator.dll
4-
cc82c9659716b564a69690a8b67e5472ea1e8e060b974306314acdd42767bf6d *validator.exe
3+
55f1292b42fa2e8a7a4b3eb360fcfffe97be0fe043b4709979fcd37b8a400456 *Scoop.Validator.dll
4+
6dfbe59d9f1c17d362bdd4509975ab40d96e09585aa8d0a1f5527dafbc1c3727 *validator.exe

bin/checksum.sha512

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
7cbbbef742f56af80f1012d7da86fe5375ac05813045756fb45d0691c36ef13c069361457500ba4200157d5ee7922fd118bf4c0635e5192e3f8c6183fd580944 *Newtonsoft.Json.dll
22
2d9c630948c21b325af7b7ad3de9219a3fdcc23fa65270a0cdb78ea9609038434f6b741a968e9758f93782a3bab57efc3072429bdf84f8ad25a94bf5a8c4bc48 *Newtonsoft.Json.Schema.dll
3-
15b0aa8b29f4e7d74ae3ff36ce7d72f6243a9b7f35890df3e549340c27edf37a73a9d16132254baf661a9aadc6fd5870d3b04452b78df79e3ccf9bee1c9bd788 *Scoop.Validator.dll
4-
384d22bfb21b2767de862f95945dca91aefb4b5eca687d20e410dc64059c5402a13c085517cb807635ff07397fee9bda31b0fdc0090c24cb424f62b285ea0477 *validator.exe
3+
6d89196ce01823093f5c3da98d34d41bc1733316d04e181d6f24982a373cc28487b8e4e74b54f5a665a550ad4a7fa6d7208d99de947b82b20e524747bdb41bdd *Scoop.Validator.dll
4+
e9b2162b3e109291c61005a9088d9ebf30fb0307fa285ccf5c54aef05fb3c02944d9513f2557e75d670682b0f3ba67a4f8df3561c715eaa5daa077b591fb4d54 *validator.exe

bin/validator.exe

1 KB
Binary file not shown.

validator.cs

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,63 @@
11
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
24
using System.IO;
5+
using System.Linq;
36

47
namespace Scoop
58
{
69
public class Program
710
{
811
public static int Main(string[] args)
912
{
10-
bool ci = (args.Length == 3 && args[2] == "-ci");
11-
bool valid = false;
13+
bool ci = String.Format("{0}", Environment.GetEnvironmentVariable("CI")).ToLower() == "true";
14+
bool valid = true;
1215

1316
if (args.Length < 2)
1417
{
15-
Console.WriteLine("Usage: validator.exe schema.json manifest.json");
18+
Console.WriteLine("Usage: validator.exe <schema> <manifest> [<manifest>...]");
1619
return 1;
1720
}
1821

19-
Scoop.Validator validator = new Scoop.Validator(args[0], ci);
20-
valid = validator.Validate(args[1]);
2122

22-
if (valid)
23-
{
24-
Console.WriteLine("Yay! {0} validates against the schema!", Path.GetFileName(args[1]));
23+
IList<string> manifests = args.ToList<String>();
24+
String schema = manifests.First();
25+
manifests.RemoveAt(0);
26+
String combinedArgs = String.Join("", manifests);
27+
if(combinedArgs.Contains("*") || combinedArgs.Contains("?")) {
28+
try {
29+
var path = new Uri(Path.Combine(Directory.GetCurrentDirectory(), combinedArgs)).LocalPath;
30+
var drive = Path.GetPathRoot(path);
31+
var pattern = path.Replace(drive, "");
32+
manifests = Directory.GetFiles(drive, pattern).ToList<String>();
33+
} catch (System.ArgumentException ex) {
34+
Console.WriteLine("Invalid path provided! ({0})", ex.Message);
35+
return 1;
36+
}
2537
}
26-
else
27-
{
28-
foreach (var error in validator.Errors)
38+
39+
Scoop.Validator validator = new Scoop.Validator(schema, ci);
40+
foreach(var manifest in manifests) {
41+
if (validator.Validate(manifest))
42+
{
43+
if(ci) {
44+
Console.WriteLine(" [+] {0} validates against the schema!", Path.GetFileName(manifest));
45+
} else {
46+
Console.WriteLine("- {0} validates against the schema!", Path.GetFileName(manifest));
47+
}
48+
}
49+
else
2950
{
30-
Console.WriteLine(error);
51+
if(ci) {
52+
Console.WriteLine(" [-] {0} has {1} Error{2}!", Path.GetFileName(manifest), validator.Errors.Count, validator.Errors.Count > 1 ? "s" : "");
53+
} else {
54+
Console.WriteLine("- {0} has {1} Error{2}!", Path.GetFileName(manifest), validator.Errors.Count, validator.Errors.Count > 1 ? "s" : "");
55+
}
56+
valid = false;
57+
foreach (var error in validator.Errors)
58+
{
59+
Console.WriteLine(error);
60+
}
3161
}
3262
}
3363

0 commit comments

Comments
 (0)