feat(ssh_config): Add check for duplicate host names

This commit is contained in:
Myzel394 2024-10-02 14:37:05 +02:00
parent 594ceeb5d1
commit 60ac7cf961
No known key found for this signature in database
GPG Key ID: ED20A1D1D423AF3F
4 changed files with 109 additions and 0 deletions

View File

@ -40,6 +40,7 @@ func Analyze(
analyzeDependents(ctx) analyzeDependents(ctx)
analyzeBlocks(ctx) analyzeBlocks(ctx)
analyzeMatchBlocks(ctx) analyzeMatchBlocks(ctx)
analyzeHostBlock(ctx)
return ctx.diagnostics return ctx.diagnostics
} }

View File

@ -14,6 +14,7 @@ func analyzeBlocks(
continue continue
} }
// Check if block is empty
if block.GetOptions().Size() == 0 { if block.GetOptions().Size() == 0 {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{ ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Range: block.GetEntryOption().LocationRange.ToLSPRange(), Range: block.GetEntryOption().LocationRange.ToLSPRange(),

View File

@ -0,0 +1,33 @@
package analyzer
import (
"config-lsp/common"
hostparser "config-lsp/handlers/ssh_config/host-parser"
"fmt"
protocol "github.com/tliron/glsp/protocol_3_16"
)
func analyzeHostBlock(
ctx *analyzerContext,
) {
hosts := make(map[string]*hostparser.HostValue, 0)
for _, block := range ctx.document.GetAllHostBlocks() {
if block == nil || block.HostValue == nil {
continue
}
for _, host := range block.HostValue.Hosts {
if _, found := hosts[host.Value.Value]; found {
ctx.diagnostics = append(ctx.diagnostics, protocol.Diagnostic{
Range: host.ToLSPRange(),
Message: fmt.Sprintf("Host %s has already been defined on line %d", host.Value.Value, hosts[host.Value.Value].Start.Line+1),
Severity: &common.SeverityError,
})
} else {
hosts[host.Value.Value] = host
}
}
}
}

View File

@ -0,0 +1,74 @@
package analyzer
import (
testutils_test "config-lsp/handlers/ssh_config/test_utils"
"testing"
protocol "github.com/tliron/glsp/protocol_3_16"
)
func TestDuplicateHostExample(
t *testing.T,
) {
d := testutils_test.DocumentFromInput(t, `
Host example.com
User root
Host example.com
User test
`)
ctx := &analyzerContext{
document: d,
diagnostics: make([]protocol.Diagnostic, 0),
}
analyzeHostBlock(ctx)
if !(len(ctx.diagnostics) == 1) {
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
}
}
func TestDuplicateMultipleHostExample(
t *testing.T,
) {
d := testutils_test.DocumentFromInput(t, `
Host example.com google.com
User root
Host test.com example.com
User test
`)
ctx := &analyzerContext{
document: d,
diagnostics: make([]protocol.Diagnostic, 0),
}
analyzeHostBlock(ctx)
if !(len(ctx.diagnostics) == 1) {
t.Errorf("Expected 1 error, got %v", len(ctx.diagnostics))
}
}
func TestNonDuplicateHostExample(
t *testing.T,
) {
d := testutils_test.DocumentFromInput(t, `
Host example.com
User root
Host example2.com
User test
`)
ctx := &analyzerContext{
document: d,
diagnostics: make([]protocol.Diagnostic, 0),
}
analyzeHostBlock(ctx)
if !(len(ctx.diagnostics) == 0) {
t.Errorf("Expected 0 error, got %v", len(ctx.diagnostics))
}
}