Skip to content

Commit 1c107cd

Browse files
authored
Add onlyIssues validation option (#205)
1 parent 0c697d5 commit 1c107cd

File tree

7 files changed

+64
-1
lines changed

7 files changed

+64
-1
lines changed

docs/config-example.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ max-issues: 10
55
ignore:
66
- UNEXPECTED_PROPERTY
77

8+
# List of only issues to consider. Cannot be used along with 'ignore'.
9+
only:
10+
- ACCESSOR_INVALID_FLOAT
11+
812
# Map of overridden severities. 0 - Error, 1 - Warning, 2 - Info, 3 - Hint
913
override:
1014
ACCESSOR_INDEX_TRIANGLE_DEGENERATE: 0

lib/cmd_line.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class ValidationTask {
8686
ValidationOptions _getValidationOptionsFromYaml(String fileName) {
8787
const kMaxIssues = 'max-issues';
8888
const kIgnore = 'ignore';
89+
const kOnly = 'only';
8990
const kOverride = 'override';
9091

9192
void abort(Object e) {
@@ -111,6 +112,7 @@ ValidationOptions _getValidationOptionsFromYaml(String fileName) {
111112

112113
var maxIssues = 0;
113114
List<String> ignoredIssues;
115+
List<String> onlyIssues;
114116
Map<String, Severity> severityOverrides;
115117

116118
if (yaml is Map) {
@@ -136,6 +138,21 @@ ValidationOptions _getValidationOptionsFromYaml(String fileName) {
136138
abort("$kYamlError 'ignored' must be a sequence.");
137139
}
138140

141+
final Object yamlOnlyIssues = yaml[kOnly];
142+
if (yamlOnlyIssues is List) {
143+
onlyIssues = List.generate(yamlOnlyIssues.length, (i) {
144+
final Object entry = yamlOnlyIssues[i];
145+
if (entry is String) {
146+
return entry;
147+
} else {
148+
abort("$kYamlError each entry in '$kOnly' must be a string.");
149+
return null;
150+
}
151+
}, growable: false);
152+
} else if (yamlOnlyIssues != null) {
153+
abort("$kYamlError 'only' must be a sequence.");
154+
}
155+
139156
final Object yamlSeveritiesMap = yaml[kOverride];
140157
if (yamlSeveritiesMap is Map) {
141158
severityOverrides = <String, Severity>{};
@@ -156,6 +173,7 @@ ValidationOptions _getValidationOptionsFromYaml(String fileName) {
156173
return ValidationOptions(
157174
maxIssues: maxIssues,
158175
ignoredIssues: ignoredIssues,
176+
onlyIssues: onlyIssues,
159177
severityOverrides: severityOverrides);
160178
} else {
161179
abort('$kYamlError document must be a map.');

lib/src/context.dart

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,21 @@ import 'package:gltf/src/gl.dart' as gl;
2525
class ValidationOptions {
2626
final int maxIssues;
2727
final Set<String> ignoredIssues = <String>{};
28+
final Set<String> onlyIssues = <String>{};
2829
final Map<String, Severity> severityOverrides;
2930

3031
ValidationOptions(
31-
{int maxIssues, List<String> ignoredIssues, this.severityOverrides})
32+
{int maxIssues,
33+
List<String> ignoredIssues,
34+
List<String> onlyIssues,
35+
this.severityOverrides})
3236
: maxIssues = maxIssues ?? 0 {
3337
if (ignoredIssues != null) {
3438
this.ignoredIssues.addAll(ignoredIssues);
3539
}
40+
if (onlyIssues != null) {
41+
this.onlyIssues.addAll(onlyIssues);
42+
}
3643
}
3744
}
3845

@@ -220,6 +227,11 @@ class Context {
220227
return;
221228
}
222229

230+
if (options.onlyIssues.isNotEmpty &&
231+
!options.onlyIssues.contains(issueType.code)) {
232+
return;
233+
}
234+
223235
if (options.maxIssues > 0 && _issues.length == options.maxIssues) {
224236
_isTruncated = true;
225237
throw const IssuesLimitExceededException();

node/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ validator.validateBytes(new Uint8Array(asset), {
5151
format: 'gltf', // skip auto-detection and parse the input as glTF JSON
5252
maxIssues: 10, // limit max number of output issues to 10
5353
ignoredIssues: ['UNSUPPORTED_EXTENSION'], // mute UNSUPPORTED_EXTENSION issue
54+
onlyIssues: ['ACCESSOR_INVALID_FLOAT'], // only consider ACCESSOR_INVALID_FLOAT an issue. Cannot be used along with ignoredIssues.
5455
severityOverrides: { 'ACCESSOR_INDEX_TRIANGLE_DEGENERATE': 0 }, // treat degenerate triangles as errors
5556
externalResourceFunction: (uri) =>
5657
new Promise((resolve, reject) => {

node/gltf_validator.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ abstract class _JSValidationOptions {
7373

7474
external List get ignoredIssues;
7575

76+
external List get onlyIssues;
77+
7678
external Object get severityOverrides;
7779
}
7880

@@ -213,6 +215,7 @@ Context _getContextFromOptions(_JSValidationOptions options) {
213215
ValidationOptions validationOptions;
214216
Map<String, Severity> severityOverrides;
215217
List<String> ignoredIssues;
218+
List<String> onlyIssues;
216219

217220
if (options != null) {
218221
if (options.format != null && options.format is! String) {
@@ -225,6 +228,28 @@ Context _getContextFromOptions(_JSValidationOptions options) {
225228
'options.maxIssues: Value must be a non-negative integer.');
226229
}
227230

231+
if (options.onlyIssues != null && options.ignoredIssues != null) {
232+
throw ArgumentError(
233+
'options.onlyIssues cannot be used along with options.ignoredIssues.');
234+
}
235+
236+
if (options.onlyIssues != null) {
237+
if (options.onlyIssues is! List) {
238+
throw ArgumentError('options.onlyIssues: Value must be an array.');
239+
}
240+
241+
onlyIssues = <String>[];
242+
for (var i = 0; i < options.onlyIssues.length; ++i) {
243+
final Object entry = options.onlyIssues[i];
244+
if (entry is String && entry.isNotEmpty) {
245+
onlyIssues.add(entry);
246+
} else {
247+
throw ArgumentError(
248+
'options.onlyIssues[$i]: Value must be a non-empty String.');
249+
}
250+
}
251+
}
252+
228253
if (options.ignoredIssues != null) {
229254
if (options.ignoredIssues is! List) {
230255
throw ArgumentError('options.ignoredIssues: Value must be an array.');
@@ -267,6 +292,7 @@ Context _getContextFromOptions(_JSValidationOptions options) {
267292
validationOptions = ValidationOptions(
268293
maxIssues: options.maxIssues,
269294
ignoredIssues: ignoredIssues,
295+
onlyIssues: onlyIssues,
270296
severityOverrides: severityOverrides);
271297
}
272298

node/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ exports.validateString = (json, options) => validator.validateString(json, optio
5252
@property {boolean} writeTimestamp - Set to `false` to omit timestamp from the validation report. Default is `true`.
5353
@property {number} maxIssues - Max number of reported issues. Use `0` for unlimited output.
5454
@property {string[]} ignoredIssues - Array of ignored issue codes.
55+
@property {string[]} onlyIssues - Array of only issues to consider. Cannot be used along with ignoredIssues.
5556
@property {Object} severityOverrides - Object with overridden severities for issue codes.
5657
*/
5758

node/module.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export const validateString = (json, options) => v.default.validateString(json,
5252
@property {boolean} writeTimestamp - Set to `false` to omit timestamp from the validation report.
5353
@property {number} maxIssues - Max number of reported issues. Use `0` for unlimited output.
5454
@property {string[]} ignoredIssues - Array of ignored issue codes.
55+
@property {string[]} onlyIssues - Array of only issues to consider. Cannot be used along with ignoredIssues.
5556
@property {Object} severityOverrides - Object with overridden severities for issue codes.
5657
*/
5758

0 commit comments

Comments
 (0)