@@ -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
3334var 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+
3550type ServerState struct {
3651 server * glspserv.Server
3752 documentStore * DocumentStore
3853 lintRequest * utils.LintFileRequest
54+ rulesetSelector RulesetSelector
3955}
4056
4157func 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+
141175func (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