From c415efadbea8322a24d90fde8875e74b1c9a2efa Mon Sep 17 00:00:00 2001 From: Rick <1450685+LinuxSuRen@users.noreply.github.com> Date: Wed, 5 Jun 2024 11:01:01 +0800 Subject: [PATCH] chore: improve the home dir getting (#474) * chore: improve the home dir getting * replace all home dir calls * upgrade goreleaser * add missing imports * fix the socket filepath --------- Co-authored-by: rick --- .github/workflows/build.yaml | 6 ++-- .github/workflows/release.yaml | 6 ++-- cmd/run.go | 7 +++-- cmd/server.go | 3 +- cmd/service.go | 3 +- go.mod | 2 +- pkg/server/remote_server.go | 3 +- pkg/server/store_ext_manager.go | 5 +-- pkg/util/home/common.go | 54 ++++++++++++++++++++++++++++++++ pkg/util/home/darwin.go | 44 ++++++++++++++++++++++++++ pkg/util/home/doc.go | 19 ++++++++++++ pkg/util/home/linux.go | 55 +++++++++++++++++++++++++++++++++ pkg/util/home/windows.go | 44 ++++++++++++++++++++++++++ 13 files changed, 237 insertions(+), 14 deletions(-) create mode 100644 pkg/util/home/common.go create mode 100644 pkg/util/home/darwin.go create mode 100644 pkg/util/home/doc.go create mode 100644 pkg/util/home/linux.go create mode 100644 pkg/util/home/windows.go diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index fe37ecc..d3e1145 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -67,12 +67,12 @@ jobs: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: ./tools/github-actions/setup-deps - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v4 + uses: goreleaser/goreleaser-action@v6 env: GITHUB_TOKEN: ${{ secrets.GH_PUBLISH_SECRETS }} with: - version: latest - args: release --skip-publish --rm-dist --snapshot + version: '~> v2' + args: release --clean --snapshot # - name: Operator # run: cd operator && make build diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 57536eb..8125d89 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -29,10 +29,10 @@ jobs: cache: "npm" cache-dependency-path: console/atest-ui/package-lock.json - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v2.9.1 + uses: goreleaser/goreleaser-action@v6 with: - version: latest - args: release --rm-dist + version: '~> v2' + args: release --clean env: GITHUB_TOKEN: ${{ secrets.GH_PUBLISH_SECRETS }} diff --git a/cmd/run.go b/cmd/run.go index 8bcce6a..7647997 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "github.com/linuxsuren/api-testing/pkg/util/home" "io" "net/http" "os" @@ -192,17 +193,19 @@ func (o *runOption) preRunE(cmd *cobra.Command, args []string) (err error) { return } +const extensionMonitor = "atest-monitor-docker" + func (o *runOption) startMonitor() (err error) { if o.monitorDocker == "" { return } var monitorBin string - if monitorBin, err = exec.LookPath("atest-monitor-docker"); err != nil { + if monitorBin, err = exec.LookPath(extensionMonitor); err != nil { return } - sockFile := os.ExpandEnv(fmt.Sprintf("$HOME/.config/atest/%s.sock", "atest-monitor-docker")) + sockFile := home.GetExtensionSocketPath(extensionMonitor) os.MkdirAll(filepath.Dir(sockFile), 0755) execer := fakeruntime.NewDefaultExecerWithContext(o.context) diff --git a/cmd/server.go b/cmd/server.go index c23b149..7947022 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -22,6 +22,7 @@ import ( "context" "errors" "fmt" + "github.com/linuxsuren/api-testing/pkg/util/home" "net" "net/http" "os" @@ -81,7 +82,7 @@ func createServerCmd(execer fakeruntime.Execer, httpServer server.HTTPServer) (c flags.StringArrayVarP(&opt.localStorage, "local-storage", "", []string{"*.yaml"}, "The local storage path") flags.IntVarP(&opt.grpcMaxRecvMsgSize, "grpc-max-recv-msg-size", "", 4*1024*1024, "The maximum received message size for gRPC clients") flags.StringVarP(&opt.consolePath, "console-path", "", "", "The path of the console") - flags.StringVarP(&opt.configDir, "config-dir", "", os.ExpandEnv("$HOME/.config/atest"), "The config directory") + flags.StringVarP(&opt.configDir, "config-dir", "", home.GetUserConfigDir(), "The config directory") flags.StringVarP(&opt.secretServer, "secret-server", "", "", "The secret server URL") flags.StringVarP(&opt.skyWalking, "skywalking", "", "", "Push the browser tracing data to the Apache SkyWalking HTTP URL") flags.StringVarP(&opt.auth, "auth", "", os.Getenv("AUTH_MODE"), "The auth mode, supported: oauth. Keep it empty to disable auth") diff --git a/cmd/service.go b/cmd/service.go index f0280fb..cac9621 100644 --- a/cmd/service.go +++ b/cmd/service.go @@ -3,6 +3,7 @@ package cmd import ( "fmt" + "github.com/linuxsuren/api-testing/pkg/util/home" "io" "os" "strings" @@ -91,7 +92,7 @@ func (o *serviceOption) preRunE(c *cobra.Command, args []string) (err error) { return } - local := os.ExpandEnv("$HOME/.config/atest") + local := home.GetUserConfigDir() if err = o.Execer.MkdirAll(local, os.ModePerm); err == nil { err = o.Execer.MkdirAll(o.LocalStorage, os.ModePerm) } diff --git a/go.mod b/go.mod index fd8f5e5..89f965f 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22.2 require ( github.com/Masterminds/sprig/v3 v3.2.3 github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 + github.com/blang/semver/v4 v4.0.0 github.com/bufbuild/protocompile v0.6.0 github.com/cucumber/godog v0.12.6 github.com/expr-lang/expr v1.15.6 @@ -42,7 +43,6 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cucumber/gherkin-go/v19 v19.0.3 // indirect github.com/cucumber/messages-go/v16 v16.0.1 // indirect diff --git a/pkg/server/remote_server.go b/pkg/server/remote_server.go index 78c2199..7493fa3 100644 --- a/pkg/server/remote_server.go +++ b/pkg/server/remote_server.go @@ -21,6 +21,7 @@ import ( "context" "errors" "fmt" + "github.com/linuxsuren/api-testing/pkg/util/home" "io" "net/http" "os" @@ -840,7 +841,7 @@ func (s *server) CreateStore(ctx context.Context, in *Store) (reply *Store, err store := ToNormalStore(in) if store.Kind.URL == "" { - store.Kind.URL = fmt.Sprintf("unix://%s", os.ExpandEnv(fmt.Sprintf("$HOME/.config/atest/%s.sock", store.Kind.Name))) + store.Kind.URL = fmt.Sprintf("unix://%s", home.GetExtensionSocketPath(store.Kind.Name)) } if err = storeFactory.CreateStore(store); err == nil && s.storeExtMgr != nil { diff --git a/pkg/server/store_ext_manager.go b/pkg/server/store_ext_manager.go index 3764767..3d3e401 100644 --- a/pkg/server/store_ext_manager.go +++ b/pkg/server/store_ext_manager.go @@ -18,6 +18,7 @@ package server import ( "errors" "fmt" + "github.com/linuxsuren/api-testing/pkg/util/home" "io" "net/http" "os" @@ -86,7 +87,7 @@ func (s *storeExtManager) Start(name, socket string) (err error) { if v, ok := s.extStatusMap[name]; ok && v { return } - targetDir := os.ExpandEnv("$HOME/.config/atest/bin") + targetDir := home.GetUserBinDir() targetBinaryFile := filepath.Join(targetDir, name) var binaryPath string @@ -98,7 +99,7 @@ func (s *storeExtManager) Start(name, socket string) (err error) { if lookErr != nil { reader, dErr := s.ociDownloader.Download(name, "", "") if dErr != nil { - if dErr == ErrDownloadNotSupport { + if errors.Is(dErr, ErrDownloadNotSupport) { err = fmt.Errorf("failed to find %s, error: %v", name, lookErr) } else { err = dErr diff --git a/pkg/util/home/common.go b/pkg/util/home/common.go new file mode 100644 index 0000000..15962f3 --- /dev/null +++ b/pkg/util/home/common.go @@ -0,0 +1,54 @@ +/* +Copyright 2024 API Testing 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. +*/ + +package home + +import ( + "bytes" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func GetUserConfigDir() string { + return filepath.Join(Dir(), ".config/atest") +} + +func GetUserBinDir() string { + return filepath.Join(GetUserConfigDir(), "bin") +} + +func GetExtensionSocketPath(name string) string { + return filepath.Join(GetUserConfigDir(), fmt.Sprintf("%s.sock", name)) +} + +func getCommonHomeDir() string { + return os.Getenv("HOME") +} + +func getHomeDirViaShell() string { + var stdout bytes.Buffer + stdout.Reset() + cmd := exec.Command("sh", "-c", "cd && pwd") + cmd.Stdout = &stdout + if err := cmd.Run(); err != nil { + return "" + } + + return strings.TrimSpace(stdout.String()) +} diff --git a/pkg/util/home/darwin.go b/pkg/util/home/darwin.go new file mode 100644 index 0000000..5de757c --- /dev/null +++ b/pkg/util/home/darwin.go @@ -0,0 +1,44 @@ +//go:build darwin + +/* +Copyright 2024 API Testing 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. +*/ + +package home + +import ( + "bytes" + "os/exec" + "strings" +) + +func Dir() string { + // First prefer the HOME environmental variable + if home := getCommonHomeDir(); home != "" { + return home + } + + var stdout bytes.Buffer + cmd := exec.Command("sh", "-c", `dscl -q . -read /Users/"$(whoami)" NFSHomeDirectory | sed 's/^[^ ]*: //'`) + cmd.Stdout = &stdout + if err := cmd.Run(); err == nil { + result := strings.TrimSpace(stdout.String()) + if result != "" { + return result + } + } + + return getHomeDirViaShell() +} diff --git a/pkg/util/home/doc.go b/pkg/util/home/doc.go new file mode 100644 index 0000000..dfeb1da --- /dev/null +++ b/pkg/util/home/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2024 API Testing 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. +*/ + +// Package home provides a way to get the home directory of OS +// Copied from https://github.com/mitchellh/go-homedir +package home diff --git a/pkg/util/home/linux.go b/pkg/util/home/linux.go new file mode 100644 index 0000000..9d4a6bd --- /dev/null +++ b/pkg/util/home/linux.go @@ -0,0 +1,55 @@ +//go:build linux + +/* +Copyright 2024 API Testing 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. +*/ + +package home + +import ( + "bytes" + "errors" + "os" + "os/exec" + "strconv" + "strings" +) + +func Dir() string { + // First prefer the HOME environmental variable + if home := getCommonHomeDir(); home != "" { + return home + } + + var stdout bytes.Buffer + cmd := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid())) + cmd.Stdout = &stdout + if err := cmd.Run(); err != nil { + // If the error is ErrNotFound, we ignore it. Otherwise, return it. + if !errors.Is(err, exec.ErrNotFound) { + return "" + } + } else { + if passwd := strings.TrimSpace(stdout.String()); passwd != "" { + // username:password:uid:gid:gecos:home:shell + passwdParts := strings.SplitN(passwd, ":", 7) + if len(passwdParts) > 5 { + return passwdParts[5] + } + } + } + + return getHomeDirViaShell() +} diff --git a/pkg/util/home/windows.go b/pkg/util/home/windows.go new file mode 100644 index 0000000..bb66cec --- /dev/null +++ b/pkg/util/home/windows.go @@ -0,0 +1,44 @@ +//go:build windows + +/* +Copyright 2024 API Testing 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. +*/ + +package home + +import ( + "os" +) + +func Dir() string { + // First prefer the HOME environmental variable + if home := getCommonHomeDir(); home != "" { + return home + } + + // Prefer standard environment variable USERPROFILE + if home := os.Getenv("USERPROFILE"); home != "" { + return home + } + + drive := os.Getenv("HOMEDRIVE") + path := os.Getenv("HOMEPATH") + home := drive + path + if drive == "" || path == "" { + return "" + } + + return home +}