Skip to content

Commit 10669a2

Browse files
tx3stndaveshanley
authored andcommitted
enable selection of dynamic rulesets within the language server
1 parent 1a0f836 commit 10669a2

File tree

1 file changed

+45
-1
lines changed

1 file changed

+45
-1
lines changed

language-server/server.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323

2424
"github.com/daveshanley/vacuum/model"
2525
"github.com/daveshanley/vacuum/motor"
26+
"github.com/daveshanley/vacuum/rulesets"
2627
"github.com/daveshanley/vacuum/utils"
2728
"github.com/spf13/viper"
2829
"github.com/tliron/glsp"
@@ -32,10 +33,25 @@ import (
3233

3334
var serverName = "vacuum"
3435

36+
// DocumentContext contains details about the file being processed by the LSP.
37+
// This allows you to add logic to the RulesetSelector based on the file name or
38+
// content of the document being processed.
39+
type DocumentContext struct {
40+
Content []byte
41+
Filename string
42+
URI string
43+
}
44+
45+
// RulesetSelector is used in NewServerWithRulesetSelector to allow you to dynamically
46+
// return what rules should be used for the language server diagnostics based on
47+
// the actual content of the OpenAPI spec being procesed.
48+
type RulesetSelector func(ctx *DocumentContext) *rulesets.RuleSet
49+
3550
type ServerState struct {
3651
server *glspserv.Server
3752
documentStore *DocumentStore
3853
lintRequest *utils.LintFileRequest
54+
rulesetSelector RulesetSelector
3955
}
4056

4157
func NewServer(version string, lintRequest *utils.LintFileRequest) *ServerState {
@@ -138,6 +154,24 @@ func NewServer(version string, lintRequest *utils.LintFileRequest) *ServerState
138154
return state
139155
}
140156

157+
// NewServerWithRulesetSelector creates a new instance of the language server with
158+
// a custom RulsetSelector function to allow you to dynamically select the ruleset
159+
// used based on the content of the spec being processed.
160+
//
161+
// This allows you to determine specifically what rules should be applied per spec, e.g.:
162+
//
163+
// Have different teams which require different rules?
164+
// Check the value of info.contact.name in the spec and return the releant rules for that team.
165+
//
166+
// Want to enable OWASP rules for only a specific server?
167+
// Check the value of servers[0].url and return the rules including the OWASP ruleset
168+
// for your specific super secure sever url.
169+
func NewServerWithRulesetSelector(version string, lintRequest *utils.LintFileRequest, selector RulesetSelector) *ServerState {
170+
state := NewServer(version, lintRequest)
171+
state.rulesetSelector = selector
172+
return state
173+
}
174+
141175
func (s *ServerState) Run() error {
142176
s.initializeConfig()
143177

@@ -161,8 +195,18 @@ func (s *ServerState) runDiagnostic(doc *Document, notify glsp.NotifyFunc) {
161195
deepGraph = true
162196
}
163197

198+
selectedRuleSet := s.lintRequest.SelectedRS
199+
if s.rulesetSelector != nil {
200+
docCtx := &DocumentContext{
201+
Content: []byte(doc.Content),
202+
Filename: specFileName,
203+
URI: doc.URI,
204+
}
205+
selectedRuleSet = s.rulesetSelector(docCtx)
206+
}
207+
164208
result := motor.ApplyRulesToRuleSet(&motor.RuleSetExecution{
165-
RuleSet: s.lintRequest.SelectedRS,
209+
RuleSet: selectedRuleSet,
166210
Spec: []byte(doc.Content),
167211
SpecFileName: specFileName,
168212
Timeout: time.Duration(s.lintRequest.TimeoutFlag) * time.Second,

0 commit comments

Comments
 (0)