Skip to content

Commit 2d23806

Browse files
committed
🪄 Implementing magic wrapper to support buf format in zed
1 parent f10d0ec commit 2d23806

File tree

8 files changed

+381
-1
lines changed

8 files changed

+381
-1
lines changed

.github/workflows/release.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: goreleaser
2+
3+
on:
4+
push:
5+
tags:
6+
- "*"
7+
8+
permissions:
9+
contents: write
10+
packages: write
11+
issues: write
12+
13+
jobs:
14+
goreleaser:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v3
19+
with:
20+
fetch-depth: 0
21+
- run: git fetch --force --tags
22+
- name: Login to Docker Registry
23+
run: |
24+
echo "${{ secrets.GITHUB_TOKEN }}" | \
25+
docker login ghcr.io -u docker --password-stdin
26+
- name: Set up Go
27+
uses: actions/setup-go@v3
28+
with:
29+
go-version: ">=1.24.2"
30+
cache: true
31+
- name: Run GoReleaser
32+
uses: goreleaser/goreleaser-action@v4
33+
with:
34+
distribution: goreleaser
35+
version: latest
36+
args: release -f configs/release.yml --clean
37+
env:
38+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ go.work.sum
2323

2424
# env file
2525
.env
26+
27+
# Added by goreleaser init:
28+
dist/

