Skip to content

Commit

Permalink
Send warning to client on CRLF line endings (#717)
Browse files Browse the repository at this point in the history
In case either `opa-fmt` or `use-rego-v1` is enabled, we'll send back
a warning to the client whenever they save a document containing CRLF
line endings. This to avoid confusion when the user tries to fix formatting
using `opa fmt`, but the editor adding back CRLF line endings after.

Also disable the nestif linter, as it's annoying.

Fixes #693

Signed-off-by: Anders Eknert <anders@styra.com>
  • Loading branch information
anderseknert authored May 14, 2024
1 parent a5aa616 commit 00ea15e
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 9 deletions.
1 change: 1 addition & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ linters:
- rowserrcheck
- wastedassign
# annoying
- nestif
- gocognit
- goerr113
- varnamelen
Expand Down
2 changes: 0 additions & 2 deletions internal/lsp/documentsymbol.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/styrainc/regal/internal/lsp/types/symbols"
)

//nolint:nestif
func documentSymbols(
contents string,
module *ast.Module,
Expand Down Expand Up @@ -173,7 +172,6 @@ func refToString(ref ast.Ref) string {
return sb.String()
}

//nolint:nestif
func getRuleDetail(rule *ast.Rule) string {
if rule.Head.Args != nil {
return "function" + rule.Head.Args.String()
Expand Down
1 change: 0 additions & 1 deletion internal/lsp/documentsymbol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ func TestRefToString(t *testing.T) {
}
}

//nolint:nestif
func TestDocumentSymbols(t *testing.T) {
t.Parallel()

Expand Down
56 changes: 56 additions & 0 deletions internal/lsp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
rparse "github.com/styrainc/regal/internal/parse"
"github.com/styrainc/regal/pkg/config"
"github.com/styrainc/regal/pkg/fixer/fixes"
"github.com/styrainc/regal/pkg/linter"
)

const (
Expand Down Expand Up @@ -114,6 +115,8 @@ func (l *LanguageServer) Handle(
return l.handleTextDocumentDidOpen(ctx, conn, req)
case "textDocument/didClose":
return struct{}{}, nil
case "textDocument/didSave":
return l.handleTextDocumentDidSave(ctx, conn, req)
case "textDocument/documentSymbol":
return l.handleTextDocumentDocumentSymbol(ctx, conn, req)
case "textDocument/didChange":
Expand Down Expand Up @@ -800,6 +803,56 @@ func (l *LanguageServer) handleTextDocumentDidChange(
return struct{}{}, nil
}

func (l *LanguageServer) handleTextDocumentDidSave(
ctx context.Context,
_ *jsonrpc2.Conn,
req *jsonrpc2.Request,
) (result any, err error) {
var params types.TextDocumentDidSaveParams
if err := json.Unmarshal(*req.Params, &params); err != nil {
return nil, fmt.Errorf("failed to unmarshal params: %w", err)
}

if params.Text != nil && l.loadedConfig != nil {
if !strings.Contains(*params.Text, "\r\n") {
return struct{}{}, nil
}

enabled, err := linter.NewLinter().WithUserConfig(*l.loadedConfig).DetermineEnabledRules(ctx)
if err != nil {
l.logError(fmt.Errorf("failed to determine enabled rules: %w", err))

return struct{}{}, nil
}

formattingEnabled := false

for _, rule := range enabled {
if rule == "opa-fmt" || rule == "use-rego-v1" {
formattingEnabled = true

break
}
}

if formattingEnabled {
resp := types.ShowMessageParams{
Type: 2, // warning
Message: "CRLF line ending detected. Please change editor setting to use LF for line endings.",
}

err := l.conn.Notify(ctx, "window/showMessage", resp)
if err != nil {
l.logError(fmt.Errorf("failed to notify: %w", err))

return struct{}{}, nil
}
}
}

return struct{}{}, nil
}

func (l *LanguageServer) handleTextDocumentDocumentSymbol(
_ context.Context,
_ *jsonrpc2.Conn,
Expand Down Expand Up @@ -1037,6 +1090,9 @@ func (l *LanguageServer) handleInitialize(
TextDocumentSyncOptions: types.TextDocumentSyncOptions{
OpenClose: true,
Change: 1, // TODO: write logic to use 2, for incremental updates
Save: types.TextDocumentSaveOptions{
IncludeText: true,
},
},
DiagnosticProvider: types.DiagnosticOptions{
Identifier: "rego",
Expand Down
19 changes: 17 additions & 2 deletions internal/lsp/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ type GeneralClientCapabilities struct {
StaleRequestSupport StaleRequestSupportClientCapabilities `json:"staleRequestSupport"`
}

type ShowMessageParams struct {
Type uint `json:"type"`
Message string `json:"message"`
}

type StaleRequestSupportClientCapabilities struct {
Cancel bool `json:"cancel"`
RetryOnContentModifieds []string `json:"retryOnContentModified"`
Expand Down Expand Up @@ -247,9 +252,19 @@ type TextDocumentInlayHintParams struct {
Range Range `json:"range"`
}

type TextDocumentSaveOptions struct {
IncludeText bool `json:"includeText"`
}

type TextDocumentDidSaveParams struct {
TextDocument TextDocumentIdentifier `json:"textDocument"`
Text *string `json:"text,omitempty"`
}

type TextDocumentSyncOptions struct {
OpenClose bool `json:"openClose"`
Change uint `json:"change"`
OpenClose bool `json:"openClose"`
Change uint `json:"change"`
Save TextDocumentSaveOptions `json:"save"`
}

type TextDocumentIdentifier struct {
Expand Down
6 changes: 2 additions & 4 deletions pkg/reporter/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (tr PrettyReporter) Publish(_ context.Context, r report.Report) error {

footer := fmt.Sprintf("%d file%s linted.", r.Summary.FilesScanned, pluralScanned)

if r.Summary.NumViolations == 0 { //nolint:nestif
if r.Summary.NumViolations == 0 {
footer += " No violations found."
} else {
pluralViolations := ""
Expand Down Expand Up @@ -256,8 +256,6 @@ func (tr JSONReporter) Publish(_ context.Context, r report.Report) error {
// Publish first prints the pretty formatted report to console for easy access in the logs. It then goes on
// to print the GitHub Actions annotations for each violation. Finally, it prints a summary of the report suitable
// for the GitHub Actions UI.
//
//nolint:nestif
func (tr GitHubReporter) Publish(ctx context.Context, r report.Report) error {
err := NewPrettyReporter(tr.out).Publish(ctx, r)
if err != nil {
Expand Down Expand Up @@ -302,7 +300,7 @@ func (tr GitHubReporter) Publish(ctx context.Context, r report.Report) error {

fmt.Fprintf(summaryFile, "%d file%s linted.", r.Summary.FilesScanned, pluralScanned)

if r.Summary.NumViolations == 0 { //nolint:nestif
if r.Summary.NumViolations == 0 {
fmt.Fprintf(summaryFile, " No violations found")
} else {
pluralViolations := ""
Expand Down

0 comments on commit 00ea15e

Please sign in to comment.