diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..f65a369 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,35 @@ +name: CI +on: + push: + branches: + - main + tags: + - "*" + pull_request: + workflow_dispatch: + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + - macos-13 + - macos-14 + - ubuntu-22.04 + - windows-2022 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.work + + - name: run checks + run: go run mage check + + - name: build snapshot + run: go run mage snapshot diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..64f5ca8 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,23 @@ +name: "Release" + +on: + push: + tags: + - v* + +jobs: + build: + name: Release + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.work + + - run: go run mage release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/update-upstream.yaml b/.github/workflows/update-upstream.yaml new file mode 100644 index 0000000..103b895 --- /dev/null +++ b/.github/workflows/update-upstream.yaml @@ -0,0 +1,40 @@ +name: "Update Upstream" + +on: + schedule: + - cron: "5 4 * * *" + workflow_dispatch: + +jobs: + build: + name: Update Upstream + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/setup-go@v5 + with: + go-version-file: go.work + + - run: go run mage updateUpstream + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - run: git diff --exit-code + id: check-diff + continue-on-error: true + + - name: create PR + if: steps.check-diff.outcome == 'failure' + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b update-upstream-${{ github.run_id }} + git add . + git commit -m "Update to latest upstream" + git push -u origin -f update-upstream-${{ github.run_id }} + gh pr create --fill --head update-upstream-${{ github.run_id }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..03992d8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.idea +.vscode +build +dist +go.work.sum diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..856d409 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,61 @@ +builds: +- main: ./cmd/protoc-gen-prost + id: es + binary: protoc-gen-prost + env: + - CGO_ENABLED=0 + targets: + - linux_amd64 + - linux_arm64 + - darwin_amd64 + - darwin_arm64 + - windows_amd64 + - windows_arm64 +- main: ./cmd/protoc-gen-prost-crate + id: es + binary: protoc-gen-prost-crate + env: + - CGO_ENABLED=0 + targets: + - linux_amd64 + - linux_arm64 + - darwin_amd64 + - darwin_arm64 + - windows_amd64 + - windows_arm64 +- main: ./cmd/protoc-gen-prost-serde + id: es + binary: protoc-gen-prost-serde + env: + - CGO_ENABLED=0 + targets: + - linux_amd64 + - linux_arm64 + - darwin_amd64 + - darwin_arm64 + - windows_amd64 + - windows_arm64 +- main: ./cmd/protoc-gen-tonic + id: es + binary: protoc-gen-tonic + env: + - CGO_ENABLED=0 + targets: + - linux_amd64 + - linux_arm64 + - darwin_amd64 + - darwin_arm64 + - windows_amd64 + - windows_arm64 +archives: +- format_overrides: + - goos: windows + format: zip +release: + mode: append +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ incpatch .Version }}-next" +changelog: + skip: true diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..41189cd --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) wasilibs authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..75c49de --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# go-protoc-gen-prost + +go-protoc-gen-prost is a distribution of [protoc-gen-prost][1]. +It does not actually reimplement any functionality of prost in Go, instead compiling it +to WebAssembly, and executing with the pure Go Wasm runtime [wazero][2]. +This means that `go install` or `go run` can be used to execute it, with no need to rely on external +package managers such as Homebrew, on any platform that Go supports. + +## Installation + +Precompiled binaries are available in the [releases](https://github.com/wasilibs/go-protoc-gen-prost/releases). +Alternatively, install the plugin using `go install`. + +```bash +$ go install github.com/wasilibs/go-protoc-gen-prost/cmd/protoc-gen-prost@latest +``` + +As long as `$GOPATH/bin`, e.g. `~/go/bin` is on the `PATH`, you can use it with protoc as normal. + +```bash +$ protoc --prost_out=out/rust -Iprotos protos/helloworld.proto +``` + +For [buf][3] users, to avoid installation entirely, it can be convenient to use `go run` in `buf.gen.yaml`. + +```yaml +version: v1 +plugins: + - plugin: prost + out: out/rust + path: ["go", "run", "github.com/wasilibs/go-protoc-gen-prost/cmd/protoc-gen-prost@latest"] +``` + +This makes it possible to have full protobuf/gRPC generation with no installation of tools, +besides Go itself, on any platform that Go supports. The above examples use `@latest`, but it is +recommended to specify a version, in which case all of the developers on your codebase will use the +same version of the tool with no special steps. + +See a full [example][5] in `go-protoc-gen-builtins`. To generate protos, enter the directory and run +`go run github.com/bufbuild/buf/cmd/buf@v1.30.0 generate`. As long as your machine has Go installed, +you will be able to generate protos. The first time using `go run` for a command, Go automatically builds +it making it slower, but subsequent invocations should be quite fast. + +[1]: https://github.com/neoeinstein/protoc-gen-prost +[2]: https://wazero.io/ +[3]: https://buf.build/ +[4]: https://github.com/wasilibs/go-protoc-gen-builtins +[5]: https://github.com/wasilibs/go-protoc-gen-builtins/tree/main/example diff --git a/buildtools/wasm/Dockerfile b/buildtools/wasm/Dockerfile new file mode 100644 index 0000000..71750f7 --- /dev/null +++ b/buildtools/wasm/Dockerfile @@ -0,0 +1,17 @@ +FROM rust:1-slim + +RUN apt-get update && apt-get install -y binaryen curl +RUN rustup target add wasm32-wasi + +ADD buildtools/wasm/version.txt version.txt +RUN mkdir -p /workspace && curl -L https://github.com/neoeinstein/protoc-gen-prost/archive/$(cat version.txt).tar.gz | tar -xz --strip-components 1 -C /workspace +WORKDIR /workspace + +# Temporarily force update to 0.12.4+ for https://github.com/tokio-rs/prost/pull/962 +RUN cargo update +RUN cargo build --release --target wasm32-wasi + +SHELL ["/bin/bash", "-c"] +RUN for f in target/wasm32-wasi/release/protoc-gen-*.wasm; do wasm-opt -o "target/$(basename $f)" --flatten --rereloop --converge -O3 "$f"; done + +CMD ["bash", "-c", "cp target/protoc-gen-*.wasm /out/"] diff --git a/buildtools/wasm/version.txt b/buildtools/wasm/version.txt new file mode 100644 index 0000000..67f2600 --- /dev/null +++ b/buildtools/wasm/version.txt @@ -0,0 +1 @@ +protoc-gen-prost-v0.3.1 \ No newline at end of file diff --git a/cmd/protoc-gen-prost-crate/main.go b/cmd/protoc-gen-prost-crate/main.go new file mode 100644 index 0000000..079cf51 --- /dev/null +++ b/cmd/protoc-gen-prost-crate/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "os" + + "github.com/wasilibs/go-protoc-gen-prost/internal/runner" + "github.com/wasilibs/go-protoc-gen-prost/internal/wasm" +) + +func main() { + os.Exit(runner.Run("protoc-gen-prost-crate", os.Args[1:], wasm.ProtocGenProstCrate, os.Stdin, os.Stdout, os.Stderr, ".")) +} diff --git a/cmd/protoc-gen-prost-serde/main.go b/cmd/protoc-gen-prost-serde/main.go new file mode 100644 index 0000000..a6b09a0 --- /dev/null +++ b/cmd/protoc-gen-prost-serde/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "os" + + "github.com/wasilibs/go-protoc-gen-prost/internal/runner" + "github.com/wasilibs/go-protoc-gen-prost/internal/wasm" +) + +func main() { + os.Exit(runner.Run("protoc-gen-prost-serde", os.Args[1:], wasm.ProtocGenProstSerde, os.Stdin, os.Stdout, os.Stderr, ".")) +} diff --git a/cmd/protoc-gen-prost/main.go b/cmd/protoc-gen-prost/main.go new file mode 100644 index 0000000..4585260 --- /dev/null +++ b/cmd/protoc-gen-prost/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "os" + + "github.com/wasilibs/go-protoc-gen-prost/internal/runner" + "github.com/wasilibs/go-protoc-gen-prost/internal/wasm" +) + +func main() { + os.Exit(runner.Run("protoc-gen-prost", os.Args[1:], wasm.ProtocGenProst, os.Stdin, os.Stdout, os.Stderr, ".")) +} diff --git a/cmd/protoc-gen-tonic/main.go b/cmd/protoc-gen-tonic/main.go new file mode 100644 index 0000000..6af2d90 --- /dev/null +++ b/cmd/protoc-gen-tonic/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "os" + + "github.com/wasilibs/go-protoc-gen-prost/internal/runner" + "github.com/wasilibs/go-protoc-gen-prost/internal/wasm" +) + +func main() { + os.Exit(runner.Run("protoc-gen-prost-tonic", os.Args[1:], wasm.ProtocGenTonic, os.Stdin, os.Stdout, os.Stderr, ".")) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..663fe37 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/wasilibs/go-protoc-gen-prost + +go 1.22 + +require github.com/tetratelabs/wazero v1.7.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..5048a45 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/tetratelabs/wazero v1.7.0 h1:jg5qPydno59wqjpGrHph81lbtHzTrWzwwtD4cD88+hQ= +github.com/tetratelabs/wazero v1.7.0/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y= diff --git a/go.work b/go.work new file mode 100644 index 0000000..5de3acb --- /dev/null +++ b/go.work @@ -0,0 +1,9 @@ +go 1.22 + +toolchain go1.22.2 + +use ( + . + ./mage + ./magefiles +) diff --git a/internal/runner/runner.go b/internal/runner/runner.go new file mode 100644 index 0000000..63a4651 --- /dev/null +++ b/internal/runner/runner.go @@ -0,0 +1,51 @@ +package runner + +import ( + "context" + "crypto/rand" + "io" + "log" + "os" + "strings" + + "github.com/tetratelabs/wazero" + "github.com/tetratelabs/wazero/experimental/sysfs" + "github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1" + "github.com/tetratelabs/wazero/sys" +) + +func Run(name string, args []string, wasm []byte, stdin io.Reader, stdout io.Writer, stderr io.Writer, cwd string) int { + ctx := context.Background() + + rt := wazero.NewRuntime(ctx) + + wasi_snapshot_preview1.MustInstantiate(ctx, rt) + + args = append([]string{name}, args...) + + root := sysfs.DirFS(cwd) + + cfg := wazero.NewModuleConfig(). + WithSysNanosleep(). + WithSysNanotime(). + WithSysWalltime(). + WithStderr(stderr). + WithStdout(stdout). + WithStdin(stdin). + WithRandSource(rand.Reader). + WithArgs(args...). + WithFSConfig(wazero.NewFSConfig().(sysfs.FSConfig).WithSysFSMount(root, "/")) + for _, env := range os.Environ() { + k, v, _ := strings.Cut(env, "=") + cfg = cfg.WithEnv(k, v) + } + + _, err := rt.InstantiateWithConfig(ctx, wasm, cfg) + if err != nil { + if sErr, ok := err.(*sys.ExitError); ok { + return int(sErr.ExitCode()) + } + log.Fatal(err) + } + return 0 +} diff --git a/internal/wasm/protoc-gen-prost-crate.wasm b/internal/wasm/protoc-gen-prost-crate.wasm new file mode 100644 index 0000000..3ecb0dd Binary files /dev/null and b/internal/wasm/protoc-gen-prost-crate.wasm differ diff --git a/internal/wasm/protoc-gen-prost-serde.wasm b/internal/wasm/protoc-gen-prost-serde.wasm new file mode 100644 index 0000000..4378849 Binary files /dev/null and b/internal/wasm/protoc-gen-prost-serde.wasm differ diff --git a/internal/wasm/protoc-gen-prost.wasm b/internal/wasm/protoc-gen-prost.wasm new file mode 100644 index 0000000..53c9b5f Binary files /dev/null and b/internal/wasm/protoc-gen-prost.wasm differ diff --git a/internal/wasm/protoc-gen-tonic.wasm b/internal/wasm/protoc-gen-tonic.wasm new file mode 100644 index 0000000..2d7f1e1 Binary files /dev/null and b/internal/wasm/protoc-gen-tonic.wasm differ diff --git a/internal/wasm/wasm.go b/internal/wasm/wasm.go new file mode 100644 index 0000000..8df5e44 --- /dev/null +++ b/internal/wasm/wasm.go @@ -0,0 +1,15 @@ +package wasm + +import _ "embed" + +//go:embed protoc-gen-prost.wasm +var ProtocGenProst []byte + +//go:embed protoc-gen-prost-crate.wasm +var ProtocGenProstCrate []byte + +//go:embed protoc-gen-prost-serde.wasm +var ProtocGenProstSerde []byte + +//go:embed protoc-gen-tonic.wasm +var ProtocGenTonic []byte diff --git a/mage/go.mod b/mage/go.mod new file mode 100644 index 0000000..c782bd3 --- /dev/null +++ b/mage/go.mod @@ -0,0 +1,5 @@ +module mage + +go 1.22 + +require github.com/magefile/mage v1.15.1-0.20230912152418-9f54e0f83e2a diff --git a/mage/go.sum b/mage/go.sum new file mode 100644 index 0000000..49ab18d --- /dev/null +++ b/mage/go.sum @@ -0,0 +1,2 @@ +github.com/magefile/mage v1.15.1-0.20230912152418-9f54e0f83e2a h1:tdPcGgyiH0K+SbsJBBm2oPyEIOTAvLBwD9TuUwVtZho= +github.com/magefile/mage v1.15.1-0.20230912152418-9f54e0f83e2a/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= diff --git a/mage/main.go b/mage/main.go new file mode 100644 index 0000000..298f01a --- /dev/null +++ b/mage/main.go @@ -0,0 +1,13 @@ +// Entrypoint to mage for running without needing to install the command. +// https://magefile.org/zeroinstall/ +package main + +import ( + "os" + + "github.com/magefile/mage/mage" +) + +func main() { + os.Exit(mage.Main()) +} diff --git a/magefiles/go.mod b/magefiles/go.mod new file mode 100644 index 0000000..95f29d0 --- /dev/null +++ b/magefiles/go.mod @@ -0,0 +1,29 @@ +module magefiles + +go 1.22 + +require ( + github.com/aymanbagabas/go-osc52 v1.0.3 // indirect + github.com/cli/safeexec v1.0.0 // indirect + github.com/cli/shurcooL-graphql v0.0.4 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/henvic/httpretty v0.0.6 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/magefile/mage v1.15.1-0.20230912152418-9f54e0f83e2a + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/muesli/termenv v0.13.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +require github.com/wasilibs/magefiles v0.0.0-20240202004439-abe7b5473f12 + +require ( + github.com/cli/go-gh/v2 v2.5.0 // indirect + github.com/google/go-github v17.0.0+incompatible // indirect +) diff --git a/magefiles/go.sum b/magefiles/go.sum new file mode 100644 index 0000000..a1589b5 --- /dev/null +++ b/magefiles/go.sum @@ -0,0 +1,64 @@ +github.com/aymanbagabas/go-osc52 v1.0.3 h1:DTwqENW7X9arYimJrPeGZcV0ln14sGMt3pHZspWD+Mg= +github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= +github.com/cli/go-gh/v2 v2.5.0 h1:uFF4l5mZ5wHAXg97u/9PERKOMrKYcoy2iiZI1OPMCwk= +github.com/cli/go-gh/v2 v2.5.0/go.mod h1:h3salfqqooVpzKmHp6aUdeNx62UmxQRpLbagFSHTJGQ= +github.com/cli/safeexec v1.0.0 h1:0VngyaIyqACHdcMNWfo6+KdUYnqEr2Sg+bSP1pdF+dI= +github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= +github.com/cli/shurcooL-graphql v0.0.4 h1:6MogPnQJLjKkaXPyGqPRXOI2qCsQdqNfUY1QSJu2GuY= +github.com/cli/shurcooL-graphql v0.0.4/go.mod h1:3waN4u02FiZivIV+p1y4d0Jo1jc6BViMA73C+sZo2fk= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/henvic/httpretty v0.0.6 h1:JdzGzKZBajBfnvlMALXXMVQWxWMF/ofTy8C3/OSUTxs= +github.com/henvic/httpretty v0.0.6/go.mod h1:X38wLjWXHkXT7r2+uK8LjCMne9rsuNaBLJ+5cU2/Pmo= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/magefile/mage v1.15.1-0.20230912152418-9f54e0f83e2a h1:tdPcGgyiH0K+SbsJBBm2oPyEIOTAvLBwD9TuUwVtZho= +github.com/magefile/mage v1.15.1-0.20230912152418-9f54e0f83e2a/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/muesli/termenv v0.13.0 h1:wK20DRpJdDX8b7Ek2QfhvqhRQFZ237RGRO0RQ/Iqdy0= +github.com/muesli/termenv v0.13.0/go.mod h1:sP1+uffeLaEYpyOTb8pLCUctGcGLnoFjSn4YJK5e2bc= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e h1:BuzhfgfWQbX0dWzYzT1zsORLnHRv3bcRcsaUk0VmXA8= +github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI= +github.com/wasilibs/magefiles v0.0.0-20240202004439-abe7b5473f12 h1:a5/Cj+ip2PUfivrZsQ4zPgm9a0oHSJbMWxmSnklQrgA= +github.com/wasilibs/magefiles v0.0.0-20240202004439-abe7b5473f12/go.mod h1:T6vadbOBwL4u8FdH5Vup+46JdQyHi4dgOFE4y44a3D8= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= +gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/magefiles/magefile.go b/magefiles/magefile.go new file mode 100644 index 0000000..ab5b168 --- /dev/null +++ b/magefiles/magefile.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + + "github.com/magefile/mage/sh" + + "github.com/wasilibs/magefiles" // mage:import +) + +func init() { + magefiles.SetLibraryName("protoc-gen-prost") + magefiles.SetLibraryRepo("neoeinstein/protoc-gen-prost") +} + +func Snapshot() error { + return sh.RunV("go", "run", fmt.Sprintf("github.com/goreleaser/goreleaser@%s", verGoReleaser), "release", "--snapshot", "--clean") +} + +func Release() error { + return sh.RunV("go", "run", fmt.Sprintf("github.com/goreleaser/goreleaser@%s", verGoReleaser), "release", "--clean") +} diff --git a/magefiles/versions.go b/magefiles/versions.go new file mode 100644 index 0000000..38884c5 --- /dev/null +++ b/magefiles/versions.go @@ -0,0 +1,3 @@ +package main + +const verGoReleaser = "v1.22.1" diff --git a/protoc_gen_prost_test.go b/protoc_gen_prost_test.go new file mode 100644 index 0000000..4c9f8bb --- /dev/null +++ b/protoc_gen_prost_test.go @@ -0,0 +1,35 @@ +package protoc_gen_prost + +import ( + "bytes" + "os" + "os/exec" + "path/filepath" + "testing" +) + +func TestBuf(t *testing.T) { + if err := os.RemoveAll(filepath.Join("build", "buf")); err != nil { + t.Fatalf("failed to remove build directory: %v", err) + } + + output := bytes.Buffer{} + cmd := exec.Command("go", "run", "github.com/bufbuild/buf/cmd/buf@v1.30.0", "generate") + cmd.Stderr = &output + cmd.Stdout = &output + cmd.Dir = "testdata" + if err := cmd.Run(); err != nil { + t.Fatalf("failed to run buf: %v\n%v", err, output.String()) + } + + for _, path := range []string{ + filepath.Join("build", "buf", "rust", "helloworld.rs"), + filepath.Join("build", "buf", "rust", "helloworld.serde.rs"), + filepath.Join("build", "buf", "rust", "helloworld.tonic.rs"), + filepath.Join("build", "buf", "rust", "mod.rs"), + } { + if _, err := os.Stat(path); err != nil { + t.Errorf("failed to stat %v: %v", path, err) + } + } +} diff --git a/testdata/buf.gen.yaml b/testdata/buf.gen.yaml new file mode 100644 index 0000000..50942d3 --- /dev/null +++ b/testdata/buf.gen.yaml @@ -0,0 +1,17 @@ +version: v1 +plugins: +- plugin: prost + out: ../build/buf/rust + path: ["go", "run", "../cmd/protoc-gen-prost"] +- plugin: prost-crate + strategy: all + opt: + - no_features + out: ../build/buf/rust + path: ["go", "run", "../cmd/protoc-gen-prost-crate"] +- plugin: prost-serde + out: ../build/buf/rust + path: ["go", "run", "../cmd/protoc-gen-prost-serde"] +- plugin: tonic + out: ../build/buf/rust + path: ["go", "run", "../cmd/protoc-gen-tonic"] diff --git a/testdata/buf.work.yaml b/testdata/buf.work.yaml new file mode 100644 index 0000000..79891ee --- /dev/null +++ b/testdata/buf.work.yaml @@ -0,0 +1,3 @@ +version: v1 +directories: +- protos diff --git a/testdata/protos/helloworld.proto b/testdata/protos/helloworld.proto new file mode 100644 index 0000000..e987213 --- /dev/null +++ b/testdata/protos/helloworld.proto @@ -0,0 +1,42 @@ +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package helloworld; + +option java_multiple_files = true; +option java_outer_classname = "HelloWorldProto"; +option java_package = "io.grpc.examples.helloworld"; +option objc_class_prefix = "HLW"; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello(HelloRequest) returns (HelloReply) {} + + rpc SayHelloStreamReply(HelloRequest) returns (stream HelloReply) {} + + rpc SayHelloBidiStream(stream HelloRequest) returns (stream HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + string name = 1; +} + +// The response message containing the greetings +message HelloReply { + string message = 1; +}