README.md

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,66 @@
11
# buf-fmt-stdin
2-
Buf protocol buffer formatter wrapper for stdin text editor integration
2+
3+
[Buf protocol buffer formatter](https://buf.build/docs/reference/cli/buf/format/) wrapper for stdin text editor integration
4+
5+
## Context
6+
7+
Some code editors support stdin integration, allowing users to pipe code directly into the editor for formatting and linting. This tool provides a convenient way to integrate Buf with such editors.
8+
9+
## Installation
10+
11+
```sh
12+
wget https://github.com/Fuabioo/buf-fmt-stdin/releases/latest/download/buf-fmt-stdin_$(uname -s)_$(uname -m).tar.gz
13+
tar -xzf buf-fmt-stdin_$(uname -s)_$(uname -m).tar.gz
14+
chmod +x buf-fmt-stdin
15+
```
16+
17+
## Usage
18+
19+
Since this is a wrapper to buf-fmt fix command then you can use any flag
20+
defined in this tool such as `--config` and `--cache-file`.
21+
22+
### Zed
23+
24+
With the [Zed editor](https://zed.dev/), you can use this tool by adding the [configuration](zed-configuration.json) to your settings json.
25+
26+
How [Zed formatting](https://zed.dev/docs/configuring-zed#formatter) works for anything other than a language server formatter is that you set up an external CLI tool, to which it will pipe the code. Currently there is no support for providing something like a filepath to the external tool or the like.
27+
28+
> For more information about Protocol Buffers language support, see [Proto - Zed](https://zed.dev/docs/languages/proto).
29+
30+
### Developing
31+
32+
If you have the go/bin directory in your PATH, you can simply run `go install` to install the tool from the source code in your local machine.
33+
Once that is done, just pipe any code into the tool or
34+
(if you already have one) use your configured text editor.
35+
36+
Execute the tool with the following command:
37+
38+
```sh
39+
echo '
40+
41+
42+
syntax = "proto3";
43+
44+
package example;
45+
46+
47+
message TestMessage {
48+
string name = 1;
49+
int32 age = 2;
50+
}' | buf-fmt-stdin
51+
```
52+
53+
This should throw the following output (the editor will know what to do with it):
54+
55+
```proto3
56+
57+
syntax = "proto3";
58+
59+
package example;
60+
61+
message TestMessage {
62+
string name = 1;
63+
int32 age = 2;
64+
}
65+
66+
```

configs/release.yml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
version: 2
2+
3+
before:
4+
hooks:
5+
- go mod tidy
6+
7+
builds:
8+
- # Regular build
9+
10+
# Custom ldflags.
11+
# For more info refer to: https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies
12+
# and https://pkg.go.dev/cmd/link
13+
#
14+
# Default: '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser'.
15+
# Templates: allowed.
16+
ldflags:
17+
- -s -w -X main.version={{.Version}}
18+
19+
# Custom build tags templates.
20+
# For more info refer to: https://pkg.go.dev/cmd/go#hdr-Build_constraints
21+
tags:
22+
- osusergo
23+
- netgo
24+
- static_build
25+
- feature
26+
27+
# Custom environment variables to be set during the builds.
28+
# Invalid environment variables will be ignored.
29+
# For more info refer to: https://pkg.go.dev/cmd/go#hdr-Environment_variables
30+
#
31+
# Default: os.Environ() ++ env config section.
32+
# Templates: allowed.
33+
env:
34+
- CGO_ENABLED=0
35+
36+
# GOARCH to build for.
37+
# For more info refer to: https://pkg.go.dev/cmd/go#hdr-Environment_variables
38+
#
39+
# Default: [ '386', 'amd64', 'arm64' ].
40+
goarch:
41+
- amd64
42+
- arm
43+
- arm64
44+
45+
# Set the modified timestamp on the output binary, typically
46+
# you would do this to ensure a build was reproducible.
47+
# Pass an empty string to skip modifying the output.
48+
#
49+
# Templates: allowed.
50+
mod_timestamp: "{{ .CommitTimestamp }}"
51+
52+
tool: "go"
53+
54+
# List of combinations of GOOS + GOARCH + GOARM to ignore.
55+
ignore:
56+
- goos: windows
57+
goarch: arm
58+
- goos: windows
59+
goarch: arm64
60+
- goos: darwin
61+
goarch: amd64
62+
63+
checksum:
64+
# https://goreleaser.com/customization/checksum/
65+
name_template: "{{ .ProjectName }}_{{ .Version }}_checksums.txt"
66+
algorithm: sha256
67+
68+
archives:
69+
- formats: [tar.gz]
70+
# this name template makes the OS and Arch compatible with the results of `uname`.
71+
name_template: >-
72+
{{ .ProjectName }}_
73+
{{- title .Os }}_
74+
{{- if eq .Arch "amd64" }}x86_64
75+
{{- else if eq .Arch "386" }}i386
76+
{{- else }}{{ .Arch }}{{ end }}
77+
{{- if .Arm }}v{{ .Arm }}{{ end }}
78+
# use zip for windows archives
79+
format_overrides:
80+
- goos: windows
81+
formats: [zip]
82+
83+
changelog:
84+
# https://goreleaser.com/customization/changelog/
85+
use: github
86+
sort: asc
87+
filters:
88+
exclude:
89+
- "^docs:"
90+
- "^test:"
91+
groups:
92+
- title: "Features 💡"
93+
regexp: "(?i).*Adding.*|(?i).*Init.*"
94+
order: 0
95+
- title: "Adjustments 🎛️"
96+
regexp: "(?i).*Update.*|(?i).*Updating.*|(?i).*Upgrading.*|(?i).*Tweaking.*"
97+
order: 1
98+
- title: "Cleanup 🧹🧽"
99+
regexp: "(?i).*Cleaning.*"
100+
order: 2
101+
- title: "Bug fixes 🐞🔧"
102+
regexp: "(?i).*Fix.*|(?i).*Bug.*"
103+
order: 3
104+
- title: Others
105+
order: 999

go.mod

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module github.com/Fuabioo/buf-fmt-stdin
2+
3+
go 1.24.0
4+
5+
require github.com/charmbracelet/log v0.4.1
6+
7+
require (
8+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
9+
github.com/charmbracelet/lipgloss v1.0.0 // indirect
10+
github.com/charmbracelet/x/ansi v0.4.2 // indirect
11+
github.com/go-logfmt/logfmt v0.6.0 // indirect
12+
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
13+
github.com/mattn/go-isatty v0.0.20 // indirect
14+
github.com/muesli/termenv v0.16.0 // indirect
15+
github.com/rivo/uniseg v0.4.7 // indirect
16+
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
17+
golang.org/x/sys v0.30.0 // indirect
18+
)

go.sum

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
2+
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
3+
github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
4+
github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=
5+
github.com/charmbracelet/log v0.4.1 h1:6AYnoHKADkghm/vt4neaNEXkxcXLSV2g1rdyFDOpTyk=
6+
github.com/charmbracelet/log v0.4.1/go.mod h1:pXgyTsqsVu4N9hGdHmQ0xEA4RsXof402LX9ZgiITn2I=
7+
github.com/charmbracelet/x/ansi v0.4.2 h1:0JM6Aj/g/KC154/gOP4vfxun0ff6itogDYk41kof+qk=
8+
github.com/charmbracelet/x/ansi v0.4.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
9+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
10+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11+
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
12+
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
13+
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
14+
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
15+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
16+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
17+
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
18+
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
19+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
20+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
21+
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
22+
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
23+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
24+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
25+
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
26+
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
27+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
28+
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
29+
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
30+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
31+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

main.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"flag"
6+
"fmt"
7+
"io"
8+
"os"
9+
"os/exec"
10+
"strings"
11+
"time"
12+
13+
"github.com/charmbracelet/log"
14+
)
15+
16+
var (
17+
version string = "dev"
18+
)
19+
20+
func main() {
21+
configFile := flag.String("config", "", "The buf.yaml file or data to use for configuration.")
22+
displayVersion := flag.Bool("version", false, "Display the version of the tool.")
23+
flag.Parse()
24+
25+
if *displayVersion {
26+
fmt.Println("Version:", version)
27+
var buffer bytes.Buffer
28+
29+
cmd := exec.Command("buf", "--version")
30+
cmd.Stdout = &buffer
31+
err := cmd.Run()
32+
if err != nil {
33+
log.Error(err)
34+
}
35+
36+
bufVersion := buffer.String()
37+
bufVersion = strings.TrimSpace(bufVersion)
38+
if bufVersion == "" {
39+
bufVersion = "unknown"
40+
}
41+
42+
buffer.Reset()
43+
44+
cmd = exec.Command("which", "buf")
45+
cmd.Stdout = &buffer
46+
err = cmd.Run()
47+
if err != nil {
48+
log.Debug(err)
49+
}
50+
51+
bufPath := buffer.String()
52+
bufPath = strings.TrimSpace(bufPath)
53+
54+
locatedAt := ""
55+
if bufPath != "" {
56+
locatedAt = fmt.Sprintf("located at %s", bufPath)
57+
}
58+
59+
fmt.Println("Your current `buf` version:", bufVersion, locatedAt)
60+
return
61+
}
62+
63+
// generate a temporary file pivot
64+
tmpFile := fmt.Sprintf("buf-original-%d.proto", time.Now().UnixNano())
65+
tmpDir, err := os.MkdirTemp("", "buf-")
66+
if err != nil {
67+
log.Fatal(err)
68+
}
69+
70+
tmpFilePath := fmt.Sprintf("%s/%s", tmpDir, tmpFile)
71+
tmpFileHandle, err := os.Create(tmpFilePath)
72+
if err != nil {
73+
log.Fatal(err)
74+
}
75+
76+
// ensure the temporary file and directory are removed on exit
77+
defer func() {
78+
os.RemoveAll(tmpDir)
79+
}()
80+
81+
// read the input from STDIN as provided by a text editor
82+
file, err := io.ReadAll(os.Stdin)
83+
if err != nil {
84+
log.Fatal(err)
85+
}
86+
87+
tmpFileHandle.Write(file)
88+
tmpFileHandle.Close()
89+
90+
// here we need to yield any parameters, for now we rely on the
91+
// php-cs-fixer CLI to handle any validations and errors
92+
args := []string{"format", tmpFilePath}
93+
if *configFile != "" {
94+
args = append(args, fmt.Sprintf("--config=%s", *configFile))
95+
}
96+
97+
cmd := exec.Command("buf", args...)
98+
99+
// the formatted file will be written to the stdout
100+
cmd.Stdout = os.Stdout
101+
cmd.Stderr = os.Stderr
102+
103+
// make it rain!
104+
err = cmd.Run()
105+
if err != nil {
106+
log.Fatal(err)
107+
}
108+
}

zed-configuration.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"languages": {
3+
"Proto": {
4+
"format_on_save": "on",
5+
"formatter": {
6+
"external": {
7+
"command": "buf-fmt-stdin",
8+
"arguments": ["--config=path/to/config"]
9+
}
10+
}
11+
}
12+
}
13+
}

0 commit comments

Comments
 (0)