feat: add LSP server, VSCode + DataGrip extensions, release infra, autofix
- pkg/lsp: JSON-RPC 2.0 LSP server (formatting, diagnostics, codeAction quick-fixes) - cmd/pgtidy: lsp and config subcommands - pkg/diagnostics: TextFix struct for byte-range autofixes - pkg/lint: MIG001/MIG003 autofixes, ApplyFixes helper, --fix flag on lint command - editors/vscode: TypeScript extension with LanguageClient, showVersion/showConfig/formatDocument commands, logo - editors/datagrip: Gradle JetBrains plugin via LSP4IJ, pluginIcon - .goreleaser.yaml, .github/workflows: CI + release pipeline - Makefile: snapshot, release, vscode-compile, vscode-package targets - go.mod + all imports: module path updated to git.warky.dev/wdevs/pgtidy - assets: logo files (256px, 128px, 1024px, ico)
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"git.warky.dev/wdevs/pgtidy/pkg/config"
|
||||
)
|
||||
|
||||
func cmdConfig(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
||||
for _, a := range args {
|
||||
if a == "-h" || a == "--help" {
|
||||
fmt.Fprintln(stdout, "pgtidy config — print effective configuration resolved from .pgtidy.yaml")
|
||||
return 0
|
||||
}
|
||||
}
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
wd = "."
|
||||
}
|
||||
st, err := config.Load(wd)
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "pgtidy: %v\n", err)
|
||||
return 2
|
||||
}
|
||||
fmt.Fprintf(stdout, "indent: %q\n", st.Indent)
|
||||
fmt.Fprintf(stdout, "newline: %q\n", st.Newline)
|
||||
fmt.Fprintf(stdout, "keyword_case: %s\n", st.KeywordCase)
|
||||
fmt.Fprintf(stdout, "ident_case: %s\n", st.IdentCase)
|
||||
fmt.Fprintf(stdout, "type_case: %s\n", st.TypeCase)
|
||||
fmt.Fprintf(stdout, "commas: %s\n", st.Commas)
|
||||
return 0
|
||||
}
|
||||
+3
-3
@@ -5,9 +5,9 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/hein/pgtidy/pkg/config"
|
||||
"github.com/hein/pgtidy/pkg/format"
|
||||
"github.com/hein/pgtidy/pkg/parser"
|
||||
"git.warky.dev/wdevs/pgtidy/pkg/config"
|
||||
"git.warky.dev/wdevs/pgtidy/pkg/format"
|
||||
"git.warky.dev/wdevs/pgtidy/pkg/parser"
|
||||
)
|
||||
|
||||
// cmdFmt implements `pgtidy fmt`. It follows the gofmt model: with no flags it
|
||||
|
||||
+28
-2
@@ -6,8 +6,8 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hein/pgtidy/pkg/diagnostics"
|
||||
"github.com/hein/pgtidy/pkg/lint"
|
||||
"git.warky.dev/wdevs/pgtidy/pkg/diagnostics"
|
||||
"git.warky.dev/wdevs/pgtidy/pkg/lint"
|
||||
)
|
||||
|
||||
// cmdLint implements `pgtidy lint`. Reads one or more SQL files (or stdin) and
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
func cmdLint(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
||||
var (
|
||||
only []string // --only=ID,ID rule filter
|
||||
fix bool
|
||||
files []string
|
||||
)
|
||||
for _, a := range args {
|
||||
@@ -26,6 +27,8 @@ func cmdLint(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
||||
case a == "-h" || a == "--help":
|
||||
lintUsage(stdout)
|
||||
return 0
|
||||
case a == "--fix":
|
||||
fix = true
|
||||
case strings.HasPrefix(a, "--only="):
|
||||
ids := strings.Split(strings.TrimPrefix(a, "--only="), ",")
|
||||
for _, id := range ids {
|
||||
@@ -89,6 +92,13 @@ func cmdLint(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
||||
fmt.Fprintf(stderr, "pgtidy: %v\n", err)
|
||||
return 2
|
||||
}
|
||||
if fix {
|
||||
fixed := lint.ApplyFixes(string(src), diags)
|
||||
if fixed != string(src) {
|
||||
io.WriteString(stdout, fixed)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
printDiags(diags)
|
||||
if len(diags) > 0 {
|
||||
found = true
|
||||
@@ -105,6 +115,21 @@ func cmdLint(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
||||
fmt.Fprintf(stderr, "pgtidy: %v\n", err)
|
||||
return 2
|
||||
}
|
||||
if fix {
|
||||
fixed := lint.ApplyFixes(string(src), diags)
|
||||
if fixed != string(src) {
|
||||
if err := os.WriteFile(path, []byte(fixed), 0o644); err != nil {
|
||||
fmt.Fprintf(stderr, "pgtidy: writing %s: %v\n", path, err)
|
||||
return 2
|
||||
}
|
||||
// Re-check to report any remaining unfixed diagnostics.
|
||||
diags, err = check(fixed, path)
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "pgtidy: %v\n", err)
|
||||
return 2
|
||||
}
|
||||
}
|
||||
}
|
||||
printDiags(diags)
|
||||
if len(diags) > 0 {
|
||||
found = true
|
||||
@@ -124,6 +149,7 @@ func lintUsage(w io.Writer) {
|
||||
Read SQL from files (or stdin) and report lint findings.
|
||||
|
||||
Flags:
|
||||
--fix Apply autofixes for fixable rules (MIG001, MIG003) and rewrite files
|
||||
--only=ID,... comma-separated rule IDs to enable (default: all rules)
|
||||
-h, --help show this help
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"git.warky.dev/wdevs/pgtidy/pkg/lsp"
|
||||
)
|
||||
|
||||
func cmdLsp(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
||||
for _, a := range args {
|
||||
if a == "-h" || a == "--help" {
|
||||
fmt.Fprintln(stdout, "pgtidy lsp — start the Language Server Protocol server (stdio transport)")
|
||||
return 0
|
||||
}
|
||||
}
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
wd = "."
|
||||
}
|
||||
if err := lsp.Serve(context.Background(), stdin, stdout, wd); err != nil {
|
||||
fmt.Fprintf(stderr, "pgtidy lsp: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
+10
-4
@@ -24,6 +24,10 @@ func run(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
||||
return cmdFmt(args[1:], stdin, stdout, stderr)
|
||||
case "lint":
|
||||
return cmdLint(args[1:], stdin, stdout, stderr)
|
||||
case "lsp":
|
||||
return cmdLsp(args[1:], stdin, stdout, stderr)
|
||||
case "config":
|
||||
return cmdConfig(args[1:], stdin, stdout, stderr)
|
||||
case "version", "--version", "-v":
|
||||
fmt.Fprintf(stdout, "pgtidy %s\n", version)
|
||||
return 0
|
||||
@@ -41,10 +45,12 @@ func usage(w io.Writer) {
|
||||
fmt.Fprint(w, `pgtidy — PostgreSQL formatter and linter
|
||||
|
||||
Usage:
|
||||
pgtidy fmt [flags] [files...] Format SQL/PL-pgSQL (stdin if no files)
|
||||
pgtidy lint [flags] [files...] Lint SQL (stdin if no files)
|
||||
pgtidy version Print version
|
||||
pgtidy help Show this help
|
||||
pgtidy fmt [flags] [files...] Format SQL/PL-pgSQL (stdin if no files)
|
||||
pgtidy lint [flags] [files...] Lint SQL (stdin if no files)
|
||||
pgtidy config Print effective configuration
|
||||
pgtidy lsp Start LSP server (stdio, for editors)
|
||||
pgtidy version Print version
|
||||
pgtidy help Show this help
|
||||
|
||||
fmt flags:
|
||||
-w, --write Rewrite files in place
|
||||
|
||||
Reference in New Issue
Block a user