mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 23:15:26 +02:00
fix(server): Improve ssh_config
This commit is contained in:
parent
e569516aae
commit
dbf543db66
@ -54,7 +54,6 @@ func Analyze(
|
||||
}
|
||||
}
|
||||
|
||||
analyzeValuesAreValid(ctx)
|
||||
analyzeTokens(ctx)
|
||||
analyzeIgnoreUnknownHasNoUnnecessary(ctx)
|
||||
analyzeDependents(ctx)
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"config-lsp/common"
|
||||
docvalues "config-lsp/doc-values"
|
||||
"config-lsp/handlers/ssh_config/ast"
|
||||
"config-lsp/handlers/ssh_config/diagnostics"
|
||||
"config-lsp/handlers/ssh_config/fields"
|
||||
"config-lsp/utils"
|
||||
"fmt"
|
||||
@ -41,12 +42,34 @@ func checkOption(
|
||||
checkIsUsingDoubleQuotes(ctx, option.Key.Value, option.Key.LocationRange)
|
||||
checkQuotesAreClosed(ctx, option.Key.Value, option.Key.LocationRange)
|
||||
|
||||
docOption, found := fields.Options[option.Key.Key]
|
||||
docOption, optionFound := fields.Options[option.Key.Key]
|
||||
|
||||
if !found {
|
||||
if !optionFound {
|
||||
// Diagnostics will be handled by `values.go`
|
||||
if !ctx.document.Indexes.CanOptionBeIgnored(option, block) {
|
||||
ctx.diagnostics = append(
|
||||
ctx.diagnostics,
|
||||
diagnostics.GenerateUnknownOption(
|
||||
option.Key.ToLSPRange(),
|
||||
option.Key.Value.Value,
|
||||
),
|
||||
)
|
||||
ctx.document.Indexes.UnknownOptions[option.Start.Line] = ast.AllOptionInfo{
|
||||
Option: option,
|
||||
Block: block,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if block != nil && block.GetBlockType() == ast.SSHBlockTypeHost && utils.KeyExists(fields.HostDisallowedOptions, option.Key.Key) {
|
||||
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
|
||||
Range: option.Key.LocationRange.ToLSPRange(),
|
||||
Message: fmt.Sprintf("Option '%s' is not allowed in Host blocks", option.Key.Key),
|
||||
Severity: &common.SeverityError,
|
||||
})
|
||||
}
|
||||
|
||||
// Check for values that are not allowed in Host blocks
|
||||
if block != nil && block.GetBlockType() == ast.SSHBlockTypeHost {
|
||||
@ -59,7 +82,7 @@ func checkOption(
|
||||
}
|
||||
}
|
||||
|
||||
if option.OptionValue != nil {
|
||||
if option.OptionValue != nil && optionFound {
|
||||
checkIsUsingDoubleQuotes(ctx, option.OptionValue.Value, option.OptionValue.LocationRange)
|
||||
checkQuotesAreClosed(ctx, option.OptionValue.Value, option.OptionValue.LocationRange)
|
||||
|
||||
|
@ -112,3 +112,79 @@ Match
|
||||
t.Fatalf("Expected 1 error, got %v", ctx.diagnostics)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnknownOptionExample(
|
||||
t *testing.T,
|
||||
) {
|
||||
d := testutils_test.DocumentFromInput(t, `
|
||||
ThisOptionDoesNotExist okay
|
||||
`)
|
||||
ctx := &analyzerContext{
|
||||
document: d,
|
||||
diagnostics: make([]protocol.Diagnostic, 0),
|
||||
}
|
||||
|
||||
analyzeStructureIsValid(ctx)
|
||||
|
||||
if !(len(ctx.diagnostics) == 1) {
|
||||
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
|
||||
}
|
||||
|
||||
if !(len(ctx.document.Indexes.UnknownOptions) == 1) {
|
||||
t.Errorf("Expected 1 unknown option, got %v", len(ctx.document.Indexes.UnknownOptions))
|
||||
}
|
||||
|
||||
if !(ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value == "ThisOptionDoesNotExist") {
|
||||
t.Errorf("Expected 'ThisOptionDoesNotExist', got %v", ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnknownOptionButIgnoredExample(
|
||||
t *testing.T,
|
||||
) {
|
||||
d := testutils_test.DocumentFromInput(t, `
|
||||
IgnoreUnknown ThisOptionDoesNotExist
|
||||
ThisOptionDoesNotExist okay
|
||||
`)
|
||||
ctx := &analyzerContext{
|
||||
document: d,
|
||||
diagnostics: make([]protocol.Diagnostic, 0),
|
||||
}
|
||||
|
||||
analyzeStructureIsValid(ctx)
|
||||
|
||||
if len(ctx.diagnostics) > 0 {
|
||||
t.Fatalf("Expected no errors, but got %v", len(ctx.diagnostics))
|
||||
}
|
||||
|
||||
if !(len(ctx.document.Indexes.UnknownOptions) == 0) {
|
||||
t.Errorf("Expected 0 unknown options, got %v", len(ctx.document.Indexes.UnknownOptions))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnknownOptionIgnoredIsAfterDefinitionExample(
|
||||
t *testing.T,
|
||||
) {
|
||||
d := testutils_test.DocumentFromInput(t, `
|
||||
ThisOptionDoesNotExist okay
|
||||
IgnoreUnknown ThisOptionDoesNotExist
|
||||
`)
|
||||
ctx := &analyzerContext{
|
||||
document: d,
|
||||
diagnostics: make([]protocol.Diagnostic, 0),
|
||||
}
|
||||
|
||||
analyzeStructureIsValid(ctx)
|
||||
|
||||
if !(len(ctx.diagnostics) == 1) {
|
||||
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
|
||||
}
|
||||
|
||||
if !(len(ctx.document.Indexes.UnknownOptions) == 1) {
|
||||
t.Errorf("Expected 1 unknown option, got %v", len(ctx.document.Indexes.UnknownOptions))
|
||||
}
|
||||
|
||||
if !(ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value == "ThisOptionDoesNotExist") {
|
||||
t.Errorf("Expected 'ThisOptionDoesNotExist', got %v", ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value)
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
package analyzer
|
||||
|
||||
import (
|
||||
"config-lsp/handlers/ssh_config/diagnostics"
|
||||
"config-lsp/handlers/ssh_config/fields"
|
||||
)
|
||||
|
||||
func analyzeValuesAreValid(
|
||||
ctx *analyzerContext,
|
||||
) {
|
||||
// Check if there are unknown options
|
||||
for _, info := range ctx.document.Config.GetAllOptions() {
|
||||
option := info.Option
|
||||
block := info.Block
|
||||
|
||||
_, found := fields.Options[option.Key.Key]
|
||||
|
||||
if !found {
|
||||
if ctx.document.Indexes.CanOptionBeIgnored(option, block) {
|
||||
// Skip
|
||||
continue
|
||||
}
|
||||
|
||||
ctx.diagnostics = append(
|
||||
ctx.diagnostics,
|
||||
diagnostics.GenerateUnknownOption(
|
||||
option.Key.ToLSPRange(),
|
||||
option.Key.Value.Value,
|
||||
),
|
||||
)
|
||||
ctx.document.Indexes.UnknownOptions[info.Option.Start.Line] = info
|
||||
}
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
package analyzer
|
||||
|
||||
import (
|
||||
testutils_test "config-lsp/handlers/ssh_config/test_utils"
|
||||
"testing"
|
||||
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func TestUnknownOptionExample(
|
||||
t *testing.T,
|
||||
) {
|
||||
d := testutils_test.DocumentFromInput(t, `
|
||||
ThisOptionDoesNotExist okay
|
||||
`)
|
||||
ctx := &analyzerContext{
|
||||
document: d,
|
||||
diagnostics: make([]protocol.Diagnostic, 0),
|
||||
}
|
||||
|
||||
analyzeValuesAreValid(ctx)
|
||||
|
||||
if !(len(ctx.diagnostics) == 1) {
|
||||
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
|
||||
}
|
||||
|
||||
if !(len(ctx.document.Indexes.UnknownOptions) == 1) {
|
||||
t.Errorf("Expected 1 unknown option, got %v", len(ctx.document.Indexes.UnknownOptions))
|
||||
}
|
||||
|
||||
if !(ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value == "ThisOptionDoesNotExist") {
|
||||
t.Errorf("Expected 'ThisOptionDoesNotExist', got %v", ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnknownOptionButIgnoredExample(
|
||||
t *testing.T,
|
||||
) {
|
||||
d := testutils_test.DocumentFromInput(t, `
|
||||
IgnoreUnknown ThisOptionDoesNotExist
|
||||
ThisOptionDoesNotExist okay
|
||||
`)
|
||||
ctx := &analyzerContext{
|
||||
document: d,
|
||||
diagnostics: make([]protocol.Diagnostic, 0),
|
||||
}
|
||||
|
||||
analyzeValuesAreValid(ctx)
|
||||
|
||||
if len(ctx.diagnostics) > 0 {
|
||||
t.Fatalf("Expected no errors, but got %v", len(ctx.diagnostics))
|
||||
}
|
||||
|
||||
if !(len(ctx.document.Indexes.UnknownOptions) == 0) {
|
||||
t.Errorf("Expected 0 unknown options, got %v", len(ctx.document.Indexes.UnknownOptions))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnknownOptionIgnoredIsAfterDefinitionExample(
|
||||
t *testing.T,
|
||||
) {
|
||||
d := testutils_test.DocumentFromInput(t, `
|
||||
ThisOptionDoesNotExist okay
|
||||
IgnoreUnknown ThisOptionDoesNotExist
|
||||
`)
|
||||
ctx := &analyzerContext{
|
||||
document: d,
|
||||
diagnostics: make([]protocol.Diagnostic, 0),
|
||||
}
|
||||
|
||||
analyzeValuesAreValid(ctx)
|
||||
|
||||
if !(len(ctx.diagnostics) == 1) {
|
||||
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
|
||||
}
|
||||
|
||||
if !(len(ctx.document.Indexes.UnknownOptions) == 1) {
|
||||
t.Errorf("Expected 1 unknown option, got %v", len(ctx.document.Indexes.UnknownOptions))
|
||||
}
|
||||
|
||||
if !(ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value == "ThisOptionDoesNotExist") {
|
||||
t.Errorf("Expected 'ThisOptionDoesNotExist', got %v", ctx.document.Indexes.UnknownOptions[0].Option.Key.Value.Value)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user