Skip to content

Commit 43a4957

Browse files
tx3stndaveshanley
authored andcommitted
fix ignores at root level
1 parent b12e63d commit 43a4957

File tree

2 files changed

+99
-7
lines changed

2 files changed

+99
-7
lines changed

motor/inline_ignore.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,25 @@ func checkInlineIgnoreByPath(specNode *yaml.Node, path string, ruleId string) bo
1515
return false
1616
}
1717

18+
// First try to find the target path
1819
nodes, err := utils.FindNodesWithoutDeserializingWithTimeout(specNode, path, time.Millisecond*500)
19-
if err != nil || len(nodes) == 0 {
20-
// If the target path doesn't exist, check the root node as fallback
21-
if path != "$" {
22-
return checkInlineIgnore(specNode, ruleId)
20+
if err == nil && len(nodes) > 0 {
21+
// Check the first matching node
22+
if checkInlineIgnore(nodes[0], ruleId) {
23+
return true
2324
}
24-
return false
2525
}
2626

27-
// Check the first matching node
28-
return checkInlineIgnore(nodes[0], ruleId)
27+
// If target path doesn't exist or doesn't have ignore, check the document root
28+
// The specNode might be the document wrapper, so check its first content node
29+
var rootNode *yaml.Node
30+
if specNode.Kind == yaml.DocumentNode && len(specNode.Content) > 0 {
31+
rootNode = specNode.Content[0]
32+
} else {
33+
rootNode = specNode
34+
}
35+
36+
return checkInlineIgnore(rootNode, ruleId)
2937
}
3038

3139
// checkInlineIgnore checks if a node should be ignored for a specific rule

motor/inline_ignore_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,3 +392,87 @@ rules:
392392

393393
assert.Greater(t, len(result.Results), 0, "Should have some results from the custom rule")
394394
}
395+
396+
func TestInlineIgnore_Integration_PathBasedIgnore(t *testing.T) {
397+
// Test both root-level ignore (when path doesn't exist) and target-path ignore (when path exists)
398+
specs := []struct {
399+
name string
400+
yaml string
401+
rule string
402+
}{
403+
{
404+
name: "root level ignore for missing path",
405+
yaml: `
406+
x-lint-ignore: missing-servers-rule
407+
openapi: 3.0.3
408+
info:
409+
title: Test API
410+
version: 1.0.0
411+
paths: {}`,
412+
rule: "missing-servers-rule",
413+
},
414+
{
415+
name: "target path ignore when path exists",
416+
yaml: `
417+
openapi: 3.0.3
418+
info:
419+
title: Test API
420+
version: 1.0.0
421+
servers:
422+
- x-lint-ignore: servers-description-rule
423+
url: https://api.example.com
424+
paths: {}`,
425+
rule: "servers-description-rule",
426+
},
427+
}
428+
429+
rulesetYaml := `
430+
extends: []
431+
rules:
432+
missing-servers-rule:
433+
description: Check for missing servers
434+
given: $
435+
severity: error
436+
then:
437+
function: truthy
438+
field: servers
439+
servers-description-rule:
440+
description: Servers must have description
441+
given: $.servers[*]
442+
severity: error
443+
then:
444+
function: truthy
445+
field: description
446+
`
447+
448+
rc := CreateRuleComposer()
449+
rs, err := rc.ComposeRuleSet([]byte(rulesetYaml))
450+
require.NoError(t, err)
451+
452+
for _, spec := range specs {
453+
t.Run(spec.name, func(t *testing.T) {
454+
execution := &RuleSetExecution{
455+
RuleSet: rs,
456+
Spec: []byte(spec.yaml),
457+
SpecFileName: "test.yaml",
458+
}
459+
460+
result := ApplyRulesToRuleSet(execution)
461+
462+
// Should have no regular results (rule was ignored)
463+
for _, res := range result.Results {
464+
assert.NotEqual(t, spec.rule, res.RuleId, "%s should be ignored", spec.rule)
465+
}
466+
467+
// Should have ignored result for the specific rule
468+
var foundIgnored bool
469+
for _, res := range result.IgnoredResults {
470+
if res.RuleId == spec.rule {
471+
foundIgnored = true
472+
break
473+
}
474+
}
475+
assert.True(t, foundIgnored, "%s should be in ignored results", spec.rule)
476+
})
477+
}
478+
}

0 commit comments

Comments
 (0)