From 726b7a6eb776049710de063aadd64e4885b3c67e Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 10:12:26 +0500 Subject: [PATCH 01/16] Remove constants.go --- cache.go | 9 +++++++++ constants.go | 10 ---------- 2 files changed, 9 insertions(+), 10 deletions(-) delete mode 100644 constants.go diff --git a/cache.go b/cache.go index 566f0fd..0f82ed3 100644 --- a/cache.go +++ b/cache.go @@ -15,6 +15,15 @@ import ( "github.com/google/go-github/v60/github" ) +const ( + owner = "liquidaty" + repo = "zsv" + triplet = "amd64-linux-gcc" + archive = "tar.gz" + suffix = triplet + "." + archive + cacheDir = "zsv" +) + func initCache() bool { log.Println("initializing cache") diff --git a/constants.go b/constants.go deleted file mode 100644 index 0ff790f..0000000 --- a/constants.go +++ /dev/null @@ -1,10 +0,0 @@ -package main - -const ( - owner = "liquidaty" - repo = "zsv" - triplet = "amd64-linux-gcc" - archive = "tar.gz" - suffix = triplet + "." + archive - cacheDir = "zsv" -) From e49e74ed57fae36bdcd32b3501662b3c54733bdd Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 10:44:47 +0500 Subject: [PATCH 02/16] Add Windows, MacOS, and FreeBSD builds --- .github/workflows/ci.yml | 54 +++++++++++++++++++++++++++++----------- README.md | 6 ++--- cache.go | 22 +++++++++++++--- main.go | 3 ++- 4 files changed, 63 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8676e0f..06fd50b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,31 +40,55 @@ jobs: if [[ $GITHUB_REF != "refs/tags/v"* ]]; then VERSION="${GITHUB_SHA::7}" fi - EXE="zsv-playground-$VERSION-linux-amd64" - ZIP="$EXE.zip" - { - echo "VERSION=$VERSION" - echo "EXE=$EXE" - echo "ZIP=$ZIP" - } | tee -a "$GITHUB_ENV" + echo "VERSION=$VERSION" | tee -a "$GITHUB_ENV" - - name: Build (linux/amd64) + - name: Build run: | - GOOS=linux GOARCH=amd64 go build -v -x -ldflags '-w -s' -o "$EXE" - zip "$ZIP" "$EXE" + for OS in linux, windows, darwin, freebsd; do + EXE="zsv-playground-$VERSION-amd64-$OS" + GOOS=linux GOARCH=amd64 go build -v -x -ldflags '-w -s' -o "$EXE" + zip "$ZIP" "$EXE" + echo "$(echo $OS | tr [:lower:] [:upper:])_ZIP=" | tee -a "$GITHUB_ENV" + done + ls -hl *.zip - - name: Upload build artifact [${{ env.ZIP }}] + - name: Upload [${{ env.LINUX_ZIP }}] uses: actions/upload-artifact@v4 with: - name: '${{ env.ZIP }}' - path: '${{ env.ZIP }}' + name: ${{ env.LINUX_ZIP }} + path: ${{ env.LINUX_ZIP }} if-no-files-found: error - - name: Upload with release [${{ env.ZIP }}] + - name: Upload ${{ env.WINDOWS_ZIP }} + uses: actions/upload-artifact@v4 + with: + name: ${{ env.WINDOWS_ZIP }} + path: ${{ env.WINDOWS_ZIP }} + if-no-files-found: error + + - name: Upload ${{ env.DARWIN_ZIP }} + uses: actions/upload-artifact@v4 + with: + name: ${{ env.DARWIN_ZIP }} + path: ${{ env.DARWIN_ZIP }} + if-no-files-found: error + + - name: Upload ${{ env.FREEBSD_ZIP }} + uses: actions/upload-artifact@v4 + with: + name: ${{ env.FREEBSD_ZIP }} + path: ${{ env.FREEBSD_ZIP }} + if-no-files-found: error + + - name: Upload with release uses: softprops/action-gh-release@v2 if: startsWith(github.ref, 'refs/tags/v') with: - files: '${{ env.ZIP }}' + files: | + ${{ env.LINUX_ZIP }} + ${{ env.WINDOWS_ZIP }} + ${{ env.DARWIN_ZIP }} + ${{ env.FREEBSD_ZIP }} - name: Bump version on release [${{ env.VERSION }}] if: startsWith(github.ref, 'refs/tags/v') diff --git a/README.md b/README.md index b08f595..6940f72 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ [![GitHub release (latest by date)](https://img.shields.io/github/v/release/iamAzeem/zsv-playground?style=flat-square)](https://github.com/iamazeem/zsv-playground/releases) [![Buy Me a Coffee](https://img.shields.io/badge/Support-Buy%20Me%20A%20Coffee-orange.svg?style=flat-square)](https://www.buymeacoffee.com/iamazeem) -[`zsv-playground`](https://github.com/iamazeem/zsv-playground) is an x64 Linux -playground for [`zsv`](https://github.com/liquidaty/zsv) CLI executable. +[`zsv-playground`](https://github.com/iamazeem/zsv-playground) is an playground +for [`zsv`](https://github.com/liquidaty/zsv) CLI executable. -Locally tested on Ubuntu 22.04 LTS with Chrome 122.0.6261.128. +Available for x64 Linux, Windows, MacOS, and FreeBSD. > [!NOTE] > diff --git a/cache.go b/cache.go index 0f82ed3..7de3313 100644 --- a/cache.go +++ b/cache.go @@ -10,6 +10,7 @@ import ( "net/http" "os" "path/filepath" + "runtime" "strings" "github.com/google/go-github/v60/github" @@ -18,12 +19,26 @@ import ( const ( owner = "liquidaty" repo = "zsv" - triplet = "amd64-linux-gcc" archive = "tar.gz" - suffix = triplet + "." + archive cacheDir = "zsv" ) +func getTriplet() string { + switch runtime.GOOS { + case "linux": + return "amd64-linux-gcc" + case "windows": + return "amd64-windows-mingw" + case "darwin": + return "amd64-macosx-gcc" + case "freebsd": + return "amd64-freebsd-gcc" + default: + log.Fatalf("%v not supported", runtime.GOOS) + return "" + } +} + func initCache() bool { log.Println("initializing cache") @@ -142,6 +157,7 @@ func setupCache() ([]string, error) { // tag > id m := map[string]int64{} + suffix := getTriplet() + "." + archive for _, r := range releases { tag := r.GetTagName() versions = append(versions, tag) @@ -254,7 +270,7 @@ func untarZsvTarGz(targetDir string, r io.Reader) error { } func getExePath(version string) string { - return fmt.Sprintf("%v/%v/%v/bin/zsv", cacheDir, version, triplet) + return fmt.Sprintf("%v/%v/%v/bin/zsv", cacheDir, version, getTriplet()) } func getExePaths(versions []string) []string { diff --git a/main.go b/main.go index 768ce16..386b505 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "log" + "runtime" ) func init() { @@ -20,7 +21,7 @@ func main() { return } - log.Printf("starting zsv playground [%v]", version) + log.Printf("starting zsv-playground %v [os: %v, arch: %v]", version, runtime.GOOS, runtime.GOARCH) zsvVersions, err := setupCache() if err != nil { From fd9ad272aba5cb69a011759ae1996ae833d92bdd Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 10:47:42 +0500 Subject: [PATCH 03/16] Fix zip creation --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06fd50b..b7d83bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,7 @@ jobs: run: | for OS in linux, windows, darwin, freebsd; do EXE="zsv-playground-$VERSION-amd64-$OS" + ZIP="$EXE.zip" GOOS=linux GOARCH=amd64 go build -v -x -ldflags '-w -s' -o "$EXE" zip "$ZIP" "$EXE" echo "$(echo $OS | tr [:lower:] [:upper:])_ZIP=" | tee -a "$GITHUB_ENV" From dff03c6d47bd723acc7cb626df554dae1ac619be Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 10:48:35 +0500 Subject: [PATCH 04/16] Fix *_ZIP env var --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7d83bf..f4cc421 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: ZIP="$EXE.zip" GOOS=linux GOARCH=amd64 go build -v -x -ldflags '-w -s' -o "$EXE" zip "$ZIP" "$EXE" - echo "$(echo $OS | tr [:lower:] [:upper:])_ZIP=" | tee -a "$GITHUB_ENV" + echo "$(echo $OS | tr [:lower:] [:upper:])_ZIP=$ZIP" | tee -a "$GITHUB_ENV" done ls -hl *.zip From 248bdadff3acfc8849688c8b7a1e78c6f8c75452 Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 10:50:15 +0500 Subject: [PATCH 05/16] Update README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6940f72..bd4f0f9 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ [![GitHub release (latest by date)](https://img.shields.io/github/v/release/iamAzeem/zsv-playground?style=flat-square)](https://github.com/iamazeem/zsv-playground/releases) [![Buy Me a Coffee](https://img.shields.io/badge/Support-Buy%20Me%20A%20Coffee-orange.svg?style=flat-square)](https://www.buymeacoffee.com/iamazeem) -[`zsv-playground`](https://github.com/iamazeem/zsv-playground) is an playground +[`zsv-playground`](https://github.com/iamazeem/zsv-playground) is a playground for [`zsv`](https://github.com/liquidaty/zsv) CLI executable. -Available for x64 Linux, Windows, MacOS, and FreeBSD. +It is available for x64 Linux, Windows, MacOS, and FreeBSD. > [!NOTE] > @@ -40,7 +40,7 @@ Available for x64 Linux, Windows, MacOS, and FreeBSD. ## Download -Download the latest binary from the +Download the latest binaries from the [releases](https://github.com/iamazeem/zsv-playground/releases) page. ## Run From e6440080046f77dc4db46a0a47fba15bf5f21324 Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 10:52:13 +0500 Subject: [PATCH 06/16] Scope constants --- cache.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cache.go b/cache.go index 7de3313..6e24bb1 100644 --- a/cache.go +++ b/cache.go @@ -17,8 +17,6 @@ import ( ) const ( - owner = "liquidaty" - repo = "zsv" archive = "tar.gz" cacheDir = "zsv" ) @@ -140,6 +138,9 @@ func setupCache() ([]string, error) { return nil, fmt.Errorf("failed to load cache") } + owner := "liquidaty" + repo := "zsv" + ctx := context.Background() client := github.NewClient(nil) opts := &github.ListOptions{Page: 1, PerPage: 3} From 4e6b5316f4adebae1f36eff5c72a9d077db1027b Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 10:54:11 +0500 Subject: [PATCH 07/16] Update log --- cache.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cache.go b/cache.go index 6e24bb1..cca606b 100644 --- a/cache.go +++ b/cache.go @@ -32,7 +32,7 @@ func getTriplet() string { case "freebsd": return "amd64-freebsd-gcc" default: - log.Fatalf("%v not supported", runtime.GOOS) + log.Printf("%v not supported", runtime.GOOS) return "" } } From 1ff32a147bfc30e92381a1b3d9b77c01addbc04b Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 10:57:31 +0500 Subject: [PATCH 08/16] Fix CI build --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4cc421..e072c94 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,10 +44,10 @@ jobs: - name: Build run: | - for OS in linux, windows, darwin, freebsd; do + for OS in linux windows darwin freebsd; do EXE="zsv-playground-$VERSION-amd64-$OS" + GOOS=linux GOARCH=amd64 go build -ldflags '-w -s' -o "$EXE" ZIP="$EXE.zip" - GOOS=linux GOARCH=amd64 go build -v -x -ldflags '-w -s' -o "$EXE" zip "$ZIP" "$EXE" echo "$(echo $OS | tr [:lower:] [:upper:])_ZIP=$ZIP" | tee -a "$GITHUB_ENV" done From 0d352923dd9cfe756894bc2b6aee0287685fa7b0 Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 11:08:37 +0500 Subject: [PATCH 09/16] Fix build OS --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e072c94..4cf4ff5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,11 +46,12 @@ jobs: run: | for OS in linux windows darwin freebsd; do EXE="zsv-playground-$VERSION-amd64-$OS" - GOOS=linux GOARCH=amd64 go build -ldflags '-w -s' -o "$EXE" + GOOS="$OS" GOARCH=amd64 go build -ldflags -v '-w -s' -o "$EXE" ZIP="$EXE.zip" zip "$ZIP" "$EXE" echo "$(echo $OS | tr [:lower:] [:upper:])_ZIP=$ZIP" | tee -a "$GITHUB_ENV" done + file zsv-playground* ls -hl *.zip - name: Upload [${{ env.LINUX_ZIP }}] From 8320ca25bae58eea6d70e263e61d8226d4989fab Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 11:13:22 +0500 Subject: [PATCH 10/16] Remove redundant build flags --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4cf4ff5..56ed72a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,7 +46,7 @@ jobs: run: | for OS in linux windows darwin freebsd; do EXE="zsv-playground-$VERSION-amd64-$OS" - GOOS="$OS" GOARCH=amd64 go build -ldflags -v '-w -s' -o "$EXE" + GOOS="$OS" GOARCH=amd64 go build -ldflags '-w -s' -o "$EXE" ZIP="$EXE.zip" zip "$ZIP" "$EXE" echo "$(echo $OS | tr [:lower:] [:upper:])_ZIP=$ZIP" | tee -a "$GITHUB_ENV" From e59324df1c3235218745d9e499f947dfa3182bbf Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 11:25:20 +0500 Subject: [PATCH 11/16] Fix zsv extraction for Windows --- cache.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cache.go b/cache.go index cca606b..df235e0 100644 --- a/cache.go +++ b/cache.go @@ -245,7 +245,7 @@ func untarZsvTarGz(targetDir string, r io.Reader) error { } // extract binary only i.e. .../bin/zsv - if !strings.HasSuffix(header.Name, "bin/") && !strings.HasSuffix(header.Name, "/bin/zsv") { + if !strings.HasSuffix(header.Name, "bin/") && !strings.HasSuffix(header.Name, "/bin/zsv") && !strings.HasSuffix(header.Name, "/bin/zsv.exe") { continue } From 6d9a66808f6799e505c06f74a970f7877a2383f4 Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 11:30:03 +0500 Subject: [PATCH 12/16] Add .exe suffix to Windows binary --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56ed72a..a69ec41 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,9 @@ jobs: run: | for OS in linux windows darwin freebsd; do EXE="zsv-playground-$VERSION-amd64-$OS" + if [[ $OS == 'windows' ]]; then + EXE="$EXE.exe" + fi GOOS="$OS" GOARCH=amd64 go build -ldflags '-w -s' -o "$EXE" ZIP="$EXE.zip" zip "$ZIP" "$EXE" From 3dac997494744b3be185d0501170e0291faa3f3b Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 11:52:34 +0500 Subject: [PATCH 13/16] Use OS specific path separator --- cache.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cache.go b/cache.go index df235e0..cd78783 100644 --- a/cache.go +++ b/cache.go @@ -271,7 +271,7 @@ func untarZsvTarGz(targetDir string, r io.Reader) error { } func getExePath(version string) string { - return fmt.Sprintf("%v/%v/%v/bin/zsv", cacheDir, version, getTriplet()) + return filepath.Join(cacheDir, version, getTriplet(), "bin", "zsv") } func getExePaths(versions []string) []string { From 4176f33b5b87f4397e63ec1637e6a252fb6689c0 Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 11:58:24 +0500 Subject: [PATCH 14/16] Use cmd on Windows and sh on *nix --- http_server.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/http_server.go b/http_server.go index 4643c9d..e1d34a6 100644 --- a/http_server.go +++ b/http_server.go @@ -11,6 +11,7 @@ import ( "os" "os/exec" "os/signal" + "runtime" "strings" "time" ) @@ -75,7 +76,12 @@ func startHTTPServer(address string, zsvVersions []string, zsvCLIsJson string) { start := time.Now() - cmd := exec.Command("sh", "-c", cli) + var cmd *exec.Cmd + if runtime.GOOS == "windows" { + cmd = exec.Command("cmd", "/C", cli) + } else { + cmd = exec.Command("sh", "-c", cli) + } cmd.Stdin = strings.NewReader(csv) output, err := cmd.CombinedOutput() From 0d3fd0f52ebf2525948c6c51363ae191db07d576 Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 12:07:39 +0500 Subject: [PATCH 15/16] Revert Windows changes --- .github/workflows/ci.yml | 13 +------------ README.md | 2 +- cache.go | 4 +--- http_server.go | 8 +------- 4 files changed, 4 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a69ec41..0f0ca13 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,11 +44,8 @@ jobs: - name: Build run: | - for OS in linux windows darwin freebsd; do + for OS in linux darwin freebsd; do EXE="zsv-playground-$VERSION-amd64-$OS" - if [[ $OS == 'windows' ]]; then - EXE="$EXE.exe" - fi GOOS="$OS" GOARCH=amd64 go build -ldflags '-w -s' -o "$EXE" ZIP="$EXE.zip" zip "$ZIP" "$EXE" @@ -64,13 +61,6 @@ jobs: path: ${{ env.LINUX_ZIP }} if-no-files-found: error - - name: Upload ${{ env.WINDOWS_ZIP }} - uses: actions/upload-artifact@v4 - with: - name: ${{ env.WINDOWS_ZIP }} - path: ${{ env.WINDOWS_ZIP }} - if-no-files-found: error - - name: Upload ${{ env.DARWIN_ZIP }} uses: actions/upload-artifact@v4 with: @@ -91,7 +81,6 @@ jobs: with: files: | ${{ env.LINUX_ZIP }} - ${{ env.WINDOWS_ZIP }} ${{ env.DARWIN_ZIP }} ${{ env.FREEBSD_ZIP }} diff --git a/README.md b/README.md index bd4f0f9..93e081c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [`zsv-playground`](https://github.com/iamazeem/zsv-playground) is a playground for [`zsv`](https://github.com/liquidaty/zsv) CLI executable. -It is available for x64 Linux, Windows, MacOS, and FreeBSD. +It is available for AMD64 Linux, MacOS, and FreeBSD. > [!NOTE] > diff --git a/cache.go b/cache.go index cd78783..53d2eeb 100644 --- a/cache.go +++ b/cache.go @@ -25,8 +25,6 @@ func getTriplet() string { switch runtime.GOOS { case "linux": return "amd64-linux-gcc" - case "windows": - return "amd64-windows-mingw" case "darwin": return "amd64-macosx-gcc" case "freebsd": @@ -245,7 +243,7 @@ func untarZsvTarGz(targetDir string, r io.Reader) error { } // extract binary only i.e. .../bin/zsv - if !strings.HasSuffix(header.Name, "bin/") && !strings.HasSuffix(header.Name, "/bin/zsv") && !strings.HasSuffix(header.Name, "/bin/zsv.exe") { + if !strings.HasSuffix(header.Name, "bin/") && !strings.HasSuffix(header.Name, "/bin/zsv") { continue } diff --git a/http_server.go b/http_server.go index e1d34a6..4643c9d 100644 --- a/http_server.go +++ b/http_server.go @@ -11,7 +11,6 @@ import ( "os" "os/exec" "os/signal" - "runtime" "strings" "time" ) @@ -76,12 +75,7 @@ func startHTTPServer(address string, zsvVersions []string, zsvCLIsJson string) { start := time.Now() - var cmd *exec.Cmd - if runtime.GOOS == "windows" { - cmd = exec.Command("cmd", "/C", cli) - } else { - cmd = exec.Command("sh", "-c", cli) - } + cmd := exec.Command("sh", "-c", cli) cmd.Stdin = strings.NewReader(csv) output, err := cmd.CombinedOutput() From d81818a951277c409204a3342fde397afa33f844 Mon Sep 17 00:00:00 2001 From: Azeem Sajid Date: Sat, 23 Mar 2024 12:12:38 +0500 Subject: [PATCH 16/16] Update log --- http_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http_server.go b/http_server.go index 4643c9d..aa0e2fa 100644 --- a/http_server.go +++ b/http_server.go @@ -106,7 +106,7 @@ func startHTTPServer(address string, zsvVersions []string, zsvCLIsJson string) { server := &http.Server{Addr: address} go func() { - log.Printf("starting http server on %v [graceful shutdown on SIGINT]", address) + log.Printf("starting http server on %v [press CTRL+C for graceful shutdown]", address) if err := server.ListenAndServe(); err != nil { log.Fatalf("failed to start HTTP server, error: %v", err) }