diff --git a/agent/cmd/main.go b/agent/cmd/main.go
index 0ce89364..619f07ff 100644
--- a/agent/cmd/main.go
+++ b/agent/cmd/main.go
@@ -8,13 +8,12 @@ import (
"github.com/yusing/godoxy/agent/pkg/agent"
"github.com/yusing/godoxy/agent/pkg/env"
"github.com/yusing/godoxy/agent/pkg/server"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/metrics/systeminfo"
httpServer "github.com/yusing/godoxy/internal/net/gphttp/server"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/pkg"
socketproxy "github.com/yusing/godoxy/socketproxy/pkg"
strutils "github.com/yusing/goutils/strings"
+ "github.com/yusing/goutils/task"
)
func main() {
@@ -27,21 +26,21 @@ func main() {
ca := &agent.PEMPair{}
err := ca.Load(env.AgentCACert)
if err != nil {
- gperr.LogFatal("init CA error", err)
+ log.Fatal().Err(err).Msg("init CA error")
}
caCert, err := ca.ToTLSCert()
if err != nil {
- gperr.LogFatal("init CA error", err)
+ log.Fatal().Err(err).Msg("init CA error")
}
srv := &agent.PEMPair{}
srv.Load(env.AgentSSLCert)
if err != nil {
- gperr.LogFatal("init SSL error", err)
+ log.Fatal().Err(err).Msg("init SSL error")
}
srvCert, err := srv.ToTLSCert()
if err != nil {
- gperr.LogFatal("init SSL error", err)
+ log.Fatal().Err(err).Msg("init SSL error")
}
log.Info().Msgf("GoDoxy Agent version %s", pkg.GetVersion())
diff --git a/agent/go.mod b/agent/go.mod
index e79d59e5..ace5e532 100644
--- a/agent/go.mod
+++ b/agent/go.mod
@@ -20,7 +20,7 @@ require (
github.com/stretchr/testify v1.11.1
github.com/yusing/godoxy v0.18.6
github.com/yusing/godoxy/socketproxy v0.0.0-00010101000000-000000000000
- github.com/yusing/goutils v0.2.1
+ github.com/yusing/goutils v0.3.1
)
require (
diff --git a/agent/go.sum b/agent/go.sum
index f7a7423e..3025ca58 100644
--- a/agent/go.sum
+++ b/agent/go.sum
@@ -208,8 +208,8 @@ github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusing/ds v0.2.0 h1:lPhDU5eA2uvquVrBrzLCrQXRJJgSXlUYA53TbuK2sQY=
github.com/yusing/ds v0.2.0/go.mod h1:XhKV4l7cZwBbbl7lRzNC9zX27zvCM0frIwiuD40ULRk=
-github.com/yusing/goutils v0.2.1 h1:KjoCrNO0otthaPCZPfQY+5GKsqs5+J77CxP+TNHYa/Y=
-github.com/yusing/goutils v0.2.1/go.mod h1:v6RZsMRdzcts4udSg0vqUIFvaD0OaUMPTwYJZ4XnQYo=
+github.com/yusing/goutils v0.3.1 h1:xCPoZ/haI8ZJ0ZaPU4g6+okSPdBczs8o98tIZ/TbpsQ=
+github.com/yusing/goutils v0.3.1/go.mod h1:meg9GcAU8yvBY21JgYjPuLsXD1Q5VdVHE32A4tG5Y5g=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
diff --git a/agent/pkg/agent/agent_pool.go b/agent/pkg/agent/agent_pool.go
index ed01115f..a3793144 100644
--- a/agent/pkg/agent/agent_pool.go
+++ b/agent/pkg/agent/agent_pool.go
@@ -2,15 +2,16 @@ package agent
import (
"iter"
+ "os"
+ "strings"
"github.com/puzpuzpuz/xsync/v4"
- "github.com/yusing/godoxy/internal/common"
)
var agentPool = xsync.NewMap[string, *AgentConfig](xsync.WithPresize(10))
func init() {
- if common.IsTest {
+ if strings.HasSuffix(os.Args[0], ".test") {
agentPool.Store("test-agent", &AgentConfig{
Addr: "test-agent",
})
@@ -63,5 +64,5 @@ func NumAgents() int {
func getAgentByAddr(addr string) (agent *AgentConfig, ok bool) {
agent, ok = agentPool.Load(addr)
- return
+ return agent, ok
}
diff --git a/agent/pkg/agent/new_agent.go b/agent/pkg/agent/new_agent.go
index ad8de0bc..df0af75d 100644
--- a/agent/pkg/agent/new_agent.go
+++ b/agent/pkg/agent/new_agent.go
@@ -3,6 +3,8 @@ package agent
import (
"crypto/aes"
"crypto/cipher"
+ "crypto/ecdsa"
+ "crypto/elliptic"
"crypto/rand"
"crypto/tls"
"crypto/x509"
@@ -10,14 +12,11 @@ import (
"encoding/base64"
"encoding/pem"
"errors"
+ "fmt"
"io"
"math/big"
"strings"
"time"
-
- "crypto/ecdsa"
- "crypto/elliptic"
- "fmt"
)
const (
@@ -244,5 +243,5 @@ func NewAgent() (ca, srv, client *PEMPair, err error) {
}
client = toPEMPair(clientCertDER, clientKey)
- return
+ return ca, srv, client, err
}
diff --git a/agent/pkg/agentproxy/config.go b/agent/pkg/agentproxy/config.go
index 1babd9b6..06b4623a 100644
--- a/agent/pkg/agentproxy/config.go
+++ b/agent/pkg/agentproxy/config.go
@@ -43,7 +43,7 @@ func proxyConfigFromHeadersLegacy(h http.Header) (cfg Config) {
cfg.Scheme = "https"
}
- return
+ return cfg
}
func proxyConfigFromHeaders(h http.Header) (cfg Config, err error) {
diff --git a/agent/pkg/server/server.go b/agent/pkg/server/server.go
index c6a23cc5..f8c92dfe 100644
--- a/agent/pkg/server/server.go
+++ b/agent/pkg/server/server.go
@@ -10,7 +10,7 @@ import (
"github.com/yusing/godoxy/agent/pkg/env"
"github.com/yusing/godoxy/agent/pkg/handler"
"github.com/yusing/godoxy/internal/net/gphttp/server"
- "github.com/yusing/godoxy/internal/task"
+ "github.com/yusing/goutils/task"
)
type Options struct {
diff --git a/cmd/main.go b/cmd/main.go
index 9f066d02..d0f53046 100755
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -9,15 +9,15 @@ import (
"github.com/yusing/godoxy/internal/common"
"github.com/yusing/godoxy/internal/config"
"github.com/yusing/godoxy/internal/dnsproviders"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/homepage"
"github.com/yusing/godoxy/internal/logging"
"github.com/yusing/godoxy/internal/logging/memlogger"
"github.com/yusing/godoxy/internal/metrics/systeminfo"
"github.com/yusing/godoxy/internal/metrics/uptime"
"github.com/yusing/godoxy/internal/net/gphttp/middleware"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/pkg"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
func parallel(fns ...func()) {
diff --git a/go.mod b/go.mod
index 068a83cc..3a4f6504 100644
--- a/go.mod
+++ b/go.mod
@@ -50,7 +50,7 @@ require (
github.com/yusing/godoxy/agent v0.0.0-20250926130035-55c1c918ba95
github.com/yusing/godoxy/internal/dnsproviders v0.0.0-20250926130035-55c1c918ba95
github.com/yusing/godoxy/internal/utils v0.1.0
- github.com/yusing/goutils v0.2.1
+ github.com/yusing/goutils v0.3.1
)
require (
diff --git a/go.sum b/go.sum
index 824ac291..e598eaca 100644
--- a/go.sum
+++ b/go.sum
@@ -1648,8 +1648,8 @@ github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusing/ds v0.2.0 h1:lPhDU5eA2uvquVrBrzLCrQXRJJgSXlUYA53TbuK2sQY=
github.com/yusing/ds v0.2.0/go.mod h1:XhKV4l7cZwBbbl7lRzNC9zX27zvCM0frIwiuD40ULRk=
-github.com/yusing/goutils v0.2.1 h1:KjoCrNO0otthaPCZPfQY+5GKsqs5+J77CxP+TNHYa/Y=
-github.com/yusing/goutils v0.2.1/go.mod h1:v6RZsMRdzcts4udSg0vqUIFvaD0OaUMPTwYJZ4XnQYo=
+github.com/yusing/goutils v0.3.1 h1:xCPoZ/haI8ZJ0ZaPU4g6+okSPdBczs8o98tIZ/TbpsQ=
+github.com/yusing/goutils v0.3.1/go.mod h1:meg9GcAU8yvBY21JgYjPuLsXD1Q5VdVHE32A4tG5Y5g=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
diff --git a/internal/acl/config.go b/internal/acl/config.go
index 33f7320d..78b0be41 100644
--- a/internal/acl/config.go
+++ b/internal/acl/config.go
@@ -7,11 +7,11 @@ import (
"github.com/puzpuzpuz/xsync/v4"
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/logging/accesslog"
"github.com/yusing/godoxy/internal/maxmind"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/utils"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
type Config struct {
diff --git a/internal/acl/matcher.go b/internal/acl/matcher.go
index 4c9fe59d..494c543b 100644
--- a/internal/acl/matcher.go
+++ b/internal/acl/matcher.go
@@ -4,8 +4,8 @@ import (
"net"
"strings"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/maxmind"
+ gperr "github.com/yusing/goutils/errs"
)
type MatcherFunc func(*maxmind.IPInfo) bool
diff --git a/internal/api/handler.go b/internal/api/handler.go
index 8677019b..96c4b37b 100644
--- a/internal/api/handler.go
+++ b/internal/api/handler.go
@@ -20,7 +20,7 @@ import (
routeApi "github.com/yusing/godoxy/internal/api/v1/route"
"github.com/yusing/godoxy/internal/auth"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
// @title GoDoxy API
diff --git a/internal/api/types/error.go b/internal/api/types/error.go
index 0951ee5a..2853bc68 100644
--- a/internal/api/types/error.go
+++ b/internal/api/types/error.go
@@ -3,7 +3,7 @@ package apitypes
import (
"errors"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type ErrorResponse struct {
diff --git a/internal/api/v1/agent/create.go b/internal/api/v1/agent/create.go
index 43545259..225240ea 100644
--- a/internal/api/v1/agent/create.go
+++ b/internal/api/v1/agent/create.go
@@ -9,7 +9,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/yusing/godoxy/agent/pkg/agent"
- apitypes "github.com/yusing/godoxy/internal/api/types"
+ apitypes "github.com/yusing/goutils/apitypes"
)
type NewAgentRequest struct {
diff --git a/internal/api/v1/agent/verify.go b/internal/api/v1/agent/verify.go
index fe2158e8..b219ebc4 100644
--- a/internal/api/v1/agent/verify.go
+++ b/internal/api/v1/agent/verify.go
@@ -8,8 +8,8 @@ import (
"github.com/gin-gonic/gin"
"github.com/yusing/godoxy/agent/pkg/agent"
"github.com/yusing/godoxy/agent/pkg/certs"
- . "github.com/yusing/godoxy/internal/api/types"
config "github.com/yusing/godoxy/internal/config/types"
+ apitypes "github.com/yusing/goutils/apitypes"
)
type VerifyNewAgentRequest struct {
@@ -35,44 +35,44 @@ type VerifyNewAgentRequest struct {
func Verify(c *gin.Context) {
var request VerifyNewAgentRequest
if err := c.ShouldBindJSON(&request); err != nil {
- c.JSON(http.StatusBadRequest, Error("invalid request", err))
+ c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err))
return
}
filename, ok := certs.AgentCertsFilepath(request.Host)
if !ok {
- c.JSON(http.StatusBadRequest, Error("invalid host", nil))
+ c.JSON(http.StatusBadRequest, apitypes.Error("invalid host", nil))
return
}
ca, err := fromEncryptedPEMPairResponse(request.CA)
if err != nil {
- c.JSON(http.StatusBadRequest, Error("invalid CA", err))
+ c.JSON(http.StatusBadRequest, apitypes.Error("invalid CA", err))
return
}
client, err := fromEncryptedPEMPairResponse(request.Client)
if err != nil {
- c.JSON(http.StatusBadRequest, Error("invalid client", err))
+ c.JSON(http.StatusBadRequest, apitypes.Error("invalid client", err))
return
}
nRoutesAdded, err := config.GetInstance().VerifyNewAgent(request.Host, ca, client, request.ContainerRuntime)
if err != nil {
- c.JSON(http.StatusBadRequest, Error("invalid request", err))
+ c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err))
return
}
zip, err := certs.ZipCert(ca.Cert, client.Cert, client.Key)
if err != nil {
- c.Error(InternalServerError(err, "failed to zip certs"))
+ c.Error(apitypes.InternalServerError(err, "failed to zip certs"))
return
}
if err := os.WriteFile(filename, zip, 0o600); err != nil {
- c.Error(InternalServerError(err, "failed to write certs"))
+ c.Error(apitypes.InternalServerError(err, "failed to write certs"))
return
}
- c.JSON(http.StatusOK, Success(fmt.Sprintf("Added %d routes", nRoutesAdded)))
+ c.JSON(http.StatusOK, apitypes.Success(fmt.Sprintf("Added %d routes", nRoutesAdded)))
}
diff --git a/internal/api/v1/cert/renew.go b/internal/api/v1/cert/renew.go
index 8d8c6f38..51597e82 100644
--- a/internal/api/v1/cert/renew.go
+++ b/internal/api/v1/cert/renew.go
@@ -8,9 +8,9 @@ import (
"github.com/rs/zerolog/log"
apitypes "github.com/yusing/godoxy/internal/api/types"
config "github.com/yusing/godoxy/internal/config/types"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/logging/memlogger"
"github.com/yusing/godoxy/internal/net/gphttp/websocket"
+ gperr "github.com/yusing/goutils/errs"
)
// @x-id "renew"
diff --git a/internal/api/v1/docker/containers.go b/internal/api/v1/docker/containers.go
index b67850d6..06f32962 100644
--- a/internal/api/v1/docker/containers.go
+++ b/internal/api/v1/docker/containers.go
@@ -6,7 +6,7 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/gin-gonic/gin"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type ContainerState = container.ContainerState // @name ContainerState
diff --git a/internal/api/v1/docker/info.go b/internal/api/v1/docker/info.go
index 995100d8..43f4caf0 100644
--- a/internal/api/v1/docker/info.go
+++ b/internal/api/v1/docker/info.go
@@ -6,7 +6,7 @@ import (
dockerSystem "github.com/docker/docker/api/types/system"
"github.com/gin-gonic/gin"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
)
diff --git a/internal/api/v1/docker/logs.go b/internal/api/v1/docker/logs.go
index 5c4c5ac0..636bacdf 100644
--- a/internal/api/v1/docker/logs.go
+++ b/internal/api/v1/docker/logs.go
@@ -13,7 +13,7 @@ import (
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/docker"
"github.com/yusing/godoxy/internal/net/gphttp/websocket"
- "github.com/yusing/godoxy/internal/task"
+ "github.com/yusing/goutils/task"
)
type LogsQueryParams struct {
diff --git a/internal/api/v1/docker/utils.go b/internal/api/v1/docker/utils.go
index f2086edb..65b2b95c 100644
--- a/internal/api/v1/docker/utils.go
+++ b/internal/api/v1/docker/utils.go
@@ -10,8 +10,8 @@ import (
apitypes "github.com/yusing/godoxy/internal/api/types"
config "github.com/yusing/godoxy/internal/config/types"
"github.com/yusing/godoxy/internal/docker"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/net/gphttp/websocket"
+ gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/http/httpheaders"
)
diff --git a/internal/api/v1/file/validate.go b/internal/api/v1/file/validate.go
index 38f13ee8..96889570 100644
--- a/internal/api/v1/file/validate.go
+++ b/internal/api/v1/file/validate.go
@@ -6,9 +6,9 @@ import (
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
config "github.com/yusing/godoxy/internal/config/types"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/net/gphttp/middleware"
"github.com/yusing/godoxy/internal/route/provider"
+ gperr "github.com/yusing/goutils/errs"
)
type ValidateFileRequest struct {
diff --git a/internal/api/v1/metrics/all_system_info.go b/internal/api/v1/metrics/all_system_info.go
index d80b8bd5..f100ace1 100644
--- a/internal/api/v1/metrics/all_system_info.go
+++ b/internal/api/v1/metrics/all_system_info.go
@@ -14,10 +14,10 @@ import (
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/agent/pkg/agent"
apitypes "github.com/yusing/godoxy/internal/api/types"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/metrics/period"
"github.com/yusing/godoxy/internal/metrics/systeminfo"
"github.com/yusing/godoxy/internal/net/gphttp/websocket"
+ gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/synk"
)
diff --git a/internal/auth/oidc.go b/internal/auth/oidc.go
index 84feec8c..d5d5b347 100644
--- a/internal/auth/oidc.go
+++ b/internal/auth/oidc.go
@@ -15,9 +15,9 @@ import (
"github.com/coreos/go-oidc/v3/oidc"
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/net/gphttp"
"github.com/yusing/godoxy/internal/utils"
+ gperr "github.com/yusing/goutils/errs"
"golang.org/x/oauth2"
"golang.org/x/time/rate"
)
diff --git a/internal/auth/oidc_test.go b/internal/auth/oidc_test.go
index 9264ba7c..131e616b 100644
--- a/internal/auth/oidc_test.go
+++ b/internal/auth/oidc_test.go
@@ -16,7 +16,7 @@ import (
"github.com/yusing/godoxy/internal/common"
"golang.org/x/oauth2"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
// setupMockOIDC configures mock OIDC provider for testing.
@@ -35,7 +35,7 @@ func setupMockOIDC(t *testing.T) {
},
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
},
- endSessionURL: Must(url.Parse("http://mock-provider/logout")),
+ endSessionURL: expect.Must(url.Parse("http://mock-provider/logout")),
oidcProvider: provider,
oidcVerifier: provider.Verifier(&oidc.Config{
ClientID: "test-client",
@@ -75,7 +75,7 @@ func (j *provider) SignClaims(t *testing.T, claims jwt.Claims) string {
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
token.Header["kid"] = keyID
signed, err := token.SignedString(j.key)
- ExpectNoError(t, err)
+ expect.NoError(t, err)
return signed
}
@@ -84,7 +84,7 @@ func setupProvider(t *testing.T) *provider {
// Generate an RSA key pair for the test.
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
- ExpectNoError(t, err)
+ expect.NoError(t, err)
// Build the matching public JWK that will be served by the endpoint.
jwk := buildRSAJWK(t, &privKey.PublicKey, keyID)
@@ -227,12 +227,12 @@ func TestOIDCCallbackHandler(t *testing.T) {
}
if tt.wantStatus == http.StatusTemporaryRedirect {
- setCookie := Must(http.ParseSetCookie(w.Header().Get("Set-Cookie")))
- ExpectEqual(t, setCookie.Name, CookieOauthToken)
- ExpectTrue(t, setCookie.Value != "")
- ExpectEqual(t, setCookie.Path, "/")
- ExpectEqual(t, setCookie.SameSite, http.SameSiteLaxMode)
- ExpectEqual(t, setCookie.HttpOnly, true)
+ setCookie := expect.Must(http.ParseSetCookie(w.Header().Get("Set-Cookie")))
+ expect.Equal(t, setCookie.Name, CookieOauthToken)
+ expect.True(t, setCookie.Value != "")
+ expect.Equal(t, setCookie.Path, "/")
+ expect.Equal(t, setCookie.SameSite, http.SameSiteLaxMode)
+ expect.Equal(t, setCookie.HttpOnly, true)
}
})
}
@@ -245,7 +245,7 @@ func TestInitOIDC(t *testing.T) {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
- ExpectNoError(t, json.NewEncoder(w).Encode(discoveryDocument(t, server)))
+ expect.NoError(t, json.NewEncoder(w).Encode(discoveryDocument(t, server)))
})
server = httptest.NewServer(mux)
t.Cleanup(server.Close)
@@ -445,9 +445,9 @@ func TestCheckToken(t *testing.T) {
// Call CheckToken and verify the result.
err := auth.CheckToken(req)
if tc.wantErr == nil {
- ExpectNoError(t, err)
+ expect.NoError(t, err)
} else {
- ExpectError(t, tc.wantErr, err)
+ expect.ErrorIs(t, tc.wantErr, err)
}
})
}
diff --git a/internal/auth/userpass.go b/internal/auth/userpass.go
index 16db865e..cab9ae54 100644
--- a/internal/auth/userpass.go
+++ b/internal/auth/userpass.go
@@ -8,8 +8,8 @@ import (
"github.com/golang-jwt/jwt/v5"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/net/gphttp"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
"golang.org/x/crypto/bcrypt"
)
diff --git a/internal/auth/userpass_test.go b/internal/auth/userpass_test.go
index e8e1d362..5746a033 100644
--- a/internal/auth/userpass_test.go
+++ b/internal/auth/userpass_test.go
@@ -9,14 +9,14 @@ import (
"testing"
"time"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
"golang.org/x/crypto/bcrypt"
)
func newMockUserPassAuth() *UserPassAuth {
return &UserPassAuth{
username: "username",
- pwdHash: Must(bcrypt.GenerateFromPassword([]byte("password"), bcrypt.DefaultCost)),
+ pwdHash: expect.Must(bcrypt.GenerateFromPassword([]byte("password"), bcrypt.DefaultCost)),
secret: []byte("abcdefghijklmnopqrstuvwxyz"),
tokenTTL: time.Hour,
}
@@ -25,17 +25,17 @@ func newMockUserPassAuth() *UserPassAuth {
func TestUserPassValidateCredentials(t *testing.T) {
auth := newMockUserPassAuth()
err := auth.validatePassword("username", "password")
- ExpectNoError(t, err)
+ expect.NoError(t, err)
err = auth.validatePassword("username", "wrong-password")
- ExpectError(t, ErrInvalidPassword, err)
+ expect.ErrorIs(t, ErrInvalidPassword, err)
err = auth.validatePassword("wrong-username", "password")
- ExpectError(t, ErrInvalidUsername, err)
+ expect.ErrorIs(t, ErrInvalidUsername, err)
}
func TestUserPassCheckToken(t *testing.T) {
auth := newMockUserPassAuth()
token, err := auth.NewToken()
- ExpectNoError(t, err)
+ expect.NoError(t, err)
tests := []struct {
token string
wantErr bool
@@ -60,9 +60,9 @@ func TestUserPassCheckToken(t *testing.T) {
}
err = auth.CheckToken(req)
if tt.wantErr {
- ExpectTrue(t, err != nil)
+ expect.True(t, err != nil)
} else {
- ExpectNoError(t, err)
+ expect.NoError(t, err)
}
}
}
@@ -96,20 +96,20 @@ func TestUserPassLoginCallbackHandler(t *testing.T) {
w := httptest.NewRecorder()
req := &http.Request{
Host: "app.example.com",
- Body: io.NopCloser(bytes.NewReader(Must(json.Marshal(tt.creds)))),
+ Body: io.NopCloser(bytes.NewReader(expect.Must(json.Marshal(tt.creds)))),
}
auth.PostAuthCallbackHandler(w, req)
if tt.wantErr {
- ExpectEqual(t, w.Code, http.StatusUnauthorized)
+ expect.Equal(t, w.Code, http.StatusUnauthorized)
} else {
- setCookie := Must(http.ParseSetCookie(w.Header().Get("Set-Cookie")))
- ExpectTrue(t, setCookie.Name == auth.TokenCookieName())
- ExpectTrue(t, setCookie.Value != "")
- ExpectEqual(t, setCookie.Domain, "example.com")
- ExpectEqual(t, setCookie.Path, "/")
- ExpectEqual(t, setCookie.SameSite, http.SameSiteLaxMode)
- ExpectEqual(t, setCookie.HttpOnly, true)
- ExpectEqual(t, w.Code, http.StatusOK)
+ setCookie := expect.Must(http.ParseSetCookie(w.Header().Get("Set-Cookie")))
+ expect.True(t, setCookie.Name == auth.TokenCookieName())
+ expect.True(t, setCookie.Value != "")
+ expect.Equal(t, setCookie.Domain, "example.com")
+ expect.Equal(t, setCookie.Path, "/")
+ expect.Equal(t, setCookie.SameSite, http.SameSiteLaxMode)
+ expect.Equal(t, setCookie.HttpOnly, true)
+ expect.Equal(t, w.Code, http.StatusOK)
}
}
}
diff --git a/internal/auth/utils.go b/internal/auth/utils.go
index c8e42b9c..d7d2bd53 100644
--- a/internal/auth/utils.go
+++ b/internal/auth/utils.go
@@ -7,7 +7,7 @@ import (
"time"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
)
diff --git a/internal/autocert/config.go b/internal/autocert/config.go
index a8bfa792..c6eafc8d 100644
--- a/internal/autocert/config.go
+++ b/internal/autocert/config.go
@@ -15,8 +15,8 @@ import (
"github.com/go-acme/lego/v4/lego"
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/utils"
+ gperr "github.com/yusing/goutils/errs"
)
type Config struct {
diff --git a/internal/autocert/provider.go b/internal/autocert/provider.go
index e7014a06..d3b45020 100644
--- a/internal/autocert/provider.go
+++ b/internal/autocert/provider.go
@@ -18,10 +18,10 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/notif"
- "github.com/yusing/godoxy/internal/task"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
+ "github.com/yusing/goutils/task"
)
type (
diff --git a/internal/autocert/providers.go b/internal/autocert/providers.go
index 26f5f2a7..54da5163 100644
--- a/internal/autocert/providers.go
+++ b/internal/autocert/providers.go
@@ -2,8 +2,8 @@ package autocert
import (
"github.com/go-acme/lego/v4/challenge"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/serialization"
+ gperr "github.com/yusing/goutils/errs"
)
type Generator func(map[string]any) (challenge.Provider, gperr.Error)
diff --git a/internal/autocert/types/provider.go b/internal/autocert/types/provider.go
index 7b271175..69fdf918 100644
--- a/internal/autocert/types/provider.go
+++ b/internal/autocert/types/provider.go
@@ -3,7 +3,7 @@ package autocert
import (
"crypto/tls"
- "github.com/yusing/godoxy/internal/task"
+ "github.com/yusing/goutils/task"
)
type Provider interface {
diff --git a/internal/config/agents.go b/internal/config/agents.go
index c7c0074d..9bbaadb8 100644
--- a/internal/config/agents.go
+++ b/internal/config/agents.go
@@ -2,8 +2,8 @@ package config
import (
"github.com/yusing/godoxy/agent/pkg/agent"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/route/provider"
+ gperr "github.com/yusing/goutils/errs"
)
func (cfg *Config) VerifyNewAgent(host string, ca agent.PEMPair, client agent.PEMPair, containerRuntime agent.ContainerRuntime) (int, gperr.Error) {
diff --git a/internal/config/config.go b/internal/config/config.go
index 6a3050a0..ef18b02a 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -18,17 +18,17 @@ import (
"github.com/yusing/godoxy/internal/common"
config "github.com/yusing/godoxy/internal/config/types"
"github.com/yusing/godoxy/internal/entrypoint"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/maxmind"
"github.com/yusing/godoxy/internal/net/gphttp/server"
"github.com/yusing/godoxy/internal/notif"
"github.com/yusing/godoxy/internal/proxmox"
proxy "github.com/yusing/godoxy/internal/route/provider"
"github.com/yusing/godoxy/internal/serialization"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/watcher"
"github.com/yusing/godoxy/internal/watcher/events"
+ gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/strings/ansi"
+ "github.com/yusing/goutils/task"
)
type Config struct {
diff --git a/internal/config/types/config.go b/internal/config/types/config.go
index 412a033b..adb9cc3c 100644
--- a/internal/config/types/config.go
+++ b/internal/config/types/config.go
@@ -9,13 +9,13 @@ import (
"github.com/yusing/godoxy/agent/pkg/agent"
"github.com/yusing/godoxy/internal/acl"
"github.com/yusing/godoxy/internal/autocert"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/logging/accesslog"
maxmind "github.com/yusing/godoxy/internal/maxmind/types"
"github.com/yusing/godoxy/internal/notif"
"github.com/yusing/godoxy/internal/proxmox"
"github.com/yusing/godoxy/internal/serialization"
"github.com/yusing/godoxy/internal/types"
+ gperr "github.com/yusing/goutils/errs"
)
type (
diff --git a/internal/dnsproviders/dummy.go b/internal/dnsproviders/dummy.go
index c35b0bb8..42ddb47a 100644
--- a/internal/dnsproviders/dummy.go
+++ b/internal/dnsproviders/dummy.go
@@ -1,7 +1,9 @@
package dnsproviders
-type DummyConfig struct{}
-type DummyProvider struct{}
+type (
+ DummyConfig struct{}
+ DummyProvider struct{}
+)
func NewDummyDefaultConfig() *DummyConfig {
return &DummyConfig{}
diff --git a/internal/dnsproviders/go.mod b/internal/dnsproviders/go.mod
index 5634cede..fb9a9206 100644
--- a/internal/dnsproviders/go.mod
+++ b/internal/dnsproviders/go.mod
@@ -148,7 +148,7 @@ require (
github.com/vultr/govultr/v3 v3.24.0 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
github.com/yusing/godoxy/internal/utils v0.1.0 // indirect
- github.com/yusing/goutils v0.2.1 // indirect
+ github.com/yusing/goutils v0.3.1 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
go.opentelemetry.io/otel v1.38.0 // indirect
diff --git a/internal/dnsproviders/go.sum b/internal/dnsproviders/go.sum
index 3e019736..673e76bc 100644
--- a/internal/dnsproviders/go.sum
+++ b/internal/dnsproviders/go.sum
@@ -1513,8 +1513,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-github.com/yusing/goutils v0.2.1 h1:KjoCrNO0otthaPCZPfQY+5GKsqs5+J77CxP+TNHYa/Y=
-github.com/yusing/goutils v0.2.1/go.mod h1:v6RZsMRdzcts4udSg0vqUIFvaD0OaUMPTwYJZ4XnQYo=
+github.com/yusing/goutils v0.3.1 h1:xCPoZ/haI8ZJ0ZaPU4g6+okSPdBczs8o98tIZ/TbpsQ=
+github.com/yusing/goutils v0.3.1/go.mod h1:meg9GcAU8yvBY21JgYjPuLsXD1Q5VdVHE32A4tG5Y5g=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
diff --git a/internal/docker/client.go b/internal/docker/client.go
index 4ed034d7..adf3928c 100644
--- a/internal/docker/client.go
+++ b/internal/docker/client.go
@@ -16,7 +16,7 @@ import (
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/agent/pkg/agent"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/task"
+ "github.com/yusing/goutils/task"
)
// TODO: implement reconnect here.
diff --git a/internal/docker/container.go b/internal/docker/container.go
index 6f4664cc..d0c187ef 100644
--- a/internal/docker/container.go
+++ b/internal/docker/container.go
@@ -14,10 +14,10 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
"github.com/yusing/godoxy/agent/pkg/agent"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/serialization"
"github.com/yusing/godoxy/internal/types"
"github.com/yusing/godoxy/internal/utils"
+ gperr "github.com/yusing/goutils/errs"
)
var DummyContainer = new(types.Container)
@@ -84,7 +84,7 @@ func FromDocker(c *container.Summary, dockerHost string) (res *types.Container)
if res.PrivateHostname == "" && res.PublicHostname == "" && res.Running {
addError(res, ErrNoNetwork)
}
- return
+ return res
}
func IsBlacklisted(c *types.Container) bool {
diff --git a/internal/docker/container_test.go b/internal/docker/container_test.go
index 3eb68a70..3dddd829 100644
--- a/internal/docker/container_test.go
+++ b/internal/docker/container_test.go
@@ -4,7 +4,7 @@ import (
"testing"
"github.com/docker/docker/api/types/container"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestContainerExplicit(t *testing.T) {
@@ -37,7 +37,7 @@ func TestContainerExplicit(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := FromDocker(&container.Summary{Names: []string{"test"}, State: "test", Labels: tt.labels}, "")
- ExpectEqual(t, c.IsExplicit, tt.isExplicit)
+ expect.Equal(t, c.IsExplicit, tt.isExplicit)
})
}
}
@@ -74,7 +74,7 @@ func TestContainerHostNetworkMode(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := FromDocker(tt.container, "")
- ExpectEqual(t, c.IsHostNetworkMode, tt.isHostNetworkMode)
+ expect.Equal(t, c.IsHostNetworkMode, tt.isHostNetworkMode)
})
}
}
@@ -109,9 +109,9 @@ func TestImageNameParsing(t *testing.T) {
t.Run(tt.full, func(t *testing.T) {
helper := containerHelper{&container.Summary{Image: tt.full}}
im := helper.parseImage()
- ExpectEqual(t, im.Author, tt.author)
- ExpectEqual(t, im.Name, tt.image)
- ExpectEqual(t, im.Tag, tt.tag)
+ expect.Equal(t, im.Author, tt.author)
+ expect.Equal(t, im.Name, tt.image)
+ expect.Equal(t, im.Tag, tt.tag)
})
}
}
diff --git a/internal/docker/label.go b/internal/docker/label.go
index 21c4391f..057efe17 100644
--- a/internal/docker/label.go
+++ b/internal/docker/label.go
@@ -5,8 +5,8 @@ import (
"strings"
"github.com/goccy/go-yaml"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/types"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
)
diff --git a/internal/entrypoint/entrypoint.go b/internal/entrypoint/entrypoint.go
index 61cd2b76..e4bd7c54 100644
--- a/internal/entrypoint/entrypoint.go
+++ b/internal/entrypoint/entrypoint.go
@@ -11,8 +11,8 @@ import (
"github.com/yusing/godoxy/internal/net/gphttp/middleware"
"github.com/yusing/godoxy/internal/net/gphttp/middleware/errorpage"
"github.com/yusing/godoxy/internal/route/routes"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/types"
+ "github.com/yusing/goutils/task"
)
type Entrypoint struct {
@@ -56,15 +56,15 @@ func (ep *Entrypoint) SetMiddlewares(mws []map[string]any) error {
func (ep *Entrypoint) SetAccessLogger(parent task.Parent, cfg *accesslog.RequestLoggerConfig) (err error) {
if cfg == nil {
ep.accessLogger = nil
- return
+ return err
}
ep.accessLogger, err = accesslog.NewAccessLogger(parent, cfg)
if err != nil {
- return
+ return err
}
log.Debug().Msg("entrypoint access logger created")
- return
+ return err
}
func (ep *Entrypoint) ServeHTTP(w http.ResponseWriter, r *http.Request) {
diff --git a/internal/entrypoint/entrypoint_benchmark_test.go b/internal/entrypoint/entrypoint_benchmark_test.go
index f1c0d555..3739f9b2 100644
--- a/internal/entrypoint/entrypoint_benchmark_test.go
+++ b/internal/entrypoint/entrypoint_benchmark_test.go
@@ -12,8 +12,8 @@ import (
"github.com/yusing/godoxy/internal/route"
"github.com/yusing/godoxy/internal/route/routes"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/types"
+ "github.com/yusing/goutils/task"
)
type noopResponseWriter struct {
@@ -24,10 +24,12 @@ type noopResponseWriter struct {
func (w *noopResponseWriter) Header() http.Header {
return http.Header{}
}
+
func (w *noopResponseWriter) Write(b []byte) (int, error) {
w.written = b
return len(b), nil
}
+
func (w *noopResponseWriter) WriteHeader(statusCode int) {
w.statusCode = statusCode
}
@@ -45,7 +47,7 @@ func (t noopTransport) RoundTrip(req *http.Request) (*http.Response, error) {
func BenchmarkEntrypointReal(b *testing.B) {
var ep Entrypoint
- var req = http.Request{
+ req := http.Request{
Method: "GET",
URL: &url.URL{Path: "/", RawPath: "/"},
Host: "test.domain.tld",
@@ -107,7 +109,7 @@ func BenchmarkEntrypointReal(b *testing.B) {
func BenchmarkEntrypoint(b *testing.B) {
var ep Entrypoint
- var req = http.Request{
+ req := http.Request{
Method: "GET",
URL: &url.URL{Path: "/", RawPath: "/"},
Host: "test.domain.tld",
diff --git a/internal/entrypoint/entrypoint_test.go b/internal/entrypoint/entrypoint_test.go
index 666af96b..51a1b6b4 100644
--- a/internal/entrypoint/entrypoint_test.go
+++ b/internal/entrypoint/entrypoint_test.go
@@ -6,7 +6,7 @@ import (
"github.com/yusing/godoxy/internal/route"
"github.com/yusing/godoxy/internal/route/routes"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
var ep = NewEntrypoint()
diff --git a/internal/gperr/README.md b/internal/gperr/README.md
deleted file mode 100644
index 1ee390e4..00000000
--- a/internal/gperr/README.md
+++ /dev/null
@@ -1,106 +0,0 @@
-# gperr
-
-gperr is an error interface that supports nested structure and subject highlighting.
-
-## Usage
-
-### gperr.Error
-
-The error interface.
-
-### gperr.New
-
-Like `errors.New`, but returns a `gperr.Error`.
-
-### gperr.Wrap
-
-Like `fmt.Errorf("%s: %w", message, err)`, but returns a `gperr.Error`.
-
-### gperr.Error.Subject
-
-Returns a new error with the subject prepended to the error message. The main subject is highlighted.
-
-```go
-err := gperr.New("error message")
-err = err.Subject("bar")
-err = err.Subject("foo")
-```
-
-Output:
-
-foo > bar: error message
-
-### gperr.Error.Subjectf
-
-Like `gperr.Error.Subject`, but formats the subject with `fmt.Sprintf`.
-
-### gperr.PrependSubject
-
-Prepends the subject to the error message like `gperr.Error.Subject`.
-
-```go
-err := gperr.New("error message")
-err = gperr.PrependSubject(err, "foo")
-err = gperr.PrependSubject(err, "bar")
-```
-
-Output:
-
-bar > foo: error message
-
-### gperr.Error.With
-
-Adds a new error to the error chain.
-
-```go
-err := gperr.New("error message")
-err = err.With(gperr.New("inner error"))
-err = err.With(gperr.New("inner error 2").With(gperr.New("inner inner error")))
-```
-
-Output:
-
-```
-error message:
- • inner error
- • inner error 2
- • inner inner error
-```
-
-### gperr.Error.Withf
-
-Like `gperr.Error.With`, but formats the error with `fmt.Errorf`.
-
-### gperr.Error.Is
-
-Returns true if the error is equal to the given error.
-
-### gperr.Builder
-
-A builder for `gperr.Error`.
-
-```go
-builder := gperr.NewBuilder("foo")
-builder.Add(gperr.New("error message"))
-builder.Addf("error message: %s", "foo")
-builder.AddRange(gperr.New("error message 1"), gperr.New("error message 2"))
-```
-
-Output:
-
-```
-foo:
- • error message
- • error message: foo
- • error message 1
- • error message 2
-```
-
-### gperr.Builder.Build
-
-Builds a `gperr.Error` from the builder.
-
-## When to return gperr.Error
-
-- When you want to return multiple errors
-- When the error has a subject
diff --git a/internal/gperr/base.go b/internal/gperr/base.go
deleted file mode 100644
index 6bdc457f..00000000
--- a/internal/gperr/base.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package gperr
-
-import (
- "encoding/json"
- "errors"
- "fmt"
-)
-
-// baseError is an immutable wrapper around an error.
-//
-//nolint:recvcheck
-type baseError struct {
- Err error `json:"err"`
-}
-
-func (err *baseError) Unwrap() error {
- return err.Err
-}
-
-func (err *baseError) Is(other error) bool {
- if other, ok := other.(*baseError); ok {
- return errors.Is(err.Err, other.Err)
- }
- return errors.Is(err.Err, other)
-}
-
-func (err baseError) Subject(subject string) Error {
- err.Err = PrependSubject(subject, err.Err)
- return &err
-}
-
-func (err *baseError) Subjectf(format string, args ...any) Error {
- if len(args) > 0 {
- return err.Subject(fmt.Sprintf(format, args...))
- }
- return err.Subject(format)
-}
-
-func (err *baseError) With(extra error) Error {
- if extra == nil {
- return err
- }
- return &nestedError{&baseError{err.Err}, []error{extra}}
-}
-
-func (err baseError) Withf(format string, args ...any) Error {
- return &nestedError{&err, []error{fmt.Errorf(format, args...)}}
-}
-
-func (err *baseError) Error() string {
- return err.Err.Error()
-}
-
-// MarshalJSON implements the json.Marshaler interface.
-func (err *baseError) MarshalJSON() ([]byte, error) {
- //nolint:errorlint
- switch err := err.Err.(type) {
- case Error, *withSubject:
- return json.Marshal(err)
- case json.Marshaler:
- return err.MarshalJSON()
- case interface{ MarshalText() ([]byte, error) }:
- return err.MarshalText()
- default:
- return json.Marshal(err.Error())
- }
-}
-
-func (err *baseError) Plain() []byte {
- return Plain(err.Err)
-}
-
-func (err *baseError) Markdown() []byte {
- return Markdown(err.Err)
-}
diff --git a/internal/gperr/builder.go b/internal/gperr/builder.go
deleted file mode 100644
index 21eca3ae..00000000
--- a/internal/gperr/builder.go
+++ /dev/null
@@ -1,161 +0,0 @@
-package gperr
-
-import (
- "fmt"
- "sync"
-)
-
-type noLock struct{}
-
-func (noLock) Lock() {}
-func (noLock) Unlock() {}
-func (noLock) RLock() {}
-func (noLock) RUnlock() {}
-
-type rwLock interface {
- sync.Locker
- RLock()
- RUnlock()
-}
-
-type Builder struct {
- about string
- errs []error
- rwLock
-}
-
-// NewBuilder creates a new Builder.
-//
-// If about is not provided, the Builder will not have a subject
-// and will expand when adding to another builder.
-func NewBuilder(about ...string) *Builder {
- if len(about) == 0 {
- return &Builder{rwLock: noLock{}}
- }
- return &Builder{about: about[0], rwLock: noLock{}}
-}
-
-func NewBuilderWithConcurrency(about ...string) *Builder {
- if len(about) == 0 {
- return &Builder{rwLock: new(sync.RWMutex)}
- }
- return &Builder{about: about[0], rwLock: new(sync.RWMutex)}
-}
-
-func (b *Builder) EnableConcurrency() {
- b.rwLock = new(sync.RWMutex)
-}
-
-func (b *Builder) About() string {
- return b.about
-}
-
-func (b *Builder) HasError() bool {
- // no need to lock, when this is called, the Builder is not used anymore
- return len(b.errs) > 0
-}
-
-func (b *Builder) Error() Error {
- if len(b.errs) == 0 {
- return nil
- }
- if len(b.errs) == 1 && b.about == "" {
- return wrap(b.errs[0])
- }
- return &nestedError{Err: New(b.about), Extras: b.errs}
-}
-
-func (b *Builder) String() string {
- err := b.Error()
- if err == nil {
- return ""
- }
- return err.Error()
-}
-
-// Add adds an error to the Builder.
-//
-// adding nil is no-op.
-func (b *Builder) Add(err error) {
- if err == nil {
- return
- }
-
- b.Lock()
- defer b.Unlock()
-
- b.add(err)
-}
-
-func (b *Builder) Adds(err string) {
- b.Lock()
- defer b.Unlock()
- b.errs = append(b.errs, newError(err))
-}
-
-func (b *Builder) Addf(format string, args ...any) {
- if len(args) > 0 {
- b.Lock()
- defer b.Unlock()
- b.errs = append(b.errs, fmt.Errorf(format, args...))
- } else {
- b.Adds(format)
- }
-}
-
-func (b *Builder) AddFrom(other *Builder, flatten bool) {
- if other == nil || !other.HasError() {
- return
- }
-
- b.Lock()
- defer b.Unlock()
- if flatten {
- b.errs = append(b.errs, other.errs...)
- } else {
- b.errs = append(b.errs, other.Error())
- }
-}
-
-func (b *Builder) AddRange(errs ...error) {
- nonNilErrs := make([]error, 0, len(errs))
- for _, err := range errs {
- if err != nil {
- nonNilErrs = append(nonNilErrs, err)
- }
- }
-
- b.Lock()
- defer b.Unlock()
-
- for _, err := range nonNilErrs {
- b.add(err)
- }
-}
-
-func (b *Builder) ForEach(fn func(error)) {
- b.RLock()
- errs := b.errs
- b.RUnlock()
-
- for _, err := range errs {
- fn(err)
- }
-}
-
-func (b *Builder) add(err error) {
- switch err := err.(type) { //nolint:errorlint
- case *baseError:
- b.errs = append(b.errs, err.Err)
- case *nestedError:
- if err.Err == nil {
- b.errs = append(b.errs, err.Extras...)
- } else {
- b.errs = append(b.errs, err)
- }
- case *MultilineError:
- b.add(&err.nestedError)
- default:
- b.errs = append(b.errs, err)
- }
-}
diff --git a/internal/gperr/builder_test.go b/internal/gperr/builder_test.go
deleted file mode 100644
index 8413dcf6..00000000
--- a/internal/gperr/builder_test.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package gperr_test
-
-import (
- "context"
- "errors"
- "io"
- "testing"
-
- . "github.com/yusing/godoxy/internal/gperr"
- . "github.com/yusing/godoxy/internal/utils/testing"
-)
-
-func TestBuilderEmpty(t *testing.T) {
- eb := NewBuilder("foo")
- ExpectTrue(t, errors.Is(eb.Error(), nil))
- ExpectFalse(t, eb.HasError())
-}
-
-func TestBuilderAddNil(t *testing.T) {
- eb := NewBuilder("foo")
- var err Error
- for range 3 {
- eb.Add(nil)
- }
- for range 3 {
- eb.Add(err)
- }
- eb.AddRange(nil, nil, err)
- ExpectFalse(t, eb.HasError())
- ExpectTrue(t, eb.Error() == nil)
-}
-
-func TestBuilderIs(t *testing.T) {
- eb := NewBuilder("foo")
- eb.Add(context.Canceled)
- eb.Add(io.ErrShortBuffer)
- ExpectTrue(t, eb.HasError())
- ExpectError(t, io.ErrShortBuffer, eb.Error())
- ExpectError(t, context.Canceled, eb.Error())
-}
-
-func TestBuilderNested(t *testing.T) {
- eb := NewBuilder("action failed")
- eb.Add(New("Action 1").Withf("Inner: 1").Withf("Inner: 2"))
- eb.Add(New("Action 2").Withf("Inner: 3"))
-
- got := eb.String()
- expected := `action failed
- • Action 1
- • Inner: 1
- • Inner: 2
- • Action 2
- • Inner: 3
-`
- ExpectEqual(t, got, expected)
-}
diff --git a/internal/gperr/error.go b/internal/gperr/error.go
deleted file mode 100644
index df94c925..00000000
--- a/internal/gperr/error.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package gperr
-
-type Error interface {
- error
-
- // Is is a wrapper for errors.Is when there is no sub-error.
- //
- // When there are sub-errors, they will also be checked.
- Is(other error) bool
- // With appends a sub-error to the error.
- With(extra error) Error
- // Withf is a wrapper for With(fmt.Errorf(format, args...)).
- Withf(format string, args ...any) Error
- // Subject prepends the given subject with a colon and space to the error message.
- //
- // If there is already a subject in the error message, the subject will be
- // prepended to the existing subject with " > ".
- //
- // Subject empty string is ignored.
- Subject(subject string) Error
- // Subjectf is a wrapper for Subject(fmt.Sprintf(format, args...)).
- Subjectf(format string, args ...any) Error
- PlainError
- MarkdownError
-}
-
-type PlainError interface {
- Plain() []byte
-}
-
-type MarkdownError interface {
- Markdown() []byte
-}
-
-// this makes JSON marshaling work,
-// as the builtin one doesn't.
-//
-//nolint:errname
-type errStr string
-
-func (err errStr) Error() string {
- return string(err)
-}
diff --git a/internal/gperr/error_test.go b/internal/gperr/error_test.go
deleted file mode 100644
index f0919324..00000000
--- a/internal/gperr/error_test.go
+++ /dev/null
@@ -1,159 +0,0 @@
-package gperr
-
-import (
- "errors"
- "strings"
- "testing"
-
- expect "github.com/yusing/godoxy/internal/utils/testing"
- "github.com/yusing/goutils/strings/ansi"
-)
-
-func TestBaseString(t *testing.T) {
- expect.Equal(t, New("error").Error(), "error")
-}
-
-func TestBaseWithSubject(t *testing.T) {
- err := New("error")
- withSubject := err.Subject("foo")
- withSubjectf := err.Subjectf("%s %s", "foo", "bar")
-
- expect.ErrorIs(t, err, withSubject)
- expect.Equal(t, ansi.StripANSI(withSubject.Error()), "foo: error")
- expect.True(t, withSubject.Is(err))
-
- expect.ErrorIs(t, err, withSubjectf)
- expect.Equal(t, ansi.StripANSI(withSubjectf.Error()), "foo bar: error")
- expect.True(t, withSubjectf.Is(err))
-}
-
-func TestBaseWithExtra(t *testing.T) {
- err := New("error")
- extra := New("bar").Subject("baz")
- withExtra := err.With(extra)
-
- expect.True(t, withExtra.Is(extra))
- expect.True(t, withExtra.Is(err))
-
- expect.True(t, errors.Is(withExtra, extra))
- expect.True(t, errors.Is(withExtra, err))
-
- expect.True(t, strings.Contains(withExtra.Error(), err.Error()))
- expect.True(t, strings.Contains(withExtra.Error(), extra.Error()))
- expect.True(t, strings.Contains(withExtra.Error(), "baz"))
-}
-
-func TestBaseUnwrap(t *testing.T) {
- err := errors.New("err")
- wrapped := Wrap(err)
-
- expect.ErrorIs(t, err, errors.Unwrap(wrapped))
-}
-
-func TestNestedUnwrap(t *testing.T) {
- err := errors.New("err")
- err2 := New("err2")
- wrapped := Wrap(err).Subject("foo").With(err2.Subject("bar"))
-
- unwrapper, ok := wrapped.(interface{ Unwrap() []error })
- expect.True(t, ok)
-
- expect.ErrorIs(t, err, wrapped)
- expect.ErrorIs(t, err2, wrapped)
- expect.Equal(t, len(unwrapper.Unwrap()), 2)
-}
-
-func TestErrorIs(t *testing.T) {
- from := errors.New("error")
- err := Wrap(from)
- expect.ErrorIs(t, from, err)
-
- expect.True(t, err.Is(from))
- expect.False(t, err.Is(New("error")))
-
- expect.True(t, errors.Is(err.Subject("foo"), from))
- expect.True(t, errors.Is(err.Withf("foo"), from))
- expect.True(t, errors.Is(err.Subject("foo").Withf("bar"), from))
-}
-
-func TestErrorImmutability(t *testing.T) {
- err := New("err")
- err2 := New("err2")
-
- for range 3 {
- // t.Logf("%d: %v %T %s", i, errors.Unwrap(err), err, err)
- _ = err.Subject("foo")
- expect.False(t, strings.Contains(err.Error(), "foo"))
-
- _ = err.With(err2)
- expect.False(t, strings.Contains(err.Error(), "extra"))
- expect.False(t, err.Is(err2))
-
- err = err.Subject("bar").Withf("baz")
- expect.True(t, err != nil)
- }
-}
-
-func TestErrorWith(t *testing.T) {
- err1 := New("err1")
- err2 := New("err2")
-
- err3 := err1.With(err2)
-
- expect.True(t, err3.Is(err1))
- expect.True(t, err3.Is(err2))
-
- _ = err2.Subject("foo")
-
- expect.True(t, err3.Is(err1))
- expect.True(t, err3.Is(err2))
-
- // check if err3 is affected by err2.Subject
- expect.False(t, strings.Contains(err3.Error(), "foo"))
-}
-
-func TestErrorStringSimple(t *testing.T) {
- errFailure := New("generic failure")
- ne := errFailure.Subject("foo bar")
- expect.Equal(t, ansi.StripANSI(ne.Error()), "foo bar: generic failure")
- ne = ne.Subject("baz")
- expect.Equal(t, ansi.StripANSI(ne.Error()), "baz > foo bar: generic failure")
-}
-
-func TestErrorStringNested(t *testing.T) {
- errFailure := New("generic failure")
- inner := errFailure.Subject("inner").
- Withf("1").
- Withf("1")
- inner2 := errFailure.Subject("inner2").
- Subject("action 2").
- Withf("2").
- Withf("2")
- inner3 := errFailure.Subject("inner3").
- Subject("action 3").
- Withf("3").
- Withf("3")
- ne := errFailure.
- Subject("foo").
- Withf("bar").
- Withf("baz").
- With(inner).
- With(inner.With(inner2.With(inner3)))
- want := `foo: generic failure
- • bar
- • baz
- • inner: generic failure
- • 1
- • 1
- • inner: generic failure
- • 1
- • 1
- • action 2 > inner2: generic failure
- • 2
- • 2
- • action 3 > inner3: generic failure
- • 3
- • 3
-`
- expect.Equal(t, ansi.StripANSI(ne.Error()), want)
-}
diff --git a/internal/gperr/hint.go b/internal/gperr/hint.go
deleted file mode 100644
index ddc59279..00000000
--- a/internal/gperr/hint.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package gperr
-
-import "github.com/yusing/goutils/strings/ansi"
-
-type Hint struct {
- Prefix string
- Message string
- Suffix string
-}
-
-var _ PlainError = (*Hint)(nil)
-var _ MarkdownError = (*Hint)(nil)
-
-func (h *Hint) Error() string {
- return h.Prefix + ansi.Info(h.Message) + h.Suffix
-}
-
-func (h *Hint) Plain() []byte {
- return []byte(h.Prefix + h.Message + h.Suffix)
-}
-
-func (h *Hint) Markdown() []byte {
- return []byte(h.Prefix + "**" + h.Message + "**" + h.Suffix)
-}
-
-func (h *Hint) MarshalText() ([]byte, error) {
- return h.Plain(), nil
-}
-
-func (h *Hint) String() string {
- return h.Error()
-}
-
-func DoYouMean(s string) error {
- if s == "" {
- return nil
- }
- return &Hint{
- Prefix: "Do you mean ",
- Message: s,
- Suffix: "?",
- }
-}
diff --git a/internal/gperr/log.go b/internal/gperr/log.go
deleted file mode 100644
index 1ace50ab..00000000
--- a/internal/gperr/log.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package gperr
-
-import (
- "os"
-
- "github.com/rs/zerolog"
- zerologlog "github.com/rs/zerolog/log"
- "github.com/yusing/godoxy/internal/common"
-)
-
-func log(msg string, err error, level zerolog.Level, logger ...*zerolog.Logger) {
- var l *zerolog.Logger
- if len(logger) > 0 {
- l = logger[0]
- } else {
- l = &zerologlog.Logger
- }
- l.WithLevel(level).Msg(New(highlightANSI(msg)).With(err).Error())
- switch level {
- case zerolog.FatalLevel:
- os.Exit(1)
- case zerolog.PanicLevel:
- panic(err)
- }
-}
-
-func LogFatal(msg string, err error, logger ...*zerolog.Logger) {
- if common.IsDebug {
- LogPanic(msg, err, logger...)
- }
- log(msg, err, zerolog.FatalLevel, logger...)
-}
-
-func LogError(msg string, err error, logger ...*zerolog.Logger) {
- log(msg, err, zerolog.ErrorLevel, logger...)
-}
-
-func LogWarn(msg string, err error, logger ...*zerolog.Logger) {
- log(msg, err, zerolog.WarnLevel, logger...)
-}
-
-func LogPanic(msg string, err error, logger ...*zerolog.Logger) {
- log(msg, err, zerolog.PanicLevel, logger...)
-}
-
-func LogDebug(msg string, err error, logger ...*zerolog.Logger) {
- log(msg, err, zerolog.DebugLevel, logger...)
-}
diff --git a/internal/gperr/multiline.go b/internal/gperr/multiline.go
deleted file mode 100644
index 35dfc973..00000000
--- a/internal/gperr/multiline.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package gperr
-
-import (
- "fmt"
- "reflect"
-)
-
-type MultilineError struct {
- nestedError
-}
-
-func Multiline() *MultilineError {
- return &MultilineError{}
-}
-
-func (m *MultilineError) add(err error) {
- if err == nil {
- return
- }
- m.Extras = append(m.Extras, err)
-}
-
-func (m *MultilineError) Addf(format string, args ...any) *MultilineError {
- m.add(fmt.Errorf(format, args...))
- return m
-}
-
-func (m *MultilineError) Adds(s string) *MultilineError {
- m.add(newError(s))
- return m
-}
-
-func (m *MultilineError) AddLines(lines ...any) *MultilineError {
- v := reflect.ValueOf(lines)
- if v.Kind() == reflect.Slice {
- for i := range v.Len() {
- switch v := v.Index(i).Interface().(type) {
- case string:
- m.add(newError(v))
- case error:
- m.add(v)
- default:
- m.add(fmt.Errorf("%v", v))
- }
- }
- }
- return m
-}
-
-func (m *MultilineError) AddLinesString(lines ...string) *MultilineError {
- for _, line := range lines {
- m.add(newError(line))
- }
- return m
-}
diff --git a/internal/gperr/multiline_test.go b/internal/gperr/multiline_test.go
deleted file mode 100644
index c277a22f..00000000
--- a/internal/gperr/multiline_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package gperr
-
-import (
- "net"
- "testing"
-
- expect "github.com/yusing/godoxy/internal/utils/testing"
-)
-
-func TestWrapMultiline(t *testing.T) {
- multiline := Multiline()
- var wrapper error = wrap(multiline)
- _, ok := wrapper.(*MultilineError)
- if !ok {
- t.Errorf("wrapper is not a MultilineError")
- }
-}
-
-func TestPrependSubjectMultiline(t *testing.T) {
- multiline := Multiline()
- multiline.Addf("line 1 %s", "test")
- multiline.Adds("line 2")
- multiline.AddLines([]any{1, "2", 3.0, net.IPv4(127, 0, 0, 1)})
- multiline.Subject("subject")
-
- builder := NewBuilder()
- builder.Add(multiline)
- expect.Equal(t, len(multiline.Extras), len(builder.errs))
-}
diff --git a/internal/gperr/nested_error.go b/internal/gperr/nested_error.go
deleted file mode 100644
index 888f3502..00000000
--- a/internal/gperr/nested_error.go
+++ /dev/null
@@ -1,152 +0,0 @@
-package gperr
-
-import (
- "errors"
- "fmt"
-)
-
-//nolint:recvcheck
-type nestedError struct {
- Err error `json:"err"`
- Extras []error `json:"extras"`
-}
-
-var emptyError = errStr("")
-
-func (err nestedError) Subject(subject string) Error {
- if err.Err == nil {
- err.Err = PrependSubject(subject, emptyError)
- } else {
- err.Err = PrependSubject(subject, err.Err)
- }
- return &err
-}
-
-func (err *nestedError) Subjectf(format string, args ...any) Error {
- if len(args) > 0 {
- return err.Subject(fmt.Sprintf(format, args...))
- }
- return err.Subject(format)
-}
-
-func (err nestedError) With(extra error) Error {
- if extra != nil {
- err.Extras = append(err.Extras, extra)
- }
- return &err
-}
-
-func (err nestedError) Withf(format string, args ...any) Error {
- if len(args) > 0 {
- err.Extras = append(err.Extras, fmt.Errorf(format, args...))
- } else {
- err.Extras = append(err.Extras, newError(format))
- }
- return &err
-}
-
-func (err *nestedError) Unwrap() []error {
- if err.Err == nil {
- if len(err.Extras) == 0 {
- return nil
- }
- return err.Extras
- }
- return append([]error{err.Err}, err.Extras...)
-}
-
-func (err *nestedError) Is(other error) bool {
- if errors.Is(err.Err, other) {
- return true
- }
- for _, e := range err.Extras {
- if errors.Is(e, other) {
- return true
- }
- }
- return false
-}
-
-var nilError = newError("")
-var bulletPrefix = []byte("• ")
-var markdownBulletPrefix = []byte("- ")
-var spaces = []byte(" ")
-
-type appendLineFunc func(buf []byte, err error, level int) []byte
-
-func (err *nestedError) fmtError(appendLine appendLineFunc) []byte {
- if err == nil {
- return appendLine(nil, nilError, 0)
- }
- if err.Err != nil {
- buf := appendLine(nil, err.Err, 0)
- if len(err.Extras) > 0 {
- buf = append(buf, '\n')
- buf = appendLines(buf, err.Extras, 1, appendLine)
- }
- return buf
- }
- return appendLines(nil, err.Extras, 0, appendLine)
-}
-
-func (err *nestedError) Error() string {
- return string(err.fmtError(appendLineNormal))
-}
-
-func (err *nestedError) Plain() []byte {
- return err.fmtError(appendLinePlain)
-}
-
-func (err *nestedError) Markdown() []byte {
- return err.fmtError(appendLineMd)
-}
-
-func appendLine(buf []byte, err error, level int, prefix []byte, format func(err error) []byte) []byte {
- if err == nil {
- return appendLine(buf, nilError, level, prefix, format)
- }
- if level == 0 {
- return append(buf, format(err)...)
- }
- buf = append(buf, spaces[:2*level]...)
- buf = append(buf, prefix...)
- buf = append(buf, format(err)...)
- return buf
-}
-
-func appendLineNormal(buf []byte, err error, level int) []byte {
- return appendLine(buf, err, level, bulletPrefix, Normal)
-}
-
-func appendLinePlain(buf []byte, err error, level int) []byte {
- return appendLine(buf, err, level, bulletPrefix, Plain)
-}
-
-func appendLineMd(buf []byte, err error, level int) []byte {
- return appendLine(buf, err, level, markdownBulletPrefix, Markdown)
-}
-
-func appendLines(buf []byte, errs []error, level int, appendLine appendLineFunc) []byte {
- if len(errs) == 0 {
- return buf
- }
- for _, err := range errs {
- switch err := wrap(err).(type) {
- case *nestedError:
- if err.Err != nil {
- buf = appendLine(buf, err.Err, level)
- buf = append(buf, '\n')
- buf = appendLines(buf, err.Extras, level+1, appendLine)
- } else {
- buf = appendLines(buf, err.Extras, level, appendLine)
- }
- default:
- if err == nil {
- continue
- }
- buf = appendLine(buf, err, level)
- buf = append(buf, '\n')
- }
- }
- return buf
-}
diff --git a/internal/gperr/subject.go b/internal/gperr/subject.go
deleted file mode 100644
index 088be5f6..00000000
--- a/internal/gperr/subject.go
+++ /dev/null
@@ -1,144 +0,0 @@
-package gperr
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "slices"
-
- "github.com/yusing/goutils/strings/ansi"
-)
-
-//nolint:errname
-type withSubject struct {
- Subjects []string
- Err error
-
- pendingSubject string
-}
-
-const subjectSep = " > "
-
-type highlightFunc func(subject string) string
-
-var _ PlainError = (*withSubject)(nil)
-var _ MarkdownError = (*withSubject)(nil)
-
-func highlightANSI(subject string) string {
- return ansi.HighlightRed + subject + ansi.Reset
-}
-
-func highlightMarkdown(subject string) string {
- return "**" + subject + "**"
-}
-
-func noHighlight(subject string) string {
- return subject
-}
-
-func PrependSubject(subject string, err error) error {
- if err == nil {
- return nil
- }
-
- //nolint:errorlint
- switch err := err.(type) {
- case *withSubject:
- return err.Prepend(subject)
- case *wrappedError:
- return &wrappedError{
- Err: PrependSubject(subject, err.Err),
- Message: err.Message,
- }
- case Error:
- return err.Subject(subject)
- }
- return &withSubject{[]string{subject}, err, ""}
-}
-
-func (err *withSubject) Prepend(subject string) *withSubject {
- if subject == "" {
- return err
- }
-
- clone := *err
- switch subject[0] {
- case '[', '(', '{':
- // since prepend is called in depth-first order,
- // the subject of the index is not yet seen
- // add it when the next subject is seen
- clone.pendingSubject += subject
- default:
- clone.Subjects = append(clone.Subjects, subject)
- if clone.pendingSubject != "" {
- clone.Subjects[len(clone.Subjects)-1] = subject + clone.pendingSubject
- clone.pendingSubject = ""
- }
- }
- return &clone
-}
-
-func (err *withSubject) Is(other error) bool {
- return errors.Is(other, err.Err)
-}
-
-func (err *withSubject) Unwrap() error {
- return err.Err
-}
-
-func (err *withSubject) Error() string {
- return string(err.fmtError(highlightANSI))
-}
-
-func (err *withSubject) Plain() []byte {
- return err.fmtError(noHighlight)
-}
-
-func (err *withSubject) Markdown() []byte {
- return err.fmtError(highlightMarkdown)
-}
-
-func (err *withSubject) fmtError(highlight highlightFunc) []byte {
- // subject is in reversed order
- size := 0
- errStr := err.Err.Error()
- subjects := err.Subjects
- if err.pendingSubject != "" {
- subjects = append(subjects, err.pendingSubject)
- }
- var buf bytes.Buffer
- for _, s := range subjects {
- size += len(s)
- }
- n := len(subjects)
- buf.Grow(size + 2 + n*len(subjectSep) + len(errStr) + len(highlight("")))
-
- for i := n - 1; i > 0; i-- {
- buf.WriteString(subjects[i])
- buf.WriteString(subjectSep)
- }
- buf.WriteString(highlight(subjects[0]))
- if errStr != "" {
- buf.WriteString(": ")
- buf.WriteString(errStr)
- }
- return buf.Bytes()
-}
-
-// MarshalJSON implements the json.Marshaler interface.
-func (err *withSubject) MarshalJSON() ([]byte, error) {
- subjects := slices.Clone(err.Subjects)
- slices.Reverse(subjects)
- reversed := struct {
- Subjects []string `json:"subjects"`
- Err error `json:"err"`
- }{
- Subjects: subjects,
- Err: err.Err,
- }
- if err.pendingSubject != "" {
- reversed.Subjects = append(reversed.Subjects, err.pendingSubject)
- }
-
- return json.Marshal(reversed)
-}
diff --git a/internal/gperr/utils.go b/internal/gperr/utils.go
deleted file mode 100644
index b39127b9..00000000
--- a/internal/gperr/utils.go
+++ /dev/null
@@ -1,133 +0,0 @@
-package gperr
-
-import (
- "fmt"
-)
-
-func newError(message string) error {
- return errStr(message)
-}
-
-func New(message string) Error {
- if message == "" {
- return nil
- }
- return &baseError{newError(message)}
-}
-
-func Errorf(format string, args ...any) Error {
- return &baseError{fmt.Errorf(format, args...)}
-}
-
-// Wrap wraps message in front of the error message.
-func Wrap(err error, message ...string) Error {
- if err == nil {
- return nil
- }
- if len(message) == 0 || message[0] == "" {
- return wrap(err)
- }
- //nolint:errorlint
- switch err := err.(type) {
- case *baseError:
- err.Err = &wrappedError{err.Err, message[0]}
- return err
- case *nestedError:
- err.Err = &wrappedError{err.Err, message[0]}
- return err
- }
- return &baseError{&wrappedError{err, message[0]}}
-}
-
-func Unwrap(err error) Error {
- //nolint:errorlint
- switch err := err.(type) {
- case interface{ Unwrap() []error }:
- return &nestedError{Extras: err.Unwrap()}
- case interface{ Unwrap() error }:
- return &baseError{err.Unwrap()}
- default:
- return &baseError{err}
- }
-}
-
-func wrap(err error) Error {
- if err == nil {
- return nil
- }
- //nolint:errorlint
- switch err := err.(type) {
- case Error:
- return err
- }
- return &baseError{err}
-}
-
-func Join(errors ...error) Error {
- n := 0
- for _, err := range errors {
- if err != nil {
- n++
- }
- }
- if n == 0 {
- return nil
- }
- errs := make([]error, n)
- i := 0
- for _, err := range errors {
- if err != nil {
- errs[i] = err
- i++
- }
- }
- return &nestedError{Extras: errs}
-}
-
-func JoinLines(main error, errors ...string) Error {
- errs := make([]error, len(errors))
- for i, err := range errors {
- if err == "" {
- continue
- }
- errs[i] = newError(err)
- }
- return &nestedError{Err: main, Extras: errs}
-}
-
-func Collect[T any, Err error, Arg any, Func func(Arg) (T, Err)](eb *Builder, fn Func, arg Arg) T {
- result, err := fn(arg)
- eb.Add(err)
- return result
-}
-
-func Normal(err error) []byte {
- if err == nil {
- return nil
- }
- return []byte(err.Error())
-}
-
-func Plain(err error) []byte {
- if err == nil {
- return nil
- }
- if p, ok := err.(PlainError); ok {
- return p.Plain()
- }
- return []byte(err.Error())
-}
-
-func Markdown(err error) []byte {
- if err == nil {
- return nil
- }
- switch err := err.(type) {
- case MarkdownError:
- return err.Markdown()
- case interface{ Unwrap() []error }:
- return appendLines(nil, err.Unwrap(), 0, appendLineMd)
- default:
- return []byte(err.Error())
- }
-}
diff --git a/internal/gperr/utils_test.go b/internal/gperr/utils_test.go
deleted file mode 100644
index b7bab9c3..00000000
--- a/internal/gperr/utils_test.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package gperr
-
-import (
- "testing"
-)
-
-type testErr struct{}
-
-func (e testErr) Error() string {
- return "test error"
-}
-
-func (e testErr) Plain() []byte {
- return []byte("test error")
-}
-
-func (e testErr) Markdown() []byte {
- return []byte("**test error**")
-}
-
-type testMultiErr struct {
- errors []error
-}
-
-func (e testMultiErr) Error() string {
- return Join(e.errors...).Error()
-}
-
-func (e testMultiErr) Unwrap() []error {
- return e.errors
-}
-
-func TestFormatting(t *testing.T) {
- err := testErr{}
- plain := Plain(err)
- if string(plain) != "test error" {
- t.Errorf("expected test error, got %s", string(plain))
- }
- md := Markdown(err)
- if string(md) != "**test error**" {
- t.Errorf("expected test error, got %s", string(md))
- }
-}
-
-func TestMultiError(t *testing.T) {
- err := testMultiErr{[]error{testErr{}, testErr{}}}
- plain := Plain(err)
- if string(plain) != "test error\ntest error\n" {
- t.Errorf("expected test error, got %s", string(plain))
- }
- md := Markdown(err)
- if string(md) != "**test error**\n**test error**\n" {
- t.Errorf("expected test error, got %s", string(md))
- }
-}
diff --git a/internal/gperr/wrapped.go b/internal/gperr/wrapped.go
deleted file mode 100644
index 810d54ac..00000000
--- a/internal/gperr/wrapped.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package gperr
-
-import (
- "errors"
- "fmt"
-)
-
-type wrappedError struct {
- Err error
- Message string
-}
-
-var _ PlainError = (*wrappedError)(nil)
-var _ MarkdownError = (*wrappedError)(nil)
-
-func (e *wrappedError) Error() string {
- return fmt.Sprintf("%s: %s", e.Message, e.Err.Error())
-}
-
-func (e *wrappedError) Plain() []byte {
- return fmt.Appendf(nil, "%s: %s", e.Message, e.Err.Error())
-}
-
-func (e *wrappedError) Markdown() []byte {
- return fmt.Appendf(nil, "**%s**: %s", e.Message, e.Err.Error())
-}
-
-func (e *wrappedError) Unwrap() error {
- return e.Err
-}
-
-func (e *wrappedError) Is(target error) bool {
- return errors.Is(e.Err, target)
-}
diff --git a/internal/homepage/homepage_test.go b/internal/homepage/homepage_test.go
index 6bf6c1d2..482c7370 100644
--- a/internal/homepage/homepage_test.go
+++ b/internal/homepage/homepage_test.go
@@ -4,7 +4,8 @@ import (
"testing"
. "github.com/yusing/godoxy/internal/homepage"
- . "github.com/yusing/godoxy/internal/utils/testing"
+
+ expect "github.com/yusing/goutils/testing"
)
func TestOverrideItem(t *testing.T) {
@@ -33,7 +34,7 @@ func TestOverrideItem(t *testing.T) {
overrides.Initialize()
overrides.OverrideItem(a.Alias, want)
got := a.GetOverride()
- ExpectEqual(t, got, Item{
+ expect.Equal(t, got, Item{
ItemConfig: want,
Alias: a.Alias,
})
@@ -58,8 +59,8 @@ func TestOverrideItem_PreservesURL(t *testing.T) {
overrides.OverrideItem(a.Alias, wantCfg)
got := a.GetOverride()
- ExpectEqual(t, got.URL, "http://origin.local")
- ExpectEqual(t, got.Name, "Overridden")
+ expect.Equal(t, got.URL, "http://origin.local")
+ expect.Equal(t, got.Name, "Overridden")
}
func TestVisibilityFavoriteAndSortOrders(t *testing.T) {
@@ -81,11 +82,11 @@ func TestVisibilityFavoriteAndSortOrders(t *testing.T) {
overrides.SetFavSortOrder(a.Alias, 2)
got := a.GetOverride()
- ExpectEqual(t, got.Show, false)
- ExpectEqual(t, got.Favorite, true)
- ExpectEqual(t, got.SortOrder, 5)
- ExpectEqual(t, got.AllSortOrder, 9)
- ExpectEqual(t, got.FavSortOrder, 2)
+ expect.Equal(t, got.Show, false)
+ expect.Equal(t, got.Favorite, true)
+ expect.Equal(t, got.SortOrder, 5)
+ expect.Equal(t, got.AllSortOrder, 9)
+ expect.Equal(t, got.FavSortOrder, 2)
}
func TestCategoryDefaultedWhenEmpty(t *testing.T) {
@@ -97,7 +98,7 @@ func TestCategoryDefaultedWhenEmpty(t *testing.T) {
},
}
got := a.GetOverride()
- ExpectEqual(t, got.Category, CategoryOthers)
+ expect.Equal(t, got.Category, CategoryOthers)
}
func TestOverrideItems_Bulk(t *testing.T) {
@@ -128,9 +129,9 @@ func TestOverrideItems_Bulk(t *testing.T) {
ga := a.GetOverride()
gb := b.GetOverride()
- ExpectEqual(t, ga.Name, "A*")
- ExpectEqual(t, ga.Category, "AX")
- ExpectEqual(t, gb.Name, "B*")
- ExpectEqual(t, gb.Category, "BY")
- ExpectEqual(t, gb.Show, false)
+ expect.Equal(t, ga.Name, "A*")
+ expect.Equal(t, ga.Category, "AX")
+ expect.Equal(t, gb.Name, "B*")
+ expect.Equal(t, gb.Category, "BY")
+ expect.Equal(t, gb.Show, false)
}
diff --git a/internal/homepage/icon_cache.go b/internal/homepage/icon_cache.go
index 78414e0a..838f350b 100644
--- a/internal/homepage/icon_cache.go
+++ b/internal/homepage/icon_cache.go
@@ -9,9 +9,9 @@ import (
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/common"
"github.com/yusing/godoxy/internal/jsonstore"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/utils"
"github.com/yusing/godoxy/internal/utils/atomic"
+ "github.com/yusing/goutils/task"
)
type cacheEntry struct {
diff --git a/internal/homepage/icon_url.go b/internal/homepage/icon_url.go
index 9ee07e33..b07463df 100644
--- a/internal/homepage/icon_url.go
+++ b/internal/homepage/icon_url.go
@@ -4,7 +4,7 @@ import (
"fmt"
"strings"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type (
diff --git a/internal/homepage/icon_url_test.go b/internal/homepage/icon_url_test.go
index 944da27c..3ba4b8a7 100644
--- a/internal/homepage/icon_url_test.go
+++ b/internal/homepage/icon_url_test.go
@@ -4,7 +4,7 @@ import (
"testing"
. "github.com/yusing/godoxy/internal/homepage"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func strPtr(s string) *string {
diff --git a/internal/homepage/integrations/qbittorrent/client.go b/internal/homepage/integrations/qbittorrent/client.go
index fd973aa7..3b225ee0 100644
--- a/internal/homepage/integrations/qbittorrent/client.go
+++ b/internal/homepage/integrations/qbittorrent/client.go
@@ -7,8 +7,8 @@ import (
"net/http"
"net/url"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/homepage/widgets"
+ gperr "github.com/yusing/goutils/errs"
)
type Client struct {
diff --git a/internal/homepage/list_icons.go b/internal/homepage/list_icons.go
index f3cc0819..ddb12b4c 100644
--- a/internal/homepage/list_icons.go
+++ b/internal/homepage/list_icons.go
@@ -15,8 +15,8 @@ import (
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/common"
"github.com/yusing/godoxy/internal/serialization"
- "github.com/yusing/godoxy/internal/task"
strutils "github.com/yusing/goutils/strings"
+ "github.com/yusing/goutils/task"
)
type (
diff --git a/internal/homepage/widgets/http.go b/internal/homepage/widgets/http.go
index 4655eec0..f4b71982 100644
--- a/internal/homepage/widgets/http.go
+++ b/internal/homepage/widgets/http.go
@@ -4,7 +4,7 @@ import (
"net/http"
"time"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
var HTTPClient = &http.Client{
diff --git a/internal/homepage/widgets/widgets.go b/internal/homepage/widgets/widgets.go
index 6ff24268..5ee440ea 100644
--- a/internal/homepage/widgets/widgets.go
+++ b/internal/homepage/widgets/widgets.go
@@ -3,8 +3,8 @@ package widgets
import (
"context"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/serialization"
+ gperr "github.com/yusing/goutils/errs"
)
type (
diff --git a/internal/idlewatcher/health.go b/internal/idlewatcher/health.go
index 73e67f2e..49a7bab4 100644
--- a/internal/idlewatcher/health.go
+++ b/internal/idlewatcher/health.go
@@ -3,10 +3,10 @@ package idlewatcher
import (
"time"
- "github.com/yusing/godoxy/internal/gperr"
idlewatcher "github.com/yusing/godoxy/internal/idlewatcher/types"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/types"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
// Start implements health.HealthMonitor.
diff --git a/internal/idlewatcher/provider/docker.go b/internal/idlewatcher/provider/docker.go
index 8302627f..51ab7ee3 100644
--- a/internal/idlewatcher/provider/docker.go
+++ b/internal/idlewatcher/provider/docker.go
@@ -5,10 +5,10 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/yusing/godoxy/internal/docker"
- "github.com/yusing/godoxy/internal/gperr"
idlewatcher "github.com/yusing/godoxy/internal/idlewatcher/types"
"github.com/yusing/godoxy/internal/types"
"github.com/yusing/godoxy/internal/watcher"
+ gperr "github.com/yusing/goutils/errs"
)
type DockerProvider struct {
diff --git a/internal/idlewatcher/provider/proxmox.go b/internal/idlewatcher/provider/proxmox.go
index 8a0c24bb..b3ac35d2 100644
--- a/internal/idlewatcher/provider/proxmox.go
+++ b/internal/idlewatcher/provider/proxmox.go
@@ -5,12 +5,12 @@ import (
"strconv"
"time"
- "github.com/yusing/godoxy/internal/gperr"
idlewatcher "github.com/yusing/godoxy/internal/idlewatcher/types"
"github.com/yusing/godoxy/internal/proxmox"
"github.com/yusing/godoxy/internal/types"
"github.com/yusing/godoxy/internal/watcher"
"github.com/yusing/godoxy/internal/watcher/events"
+ gperr "github.com/yusing/goutils/errs"
)
type ProxmoxProvider struct {
diff --git a/internal/idlewatcher/types/container_status.go b/internal/idlewatcher/types/container_status.go
index d392aadf..c2f13b76 100644
--- a/internal/idlewatcher/types/container_status.go
+++ b/internal/idlewatcher/types/container_status.go
@@ -1,6 +1,6 @@
package idlewatcher
-import "github.com/yusing/godoxy/internal/gperr"
+import gperr "github.com/yusing/goutils/errs"
type ContainerStatus string
diff --git a/internal/idlewatcher/types/provider.go b/internal/idlewatcher/types/provider.go
index 6ac12a1a..66af96a4 100644
--- a/internal/idlewatcher/types/provider.go
+++ b/internal/idlewatcher/types/provider.go
@@ -3,9 +3,9 @@ package idlewatcher
import (
"context"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/types"
"github.com/yusing/godoxy/internal/watcher/events"
+ gperr "github.com/yusing/goutils/errs"
)
type Provider interface {
diff --git a/internal/idlewatcher/watcher.go b/internal/idlewatcher/watcher.go
index c73cbdb4..8adb3be3 100644
--- a/internal/idlewatcher/watcher.go
+++ b/internal/idlewatcher/watcher.go
@@ -12,18 +12,18 @@ import (
"github.com/rs/zerolog/log"
"github.com/yusing/ds/ordered"
"github.com/yusing/godoxy/internal/docker"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/idlewatcher/provider"
idlewatcher "github.com/yusing/godoxy/internal/idlewatcher/types"
nettypes "github.com/yusing/godoxy/internal/net/types"
"github.com/yusing/godoxy/internal/route/routes"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/types"
U "github.com/yusing/godoxy/internal/utils"
"github.com/yusing/godoxy/internal/utils/atomic"
"github.com/yusing/godoxy/internal/watcher/events"
"github.com/yusing/godoxy/internal/watcher/health/monitor"
+ gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/http/reverseproxy"
+ "github.com/yusing/goutils/task"
"golang.org/x/sync/errgroup"
"golang.org/x/sync/singleflight"
)
diff --git a/internal/jsonstore/jsonstore.go b/internal/jsonstore/jsonstore.go
index aaa2e6c7..d264cf6d 100644
--- a/internal/jsonstore/jsonstore.go
+++ b/internal/jsonstore/jsonstore.go
@@ -10,9 +10,9 @@ import (
"github.com/puzpuzpuz/xsync/v4"
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/serialization"
- "github.com/yusing/godoxy/internal/task"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
type namespace string
diff --git a/internal/logging/accesslog/access_logger.go b/internal/logging/accesslog/access_logger.go
index 334a4607..f17b20e8 100644
--- a/internal/logging/accesslog/access_logger.go
+++ b/internal/logging/accesslog/access_logger.go
@@ -9,12 +9,12 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
- "github.com/yusing/godoxy/internal/gperr"
maxmind "github.com/yusing/godoxy/internal/maxmind/types"
- "github.com/yusing/godoxy/internal/task"
+ gperr "github.com/yusing/goutils/errs"
ioutils "github.com/yusing/goutils/io"
strutils "github.com/yusing/goutils/strings"
"github.com/yusing/goutils/synk"
+ "github.com/yusing/goutils/task"
"golang.org/x/time/rate"
)
diff --git a/internal/logging/accesslog/access_logger_test.go b/internal/logging/accesslog/access_logger_test.go
index 8b5c291c..eca91336 100644
--- a/internal/logging/accesslog/access_logger_test.go
+++ b/internal/logging/accesslog/access_logger_test.go
@@ -9,9 +9,9 @@ import (
"time"
. "github.com/yusing/godoxy/internal/logging/accesslog"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/utils"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ "github.com/yusing/goutils/task"
+ expect "github.com/yusing/goutils/testing"
)
const (
diff --git a/internal/logging/accesslog/back_scanner_test.go b/internal/logging/accesslog/back_scanner_test.go
index 08cab2fa..d06c5ffe 100644
--- a/internal/logging/accesslog/back_scanner_test.go
+++ b/internal/logging/accesslog/back_scanner_test.go
@@ -9,9 +9,10 @@ import (
"testing"
"github.com/spf13/afero"
- "github.com/yusing/godoxy/internal/task"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
+
strutils "github.com/yusing/goutils/strings"
+ "github.com/yusing/goutils/task"
)
func TestBackScanner(t *testing.T) {
diff --git a/internal/logging/accesslog/config.go b/internal/logging/accesslog/config.go
index a066aabb..eeb575af 100644
--- a/internal/logging/accesslog/config.go
+++ b/internal/logging/accesslog/config.go
@@ -3,8 +3,8 @@ package accesslog
import (
"time"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/serialization"
+ gperr "github.com/yusing/goutils/errs"
)
type (
diff --git a/internal/logging/accesslog/config_test.go b/internal/logging/accesslog/config_test.go
index 0f5e00d8..33c7036c 100644
--- a/internal/logging/accesslog/config_test.go
+++ b/internal/logging/accesslog/config_test.go
@@ -6,7 +6,7 @@ import (
"github.com/yusing/godoxy/internal/docker"
. "github.com/yusing/godoxy/internal/logging/accesslog"
"github.com/yusing/godoxy/internal/serialization"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestNewConfig(t *testing.T) {
diff --git a/internal/logging/accesslog/fields_test.go b/internal/logging/accesslog/fields_test.go
index cef9a7c5..5d21bcd0 100644
--- a/internal/logging/accesslog/fields_test.go
+++ b/internal/logging/accesslog/fields_test.go
@@ -4,7 +4,7 @@ import (
"testing"
. "github.com/yusing/godoxy/internal/logging/accesslog"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
// Cookie header should be removed,
diff --git a/internal/logging/accesslog/file_logger_test.go b/internal/logging/accesslog/file_logger_test.go
index 68c9a5eb..3d4d9781 100644
--- a/internal/logging/accesslog/file_logger_test.go
+++ b/internal/logging/accesslog/file_logger_test.go
@@ -6,9 +6,8 @@ import (
"sync"
"testing"
- expect "github.com/yusing/godoxy/internal/utils/testing"
-
- "github.com/yusing/godoxy/internal/task"
+ "github.com/yusing/goutils/task"
+ expect "github.com/yusing/goutils/testing"
)
func TestConcurrentFileLoggersShareSameAccessLogIO(t *testing.T) {
diff --git a/internal/logging/accesslog/filter.go b/internal/logging/accesslog/filter.go
index 0659904b..03ba7bf6 100644
--- a/internal/logging/accesslog/filter.go
+++ b/internal/logging/accesslog/filter.go
@@ -5,8 +5,8 @@ import (
"net/http"
"strings"
- "github.com/yusing/godoxy/internal/gperr"
nettypes "github.com/yusing/godoxy/internal/net/types"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
)
diff --git a/internal/logging/accesslog/filter_test.go b/internal/logging/accesslog/filter_test.go
index 995ff895..35bbcae4 100644
--- a/internal/logging/accesslog/filter_test.go
+++ b/internal/logging/accesslog/filter_test.go
@@ -7,8 +7,8 @@ import (
. "github.com/yusing/godoxy/internal/logging/accesslog"
nettypes "github.com/yusing/godoxy/internal/net/types"
- expect "github.com/yusing/godoxy/internal/utils/testing"
strutils "github.com/yusing/goutils/strings"
+ expect "github.com/yusing/goutils/testing"
)
func TestStatusCodeFilter(t *testing.T) {
diff --git a/internal/logging/accesslog/retention.go b/internal/logging/accesslog/retention.go
index d5bd4e40..f941696d 100644
--- a/internal/logging/accesslog/retention.go
+++ b/internal/logging/accesslog/retention.go
@@ -4,7 +4,7 @@ import (
"fmt"
"strconv"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
)
@@ -70,7 +70,7 @@ func (r *Retention) Parse(v string) (err error) {
if !r.IsValid() {
return ErrZeroValue
}
- return
+ return err
}
func (r *Retention) String() string {
diff --git a/internal/logging/accesslog/retention_test.go b/internal/logging/accesslog/retention_test.go
index cacabad8..2f1adbd6 100644
--- a/internal/logging/accesslog/retention_test.go
+++ b/internal/logging/accesslog/retention_test.go
@@ -4,7 +4,7 @@ import (
"testing"
. "github.com/yusing/godoxy/internal/logging/accesslog"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestParseRetention(t *testing.T) {
diff --git a/internal/logging/accesslog/rotate.go b/internal/logging/accesslog/rotate.go
index d81d43f6..536e02ac 100644
--- a/internal/logging/accesslog/rotate.go
+++ b/internal/logging/accesslog/rotate.go
@@ -6,8 +6,8 @@ import (
"time"
"github.com/rs/zerolog"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/utils"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
"github.com/yusing/goutils/synk"
)
@@ -251,14 +251,14 @@ func rotateLogFileBySize(file supportRotate, config *Retention) (result *RotateR
// otherwise it returns zero time.
func ParseLogTime(line []byte) (t time.Time) {
if len(line) == 0 {
- return
+ return t
}
if timeStr := ExtractTime(line); timeStr != nil {
t, _ = time.Parse(LogTimeFormat, string(timeStr)) // ignore error
- return
+ return t
}
- return
+ return t
}
var timeJSON = []byte(`"time":"`)
@@ -272,8 +272,8 @@ func ExtractTime(line []byte) []byte {
switch line[0] {
case '{': // JSON format
if i := bytes.Index(line, timeJSON); i != -1 {
- var jsonStart = i + len(`"time":"`)
- var jsonEnd = i + len(`"time":"`) + len(LogTimeFormat)
+ jsonStart := i + len(`"time":"`)
+ jsonEnd := i + len(`"time":"`) + len(LogTimeFormat)
if len(line) < jsonEnd {
return nil
}
diff --git a/internal/logging/accesslog/rotate_test.go b/internal/logging/accesslog/rotate_test.go
index f3c7bf04..e74e6567 100644
--- a/internal/logging/accesslog/rotate_test.go
+++ b/internal/logging/accesslog/rotate_test.go
@@ -7,10 +7,10 @@ import (
"time"
. "github.com/yusing/godoxy/internal/logging/accesslog"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/utils"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
strutils "github.com/yusing/goutils/strings"
+ "github.com/yusing/goutils/task"
)
var (
diff --git a/internal/logging/accesslog/status_code_range.go b/internal/logging/accesslog/status_code_range.go
index 07ba7974..9c26d987 100644
--- a/internal/logging/accesslog/status_code_range.go
+++ b/internal/logging/accesslog/status_code_range.go
@@ -3,7 +3,7 @@ package accesslog
import (
"strconv"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
)
diff --git a/internal/logging/memlogger/mem_logger.go b/internal/logging/memlogger/mem_logger.go
index 6798312d..77f2d04d 100644
--- a/internal/logging/memlogger/mem_logger.go
+++ b/internal/logging/memlogger/mem_logger.go
@@ -61,11 +61,11 @@ func (m *memLogger) Write(p []byte) (n int, err error) {
pos, err := m.writeBuf(p)
if err != nil {
// not logging the error here, it will cause Run to be called again = infinite loop
- return
+ return n, err
}
m.notifyWS(pos, n)
- return
+ return n, err
}
func (m *memLogger) ServeHTTP(c *gin.Context) {
@@ -149,7 +149,7 @@ func (m *memLogger) writeBuf(b []byte) (pos int, err error) {
defer m.Unlock()
pos = m.Len()
_, err = m.Buffer.Write(b)
- return
+ return pos, err
}
func (m *memLogger) events() (logs <-chan []byte, cancel func()) {
diff --git a/internal/maxmind/instance.go b/internal/maxmind/instance.go
index 2848693a..056417c4 100644
--- a/internal/maxmind/instance.go
+++ b/internal/maxmind/instance.go
@@ -5,9 +5,9 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/notif"
- "github.com/yusing/godoxy/internal/task"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
var instance *MaxMind
diff --git a/internal/maxmind/maxmind.go b/internal/maxmind/maxmind.go
index 63572239..e6ceb8fb 100644
--- a/internal/maxmind/maxmind.go
+++ b/internal/maxmind/maxmind.go
@@ -15,9 +15,9 @@ import (
"github.com/oschwald/maxminddb-golang"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
maxmind "github.com/yusing/godoxy/internal/maxmind/types"
- "github.com/yusing/godoxy/internal/task"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
/*
diff --git a/internal/maxmind/maxmind_test.go b/internal/maxmind/maxmind_test.go
index 4d6acfc7..0c59675d 100644
--- a/internal/maxmind/maxmind_test.go
+++ b/internal/maxmind/maxmind_test.go
@@ -10,7 +10,7 @@ import (
"github.com/oschwald/maxminddb-golang"
maxmind "github.com/yusing/godoxy/internal/maxmind/types"
- "github.com/yusing/godoxy/internal/task"
+ "github.com/yusing/goutils/task"
)
func testCfg() *MaxMind {
diff --git a/internal/maxmind/types/config.go b/internal/maxmind/types/config.go
index 15f44eac..4fa21987 100644
--- a/internal/maxmind/types/config.go
+++ b/internal/maxmind/types/config.go
@@ -3,7 +3,7 @@ package maxmind
import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type (
diff --git a/internal/metrics/period/poller.go b/internal/metrics/period/poller.go
index e9fe4662..241085eb 100644
--- a/internal/metrics/period/poller.go
+++ b/internal/metrics/period/poller.go
@@ -11,9 +11,9 @@ import (
"time"
"github.com/rs/zerolog/log"
- "github.com/yusing/godoxy/internal/gperr"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/utils/atomic"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
type (
diff --git a/internal/metrics/systeminfo/system_info.go b/internal/metrics/systeminfo/system_info.go
index ddc833a1..a489e7a4 100644
--- a/internal/metrics/systeminfo/system_info.go
+++ b/internal/metrics/systeminfo/system_info.go
@@ -16,8 +16,8 @@ import (
"github.com/shirou/gopsutil/v4/sensors"
"github.com/shirou/gopsutil/v4/warning"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/metrics/period"
+ gperr "github.com/yusing/goutils/errs"
)
// json tags are left for tests
diff --git a/internal/metrics/systeminfo/system_info_test.go b/internal/metrics/systeminfo/system_info_test.go
index 805150d3..d6bc1d4e 100644
--- a/internal/metrics/systeminfo/system_info_test.go
+++ b/internal/metrics/systeminfo/system_info_test.go
@@ -10,96 +10,98 @@ import (
"github.com/shirou/gopsutil/v4/mem"
"github.com/shirou/gopsutil/v4/net"
"github.com/shirou/gopsutil/v4/sensors"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
// Create test data
-var cpuAvg = 45.67
-var testInfo = &SystemInfo{
- Timestamp: 123456,
- CPUAverage: &cpuAvg,
- Memory: &mem.VirtualMemoryStat{
- Total: 16000000000,
- Available: 8000000000,
- Used: 8000000000,
- UsedPercent: 50.0,
- },
- Disks: map[string]*disk.UsageStat{
- "sda": {
- Path: "/",
- Fstype: "ext4",
- Total: 500000000000,
- Free: 250000000000,
- Used: 250000000000,
+var (
+ cpuAvg = 45.67
+ testInfo = &SystemInfo{
+ Timestamp: 123456,
+ CPUAverage: &cpuAvg,
+ Memory: &mem.VirtualMemoryStat{
+ Total: 16000000000,
+ Available: 8000000000,
+ Used: 8000000000,
UsedPercent: 50.0,
},
- "nvme0n1": {
- Path: "/",
- Fstype: "zfs",
- Total: 500000000000,
- Free: 250000000000,
- Used: 250000000000,
- UsedPercent: 50.0,
+ Disks: map[string]*disk.UsageStat{
+ "sda": {
+ Path: "/",
+ Fstype: "ext4",
+ Total: 500000000000,
+ Free: 250000000000,
+ Used: 250000000000,
+ UsedPercent: 50.0,
+ },
+ "nvme0n1": {
+ Path: "/",
+ Fstype: "zfs",
+ Total: 500000000000,
+ Free: 250000000000,
+ Used: 250000000000,
+ UsedPercent: 50.0,
+ },
},
- },
- DisksIO: map[string]*disk.IOCountersStat{
- "media": {
- Name: "media",
- ReadBytes: 1000000,
- WriteBytes: 2000000,
- ReadSpeed: 100.5,
- WriteSpeed: 200.5,
- Iops: 1000,
+ DisksIO: map[string]*disk.IOCountersStat{
+ "media": {
+ Name: "media",
+ ReadBytes: 1000000,
+ WriteBytes: 2000000,
+ ReadSpeed: 100.5,
+ WriteSpeed: 200.5,
+ Iops: 1000,
+ },
+ "nvme0n1": {
+ Name: "nvme0n1",
+ ReadBytes: 1000000,
+ WriteBytes: 2000000,
+ ReadSpeed: 100.5,
+ WriteSpeed: 200.5,
+ Iops: 1000,
+ },
},
- "nvme0n1": {
- Name: "nvme0n1",
- ReadBytes: 1000000,
- WriteBytes: 2000000,
- ReadSpeed: 100.5,
- WriteSpeed: 200.5,
- Iops: 1000,
+ Network: &net.IOCountersStat{
+ BytesSent: 5000000,
+ BytesRecv: 10000000,
+ UploadSpeed: 1024.5,
+ DownloadSpeed: 2048.5,
},
- },
- Network: &net.IOCountersStat{
- BytesSent: 5000000,
- BytesRecv: 10000000,
- UploadSpeed: 1024.5,
- DownloadSpeed: 2048.5,
- },
- Sensors: []sensors.TemperatureStat{
- {
- SensorKey: "cpu_temp",
- Temperature: 30.0,
- High: 40.0,
- Critical: 50.0,
+ Sensors: []sensors.TemperatureStat{
+ {
+ SensorKey: "cpu_temp",
+ Temperature: 30.0,
+ High: 40.0,
+ Critical: 50.0,
+ },
+ {
+ SensorKey: "gpu_temp",
+ Temperature: 40.0,
+ High: 50.0,
+ Critical: 60.0,
+ },
},
- {
- SensorKey: "gpu_temp",
- Temperature: 40.0,
- High: 50.0,
- Critical: 60.0,
- },
- },
-}
+ }
+)
func TestSystemInfo(t *testing.T) {
// Test marshaling
data, err := json.Marshal(testInfo)
- ExpectNoError(t, err)
+ expect.NoError(t, err)
// Test unmarshaling back
var decoded SystemInfo
err = json.Unmarshal(data, &decoded)
- ExpectNoError(t, err)
+ expect.NoError(t, err)
// Compare original and decoded
- ExpectEqual(t, decoded.Timestamp, testInfo.Timestamp)
- ExpectEqual(t, *decoded.CPUAverage, *testInfo.CPUAverage)
- ExpectEqual(t, decoded.Memory, testInfo.Memory)
- ExpectEqual(t, decoded.Disks, testInfo.Disks)
- ExpectEqual(t, decoded.DisksIO, testInfo.DisksIO)
- ExpectEqual(t, decoded.Network, testInfo.Network)
- ExpectEqual(t, decoded.Sensors, testInfo.Sensors)
+ expect.Equal(t, decoded.Timestamp, testInfo.Timestamp)
+ expect.Equal(t, *decoded.CPUAverage, *testInfo.CPUAverage)
+ expect.Equal(t, decoded.Memory, testInfo.Memory)
+ expect.Equal(t, decoded.Disks, testInfo.Disks)
+ expect.Equal(t, decoded.DisksIO, testInfo.DisksIO)
+ expect.Equal(t, decoded.Network, testInfo.Network)
+ expect.Equal(t, decoded.Sensors, testInfo.Sensors)
// Test nil fields
nilInfo := &SystemInfo{
@@ -107,18 +109,18 @@ func TestSystemInfo(t *testing.T) {
}
data, err = json.Marshal(nilInfo)
- ExpectNoError(t, err)
+ expect.NoError(t, err)
var decodedNil SystemInfo
err = json.Unmarshal(data, &decodedNil)
- ExpectNoError(t, err)
+ expect.NoError(t, err)
- ExpectEqual(t, decodedNil.Timestamp, nilInfo.Timestamp)
- ExpectTrue(t, decodedNil.CPUAverage == nil)
- ExpectTrue(t, decodedNil.Memory == nil)
- ExpectTrue(t, decodedNil.Disks == nil)
- ExpectTrue(t, decodedNil.Network == nil)
- ExpectTrue(t, decodedNil.Sensors == nil)
+ expect.Equal(t, decodedNil.Timestamp, nilInfo.Timestamp)
+ expect.True(t, decodedNil.CPUAverage == nil)
+ expect.True(t, decodedNil.Memory == nil)
+ expect.True(t, decodedNil.Disks == nil)
+ expect.True(t, decodedNil.Network == nil)
+ expect.True(t, decodedNil.Sensors == nil)
}
func TestSerialize(t *testing.T) {
@@ -130,15 +132,15 @@ func TestSerialize(t *testing.T) {
t.Run(string(query), func(t *testing.T) {
_, result := aggregate(entries, url.Values{"aggregate": []string{string(query)}})
s, err := result.MarshalJSON()
- ExpectNoError(t, err)
+ expect.NoError(t, err)
var v []map[string]any
- ExpectNoError(t, json.Unmarshal(s, &v))
- ExpectEqual(t, len(v), len(result.Entries))
+ expect.NoError(t, json.Unmarshal(s, &v))
+ expect.Equal(t, len(v), len(result.Entries))
for i, m := range v {
for k, v := range m {
// some int64 values are converted to float64 on json.Unmarshal
vv := reflect.ValueOf(result.Entries[i][k])
- ExpectEqual(t, reflect.ValueOf(v).Convert(vv.Type()).Interface(), vv.Interface())
+ expect.Equal(t, reflect.ValueOf(v).Convert(vv.Type()).Interface(), vv.Interface())
}
}
})
diff --git a/internal/metrics/uptime/uptime.go b/internal/metrics/uptime/uptime.go
index 03217b39..08793f95 100644
--- a/internal/metrics/uptime/uptime.go
+++ b/internal/metrics/uptime/uptime.go
@@ -4,9 +4,8 @@ import (
"context"
"encoding/json"
"net/url"
- "time"
-
"slices"
+ "time"
"github.com/lithammer/fuzzysearch/fuzzy"
config "github.com/yusing/godoxy/internal/config/types"
diff --git a/internal/net/gphttp/content_type_test.go b/internal/net/gphttp/content_type_test.go
index 827c5d69..aa167ea2 100644
--- a/internal/net/gphttp/content_type_test.go
+++ b/internal/net/gphttp/content_type_test.go
@@ -4,38 +4,38 @@ import (
"net/http"
"testing"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestContentTypes(t *testing.T) {
- ExpectTrue(t, GetContentType(http.Header{"Content-Type": {"text/html"}}).IsHTML())
- ExpectTrue(t, GetContentType(http.Header{"Content-Type": {"text/html; charset=utf-8"}}).IsHTML())
- ExpectTrue(t, GetContentType(http.Header{"Content-Type": {"application/xhtml+xml"}}).IsHTML())
- ExpectFalse(t, GetContentType(http.Header{"Content-Type": {"text/plain"}}).IsHTML())
+ expect.True(t, GetContentType(http.Header{"Content-Type": {"text/html"}}).IsHTML())
+ expect.True(t, GetContentType(http.Header{"Content-Type": {"text/html; charset=utf-8"}}).IsHTML())
+ expect.True(t, GetContentType(http.Header{"Content-Type": {"application/xhtml+xml"}}).IsHTML())
+ expect.False(t, GetContentType(http.Header{"Content-Type": {"text/plain"}}).IsHTML())
- ExpectTrue(t, GetContentType(http.Header{"Content-Type": {"application/json"}}).IsJSON())
- ExpectTrue(t, GetContentType(http.Header{"Content-Type": {"application/json; charset=utf-8"}}).IsJSON())
- ExpectFalse(t, GetContentType(http.Header{"Content-Type": {"text/html"}}).IsJSON())
+ expect.True(t, GetContentType(http.Header{"Content-Type": {"application/json"}}).IsJSON())
+ expect.True(t, GetContentType(http.Header{"Content-Type": {"application/json; charset=utf-8"}}).IsJSON())
+ expect.False(t, GetContentType(http.Header{"Content-Type": {"text/html"}}).IsJSON())
- ExpectTrue(t, GetContentType(http.Header{"Content-Type": {"text/plain"}}).IsPlainText())
- ExpectTrue(t, GetContentType(http.Header{"Content-Type": {"text/plain; charset=utf-8"}}).IsPlainText())
- ExpectFalse(t, GetContentType(http.Header{"Content-Type": {"text/html"}}).IsPlainText())
+ expect.True(t, GetContentType(http.Header{"Content-Type": {"text/plain"}}).IsPlainText())
+ expect.True(t, GetContentType(http.Header{"Content-Type": {"text/plain; charset=utf-8"}}).IsPlainText())
+ expect.False(t, GetContentType(http.Header{"Content-Type": {"text/html"}}).IsPlainText())
}
func TestAcceptContentTypes(t *testing.T) {
- ExpectTrue(t, GetAccept(http.Header{"Accept": {"text/html", "text/plain"}}).AcceptPlainText())
- ExpectTrue(t, GetAccept(http.Header{"Accept": {"text/html", "text/plain; charset=utf-8"}}).AcceptPlainText())
- ExpectTrue(t, GetAccept(http.Header{"Accept": {"text/html", "text/plain"}}).AcceptHTML())
- ExpectTrue(t, GetAccept(http.Header{"Accept": {"application/json"}}).AcceptJSON())
- ExpectTrue(t, GetAccept(http.Header{"Accept": {"*/*"}}).AcceptPlainText())
- ExpectTrue(t, GetAccept(http.Header{"Accept": {"*/*"}}).AcceptHTML())
- ExpectTrue(t, GetAccept(http.Header{"Accept": {"*/*"}}).AcceptJSON())
- ExpectTrue(t, GetAccept(http.Header{"Accept": {"text/*"}}).AcceptPlainText())
- ExpectTrue(t, GetAccept(http.Header{"Accept": {"text/*"}}).AcceptHTML())
+ expect.True(t, GetAccept(http.Header{"Accept": {"text/html", "text/plain"}}).AcceptPlainText())
+ expect.True(t, GetAccept(http.Header{"Accept": {"text/html", "text/plain; charset=utf-8"}}).AcceptPlainText())
+ expect.True(t, GetAccept(http.Header{"Accept": {"text/html", "text/plain"}}).AcceptHTML())
+ expect.True(t, GetAccept(http.Header{"Accept": {"application/json"}}).AcceptJSON())
+ expect.True(t, GetAccept(http.Header{"Accept": {"*/*"}}).AcceptPlainText())
+ expect.True(t, GetAccept(http.Header{"Accept": {"*/*"}}).AcceptHTML())
+ expect.True(t, GetAccept(http.Header{"Accept": {"*/*"}}).AcceptJSON())
+ expect.True(t, GetAccept(http.Header{"Accept": {"text/*"}}).AcceptPlainText())
+ expect.True(t, GetAccept(http.Header{"Accept": {"text/*"}}).AcceptHTML())
- ExpectFalse(t, GetAccept(http.Header{"Accept": {"text/plain"}}).AcceptHTML())
- ExpectFalse(t, GetAccept(http.Header{"Accept": {"text/plain; charset=utf-8"}}).AcceptHTML())
- ExpectFalse(t, GetAccept(http.Header{"Accept": {"text/html"}}).AcceptPlainText())
- ExpectFalse(t, GetAccept(http.Header{"Accept": {"text/html"}}).AcceptJSON())
- ExpectFalse(t, GetAccept(http.Header{"Accept": {"text/*"}}).AcceptJSON())
+ expect.False(t, GetAccept(http.Header{"Accept": {"text/plain"}}).AcceptHTML())
+ expect.False(t, GetAccept(http.Header{"Accept": {"text/plain; charset=utf-8"}}).AcceptHTML())
+ expect.False(t, GetAccept(http.Header{"Accept": {"text/html"}}).AcceptPlainText())
+ expect.False(t, GetAccept(http.Header{"Accept": {"text/html"}}).AcceptJSON())
+ expect.False(t, GetAccept(http.Header{"Accept": {"text/*"}}).AcceptJSON())
}
diff --git a/internal/net/gphttp/loadbalancer/ip_hash.go b/internal/net/gphttp/loadbalancer/ip_hash.go
index a71f8e29..1abce638 100644
--- a/internal/net/gphttp/loadbalancer/ip_hash.go
+++ b/internal/net/gphttp/loadbalancer/ip_hash.go
@@ -6,9 +6,9 @@ import (
"net/http"
"sync"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/net/gphttp/middleware"
"github.com/yusing/godoxy/internal/types"
+ gperr "github.com/yusing/goutils/errs"
)
type ipHash struct {
diff --git a/internal/net/gphttp/loadbalancer/loadbalancer.go b/internal/net/gphttp/loadbalancer/loadbalancer.go
index 7f67f743..14c87789 100644
--- a/internal/net/gphttp/loadbalancer/loadbalancer.go
+++ b/internal/net/gphttp/loadbalancer/loadbalancer.go
@@ -8,11 +8,11 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
- "github.com/yusing/godoxy/internal/gperr"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/types"
"github.com/yusing/godoxy/internal/utils/pool"
+ gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/http/httpheaders"
+ "github.com/yusing/goutils/task"
)
// TODO: stats of each server.
diff --git a/internal/net/gphttp/loadbalancer/loadbalancer_test.go b/internal/net/gphttp/loadbalancer/loadbalancer_test.go
index dda958c6..430cd7c7 100644
--- a/internal/net/gphttp/loadbalancer/loadbalancer_test.go
+++ b/internal/net/gphttp/loadbalancer/loadbalancer_test.go
@@ -4,7 +4,7 @@ import (
"testing"
"github.com/yusing/godoxy/internal/types"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestRebalance(t *testing.T) {
@@ -15,7 +15,7 @@ func TestRebalance(t *testing.T) {
lb.AddServer(TestNewServer(0))
}
lb.rebalance()
- ExpectEqual(t, lb.sumWeight, maxWeight)
+ expect.Equal(t, lb.sumWeight, maxWeight)
})
t.Run("less", func(t *testing.T) {
lb := New(new(types.LoadBalancerConfig))
@@ -26,7 +26,7 @@ func TestRebalance(t *testing.T) {
lb.AddServer(TestNewServer(float64(maxWeight) * .1))
lb.rebalance()
// t.Logf("%s", U.Must(json.MarshalIndent(lb.pool, "", " ")))
- ExpectEqual(t, lb.sumWeight, maxWeight)
+ expect.Equal(t, lb.sumWeight, maxWeight)
})
t.Run("more", func(t *testing.T) {
lb := New(new(types.LoadBalancerConfig))
@@ -39,6 +39,6 @@ func TestRebalance(t *testing.T) {
lb.AddServer(TestNewServer(float64(maxWeight) * .1))
lb.rebalance()
// t.Logf("%s", U.Must(json.MarshalIndent(lb.pool, "", " ")))
- ExpectEqual(t, lb.sumWeight, maxWeight)
+ expect.Equal(t, lb.sumWeight, maxWeight)
})
}
diff --git a/internal/net/gphttp/middleware/bypass_test.go b/internal/net/gphttp/middleware/bypass_test.go
index 98126767..c7131d77 100644
--- a/internal/net/gphttp/middleware/bypass_test.go
+++ b/internal/net/gphttp/middleware/bypass_test.go
@@ -14,9 +14,9 @@ import (
. "github.com/yusing/godoxy/internal/net/gphttp/middleware"
"github.com/yusing/godoxy/internal/route"
routeTypes "github.com/yusing/godoxy/internal/route/types"
- "github.com/yusing/godoxy/internal/task"
- expect "github.com/yusing/godoxy/internal/utils/testing"
"github.com/yusing/goutils/http/reverseproxy"
+ "github.com/yusing/goutils/task"
+ expect "github.com/yusing/goutils/testing"
)
func noOpHandler(w http.ResponseWriter, r *http.Request) {}
diff --git a/internal/net/gphttp/middleware/captcha/hcaptcha.go b/internal/net/gphttp/middleware/captcha/hcaptcha.go
index 1adc18b1..e6da96d8 100644
--- a/internal/net/gphttp/middleware/captcha/hcaptcha.go
+++ b/internal/net/gphttp/middleware/captcha/hcaptcha.go
@@ -12,7 +12,7 @@ import (
_ "embed"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type HcaptchaProvider struct {
diff --git a/internal/net/gphttp/middleware/captcha/provider.go b/internal/net/gphttp/middleware/captcha/provider.go
index de3f9970..e8c2d470 100644
--- a/internal/net/gphttp/middleware/captcha/provider.go
+++ b/internal/net/gphttp/middleware/captcha/provider.go
@@ -4,7 +4,7 @@ import (
"net/http"
"time"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type Provider interface {
@@ -16,6 +16,4 @@ type Provider interface {
FormHTML() string
}
-var (
- ErrCaptchaVerificationFailed = gperr.New("captcha verification failed")
-)
+var ErrCaptchaVerificationFailed = gperr.New("captcha verification failed")
diff --git a/internal/net/gphttp/middleware/cidr_whitelist_test.go b/internal/net/gphttp/middleware/cidr_whitelist_test.go
index 8aef7c1f..9de55033 100644
--- a/internal/net/gphttp/middleware/cidr_whitelist_test.go
+++ b/internal/net/gphttp/middleware/cidr_whitelist_test.go
@@ -7,9 +7,9 @@ import (
"strings"
"testing"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/serialization"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ gperr "github.com/yusing/goutils/errs"
+ expect "github.com/yusing/goutils/testing"
)
//go:embed test_data/cidr_whitelist_test.yml
@@ -23,32 +23,32 @@ func TestCIDRWhitelistValidation(t *testing.T) {
"allow": []string{"192.168.2.100/32"},
"message": testMessage,
})
- ExpectNoError(t, err)
+ expect.NoError(t, err)
_, err = CIDRWhiteList.New(OptionsRaw{
"allow": []string{"192.168.2.100/32"},
"message": testMessage,
"status": 403,
})
- ExpectNoError(t, err)
+ expect.NoError(t, err)
_, err = CIDRWhiteList.New(OptionsRaw{
"allow": []string{"192.168.2.100/32"},
"message": testMessage,
"status_code": 403,
})
- ExpectNoError(t, err)
+ expect.NoError(t, err)
})
t.Run("missing allow", func(t *testing.T) {
_, err := CIDRWhiteList.New(OptionsRaw{
"message": testMessage,
})
- ExpectError(t, serialization.ErrValidationError, err)
+ expect.ErrorIs(t, serialization.ErrValidationError, err)
})
t.Run("invalid cidr", func(t *testing.T) {
_, err := CIDRWhiteList.New(OptionsRaw{
"allow": []string{"192.168.2.100/123"},
"message": testMessage,
})
- ExpectErrorT[*net.ParseError](t, err)
+ expect.ErrorT[*net.ParseError](t, err)
})
t.Run("invalid status code", func(t *testing.T) {
_, err := CIDRWhiteList.New(OptionsRaw{
@@ -56,14 +56,14 @@ func TestCIDRWhitelistValidation(t *testing.T) {
"status_code": 600,
"message": testMessage,
})
- ExpectError(t, serialization.ErrValidationError, err)
+ expect.ErrorIs(t, serialization.ErrValidationError, err)
})
}
func TestCIDRWhitelist(t *testing.T) {
errs := gperr.NewBuilder("")
mids := BuildMiddlewaresFromYAML("", testCIDRWhitelistCompose, errs)
- ExpectNoError(t, errs.Error())
+ expect.NoError(t, errs.Error())
deny = mids["deny@file"]
accept = mids["accept@file"]
if deny == nil || accept == nil {
@@ -74,9 +74,9 @@ func TestCIDRWhitelist(t *testing.T) {
t.Parallel()
for range 10 {
result, err := newMiddlewareTest(deny, nil)
- ExpectNoError(t, err)
- ExpectEqual(t, result.ResponseStatus, cidrWhitelistDefaults.StatusCode)
- ExpectEqual(t, strings.TrimSpace(string(result.Data)), cidrWhitelistDefaults.Message)
+ expect.NoError(t, err)
+ expect.Equal(t, result.ResponseStatus, cidrWhitelistDefaults.StatusCode)
+ expect.Equal(t, strings.TrimSpace(string(result.Data)), cidrWhitelistDefaults.Message)
}
})
@@ -84,8 +84,8 @@ func TestCIDRWhitelist(t *testing.T) {
t.Parallel()
for range 10 {
result, err := newMiddlewareTest(accept, nil)
- ExpectNoError(t, err)
- ExpectEqual(t, result.ResponseStatus, http.StatusOK)
+ expect.NoError(t, err)
+ expect.Equal(t, result.ResponseStatus, http.StatusOK)
}
})
}
diff --git a/internal/net/gphttp/middleware/cloudflare_real_ip.go b/internal/net/gphttp/middleware/cloudflare_real_ip.go
index 1214f099..88abd828 100644
--- a/internal/net/gphttp/middleware/cloudflare_real_ip.go
+++ b/internal/net/gphttp/middleware/cloudflare_real_ip.go
@@ -63,14 +63,14 @@ func (cri *cloudflareRealIP) before(w http.ResponseWriter, r *http.Request) bool
func tryFetchCFCIDR() (cfCIDRs []*nettypes.CIDR) {
if time.Since(cfCIDRsLastUpdate.Load()) < cfCIDRsUpdateInterval {
- return
+ return cfCIDRs
}
cfCIDRsMu.Lock()
defer cfCIDRsMu.Unlock()
if time.Since(cfCIDRsLastUpdate.Load()) < cfCIDRsUpdateInterval {
- return
+ return cfCIDRs
}
if common.IsTest {
@@ -93,7 +93,7 @@ func tryFetchCFCIDR() (cfCIDRs []*nettypes.CIDR) {
cfCIDRsLastUpdate.Store(time.Now())
log.Info().Msg("cloudflare CIDR range updated")
- return
+ return cfCIDRs
}
func fetchUpdateCFIPRange(endpoint string, cfCIDRs *[]*nettypes.CIDR) error {
diff --git a/internal/net/gphttp/middleware/errorpage/error_page.go b/internal/net/gphttp/middleware/errorpage/error_page.go
index c3afc158..6a576afa 100644
--- a/internal/net/gphttp/middleware/errorpage/error_page.go
+++ b/internal/net/gphttp/middleware/errorpage/error_page.go
@@ -9,11 +9,11 @@ import (
"github.com/puzpuzpuz/xsync/v4"
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/utils"
"github.com/yusing/godoxy/internal/watcher"
"github.com/yusing/godoxy/internal/watcher/events"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
const errPagesBasePath = common.ErrorPagesBasePath
@@ -42,7 +42,7 @@ func GetErrorPageByStatus(statusCode int) (content []byte, ok bool) {
if !ok && statusCode != 404 {
return fileContentMap.Load("404.html")
}
- return
+ return content, ok
}
func loadContent() {
diff --git a/internal/net/gphttp/middleware/middleware.go b/internal/net/gphttp/middleware/middleware.go
index 3100698a..fefcac7f 100644
--- a/internal/net/gphttp/middleware/middleware.go
+++ b/internal/net/gphttp/middleware/middleware.go
@@ -10,9 +10,9 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
- "github.com/yusing/godoxy/internal/gperr"
gphttp "github.com/yusing/godoxy/internal/net/gphttp"
"github.com/yusing/godoxy/internal/serialization"
+ gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/http/reverseproxy"
)
@@ -207,10 +207,10 @@ func PatchReverseProxy(rp *ReverseProxy, middlewaresMap map[string]OptionsRaw) (
var middlewares []*Middleware
middlewares, err = compileMiddlewares(middlewaresMap)
if err != nil {
- return
+ return err
}
patchReverseProxy(rp, middlewares)
- return
+ return err
}
func patchReverseProxy(rp *ReverseProxy, middlewares []*Middleware) {
diff --git a/internal/net/gphttp/middleware/middleware_builder.go b/internal/net/gphttp/middleware/middleware_builder.go
index 7264e830..f5a14c08 100644
--- a/internal/net/gphttp/middleware/middleware_builder.go
+++ b/internal/net/gphttp/middleware/middleware_builder.go
@@ -7,7 +7,7 @@ import (
"sort"
"github.com/goccy/go-yaml"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
var ErrMissingMiddlewareUse = gperr.New("missing middleware 'use' field")
diff --git a/internal/net/gphttp/middleware/middleware_builder_test.go b/internal/net/gphttp/middleware/middleware_builder_test.go
index fee87995..2233fe3c 100644
--- a/internal/net/gphttp/middleware/middleware_builder_test.go
+++ b/internal/net/gphttp/middleware/middleware_builder_test.go
@@ -5,8 +5,8 @@ import (
"encoding/json"
"testing"
- "github.com/yusing/godoxy/internal/gperr"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ gperr "github.com/yusing/goutils/errs"
+ expect "github.com/yusing/goutils/testing"
)
//go:embed test_data/middleware_compose.yml
@@ -15,8 +15,8 @@ var testMiddlewareCompose []byte
func TestBuild(t *testing.T) {
errs := gperr.NewBuilder("")
middlewares := BuildMiddlewaresFromYAML("", testMiddlewareCompose, errs)
- ExpectNoError(t, errs.Error())
- Must(json.MarshalIndent(middlewares, "", " "))
+ expect.NoError(t, errs.Error())
+ expect.Must(json.MarshalIndent(middlewares, "", " "))
// t.Log(string(data))
// TODO: test
}
diff --git a/internal/net/gphttp/middleware/middleware_chain.go b/internal/net/gphttp/middleware/middleware_chain.go
index 360497d1..ad589a17 100644
--- a/internal/net/gphttp/middleware/middleware_chain.go
+++ b/internal/net/gphttp/middleware/middleware_chain.go
@@ -3,7 +3,7 @@ package middleware
import (
"net/http"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type middlewareChain struct {
diff --git a/internal/net/gphttp/middleware/middleware_test.go b/internal/net/gphttp/middleware/middleware_test.go
index 8c003025..4f289f45 100644
--- a/internal/net/gphttp/middleware/middleware_test.go
+++ b/internal/net/gphttp/middleware/middleware_test.go
@@ -6,7 +6,7 @@ import (
"strings"
"testing"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
type testPriority struct {
@@ -28,10 +28,10 @@ func TestMiddlewarePriority(t *testing.T) {
"priority": p,
"value": i,
})
- ExpectNoError(t, err)
+ expect.NoError(t, err)
chain[i] = mid
}
res, err := newMiddlewaresTest(chain, nil)
- ExpectNoError(t, err)
- ExpectEqual(t, strings.Join(res.ResponseHeaders["Test-Value"], ","), "3,0,1,2")
+ expect.NoError(t, err)
+ expect.Equal(t, strings.Join(res.ResponseHeaders["Test-Value"], ","), "3,0,1,2")
}
diff --git a/internal/net/gphttp/middleware/middlewares.go b/internal/net/gphttp/middleware/middlewares.go
index 56e7342e..7360f7f7 100644
--- a/internal/net/gphttp/middleware/middlewares.go
+++ b/internal/net/gphttp/middleware/middlewares.go
@@ -7,8 +7,8 @@ import (
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/utils"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
)
diff --git a/internal/net/gphttp/middleware/modify_html_test.go b/internal/net/gphttp/middleware/modify_html_test.go
index c17bd970..213f536c 100644
--- a/internal/net/gphttp/middleware/modify_html_test.go
+++ b/internal/net/gphttp/middleware/modify_html_test.go
@@ -6,7 +6,7 @@ import (
"strings"
"testing"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestInjectCSS(t *testing.T) {
diff --git a/internal/net/gphttp/middleware/modify_request_test.go b/internal/net/gphttp/middleware/modify_request_test.go
index 85ceb3d2..e383610c 100644
--- a/internal/net/gphttp/middleware/modify_request_test.go
+++ b/internal/net/gphttp/middleware/modify_request_test.go
@@ -8,7 +8,7 @@ import (
"testing"
nettypes "github.com/yusing/godoxy/internal/net/types"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestModifyRequest(t *testing.T) {
@@ -44,10 +44,10 @@ func TestModifyRequest(t *testing.T) {
t.Run("set_options", func(t *testing.T) {
mr, err := ModifyRequest.New(opts)
- ExpectNoError(t, err)
- ExpectEqual(t, mr.impl.(*modifyRequest).SetHeaders, opts["set_headers"].(map[string]string))
- ExpectEqual(t, mr.impl.(*modifyRequest).AddHeaders, opts["add_headers"].(map[string]string))
- ExpectEqual(t, mr.impl.(*modifyRequest).HideHeaders, opts["hide_headers"].([]string))
+ expect.NoError(t, err)
+ expect.Equal(t, mr.impl.(*modifyRequest).SetHeaders, opts["set_headers"].(map[string]string))
+ expect.Equal(t, mr.impl.(*modifyRequest).AddHeaders, opts["add_headers"].(map[string]string))
+ expect.Equal(t, mr.impl.(*modifyRequest).HideHeaders, opts["hide_headers"].([]string))
})
t.Run("request_headers", func(t *testing.T) {
@@ -62,38 +62,38 @@ func TestModifyRequest(t *testing.T) {
"Content-Type": []string{"application/json"},
},
})
- ExpectNoError(t, err)
- ExpectEqual(t, result.RequestHeaders.Get("User-Agent"), "go-proxy/v0.5.0")
- ExpectEqual(t, result.RequestHeaders.Get("Host"), "test.example.com")
- ExpectTrue(t, slices.Contains(result.RequestHeaders.Values("Accept-Encoding"), "test-value"))
- ExpectEqual(t, result.RequestHeaders.Get("Accept"), "")
+ expect.NoError(t, err)
+ expect.Equal(t, result.RequestHeaders.Get("User-Agent"), "go-proxy/v0.5.0")
+ expect.Equal(t, result.RequestHeaders.Get("Host"), "test.example.com")
+ expect.True(t, slices.Contains(result.RequestHeaders.Values("Accept-Encoding"), "test-value"))
+ expect.Equal(t, result.RequestHeaders.Get("Accept"), "")
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Method"), "GET")
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Scheme"), reqURL.Scheme)
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Host"), reqURL.Hostname())
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Port"), reqURL.Port())
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Addr"), reqURL.Host)
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Path"), reqURL.Path)
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Query"), reqURL.RawQuery)
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Url"), reqURL.String())
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Uri"), reqURL.RequestURI())
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Content-Type"), "application/json")
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Content-Length"), "100")
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Method"), "GET")
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Scheme"), reqURL.Scheme)
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Host"), reqURL.Hostname())
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Port"), reqURL.Port())
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Addr"), reqURL.Host)
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Path"), reqURL.Path)
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Query"), reqURL.RawQuery)
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Url"), reqURL.String())
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Uri"), reqURL.RequestURI())
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Content-Type"), "application/json")
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Content-Length"), "100")
remoteHost, remotePort, _ := net.SplitHostPort(result.RemoteAddr)
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Remote-Host"), remoteHost)
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Remote-Port"), remotePort)
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Remote-Addr"), result.RemoteAddr)
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Remote-Host"), remoteHost)
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Remote-Port"), remotePort)
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Remote-Addr"), result.RemoteAddr)
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Upstream-Scheme"), upstreamURL.Scheme)
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Upstream-Host"), upstreamURL.Hostname())
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Upstream-Port"), upstreamURL.Port())
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Upstream-Addr"), upstreamURL.Host)
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Upstream-Url"), upstreamURL.String())
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Upstream-Scheme"), upstreamURL.Scheme)
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Upstream-Host"), upstreamURL.Hostname())
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Upstream-Port"), upstreamURL.Port())
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Upstream-Addr"), upstreamURL.Host)
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Upstream-Url"), upstreamURL.String())
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Header-Content-Type"), "application/json")
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Header-Content-Type"), "application/json")
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Arg-Arg_1"), "b")
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Arg-Arg_1"), "b")
})
t.Run("add_prefix", func(t *testing.T) {
@@ -137,8 +137,8 @@ func TestModifyRequest(t *testing.T) {
reqURL: reqURL,
upstreamURL: upstreamURL,
})
- ExpectNoError(t, err)
- ExpectEqual(t, result.RequestHeaders.Get("X-Test-Req-Path"), tt.expectedPath)
+ expect.NoError(t, err)
+ expect.Equal(t, result.RequestHeaders.Get("X-Test-Req-Path"), tt.expectedPath)
})
}
})
diff --git a/internal/net/gphttp/middleware/modify_response_test.go b/internal/net/gphttp/middleware/modify_response_test.go
index ea90a525..45ba6e51 100644
--- a/internal/net/gphttp/middleware/modify_response_test.go
+++ b/internal/net/gphttp/middleware/modify_response_test.go
@@ -8,7 +8,7 @@ import (
"testing"
nettypes "github.com/yusing/godoxy/internal/net/types"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestModifyResponse(t *testing.T) {
@@ -47,10 +47,10 @@ func TestModifyResponse(t *testing.T) {
t.Run("set_options", func(t *testing.T) {
mr, err := ModifyResponse.New(opts)
- ExpectNoError(t, err)
- ExpectEqual(t, mr.impl.(*modifyResponse).SetHeaders, opts["set_headers"].(map[string]string))
- ExpectEqual(t, mr.impl.(*modifyResponse).AddHeaders, opts["add_headers"].(map[string]string))
- ExpectEqual(t, mr.impl.(*modifyResponse).HideHeaders, opts["hide_headers"].([]string))
+ expect.NoError(t, err)
+ expect.Equal(t, mr.impl.(*modifyResponse).SetHeaders, opts["set_headers"].(map[string]string))
+ expect.Equal(t, mr.impl.(*modifyResponse).AddHeaders, opts["add_headers"].(map[string]string))
+ expect.Equal(t, mr.impl.(*modifyResponse).HideHeaders, opts["hide_headers"].([]string))
})
t.Run("response_headers", func(t *testing.T) {
@@ -70,39 +70,39 @@ func TestModifyResponse(t *testing.T) {
respBody: bytes.Repeat([]byte("a"), 50),
respStatus: http.StatusOK,
})
- ExpectNoError(t, err)
- ExpectTrue(t, slices.Contains(result.ResponseHeaders.Values("Accept-Encoding"), "test-value"))
- ExpectEqual(t, result.ResponseHeaders.Get("Accept"), "")
+ expect.NoError(t, err)
+ expect.True(t, slices.Contains(result.ResponseHeaders.Values("Accept-Encoding"), "test-value"))
+ expect.Equal(t, result.ResponseHeaders.Get("Accept"), "")
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Resp-Status"), "200")
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Resp-Content-Type"), "application/json")
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Resp-Content-Length"), "50")
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Resp-Header-Content-Type"), "application/json")
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Resp-Status"), "200")
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Resp-Content-Type"), "application/json")
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Resp-Content-Length"), "50")
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Resp-Header-Content-Type"), "application/json")
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Req-Method"), http.MethodGet)
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Req-Scheme"), reqURL.Scheme)
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Req-Host"), reqURL.Hostname())
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Req-Port"), reqURL.Port())
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Req-Addr"), reqURL.Host)
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Req-Path"), reqURL.Path)
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Req-Query"), reqURL.RawQuery)
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Req-Url"), reqURL.String())
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Req-Uri"), reqURL.RequestURI())
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Req-Content-Type"), "application/json")
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Req-Content-Length"), "100")
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Req-Method"), http.MethodGet)
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Req-Scheme"), reqURL.Scheme)
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Req-Host"), reqURL.Hostname())
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Req-Port"), reqURL.Port())
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Req-Addr"), reqURL.Host)
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Req-Path"), reqURL.Path)
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Req-Query"), reqURL.RawQuery)
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Req-Url"), reqURL.String())
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Req-Uri"), reqURL.RequestURI())
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Req-Content-Type"), "application/json")
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Req-Content-Length"), "100")
remoteHost, remotePort, _ := net.SplitHostPort(result.RemoteAddr)
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Remote-Host"), remoteHost)
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Remote-Port"), remotePort)
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Remote-Addr"), result.RemoteAddr)
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Remote-Host"), remoteHost)
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Remote-Port"), remotePort)
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Remote-Addr"), result.RemoteAddr)
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Upstream-Scheme"), upstreamURL.Scheme)
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Upstream-Host"), upstreamURL.Hostname())
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Upstream-Port"), upstreamURL.Port())
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Upstream-Addr"), upstreamURL.Host)
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Upstream-Url"), upstreamURL.String())
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Upstream-Scheme"), upstreamURL.Scheme)
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Upstream-Host"), upstreamURL.Hostname())
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Upstream-Port"), upstreamURL.Port())
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Upstream-Addr"), upstreamURL.Host)
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Upstream-Url"), upstreamURL.String())
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Header-Content-Type"), "application/json")
- ExpectEqual(t, result.ResponseHeaders.Get("X-Test-Arg-Arg_1"), "b")
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Header-Content-Type"), "application/json")
+ expect.Equal(t, result.ResponseHeaders.Get("X-Test-Arg-Arg_1"), "b")
})
}
diff --git a/internal/net/gphttp/middleware/oidc.go b/internal/net/gphttp/middleware/oidc.go
index 54d8d25c..bf21a7cb 100644
--- a/internal/net/gphttp/middleware/oidc.go
+++ b/internal/net/gphttp/middleware/oidc.go
@@ -8,7 +8,7 @@ import (
"sync/atomic"
"github.com/yusing/godoxy/internal/auth"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type oidcMiddleware struct {
diff --git a/internal/net/gphttp/middleware/oidc_test.go b/internal/net/gphttp/middleware/oidc_test.go
index 93ab7260..69481827 100644
--- a/internal/net/gphttp/middleware/oidc_test.go
+++ b/internal/net/gphttp/middleware/oidc_test.go
@@ -3,7 +3,7 @@ package middleware
import (
"testing"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestOIDCMiddlewarePerRouteConfig(t *testing.T) {
@@ -16,20 +16,20 @@ func TestOIDCMiddlewarePerRouteConfig(t *testing.T) {
Scopes: "openid,profile,email,groups",
}
- ExpectEqual(t, middleware.AllowedUsers, []string{"custom-user"})
- ExpectEqual(t, middleware.AllowedGroups, []string{"custom-group"})
- ExpectEqual(t, middleware.ClientID, "custom-client-id")
- ExpectEqual(t, middleware.ClientSecret, "custom-client-secret")
- ExpectEqual(t, middleware.Scopes, "openid,profile,email,groups")
+ expect.Equal(t, middleware.AllowedUsers, []string{"custom-user"})
+ expect.Equal(t, middleware.AllowedGroups, []string{"custom-group"})
+ expect.Equal(t, middleware.ClientID, "custom-client-id")
+ expect.Equal(t, middleware.ClientSecret, "custom-client-secret")
+ expect.Equal(t, middleware.Scopes, "openid,profile,email,groups")
})
t.Run("middleware struct handles empty values", func(t *testing.T) {
middleware := &oidcMiddleware{}
- ExpectEqual(t, middleware.AllowedUsers, nil)
- ExpectEqual(t, middleware.AllowedGroups, nil)
- ExpectEqual(t, middleware.ClientID, "")
- ExpectEqual(t, middleware.ClientSecret, "")
- ExpectEqual(t, middleware.Scopes, "")
+ expect.Equal(t, middleware.AllowedUsers, nil)
+ expect.Equal(t, middleware.AllowedGroups, nil)
+ expect.Equal(t, middleware.ClientID, "")
+ expect.Equal(t, middleware.ClientSecret, "")
+ expect.Equal(t, middleware.Scopes, "")
})
}
diff --git a/internal/net/gphttp/middleware/rate_limit_test.go b/internal/net/gphttp/middleware/rate_limit_test.go
index 35af0c53..d24818a8 100644
--- a/internal/net/gphttp/middleware/rate_limit_test.go
+++ b/internal/net/gphttp/middleware/rate_limit_test.go
@@ -4,7 +4,7 @@ import (
"net/http"
"testing"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestRateLimit(t *testing.T) {
@@ -15,13 +15,13 @@ func TestRateLimit(t *testing.T) {
}
rl, err := RateLimiter.New(opts)
- ExpectNoError(t, err)
+ expect.NoError(t, err)
for range 10 {
result, err := newMiddlewareTest(rl, nil)
- ExpectNoError(t, err)
- ExpectEqual(t, result.ResponseStatus, http.StatusOK)
+ expect.NoError(t, err)
+ expect.Equal(t, result.ResponseStatus, http.StatusOK)
}
result, err := newMiddlewareTest(rl, nil)
- ExpectNoError(t, err)
- ExpectEqual(t, result.ResponseStatus, http.StatusTooManyRequests)
+ expect.NoError(t, err)
+ expect.Equal(t, result.ResponseStatus, http.StatusTooManyRequests)
}
diff --git a/internal/net/gphttp/middleware/real_ip_test.go b/internal/net/gphttp/middleware/real_ip_test.go
index 38a6952e..b539642c 100644
--- a/internal/net/gphttp/middleware/real_ip_test.go
+++ b/internal/net/gphttp/middleware/real_ip_test.go
@@ -7,8 +7,8 @@ import (
"testing"
nettypes "github.com/yusing/godoxy/internal/net/types"
- . "github.com/yusing/godoxy/internal/utils/testing"
"github.com/yusing/goutils/http/httpheaders"
+ expect "github.com/yusing/goutils/testing"
)
func TestSetRealIPOpts(t *testing.T) {
@@ -41,11 +41,11 @@ func TestSetRealIPOpts(t *testing.T) {
}
ri, err := RealIP.New(opts)
- ExpectNoError(t, err)
- ExpectEqual(t, ri.impl.(*realIP).Header, optExpected.Header)
- ExpectEqual(t, ri.impl.(*realIP).Recursive, optExpected.Recursive)
+ expect.NoError(t, err)
+ expect.Equal(t, ri.impl.(*realIP).Header, optExpected.Header)
+ expect.Equal(t, ri.impl.(*realIP).Recursive, optExpected.Recursive)
for i, CIDR := range ri.impl.(*realIP).From {
- ExpectEqual(t, CIDR.String(), optExpected.From[i].String())
+ expect.Equal(t, CIDR.String(), optExpected.From[i].String())
}
}
@@ -62,15 +62,15 @@ func TestSetRealIP(t *testing.T) {
"set_headers": map[string]string{testHeader: testRealIP},
}
realip, err := RealIP.New(opts)
- ExpectNoError(t, err)
+ expect.NoError(t, err)
mr, err := ModifyRequest.New(optsMr)
- ExpectNoError(t, err)
+ expect.NoError(t, err)
mid := NewMiddlewareChain("test", []*Middleware{mr, realip})
result, err := newMiddlewareTest(mid, nil)
- ExpectNoError(t, err)
- ExpectEqual(t, result.ResponseStatus, http.StatusOK)
- ExpectEqual(t, strings.Split(result.RemoteAddr, ":")[0], testRealIP)
+ expect.NoError(t, err)
+ expect.Equal(t, result.ResponseStatus, http.StatusOK)
+ expect.Equal(t, strings.Split(result.RemoteAddr, ":")[0], testRealIP)
}
diff --git a/internal/net/gphttp/middleware/redirect_http_test.go b/internal/net/gphttp/middleware/redirect_http_test.go
index d8ccca85..0a2dc0f7 100644
--- a/internal/net/gphttp/middleware/redirect_http_test.go
+++ b/internal/net/gphttp/middleware/redirect_http_test.go
@@ -5,22 +5,22 @@ import (
"testing"
nettypes "github.com/yusing/godoxy/internal/net/types"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestRedirectToHTTPs(t *testing.T) {
result, err := newMiddlewareTest(RedirectHTTP, &testArgs{
reqURL: nettypes.MustParseURL("http://example.com"),
})
- ExpectNoError(t, err)
- ExpectEqual(t, result.ResponseStatus, http.StatusPermanentRedirect)
- ExpectEqual(t, result.ResponseHeaders.Get("Location"), "https://example.com")
+ expect.NoError(t, err)
+ expect.Equal(t, result.ResponseStatus, http.StatusPermanentRedirect)
+ expect.Equal(t, result.ResponseHeaders.Get("Location"), "https://example.com")
}
func TestNoRedirect(t *testing.T) {
result, err := newMiddlewareTest(RedirectHTTP, &testArgs{
reqURL: nettypes.MustParseURL("https://example.com"),
})
- ExpectNoError(t, err)
- ExpectEqual(t, result.ResponseStatus, http.StatusOK)
+ expect.NoError(t, err)
+ expect.Equal(t, result.ResponseStatus, http.StatusOK)
}
diff --git a/internal/net/gphttp/middleware/test_utils.go b/internal/net/gphttp/middleware/test_utils.go
index 2e8128ba..e3226c6a 100644
--- a/internal/net/gphttp/middleware/test_utils.go
+++ b/internal/net/gphttp/middleware/test_utils.go
@@ -10,9 +10,8 @@ import (
"net/http/httptest"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
nettypes "github.com/yusing/godoxy/internal/net/types"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/http/reverseproxy"
)
@@ -96,13 +95,13 @@ type testArgs struct {
func (args *testArgs) setDefaults() {
if args.reqURL == nil {
- args.reqURL = Must(nettypes.ParseURL("https://example.com"))
+ args.reqURL = nettypes.MustParseURL("https://example.com")
}
if args.reqMethod == "" {
args.reqMethod = http.MethodGet
}
if args.upstreamURL == nil {
- args.upstreamURL = Must(nettypes.ParseURL("https://10.0.0.1:8443")) // dummy url, no actual effect
+ args.upstreamURL = nettypes.MustParseURL("https://10.0.0.1:8443") // dummy url, no actual effect
}
if args.respHeaders == nil {
args.respHeaders = http.Header{}
diff --git a/internal/net/gphttp/middleware/themed.go b/internal/net/gphttp/middleware/themed.go
index bcc4b6ba..32032473 100644
--- a/internal/net/gphttp/middleware/themed.go
+++ b/internal/net/gphttp/middleware/themed.go
@@ -10,7 +10,7 @@ import (
_ "embed"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type themed struct {
diff --git a/internal/net/gphttp/serve_mux.go b/internal/net/gphttp/serve_mux.go
index 902c0e2a..7b5f1089 100644
--- a/internal/net/gphttp/serve_mux.go
+++ b/internal/net/gphttp/serve_mux.go
@@ -17,7 +17,7 @@ func (mux ServeMux) Handle(pattern string, handler http.Handler) (err error) {
}
}()
mux.ServeMux.Handle(pattern, handler)
- return
+ return err
}
func (mux ServeMux) HandleFunc(pattern string, handler http.HandlerFunc) (err error) {
@@ -27,5 +27,5 @@ func (mux ServeMux) HandleFunc(pattern string, handler http.HandlerFunc) (err er
}
}()
mux.ServeMux.HandleFunc(pattern, handler)
- return
+ return err
}
diff --git a/internal/net/gphttp/server/server.go b/internal/net/gphttp/server/server.go
index 020ff153..fb0d15cf 100644
--- a/internal/net/gphttp/server/server.go
+++ b/internal/net/gphttp/server/server.go
@@ -16,7 +16,7 @@ import (
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/acl"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/task"
+ "github.com/yusing/goutils/task"
)
type CertProvider interface {
@@ -173,7 +173,7 @@ func WithProxyProtocolSupport(value bool) ServerStartOption {
func Start[Server httpServer](parent task.Parent, srv Server, optFns ...ServerStartOption) (port int) {
if srv == nil {
- return
+ return port
}
var opts ServerStartOptions
@@ -200,7 +200,7 @@ func Start[Server httpServer](parent task.Parent, srv Server, optFns ...ServerSt
l, err := lc.Listen(task.Context(), "tcp", srv.Addr)
if err != nil {
HandleError(opts.logger, err, "failed to listen on port")
- return
+ return port
}
port = l.Addr().(*net.TCPAddr).Port
if opts.proxyProto {
@@ -224,7 +224,7 @@ func Start[Server httpServer](parent task.Parent, srv Server, optFns ...ServerSt
l, err := lc.ListenPacket(task.Context(), "udp", srv.Addr)
if err != nil {
HandleError(opts.logger, err, "failed to listen on port")
- return
+ return port
}
port = l.LocalAddr().(*net.UDPAddr).Port
for _, wrapper := range opts.udpWrappers {
diff --git a/internal/net/types/cidr.go b/internal/net/types/cidr.go
index d9959a74..d0f4e87c 100644
--- a/internal/net/types/cidr.go
+++ b/internal/net/types/cidr.go
@@ -10,7 +10,7 @@ type CIDR net.IPNet
func ParseCIDR(v string) (cidr CIDR, err error) {
err = cidr.Parse(v)
- return
+ return cidr, err
}
func (cidr *CIDR) Parse(v string) error {
diff --git a/internal/notif/base.go b/internal/notif/base.go
index 896c0b7f..30e4a169 100644
--- a/internal/notif/base.go
+++ b/internal/notif/base.go
@@ -6,7 +6,7 @@ import (
"net/url"
"strings"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type ProviderBase struct {
diff --git a/internal/notif/body.go b/internal/notif/body.go
index e47f7afb..a1252c95 100644
--- a/internal/notif/body.go
+++ b/internal/notif/body.go
@@ -5,7 +5,7 @@ import (
"encoding/json"
"strings"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type (
diff --git a/internal/notif/config.go b/internal/notif/config.go
index 8b1dde37..c4838067 100644
--- a/internal/notif/config.go
+++ b/internal/notif/config.go
@@ -1,8 +1,8 @@
package notif
import (
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/serialization"
+ gperr "github.com/yusing/goutils/errs"
)
type NotificationConfig struct {
diff --git a/internal/notif/config_test.go b/internal/notif/config_test.go
index 3093c8f7..67f04d5d 100644
--- a/internal/notif/config_test.go
+++ b/internal/notif/config_test.go
@@ -5,7 +5,7 @@ import (
"testing"
"github.com/yusing/godoxy/internal/serialization"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestNotificationConfig(t *testing.T) {
@@ -183,11 +183,11 @@ func TestNotificationConfig(t *testing.T) {
provider := tt.cfg["provider"]
err := serialization.MapUnmarshalValidate(tt.cfg, &cfg)
if tt.wantErr {
- ExpectHasError(t, err)
+ expect.NotNil(t, err)
} else {
- ExpectNoError(t, err)
- ExpectEqual(t, provider.(string), cfg.ProviderName)
- ExpectEqual(t, cfg.Provider, tt.expected)
+ expect.NoError(t, err)
+ expect.Equal(t, provider.(string), cfg.ProviderName)
+ expect.Equal(t, cfg.Provider, tt.expected)
}
})
}
diff --git a/internal/notif/dispatcher.go b/internal/notif/dispatcher.go
index 503e83f0..756fc413 100644
--- a/internal/notif/dispatcher.go
+++ b/internal/notif/dispatcher.go
@@ -8,8 +8,8 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
- "github.com/yusing/godoxy/internal/task"
F "github.com/yusing/godoxy/internal/utils/functional"
+ "github.com/yusing/goutils/task"
)
type (
diff --git a/internal/notif/ntfy.go b/internal/notif/ntfy.go
index da566b53..5f2c3b7e 100644
--- a/internal/notif/ntfy.go
+++ b/internal/notif/ntfy.go
@@ -4,7 +4,7 @@ import (
"net/http"
"github.com/rs/zerolog"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
// See https://docs.ntfy.sh/publish
diff --git a/internal/notif/providers.go b/internal/notif/providers.go
index 894cd134..bfab08f2 100644
--- a/internal/notif/providers.go
+++ b/internal/notif/providers.go
@@ -8,8 +8,8 @@ import (
"net/http"
"time"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/serialization"
+ gperr "github.com/yusing/goutils/errs"
)
type (
diff --git a/internal/notif/webhook.go b/internal/notif/webhook.go
index 40ed7084..4f073d99 100644
--- a/internal/notif/webhook.go
+++ b/internal/notif/webhook.go
@@ -7,7 +7,7 @@ import (
"net/http"
"strings"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type Webhook struct {
diff --git a/internal/proxmox/config.go b/internal/proxmox/config.go
index 0d287fb5..b0feba2d 100644
--- a/internal/proxmox/config.go
+++ b/internal/proxmox/config.go
@@ -9,8 +9,8 @@ import (
"time"
"github.com/luthermonson/go-proxmox"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/net/gphttp"
+ gperr "github.com/yusing/goutils/errs"
)
type Config struct {
diff --git a/internal/route/common.go b/internal/route/common.go
index 4bd12972..a1f1a785 100644
--- a/internal/route/common.go
+++ b/internal/route/common.go
@@ -1,9 +1,9 @@
package route
import (
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/route/routes"
"github.com/yusing/godoxy/internal/types"
+ gperr "github.com/yusing/goutils/errs"
)
func checkExists(r types.Route) gperr.Error {
diff --git a/internal/route/fileserver.go b/internal/route/fileserver.go
index 3126d366..e3f3c55d 100644
--- a/internal/route/fileserver.go
+++ b/internal/route/fileserver.go
@@ -5,13 +5,13 @@ import (
"path"
"path/filepath"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/logging/accesslog"
gphttp "github.com/yusing/godoxy/internal/net/gphttp"
"github.com/yusing/godoxy/internal/net/gphttp/middleware"
"github.com/yusing/godoxy/internal/route/routes"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/watcher/health/monitor"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
type (
diff --git a/internal/route/fileserver_test.go b/internal/route/fileserver_test.go
index c2bb5732..caa0144a 100644
--- a/internal/route/fileserver_test.go
+++ b/internal/route/fileserver_test.go
@@ -10,26 +10,26 @@ import (
"path/filepath"
"testing"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestPathTraversalAttack(t *testing.T) {
tmp := t.TempDir()
root := filepath.Join(tmp, "static")
- if err := os.Mkdir(root, 0755); err != nil {
+ if err := os.Mkdir(root, 0o755); err != nil {
t.Fatalf("Failed to create root directory: %v", err)
}
// Create a file inside the root
validPath := "test.txt"
validContent := "test content"
- if err := os.WriteFile(filepath.Join(root, validPath), []byte(validContent), 0644); err != nil {
+ if err := os.WriteFile(filepath.Join(root, validPath), []byte(validContent), 0o644); err != nil {
t.Fatalf("Failed to create test file: %v", err)
}
// create one at ..
secretFile := "secret.txt"
- if err := os.WriteFile(filepath.Join(tmp, secretFile), []byte(validContent), 0644); err != nil {
+ if err := os.WriteFile(filepath.Join(tmp, secretFile), []byte(validContent), 0o644); err != nil {
t.Fatalf("Failed to create test file: %v", err)
}
@@ -108,7 +108,7 @@ func TestPathTraversalAttack(t *testing.T) {
t.Errorf("Expected status 404 or 400, got %d in url %s", resp.StatusCode, u.String())
}
- u = Must(url.Parse(ts.URL + "/" + p))
+ u = expect.Must(url.Parse(ts.URL + "/" + p))
resp, err = http.DefaultClient.Do(&http.Request{
Method: http.MethodGet,
URL: u,
diff --git a/internal/route/port_selection.go b/internal/route/port_selection.go
index b248025b..eb5afadb 100644
--- a/internal/route/port_selection.go
+++ b/internal/route/port_selection.go
@@ -67,7 +67,7 @@ func getSchemePortByImageName(imageName string) (scheme string, port int, ok boo
if port, ok := ImageNamePortMapTCP[imageName]; ok {
return "tcp", port, true
}
- return
+ return scheme, port, ok
}
func getSchemePortByAlias(alias string) (scheme string, port int, ok bool) {
@@ -77,5 +77,5 @@ func getSchemePortByAlias(alias string) (scheme string, port int, ok bool) {
if port, ok := AliasPortMapHTTPS[alias]; ok {
return "https", port, true
}
- return
+ return scheme, port, ok
}
diff --git a/internal/route/provider/agent.go b/internal/route/provider/agent.go
index f4e4f4d8..0d35532b 100644
--- a/internal/route/provider/agent.go
+++ b/internal/route/provider/agent.go
@@ -3,9 +3,9 @@ package provider
import (
"github.com/rs/zerolog"
"github.com/yusing/godoxy/agent/pkg/agent"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/route"
"github.com/yusing/godoxy/internal/watcher"
+ gperr "github.com/yusing/goutils/errs"
)
type AgentProvider struct {
diff --git a/internal/route/provider/docker.go b/internal/route/provider/docker.go
index 680af79f..8ceecf9f 100755
--- a/internal/route/provider/docker.go
+++ b/internal/route/provider/docker.go
@@ -10,11 +10,11 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/docker"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/route"
"github.com/yusing/godoxy/internal/serialization"
"github.com/yusing/godoxy/internal/types"
"github.com/yusing/godoxy/internal/watcher"
+ gperr "github.com/yusing/goutils/errs"
)
type DockerProvider struct {
diff --git a/internal/route/provider/docker_labels_test.go b/internal/route/provider/docker_labels_test.go
index f5b27c9f..bb7e4b54 100644
--- a/internal/route/provider/docker_labels_test.go
+++ b/internal/route/provider/docker_labels_test.go
@@ -6,7 +6,7 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/goccy/go-yaml"
"github.com/yusing/godoxy/internal/docker"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
_ "embed"
)
@@ -18,7 +18,7 @@ func TestParseDockerLabels(t *testing.T) {
var provider DockerProvider
labels := make(map[string]string)
- ExpectNoError(t, yaml.Unmarshal(testDockerLabelsYAML, &labels))
+ expect.NoError(t, yaml.Unmarshal(testDockerLabelsYAML, &labels))
routes, err := provider.routesFromContainerLabels(
docker.FromDocker(&container.Summary{
@@ -30,7 +30,7 @@ func TestParseDockerLabels(t *testing.T) {
},
}, "/var/run/docker.sock"),
)
- ExpectNoError(t, err)
- ExpectTrue(t, routes.Contains("app"))
- ExpectTrue(t, routes.Contains("app1"))
+ expect.NoError(t, err)
+ expect.True(t, routes.Contains("app"))
+ expect.True(t, routes.Contains("app1"))
}
diff --git a/internal/route/provider/docker_test.go b/internal/route/provider/docker_test.go
index 83dbc416..34ae657c 100644
--- a/internal/route/provider/docker_test.go
+++ b/internal/route/provider/docker_test.go
@@ -10,7 +10,7 @@ import (
D "github.com/yusing/godoxy/internal/docker"
"github.com/yusing/godoxy/internal/route"
T "github.com/yusing/godoxy/internal/route/types"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
var dummyNames = []string{"/a"}
diff --git a/internal/route/provider/event_handler.go b/internal/route/provider/event_handler.go
index 0bd29102..eacd5670 100644
--- a/internal/route/provider/event_handler.go
+++ b/internal/route/provider/event_handler.go
@@ -1,12 +1,12 @@
package provider
import (
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/route"
provider "github.com/yusing/godoxy/internal/route/provider/types"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/watcher"
eventsPkg "github.com/yusing/godoxy/internal/watcher/events"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
type EventHandler struct {
diff --git a/internal/route/provider/file.go b/internal/route/provider/file.go
index b373567f..bc4b1d8d 100644
--- a/internal/route/provider/file.go
+++ b/internal/route/provider/file.go
@@ -8,10 +8,10 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/route"
"github.com/yusing/godoxy/internal/serialization"
W "github.com/yusing/godoxy/internal/watcher"
+ gperr "github.com/yusing/goutils/errs"
)
type FileProvider struct {
@@ -44,12 +44,12 @@ func removeXPrefix(m map[string]any) gperr.Error {
func validate(data []byte) (routes route.Routes, err gperr.Error) {
err = serialization.UnmarshalValidateYAMLIntercept(data, &routes, removeXPrefix)
- return
+ return routes, err
}
func Validate(data []byte) (err gperr.Error) {
_, err = validate(data)
- return
+ return err
}
func (p *FileProvider) String() string {
diff --git a/internal/route/provider/file_test.go b/internal/route/provider/file_test.go
index f37d36a7..e51e7b90 100644
--- a/internal/route/provider/file_test.go
+++ b/internal/route/provider/file_test.go
@@ -5,7 +5,7 @@ import (
_ "embed"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
//go:embed all_fields.yaml
@@ -13,5 +13,5 @@ var testAllFieldsYAML []byte
func TestFile(t *testing.T) {
_, err := validate(testAllFieldsYAML)
- ExpectNoError(t, err)
+ expect.NoError(t, err)
}
diff --git a/internal/route/provider/provider.go b/internal/route/provider/provider.go
index 05099f4a..61e25c26 100644
--- a/internal/route/provider/provider.go
+++ b/internal/route/provider/provider.go
@@ -13,14 +13,14 @@ import (
"github.com/yusing/godoxy/agent/pkg/agent"
"github.com/yusing/godoxy/internal/common"
"github.com/yusing/godoxy/internal/docker"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/route"
provider "github.com/yusing/godoxy/internal/route/provider/types"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/types"
W "github.com/yusing/godoxy/internal/watcher"
"github.com/yusing/godoxy/internal/watcher/events"
"github.com/yusing/goutils/env"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
type (
@@ -66,7 +66,7 @@ func NewFileProvider(filename string) (p *Provider, err error) {
return nil, err
}
p.watcher = p.NewWatcher()
- return
+ return p, err
}
func NewDockerProvider(name string, dockerHost string) *Provider {
@@ -146,7 +146,7 @@ func (p *Provider) Start(parent task.Parent) gperr.Error {
func (p *Provider) LoadRoutes() (err gperr.Error) {
p.routes, err = p.loadRoutes()
- return
+ return err
}
func (p *Provider) NumRoutes() int {
diff --git a/internal/route/reverse_proxy.go b/internal/route/reverse_proxy.go
index a97011d1..6cee411d 100755
--- a/internal/route/reverse_proxy.go
+++ b/internal/route/reverse_proxy.go
@@ -6,7 +6,6 @@ import (
"github.com/yusing/godoxy/agent/pkg/agent"
"github.com/yusing/godoxy/agent/pkg/agentproxy"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/homepage"
"github.com/yusing/godoxy/internal/idlewatcher"
"github.com/yusing/godoxy/internal/logging/accesslog"
@@ -15,11 +14,12 @@ import (
"github.com/yusing/godoxy/internal/net/gphttp/middleware"
nettypes "github.com/yusing/godoxy/internal/net/types"
"github.com/yusing/godoxy/internal/route/routes"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/types"
"github.com/yusing/godoxy/internal/watcher/health/monitor"
"github.com/yusing/godoxy/pkg"
+ gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/http/reverseproxy"
+ "github.com/yusing/goutils/task"
)
type ReveseProxyRoute struct {
diff --git a/internal/route/route.go b/internal/route/route.go
index 2fafe066..bae72fe7 100644
--- a/internal/route/route.go
+++ b/internal/route/route.go
@@ -12,14 +12,14 @@ import (
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/agent/pkg/agent"
"github.com/yusing/godoxy/internal/docker"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/homepage"
netutils "github.com/yusing/godoxy/internal/net"
nettypes "github.com/yusing/godoxy/internal/net/types"
"github.com/yusing/godoxy/internal/proxmox"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/types"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
+ "github.com/yusing/goutils/task"
"github.com/yusing/godoxy/internal/common"
config "github.com/yusing/godoxy/internal/config/types"
@@ -721,5 +721,5 @@ func preferredPort(portMapping map[int]container.Port) (res int) {
res = port
}
}
- return
+ return res
}
diff --git a/internal/route/route_test.go b/internal/route/route_test.go
index b19a5ee1..63ce73d6 100644
--- a/internal/route/route_test.go
+++ b/internal/route/route_test.go
@@ -7,7 +7,7 @@ import (
"github.com/yusing/godoxy/internal/common"
route "github.com/yusing/godoxy/internal/route/types"
"github.com/yusing/godoxy/internal/types"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestRouteValidate(t *testing.T) {
diff --git a/internal/route/rules/do.go b/internal/route/rules/do.go
index 4936d20d..1eae30c0 100644
--- a/internal/route/rules/do.go
+++ b/internal/route/rules/do.go
@@ -6,9 +6,9 @@ import (
"strconv"
"strings"
- "github.com/yusing/godoxy/internal/gperr"
gphttp "github.com/yusing/godoxy/internal/net/gphttp"
nettypes "github.com/yusing/godoxy/internal/net/types"
+ gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/http/reverseproxy"
strutils "github.com/yusing/goutils/strings"
)
diff --git a/internal/route/rules/do_test.go b/internal/route/rules/do_test.go
index 87c19f29..16b84efc 100644
--- a/internal/route/rules/do_test.go
+++ b/internal/route/rules/do_test.go
@@ -3,7 +3,7 @@ package rules
import (
"testing"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestParseCommands(t *testing.T) {
@@ -131,9 +131,9 @@ func TestParseCommands(t *testing.T) {
cmd := Command{}
err := cmd.Parse(tt.input)
if tt.wantErr != nil {
- ExpectError(t, tt.wantErr, err)
+ expect.ErrorIs(t, tt.wantErr, err)
} else {
- ExpectNoError(t, err)
+ expect.NoError(t, err)
}
})
}
diff --git a/internal/route/rules/errors.go b/internal/route/rules/errors.go
index bae209f1..789e85d7 100644
--- a/internal/route/rules/errors.go
+++ b/internal/route/rules/errors.go
@@ -1,7 +1,7 @@
package rules
import (
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
var (
diff --git a/internal/route/rules/on.go b/internal/route/rules/on.go
index 3149588a..ad2f6447 100644
--- a/internal/route/rules/on.go
+++ b/internal/route/rules/on.go
@@ -2,14 +2,13 @@ package rules
import (
"net/http"
+ "slices"
"strings"
- "slices"
-
"github.com/gobwas/glob"
- "github.com/yusing/godoxy/internal/gperr"
nettypes "github.com/yusing/godoxy/internal/net/types"
"github.com/yusing/godoxy/internal/route/routes"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
)
@@ -248,8 +247,10 @@ var checkers = map[string]struct {
},
}
-var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
-var andSeps = [256]uint8{'&': 1, '\n': 1}
+var (
+ asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
+ andSeps = [256]uint8{'&': 1, '\n': 1}
+)
func indexAnd(s string) int {
for i, c := range s {
diff --git a/internal/route/rules/on_internal_test.go b/internal/route/rules/on_internal_test.go
index 9fb349c8..2d8ed89a 100644
--- a/internal/route/rules/on_internal_test.go
+++ b/internal/route/rules/on_internal_test.go
@@ -3,8 +3,8 @@ package rules
import (
"testing"
- "github.com/yusing/godoxy/internal/gperr"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ gperr "github.com/yusing/goutils/errs"
+ expect "github.com/yusing/goutils/testing"
)
func TestSplitAnd(t *testing.T) {
diff --git a/internal/route/rules/on_test.go b/internal/route/rules/on_test.go
index 32af7b90..3061926c 100644
--- a/internal/route/rules/on_test.go
+++ b/internal/route/rules/on_test.go
@@ -10,7 +10,7 @@ import (
"github.com/yusing/godoxy/internal/route"
"github.com/yusing/godoxy/internal/route/routes"
. "github.com/yusing/godoxy/internal/route/rules"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
"golang.org/x/crypto/bcrypt"
)
diff --git a/internal/route/rules/parser.go b/internal/route/rules/parser.go
index c3a48931..ac04a2ff 100644
--- a/internal/route/rules/parser.go
+++ b/internal/route/rules/parser.go
@@ -4,7 +4,7 @@ import (
"bytes"
"unicode"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
var escapedChars = map[rune]rune{
@@ -57,7 +57,7 @@ func parse(v string) (subject string, args []string, err gperr.Error) {
buf.WriteRune(ch)
} else {
err = ErrUnsupportedEscapeChar.Subjectf("\\%c", r)
- return
+ return subject, args, err
}
escaped = false
continue
@@ -93,5 +93,5 @@ func parse(v string) (subject string, args []string, err gperr.Error) {
} else {
flush(false)
}
- return
+ return subject, args, err
}
diff --git a/internal/route/rules/parser_test.go b/internal/route/rules/parser_test.go
index b8cb054c..0ac3ec7d 100644
--- a/internal/route/rules/parser_test.go
+++ b/internal/route/rules/parser_test.go
@@ -4,8 +4,8 @@ import (
"strconv"
"testing"
- "github.com/yusing/godoxy/internal/gperr"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ gperr "github.com/yusing/goutils/errs"
+ expect "github.com/yusing/goutils/testing"
)
func TestParser(t *testing.T) {
@@ -68,15 +68,15 @@ func TestParser(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
subject, args, err := parse(tt.input)
if tt.wantErr != nil {
- ExpectError(t, tt.wantErr, err)
+ expect.ErrorIs(t, tt.wantErr, err)
return
}
// t.Log(subject, args, err)
- ExpectNoError(t, err)
- ExpectEqual(t, subject, tt.subject)
- ExpectEqual(t, len(args), len(tt.args))
+ expect.NoError(t, err)
+ expect.Equal(t, subject, tt.subject)
+ expect.Equal(t, len(args), len(tt.args))
for i, arg := range args {
- ExpectEqual(t, arg, tt.args[i])
+ expect.Equal(t, arg, tt.args[i])
}
})
}
@@ -89,7 +89,7 @@ func TestParser(t *testing.T) {
for i, test := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
_, _, err := parse(test)
- ExpectError(t, ErrUnterminatedQuotes, err)
+ expect.ErrorIs(t, ErrUnterminatedQuotes, err)
})
}
})
diff --git a/internal/route/rules/rules.go b/internal/route/rules/rules.go
index 540cbc54..f90ce5c5 100644
--- a/internal/route/rules/rules.go
+++ b/internal/route/rules/rules.go
@@ -130,5 +130,5 @@ func (rule *Rule) Check(cached Cache, r *http.Request) bool {
func (rule *Rule) Handle(cached Cache, w http.ResponseWriter, r *http.Request) (proceed bool) {
proceed = rule.Do.exec.Handle(cached, w, r)
- return
+ return proceed
}
diff --git a/internal/route/rules/rules_test.go b/internal/route/rules/rules_test.go
index c620bc0b..1bc93ff6 100644
--- a/internal/route/rules/rules_test.go
+++ b/internal/route/rules/rules_test.go
@@ -4,7 +4,7 @@ import (
"testing"
"github.com/yusing/godoxy/internal/serialization"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestParseRule(t *testing.T) {
@@ -29,18 +29,18 @@ func TestParseRule(t *testing.T) {
Rules Rules
}
err := serialization.MapUnmarshalValidate(serialization.SerializedObject{"rules": test}, &rules)
- ExpectNoError(t, err)
- ExpectEqual(t, len(rules.Rules), len(test))
- ExpectEqual(t, rules.Rules[0].Name, "test")
- ExpectEqual(t, rules.Rules[0].On.String(), "method POST")
- ExpectEqual(t, rules.Rules[0].Do.String(), "error 403 Forbidden")
+ expect.NoError(t, err)
+ expect.Equal(t, len(rules.Rules), len(test))
+ expect.Equal(t, rules.Rules[0].Name, "test")
+ expect.Equal(t, rules.Rules[0].On.String(), "method POST")
+ expect.Equal(t, rules.Rules[0].Do.String(), "error 403 Forbidden")
- ExpectEqual(t, rules.Rules[1].Name, "auth")
- ExpectEqual(t, rules.Rules[1].On.String(), `basic_auth "username" "password" | basic_auth username2 "password2" | basic_auth "username3" "password3"`)
- ExpectEqual(t, rules.Rules[1].Do.String(), "bypass")
+ expect.Equal(t, rules.Rules[1].Name, "auth")
+ expect.Equal(t, rules.Rules[1].On.String(), `basic_auth "username" "password" | basic_auth username2 "password2" | basic_auth "username3" "password3"`)
+ expect.Equal(t, rules.Rules[1].Do.String(), "bypass")
- ExpectEqual(t, rules.Rules[2].Name, "default")
- ExpectEqual(t, rules.Rules[2].Do.String(), "require_basic_auth any_realm")
+ expect.Equal(t, rules.Rules[2].Name, "default")
+ expect.Equal(t, rules.Rules[2].Do.String(), "require_basic_auth any_realm")
}
// TODO: real tests.
diff --git a/internal/route/rules/validate.go b/internal/route/rules/validate.go
index 389c49c4..0736089f 100644
--- a/internal/route/rules/validate.go
+++ b/internal/route/rules/validate.go
@@ -8,9 +8,9 @@ import (
"strings"
"github.com/gobwas/glob"
- "github.com/yusing/godoxy/internal/gperr"
gphttp "github.com/yusing/godoxy/internal/net/gphttp"
nettypes "github.com/yusing/godoxy/internal/net/types"
+ gperr "github.com/yusing/goutils/errs"
)
type (
diff --git a/internal/route/stream.go b/internal/route/stream.go
index 82a69db8..a1f98f0c 100755
--- a/internal/route/stream.go
+++ b/internal/route/stream.go
@@ -7,14 +7,14 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/idlewatcher"
nettypes "github.com/yusing/godoxy/internal/net/types"
"github.com/yusing/godoxy/internal/route/routes"
"github.com/yusing/godoxy/internal/route/stream"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/types"
"github.com/yusing/godoxy/internal/watcher/health/monitor"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
// TODO: support stream load balance.
diff --git a/internal/route/stream/tcp_tcp.go b/internal/route/stream/tcp_tcp.go
index d32ab4ec..a260b92e 100644
--- a/internal/route/stream/tcp_tcp.go
+++ b/internal/route/stream/tcp_tcp.go
@@ -168,12 +168,12 @@ type wrapperConn struct {
func (w *wrapperConn) Read(b []byte) (n int, err error) {
n, err = w.Conn.Read(b)
if err != nil {
- return
+ return n, err
}
if w.onRead != nil {
if err = w.onRead(w.ctx); err != nil {
- return
+ return n, err
}
}
- return
+ return n, err
}
diff --git a/internal/route/types/http_config.go b/internal/route/types/http_config.go
index 3a975539..03a65dde 100644
--- a/internal/route/types/http_config.go
+++ b/internal/route/types/http_config.go
@@ -8,7 +8,7 @@ import (
"strings"
"time"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type HTTPConfig struct {
diff --git a/internal/route/types/http_config_test.go b/internal/route/types/http_config_test.go
index 310f5243..b11b22ed 100644
--- a/internal/route/types/http_config_test.go
+++ b/internal/route/types/http_config_test.go
@@ -7,7 +7,7 @@ import (
. "github.com/yusing/godoxy/internal/route"
route "github.com/yusing/godoxy/internal/route/types"
"github.com/yusing/godoxy/internal/serialization"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestHTTPConfigDeserialize(t *testing.T) {
diff --git a/internal/route/types/port.go b/internal/route/types/port.go
index 8d88b82b..01f79013 100644
--- a/internal/route/types/port.go
+++ b/internal/route/types/port.go
@@ -3,7 +3,7 @@ package route
import (
"strconv"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
)
diff --git a/internal/route/types/scheme.go b/internal/route/types/scheme.go
index ca59be1a..1b2e33e4 100644
--- a/internal/route/types/scheme.go
+++ b/internal/route/types/scheme.go
@@ -1,7 +1,7 @@
package route
import (
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type Scheme string
diff --git a/internal/serialization/serialization.go b/internal/serialization/serialization.go
index 99eb536d..7da99008 100644
--- a/internal/serialization/serialization.go
+++ b/internal/serialization/serialization.go
@@ -13,8 +13,8 @@ import (
"github.com/go-playground/validator/v10"
"github.com/goccy/go-yaml"
"github.com/puzpuzpuz/xsync/v4"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/utils"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
)
@@ -146,7 +146,7 @@ func dive(dst reflect.Value) (v reflect.Value, t reflect.Type, err gperr.Error)
if dst.IsNil() {
if !dst.CanSet() {
err = gperr.Errorf("dive: dst is %w and is not settable", ErrNilValue)
- return
+ return v, t, err
}
dst.Set(New(dstT.Elem()))
}
@@ -437,20 +437,20 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gpe
}
if dst.Kind() == reflect.String {
dst.SetString(src)
- return
+ return convertible, convErr
}
switch dstT {
case reflect.TypeFor[time.Duration]():
if src == "" {
dst.Set(reflect.Zero(dstT))
- return
+ return convertible, convErr
}
d, err := time.ParseDuration(src)
if err != nil {
return true, gperr.Wrap(err)
}
dst.Set(reflect.ValueOf(d))
- return
+ return convertible, convErr
default:
}
if dstKind := dst.Kind(); isIntFloat(dstKind) {
@@ -470,7 +470,7 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gpe
return true, gperr.Wrap(err)
}
dst.Set(reflect.ValueOf(i).Convert(dstT))
- return
+ return convertible, convErr
}
// check if (*T).Convertor is implemented
if parser, ok := dst.Addr().Interface().(strutils.Parser); ok {
@@ -496,7 +496,7 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gpe
if errs.HasError() {
return true, errs.Error()
}
- return
+ return convertible, convErr
}
sl := make([]any, 0)
err := yaml.Unmarshal([]byte(src), &sl)
diff --git a/internal/serialization/serialization_test.go b/internal/serialization/serialization_test.go
index c63d986a..61c27748 100644
--- a/internal/serialization/serialization_test.go
+++ b/internal/serialization/serialization_test.go
@@ -8,7 +8,7 @@ import (
"github.com/goccy/go-yaml"
"github.com/stretchr/testify/require"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestDeserialize(t *testing.T) {
@@ -43,8 +43,8 @@ func TestDeserialize(t *testing.T) {
t.Run("deserialize", func(t *testing.T) {
var s2 S
err := MapUnmarshalValidate(testStructSerialized, &s2)
- ExpectNoError(t, err)
- ExpectEqual(t, s2, testStruct)
+ expect.NoError(t, err)
+ expect.Equal(t, s2, testStruct)
})
}
@@ -63,16 +63,16 @@ func TestDeserializeAnonymousField(t *testing.T) {
// all, anon := extractFields(reflect.TypeOf(s2))
// t.Fatalf("anon %v, all %v", anon, all)
err := MapUnmarshalValidate(map[string]any{"a": 1, "b": 2, "c": 3}, &s)
- ExpectNoError(t, err)
- ExpectEqual(t, s.A, 1)
- ExpectEqual(t, s.B, 2)
- ExpectEqual(t, s.C, 3)
+ expect.NoError(t, err)
+ expect.Equal(t, s.A, 1)
+ expect.Equal(t, s.B, 2)
+ expect.Equal(t, s.C, 3)
err = MapUnmarshalValidate(map[string]any{"a": 1, "b": 2, "c": 3}, &s2)
- ExpectNoError(t, err)
- ExpectEqual(t, s2.A, 1)
- ExpectEqual(t, s2.B, 2)
- ExpectEqual(t, s2.C, 3)
+ expect.NoError(t, err)
+ expect.Equal(t, s2.A, 1)
+ expect.Equal(t, s2.B, 2)
+ expect.Equal(t, s2.C, 3)
}
func TestPointerPrimitives(t *testing.T) {
@@ -90,44 +90,44 @@ func TestPointerPrimitives(t *testing.T) {
var test testType
err := MapUnmarshalValidate(map[string]any{"b": true, "i8": int8(127), "i16": int16(127), "i32": int32(127), "i64": int64(127), "u8": uint8(127), "u16": uint16(127), "u32": uint32(127), "u64": uint64(127)}, &test)
- ExpectNoError(t, err)
- ExpectEqual(t, *test.B, true)
- ExpectEqual(t, *test.I8, int8(127))
- ExpectEqual(t, *test.I16, int16(127))
- ExpectEqual(t, *test.I32, int32(127))
- ExpectEqual(t, *test.I64, int64(127))
- ExpectEqual(t, *test.U8, uint8(127))
- ExpectEqual(t, *test.U16, uint16(127))
- ExpectEqual(t, *test.U32, uint32(127))
- ExpectEqual(t, *test.U64, uint64(127))
+ expect.NoError(t, err)
+ expect.Equal(t, *test.B, true)
+ expect.Equal(t, *test.I8, int8(127))
+ expect.Equal(t, *test.I16, int16(127))
+ expect.Equal(t, *test.I32, int32(127))
+ expect.Equal(t, *test.I64, int64(127))
+ expect.Equal(t, *test.U8, uint8(127))
+ expect.Equal(t, *test.U16, uint16(127))
+ expect.Equal(t, *test.U32, uint32(127))
+ expect.Equal(t, *test.U64, uint64(127))
// zero values
err = MapUnmarshalValidate(map[string]any{"b": false, "i8": int8(0), "i16": int16(0), "i32": int32(0), "i64": int64(0), "u8": uint8(0), "u16": uint16(0), "u32": uint32(0), "u64": uint64(0)}, &test)
- ExpectNoError(t, err)
- ExpectEqual(t, *test.B, false)
- ExpectEqual(t, *test.I8, int8(0))
- ExpectEqual(t, *test.I16, int16(0))
- ExpectEqual(t, *test.I32, int32(0))
- ExpectEqual(t, *test.I64, int64(0))
- ExpectEqual(t, *test.U8, uint8(0))
- ExpectEqual(t, *test.U16, uint16(0))
- ExpectEqual(t, *test.U32, uint32(0))
- ExpectEqual(t, *test.U64, uint64(0))
+ expect.NoError(t, err)
+ expect.Equal(t, *test.B, false)
+ expect.Equal(t, *test.I8, int8(0))
+ expect.Equal(t, *test.I16, int16(0))
+ expect.Equal(t, *test.I32, int32(0))
+ expect.Equal(t, *test.I64, int64(0))
+ expect.Equal(t, *test.U8, uint8(0))
+ expect.Equal(t, *test.U16, uint16(0))
+ expect.Equal(t, *test.U32, uint32(0))
+ expect.Equal(t, *test.U64, uint64(0))
// nil values
err = MapUnmarshalValidate(map[string]any{"b": true, "i8": int8(127), "i16": int16(127), "i32": int32(127), "i64": int64(127), "u8": uint8(127), "u16": uint16(127), "u32": uint32(127), "u64": uint64(127)}, &test)
- ExpectNoError(t, err)
+ expect.NoError(t, err)
err = MapUnmarshalValidate(map[string]any{"b": nil, "i8": nil, "i16": nil, "i32": nil, "i64": nil, "u8": nil, "u16": nil, "u32": nil, "u64": nil}, &test)
- ExpectNoError(t, err)
- ExpectEqual(t, test.B, nil)
- ExpectEqual(t, test.I8, nil)
- ExpectEqual(t, test.I16, nil)
- ExpectEqual(t, test.I32, nil)
- ExpectEqual(t, test.I64, nil)
- ExpectEqual(t, test.U8, nil)
- ExpectEqual(t, test.U16, nil)
- ExpectEqual(t, test.U32, nil)
- ExpectEqual(t, test.U64, nil)
+ expect.NoError(t, err)
+ expect.Equal(t, test.B, nil)
+ expect.Equal(t, test.I8, nil)
+ expect.Equal(t, test.I16, nil)
+ expect.Equal(t, test.I32, nil)
+ expect.Equal(t, test.I64, nil)
+ expect.Equal(t, test.U8, nil)
+ expect.Equal(t, test.U16, nil)
+ expect.Equal(t, test.U32, nil)
+ expect.Equal(t, test.U64, nil)
}
func TestStringIntConvert(t *testing.T) {
@@ -146,44 +146,44 @@ func TestStringIntConvert(t *testing.T) {
ok, err := ConvertString(s, reflect.ValueOf(&test.i8))
- ExpectTrue(t, ok)
- ExpectNoError(t, err)
- ExpectEqual(t, test.i8, int8(127))
+ expect.True(t, ok)
+ expect.NoError(t, err)
+ expect.Equal(t, test.i8, int8(127))
ok, err = ConvertString(s, reflect.ValueOf(&test.i16))
- ExpectTrue(t, ok)
- ExpectNoError(t, err)
- ExpectEqual(t, test.i16, int16(127))
+ expect.True(t, ok)
+ expect.NoError(t, err)
+ expect.Equal(t, test.i16, int16(127))
ok, err = ConvertString(s, reflect.ValueOf(&test.i32))
- ExpectTrue(t, ok)
- ExpectNoError(t, err)
- ExpectEqual(t, test.i32, int32(127))
+ expect.True(t, ok)
+ expect.NoError(t, err)
+ expect.Equal(t, test.i32, int32(127))
ok, err = ConvertString(s, reflect.ValueOf(&test.i64))
- ExpectTrue(t, ok)
- ExpectNoError(t, err)
- ExpectEqual(t, test.i64, int64(127))
+ expect.True(t, ok)
+ expect.NoError(t, err)
+ expect.Equal(t, test.i64, int64(127))
ok, err = ConvertString(s, reflect.ValueOf(&test.u8))
- ExpectTrue(t, ok)
- ExpectNoError(t, err)
- ExpectEqual(t, test.u8, uint8(127))
+ expect.True(t, ok)
+ expect.NoError(t, err)
+ expect.Equal(t, test.u8, uint8(127))
ok, err = ConvertString(s, reflect.ValueOf(&test.u16))
- ExpectTrue(t, ok)
- ExpectNoError(t, err)
- ExpectEqual(t, test.u16, uint16(127))
+ expect.True(t, ok)
+ expect.NoError(t, err)
+ expect.Equal(t, test.u16, uint16(127))
ok, err = ConvertString(s, reflect.ValueOf(&test.u32))
- ExpectTrue(t, ok)
- ExpectNoError(t, err)
- ExpectEqual(t, test.u32, uint32(127))
+ expect.True(t, ok)
+ expect.NoError(t, err)
+ expect.Equal(t, test.u32, uint32(127))
ok, err = ConvertString(s, reflect.ValueOf(&test.u64))
- ExpectTrue(t, ok)
- ExpectNoError(t, err)
- ExpectEqual(t, test.u64, uint64(127))
+ expect.True(t, ok)
+ expect.NoError(t, err)
+ expect.Equal(t, test.u64, uint64(127))
}
type testModel struct {
@@ -199,33 +199,33 @@ type testType struct {
func (c *testType) Parse(v string) (err error) {
c.bar = v
c.foo, err = strconv.Atoi(v)
- return
+ return err
}
func TestConvertor(t *testing.T) {
t.Run("valid", func(t *testing.T) {
m := new(testModel)
- ExpectNoError(t, MapUnmarshalValidate(map[string]any{"Test": "123"}, m))
+ expect.NoError(t, MapUnmarshalValidate(map[string]any{"Test": "123"}, m))
- ExpectEqual(t, m.Test.foo, 123)
- ExpectEqual(t, m.Test.bar, "123")
+ expect.Equal(t, m.Test.foo, 123)
+ expect.Equal(t, m.Test.bar, "123")
})
t.Run("int_to_string", func(t *testing.T) {
m := new(testModel)
- ExpectNoError(t, MapUnmarshalValidate(map[string]any{"Test": "123"}, m))
+ expect.NoError(t, MapUnmarshalValidate(map[string]any{"Test": "123"}, m))
- ExpectEqual(t, m.Test.foo, 123)
- ExpectEqual(t, m.Test.bar, "123")
+ expect.Equal(t, m.Test.foo, 123)
+ expect.Equal(t, m.Test.bar, "123")
- ExpectNoError(t, MapUnmarshalValidate(map[string]any{"Baz": 123}, m))
- ExpectEqual(t, m.Baz, "123")
+ expect.NoError(t, MapUnmarshalValidate(map[string]any{"Baz": 123}, m))
+ expect.Equal(t, m.Baz, "123")
})
t.Run("invalid", func(t *testing.T) {
m := new(testModel)
err := MapUnmarshalValidate(map[string]any{"Test": struct{ a int }{1}}, m)
- ExpectError(t, ErrUnsupportedConversion, err)
+ expect.ErrorIs(t, ErrUnsupportedConversion, err)
})
t.Run("set_empty", func(t *testing.T) {
@@ -233,8 +233,8 @@ func TestConvertor(t *testing.T) {
Test: testType{1, "2"},
Baz: "3",
}
- ExpectNoError(t, MapUnmarshalValidate(map[string]any{"Test": nil, "Baz": nil}, &m))
- ExpectEqual(t, m, testModel{})
+ expect.NoError(t, MapUnmarshalValidate(map[string]any{"Test": nil, "Baz": nil}, &m))
+ expect.Equal(t, m, testModel{})
})
}
@@ -242,23 +242,23 @@ func TestStringToSlice(t *testing.T) {
t.Run("comma_separated", func(t *testing.T) {
dst := make([]string, 0)
convertible, err := ConvertString("a,b,c", reflect.ValueOf(&dst))
- ExpectTrue(t, convertible)
- ExpectNoError(t, err)
- ExpectEqual(t, dst, []string{"a", "b", "c"})
+ expect.True(t, convertible)
+ expect.NoError(t, err)
+ expect.Equal(t, dst, []string{"a", "b", "c"})
})
t.Run("yaml-like", func(t *testing.T) {
dst := make([]string, 0)
convertible, err := ConvertString("- a\n- b\n- c", reflect.ValueOf(&dst))
- ExpectTrue(t, convertible)
- ExpectNoError(t, err)
- ExpectEqual(t, dst, []string{"a", "b", "c"})
+ expect.True(t, convertible)
+ expect.NoError(t, err)
+ expect.Equal(t, dst, []string{"a", "b", "c"})
})
t.Run("single-line-yaml-like", func(t *testing.T) {
dst := make([]string, 0)
convertible, err := ConvertString("- a", reflect.ValueOf(&dst))
- ExpectTrue(t, convertible)
- ExpectNoError(t, err)
- ExpectEqual(t, dst, []string{"a"})
+ expect.True(t, convertible)
+ expect.NoError(t, err)
+ expect.Equal(t, dst, []string{"a"})
})
}
@@ -280,9 +280,9 @@ func TestStringToMap(t *testing.T) {
t.Run("yaml-like", func(t *testing.T) {
dst := make(map[string]string)
convertible, err := ConvertString(" a: b\n c: d", reflect.ValueOf(&dst))
- ExpectTrue(t, convertible)
- ExpectNoError(t, err)
- ExpectEqual(t, dst, map[string]string{"a": "b", "c": "d"})
+ expect.True(t, convertible)
+ expect.NoError(t, err)
+ expect.Equal(t, dst, map[string]string{"a": "b", "c": "d"})
})
}
@@ -307,9 +307,9 @@ func TestStringToStruct(t *testing.T) {
B int
}{}
convertible, err := ConvertString(" A: a\n B: 123", reflect.ValueOf(&dst))
- ExpectTrue(t, convertible)
- ExpectNoError(t, err)
- ExpectEqual(t, dst, struct {
+ expect.True(t, convertible)
+ expect.NoError(t, err)
+ expect.Equal(t, dst, struct {
A string
B int
}{"a", 123})
diff --git a/internal/serialization/time_test.go b/internal/serialization/time_test.go
index ce1c4f87..fabb12bc 100644
--- a/internal/serialization/time_test.go
+++ b/internal/serialization/time_test.go
@@ -5,7 +5,7 @@ import (
"time"
"github.com/stretchr/testify/require"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
// NOTE: -ldflags=-checklinkname=0 is required to test this function
diff --git a/internal/serialization/validation.go b/internal/serialization/validation.go
index 1ace564e..058fa9a0 100644
--- a/internal/serialization/validation.go
+++ b/internal/serialization/validation.go
@@ -2,7 +2,7 @@ package serialization
import (
"github.com/go-playground/validator/v10"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
var validate = validator.New()
diff --git a/internal/task/debug.go b/internal/task/debug.go
deleted file mode 100644
index d4f0cd0c..00000000
--- a/internal/task/debug.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package task
-
-import (
- "fmt"
-
- "github.com/rs/zerolog/log"
- "github.com/yusing/godoxy/internal/gperr"
-)
-
-// debug only.
-func listStuckedCallbacks(t *Task) []string {
- callbacks := make([]string, 0)
- if t.onFinish != nil {
- for c := range t.onFinish.Range {
- callbacks = append(callbacks, c.about)
- }
- }
- if t.onCancel != nil {
- for c := range t.onCancel.Range {
- callbacks = append(callbacks, c.about)
- }
- }
- if t.children != nil {
- for c := range t.children.Range {
- callbacks = append(callbacks, listStuckedCallbacks(c)...)
- }
- }
- return callbacks
-}
-
-// debug only.
-func listStuckedChildren(t *Task) []string {
- if t.children != nil {
- children := make([]string, 0)
- for c := range t.children.Range {
- children = append(children, c.String())
- children = append(children, listStuckedCallbacks(c)...)
- }
- return children
- }
- return nil
-}
-
-func (t *Task) reportStucked() {
- callbacks := listStuckedCallbacks(t)
- children := listStuckedChildren(t)
- if len(callbacks) == 0 && len(children) == 0 {
- return
- }
- fmtOutput := gperr.NewBuilder(fmt.Sprintf("%s stucked callbacks: %d, stucked children: %d", t.String(), len(callbacks), len(children)))
- if len(callbacks) > 0 {
- callbackBuilder := gperr.NewBuilder("callbacks")
- for _, c := range callbacks {
- callbackBuilder.Adds(c)
- }
- fmtOutput.Add(callbackBuilder.Error())
- }
- if len(children) > 0 {
- childrenBuilder := gperr.NewBuilder("children")
- for _, c := range children {
- childrenBuilder.Adds(c)
- }
- fmtOutput.Add(childrenBuilder.Error())
- }
- log.Warn().Msg(fmtOutput.String())
-}
diff --git a/internal/task/task.go b/internal/task/task.go
deleted file mode 100644
index 69e154ea..00000000
--- a/internal/task/task.go
+++ /dev/null
@@ -1,246 +0,0 @@
-package task
-
-import (
- "context"
- "sync"
- "time"
-
- "github.com/yusing/godoxy/internal/gperr"
-)
-
-type (
- TaskStarter interface {
- // Start starts the object that implements TaskStarter,
- // and returns an error if it fails to start.
- //
- // callerSubtask.Finish must be called when start fails or the object is finished.
- Start(parent Parent) gperr.Error
- Task() *Task
- }
- TaskFinisher interface {
- Finish(reason any)
- }
- Callback struct {
- fn func()
- about string
- }
- // Task controls objects' lifetime.
- //
- // Objects that uses a Task should implement the TaskStarter and the TaskFinisher interface.
- //
- // Use Task.Finish to stop all subtasks of the Task.
- Task struct {
- parent *Task
- name string
- ctx context.Context
- cancel context.CancelCauseFunc
- done chan struct{}
- finishCalled bool
- onCancel *withWg[*Callback]
- onFinish *withWg[*Callback]
- children *withWg[*Task]
-
- mu sync.Mutex
- }
- Parent interface {
- Context() context.Context
- // Subtask returns a new subtask with the given name, derived from the parent's context.
- //
- // This should not be called after Finish is called on the task or its parent task.
- Subtask(name string, needFinish bool) *Task
- Name() string
- Finish(reason any)
- OnCancel(name string, f func())
- }
-)
-
-const taskTimeout = 3 * time.Second
-
-func (t *Task) Context() context.Context {
- return t.ctx
-}
-
-func (t *Task) Name() string {
- return t.name
-}
-
-// String returns the full name of the task.
-func (t *Task) String() string {
- return t.fullName()
-}
-
-// MarshalText implements encoding.TextMarshaler.
-func (t *Task) MarshalText() ([]byte, error) {
- return []byte(t.fullName()), nil
-}
-
-// Finish marks the task as finished, with the given reason (if any).
-func (t *Task) Finish(reason any) {
- t.finish(reason, false)
-}
-
-// FinishCause returns the reason / error that caused the task to be finished.
-func (t *Task) FinishCause() error {
- return context.Cause(t.ctx)
-}
-
-// FinishAndWait cancel all subtasks and wait for them to finish,
-// then marks the task as finished, with the given reason (if any).
-func (t *Task) FinishAndWait(reason any) {
- t.finish(reason, true)
-}
-
-// OnFinished calls fn when the task is canceled and all subtasks are finished.
-//
-// It should not be called after Finish is called.
-func (t *Task) OnFinished(about string, fn func()) {
- if !t.needFinish() {
- t.OnCancel(about, fn)
- return
- }
-
- t.mu.Lock()
- if t.onFinish == nil {
- t.onFinish = newWithWg[*Callback]()
- t.mu.Unlock()
-
- go func() {
- <-t.ctx.Done()
- <-t.done
- for cb := range t.onFinish.Range {
- go func(cb *Callback) {
- invokeWithRecover(cb)
- t.onFinish.Delete(cb)
- }(cb)
- }
- }()
- } else {
- t.mu.Unlock()
- }
-
- t.onFinish.Add(&Callback{fn: fn, about: about})
-}
-
-// OnCancel calls fn when the task is canceled.
-//
-// It should not be called after Finish is called.
-func (t *Task) OnCancel(about string, fn func()) {
- t.mu.Lock()
- if t.onCancel == nil {
- t.onCancel = newWithWg[*Callback]()
- t.mu.Unlock()
-
- go func() {
- <-t.ctx.Done()
- for cb := range t.onCancel.Range {
- go func(cb *Callback) {
- invokeWithRecover(cb)
- t.onCancel.Delete(cb)
- }(cb)
- }
- }()
- } else {
- t.mu.Unlock()
- }
-
- t.onCancel.Add(&Callback{fn: fn, about: about})
-}
-
-// Subtask returns a new subtask with the given name, derived from the parent's context.
-//
-// This should not be called after Finish is called on the task or its parent task.
-func (t *Task) Subtask(name string, needFinish bool) *Task {
- t.mu.Lock()
- if t.children == nil {
- t.children = newWithWg[*Task]()
- t.mu.Unlock()
- } else {
- t.mu.Unlock()
- }
-
- child := &Task{
- name: name,
- parent: t,
- }
-
- t.children.Add(child)
-
- child.ctx, child.cancel = context.WithCancelCause(t.ctx)
-
- if needFinish {
- child.done = make(chan struct{})
- } else {
- child.done = closedCh
- go func() {
- <-child.ctx.Done()
- child.Finish(t.FinishCause())
- }()
- }
-
- logStarted(child)
- return child
-}
-
-func (t *Task) finish(reason any, wait bool) {
- t.mu.Lock()
- if t.finishCalled {
- t.mu.Unlock()
- // wait but not report stucked (again)
- t.waitFinish(taskTimeout)
- return
- }
-
- t.finishCalled = true
- t.mu.Unlock()
-
- if t.needFinish() {
- close(t.done)
- }
-
- t.cancel(fmtCause(reason))
- if wait && !t.waitFinish(taskTimeout) {
- t.reportStucked()
- }
- if t != root {
- t.parent.children.Delete(t)
- }
- logFinished(t)
-}
-
-func (t *Task) waitFinish(timeout time.Duration) bool {
- if t.children == nil && t.onCancel == nil && t.onFinish == nil {
- return true
- }
- done := make(chan struct{})
- go func() {
- if t.children != nil {
- t.children.Wait()
- }
- if t.onCancel != nil {
- t.onCancel.Wait()
- }
- if t.onFinish != nil {
- t.onFinish.Wait()
- }
- <-t.done
- close(done)
- }()
- timeoutCh := time.After(timeout)
- select {
- case <-done:
- return true
- case <-timeoutCh:
- return false
- }
-}
-
-func (t *Task) fullName() string {
- if t.parent == root {
- return t.name
- }
- return t.parent.fullName() + "." + t.name
-}
-
-func (t *Task) needFinish() bool {
- return t.done != closedCh
-}
diff --git a/internal/task/task_debug.go b/internal/task/task_debug.go
deleted file mode 100644
index 873853e9..00000000
--- a/internal/task/task_debug.go
+++ /dev/null
@@ -1,21 +0,0 @@
-//go:build debug
-
-package task
-
-import (
- "runtime/debug"
-
- "github.com/rs/zerolog/log"
-)
-
-func panicWithDebugStack() {
- panic(string(debug.Stack()))
-}
-
-func logStarted(t *Task) {
- log.Info().Msg("task " + t.String() + " started")
-}
-
-func logFinished(t *Task) {
- log.Info().Msg("task " + t.String() + " finished")
-}
diff --git a/internal/task/task_prod.go b/internal/task/task_prod.go
deleted file mode 100644
index 90a18a8b..00000000
--- a/internal/task/task_prod.go
+++ /dev/null
@@ -1,15 +0,0 @@
-//go:build !debug
-
-package task
-
-func panicWithDebugStack() {
- // do nothing
-}
-
-func logStarted(t *Task) {
- // do nothing
-}
-
-func logFinished(t *Task) {
- // do nothing
-}
diff --git a/internal/task/task_test.go b/internal/task/task_test.go
deleted file mode 100644
index 8501c43c..00000000
--- a/internal/task/task_test.go
+++ /dev/null
@@ -1,161 +0,0 @@
-package task
-
-import (
- "context"
- "sync"
- "testing"
- "time"
-
- expect "github.com/yusing/godoxy/internal/utils/testing"
-)
-
-func testTask() *Task {
- return RootTask("test", true)
-}
-
-func TestChildTaskCancellation(t *testing.T) {
- t.Cleanup(testCleanup)
-
- parent := testTask()
- child := parent.Subtask("", true)
-
- go func() {
- defer child.Finish(nil)
- for {
- select {
- case <-child.Context().Done():
- return
- default:
- continue
- }
- }
- }()
-
- parent.Finish(nil) // should also cancel child
-
- select {
- case <-child.Context().Done():
- expect.ErrorIs(t, context.Canceled, child.Context().Err())
- default:
- t.Fatal("subTask context was not canceled as expected")
- }
-}
-
-func TestTaskStuck(t *testing.T) {
- t.Cleanup(testCleanup)
- task := testTask()
- task.OnCancel("second", func() {
- time.Sleep(time.Second)
- })
- done := make(chan struct{})
- go func() {
- task.FinishAndWait(nil)
- close(done)
- }()
- time.Sleep(time.Millisecond * 100)
- select {
- case <-done:
- t.Fatal("task finished unexpectedly")
- default:
- }
- time.Sleep(time.Second)
- select {
- case <-done:
- default:
- t.Fatal("task did not finish")
- }
-}
-
-func TestTaskOnCancelOnFinished(t *testing.T) {
- t.Cleanup(testCleanup)
- task := testTask()
-
- var shouldTrueOnCancel bool
- var shouldTrueOnFinish bool
-
- task.OnCancel("", func() {
- shouldTrueOnCancel = true
- })
- task.OnFinished("", func() {
- shouldTrueOnFinish = true
- })
-
- expect.False(t, shouldTrueOnFinish)
- task.FinishAndWait(nil)
- expect.True(t, shouldTrueOnCancel)
- expect.True(t, shouldTrueOnFinish)
-}
-
-func TestCommonFlowWithGracefulShutdown(t *testing.T) {
- t.Cleanup(testCleanup)
- task := testTask()
-
- finished := false
-
- task.OnFinished("", func() {
- finished = true
- })
-
- go func() {
- defer task.FinishAndWait(nil)
- for {
- select {
- case <-task.Context().Done():
- return
- default:
- continue
- }
- }
- }()
-
- expect.NoError(t, gracefulShutdown(1*time.Second))
- expect.True(t, finished)
-
- expect.ErrorIs(t, ErrProgramExiting, context.Cause(task.Context()))
- expect.ErrorIs(t, context.Canceled, task.Context().Err())
- expect.ErrorIs(t, ErrProgramExiting, task.FinishCause())
-}
-
-func TestTimeoutOnGracefulShutdown(t *testing.T) {
- t.Cleanup(testCleanup)
- _ = testTask()
-
- expect.ErrorIs(t, context.DeadlineExceeded, gracefulShutdown(time.Millisecond))
-}
-
-func TestFinishMultipleCalls(t *testing.T) {
- t.Cleanup(testCleanup)
- task := testTask()
- var wg sync.WaitGroup
- n := 20
- for range n {
- wg.Go(func() {
- task.Finish(nil)
- })
- }
- wg.Wait()
-}
-
-func BenchmarkTasksNoFinish(b *testing.B) {
- for b.Loop() {
- task := RootTask("", false)
- task.Subtask("", false).Finish(nil)
- task.Finish(nil)
- }
-}
-
-func BenchmarkTasksNeedFinish(b *testing.B) {
- for b.Loop() {
- task := testTask()
- task.Subtask("", true).Finish(nil)
- task.Finish(nil)
- }
-}
-
-func BenchmarkContextWithCancel(b *testing.B) {
- for b.Loop() {
- task, taskCancel := context.WithCancelCause(b.Context())
- taskCancel(nil)
- <-task.Done()
- }
-}
diff --git a/internal/task/utils.go b/internal/task/utils.go
deleted file mode 100644
index 9135e5f5..00000000
--- a/internal/task/utils.go
+++ /dev/null
@@ -1,117 +0,0 @@
-package task
-
-import (
- "context"
- "errors"
- "fmt"
- "os"
- "os/signal"
- "syscall"
- "time"
-
- "github.com/rs/zerolog/log"
-)
-
-var ErrProgramExiting = errors.New("program exiting")
-
-var root *Task
-
-var closedCh = make(chan struct{})
-
-func init() {
- close(closedCh)
- initRoot()
-}
-
-func initRoot() {
- ctx, cancel := context.WithCancelCause(context.Background())
- root = &Task{
- name: "root",
- ctx: ctx,
- cancel: cancel,
- done: closedCh,
- }
- root.parent = root
-}
-
-func testCleanup() {
- root.cancel(nil)
- initRoot()
-}
-
-// RootTask returns a new Task with the given name, derived from the root context.
-//
-//go:inline
-func RootTask(name string, needFinish bool) *Task {
- return root.Subtask(name, needFinish)
-}
-
-func RootContext() context.Context {
- return root.Context()
-}
-
-func RootContextCanceled() <-chan struct{} {
- return root.Context().Done()
-}
-
-func OnProgramExit(about string, fn func()) {
- root.OnCancel(about, fn)
-}
-
-// WaitExit waits for a signal to shutdown the program, and then waits for all tasks to finish, up to the given timeout.
-//
-// If the timeout is exceeded, it prints a list of all tasks that were
-// still running when the timeout was reached, and their current tree
-// of subtasks.
-func WaitExit(shutdownTimeout int) {
- sig := make(chan os.Signal, 1)
- signal.Notify(sig, syscall.SIGINT)
- signal.Notify(sig, syscall.SIGTERM)
- signal.Notify(sig, syscall.SIGHUP)
-
- // wait for signal
- <-sig
-
- // gracefully shutdown
- log.Info().Msg("shutting down")
- if err := gracefulShutdown(time.Second * time.Duration(shutdownTimeout)); err != nil {
- root.reportStucked()
- }
-}
-
-// gracefulShutdown waits for all tasks to finish, up to the given timeout.
-//
-// If the timeout is exceeded, it prints a list of all tasks that were
-// still running when the timeout was reached, and their current tree
-// of subtasks.
-func gracefulShutdown(timeout time.Duration) error {
- root.Finish(ErrProgramExiting)
- if !root.waitFinish(timeout) {
- return context.DeadlineExceeded
- }
- return nil
-}
-
-func invokeWithRecover(cb *Callback) {
- defer func() {
- if err := recover(); err != nil {
- log.Err(fmtCause(err)).Str("callback", cb.about).Msg("panic")
- panicWithDebugStack()
- }
- }()
- cb.fn()
-}
-
-//go:inline
-func fmtCause(cause any) error {
- switch cause := cause.(type) {
- case nil:
- return nil
- case error:
- return cause
- case string:
- return errors.New(cause)
- default:
- return fmt.Errorf("%v", cause)
- }
-}
diff --git a/internal/task/with.go b/internal/task/with.go
deleted file mode 100644
index bfb47ada..00000000
--- a/internal/task/with.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package task
-
-import (
- "sync"
-
- "github.com/puzpuzpuz/xsync/v4"
-)
-
-type withWg[T comparable] struct {
- m *xsync.Map[T, struct{}]
- wg sync.WaitGroup
-}
-
-func newWithWg[T comparable]() *withWg[T] {
- return &withWg[T]{
- m: xsync.NewMap[T, struct{}](),
- }
-}
-
-func (w *withWg[T]) Add(ele T) {
- w.wg.Add(1)
- w.m.Store(ele, struct{}{})
-}
-
-func (w *withWg[T]) AddWithoutWG(ele T) {
- w.m.Store(ele, struct{}{})
-}
-
-func (w *withWg[T]) Delete(key T) {
- w.wg.Done()
- w.m.Delete(key)
-}
-
-func (w *withWg[T]) DeleteWithoutWG(key T) {
- w.m.Delete(key)
-}
-
-func (w *withWg[T]) Wait() {
- w.wg.Wait()
-}
-
-func (w *withWg[T]) Range(yield func(T) bool) {
- for ele := range w.m.Range {
- if !yield(ele) {
- break
- }
- }
-}
diff --git a/internal/types/docker.go b/internal/types/docker.go
index bdd54de7..be40e795 100644
--- a/internal/types/docker.go
+++ b/internal/types/docker.go
@@ -6,8 +6,8 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/yusing/ds/ordered"
"github.com/yusing/godoxy/agent/pkg/agent"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/utils"
+ gperr "github.com/yusing/goutils/errs"
)
type (
diff --git a/internal/types/health.go b/internal/types/health.go
index e99192db..c9bbc085 100644
--- a/internal/types/health.go
+++ b/internal/types/health.go
@@ -7,8 +7,8 @@ import (
"strconv"
"time"
- "github.com/yusing/godoxy/internal/task"
strutils "github.com/yusing/goutils/strings"
+ "github.com/yusing/goutils/task"
)
type (
diff --git a/internal/types/idlewatcher.go b/internal/types/idlewatcher.go
index a850dd5d..8ebb876b 100644
--- a/internal/types/idlewatcher.go
+++ b/internal/types/idlewatcher.go
@@ -6,7 +6,7 @@ import (
"strings"
"time"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type (
diff --git a/internal/types/idlewatcher_test.go b/internal/types/idlewatcher_test.go
index aac0af8e..df7cafb4 100644
--- a/internal/types/idlewatcher_test.go
+++ b/internal/types/idlewatcher_test.go
@@ -3,7 +3,7 @@ package types
import (
"testing"
- expect "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestValidateStartEndpoint(t *testing.T) {
diff --git a/internal/types/routes.go b/internal/types/routes.go
index 7b5e701c..4feed2c7 100644
--- a/internal/types/routes.go
+++ b/internal/types/routes.go
@@ -6,9 +6,9 @@ import (
"github.com/yusing/godoxy/agent/pkg/agent"
"github.com/yusing/godoxy/internal/homepage"
nettypes "github.com/yusing/godoxy/internal/net/types"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/utils/pool"
"github.com/yusing/goutils/http/reverseproxy"
+ "github.com/yusing/goutils/task"
)
type (
diff --git a/internal/utils/atomic/std.go b/internal/utils/atomic/std.go
index a57315ad..97bbf851 100644
--- a/internal/utils/atomic/std.go
+++ b/internal/utils/atomic/std.go
@@ -2,6 +2,8 @@ package atomic
import "sync/atomic"
-type Bool = atomic.Bool
-type Int32 = atomic.Int32
-type Int64 = atomic.Int64
+type (
+ Bool = atomic.Bool
+ Int32 = atomic.Int32
+ Int64 = atomic.Int64
+)
diff --git a/internal/utils/go.mod b/internal/utils/go.mod
index 526fa67c..53f36808 100644
--- a/internal/utils/go.mod
+++ b/internal/utils/go.mod
@@ -5,8 +5,7 @@ go 1.25.1
require (
github.com/puzpuzpuz/xsync/v4 v4.2.0
github.com/rs/zerolog v1.34.0
- github.com/stretchr/testify v1.11.1
- github.com/yusing/goutils v0.2.1
+ github.com/yusing/goutils v0.3.1
go.uber.org/atomic v1.11.0
)
@@ -15,6 +14,7 @@ require (
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
+ github.com/stretchr/testify v1.11.1 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/text v0.29.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/internal/utils/go.sum b/internal/utils/go.sum
index 923171bb..5fa2ba31 100644
--- a/internal/utils/go.sum
+++ b/internal/utils/go.sum
@@ -19,8 +19,8 @@ github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
-github.com/yusing/goutils v0.2.1 h1:KjoCrNO0otthaPCZPfQY+5GKsqs5+J77CxP+TNHYa/Y=
-github.com/yusing/goutils v0.2.1/go.mod h1:v6RZsMRdzcts4udSg0vqUIFvaD0OaUMPTwYJZ4XnQYo=
+github.com/yusing/goutils v0.3.1 h1:xCPoZ/haI8ZJ0ZaPU4g6+okSPdBczs8o98tIZ/TbpsQ=
+github.com/yusing/goutils v0.3.1/go.mod h1:meg9GcAU8yvBY21JgYjPuLsXD1Q5VdVHE32A4tG5Y5g=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
diff --git a/internal/utils/ref_count_test.go b/internal/utils/ref_count_test.go
index 7eae0492..a40cc75b 100644
--- a/internal/utils/ref_count_test.go
+++ b/internal/utils/ref_count_test.go
@@ -5,7 +5,7 @@ import (
"testing"
"time"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestRefCounterAddSub(t *testing.T) {
@@ -19,7 +19,7 @@ func TestRefCounterAddSub(t *testing.T) {
}
wg.Wait()
- ExpectEqual(t, int(rc.refCount), 0)
+ expect.Equal(t, int(rc.refCount), 0)
select {
case <-rc.Zero():
@@ -44,7 +44,7 @@ func TestRefCounterMultipleAddSub(t *testing.T) {
}()
}
wg.Wait()
- ExpectEqual(t, int(rc.refCount), numAdds+1)
+ expect.Equal(t, int(rc.refCount), numAdds+1)
wg.Add(numSubs)
for range numSubs {
@@ -54,7 +54,7 @@ func TestRefCounterMultipleAddSub(t *testing.T) {
}()
}
wg.Wait()
- ExpectEqual(t, int(rc.refCount), numAdds+1-numSubs)
+ expect.Equal(t, int(rc.refCount), numAdds+1-numSubs)
rc.Sub()
select {
diff --git a/internal/utils/slices_test.go b/internal/utils/slices_test.go
index 31dd4406..c405cfda 100644
--- a/internal/utils/slices_test.go
+++ b/internal/utils/slices_test.go
@@ -5,7 +5,7 @@ import (
"strings"
"testing"
- . "github.com/yusing/godoxy/internal/utils/testing"
+ expect "github.com/yusing/goutils/testing"
)
func TestIntersect(t *testing.T) {
@@ -19,7 +19,7 @@ func TestIntersect(t *testing.T) {
result := Intersect(slice1, slice2)
slices.Sort(result)
slices.Sort(want)
- ExpectEqual(t, result, want)
+ expect.Equal(t, result, want)
})
t.Run("intersection", func(t *testing.T) {
var (
@@ -30,7 +30,7 @@ func TestIntersect(t *testing.T) {
result := Intersect(slice1, slice2)
slices.Sort(result)
slices.Sort(want)
- ExpectEqual(t, result, want)
+ expect.Equal(t, result, want)
})
})
t.Run("ints", func(t *testing.T) {
@@ -43,7 +43,7 @@ func TestIntersect(t *testing.T) {
result := Intersect(slice1, slice2)
slices.Sort(result)
slices.Sort(want)
- ExpectEqual(t, result, want)
+ expect.Equal(t, result, want)
})
t.Run("intersection", func(t *testing.T) {
var (
@@ -54,7 +54,7 @@ func TestIntersect(t *testing.T) {
result := Intersect(slice1, slice2)
slices.Sort(result)
slices.Sort(want)
- ExpectEqual(t, result, want)
+ expect.Equal(t, result, want)
})
})
t.Run("complex", func(t *testing.T) {
@@ -75,7 +75,7 @@ func TestIntersect(t *testing.T) {
slices.SortFunc(want, func(i T, j T) int {
return strings.Compare(i.A, j.A)
})
- ExpectEqual(t, result, want)
+ expect.Equal(t, result, want)
})
t.Run("intersection", func(t *testing.T) {
var (
@@ -90,7 +90,7 @@ func TestIntersect(t *testing.T) {
slices.SortFunc(want, func(i T, j T) int {
return strings.Compare(i.A, j.A)
})
- ExpectEqual(t, result, want)
+ expect.Equal(t, result, want)
})
})
}
diff --git a/internal/utils/testing/expect.go b/internal/utils/testing/expect.go
deleted file mode 100644
index cd4c37dd..00000000
--- a/internal/utils/testing/expect.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package expect
-
-import (
- "os"
- "strings"
- "testing"
-
- "github.com/stretchr/testify/require"
-)
-
-var isTest = strings.HasSuffix(os.Args[0], ".test")
-
-func init() {
- if isTest {
- // force verbose output
- os.Args = append([]string{os.Args[0], "-test.v"}, os.Args[1:]...)
- }
-}
-
-func Must[Result any](r Result, err error) Result {
- if err != nil {
- panic(err)
- }
- return r
-}
-
-var (
- NoError = require.NoError
- HasError = require.Error
- True = require.True
- False = require.False
- Nil = require.Nil
- NotNil = require.NotNil
- ErrorContains = require.ErrorContains
- Panics = require.Panics
- Greater = require.Greater
- Less = require.Less
- GreaterOrEqual = require.GreaterOrEqual
- LessOrEqual = require.LessOrEqual
-)
-
-func ErrorIs(t *testing.T, expected error, err error, msgAndArgs ...any) {
- t.Helper()
- require.ErrorIs(t, err, expected, msgAndArgs...)
-}
-
-func ErrorT[T error](t *testing.T, err error, msgAndArgs ...any) {
- t.Helper()
- var errAs T
- require.ErrorAs(t, err, &errAs, msgAndArgs...)
-}
-
-func Equal[T any](t *testing.T, got T, want T, msgAndArgs ...any) {
- t.Helper()
- require.EqualValues(t, want, got, msgAndArgs...)
-}
-
-func NotEqual[T any](t *testing.T, got T, want T, msgAndArgs ...any) {
- t.Helper()
- require.NotEqual(t, want, got, msgAndArgs...)
-}
-
-func Contains[T any](t *testing.T, got T, wants []T, msgAndArgs ...any) {
- t.Helper()
- require.Contains(t, wants, got, msgAndArgs...)
-}
-
-func StringsContain(t *testing.T, got string, want string, msgAndArgs ...any) {
- t.Helper()
- require.Contains(t, got, want, msgAndArgs...)
-}
-
-func Type[T any](t *testing.T, got any, msgAndArgs ...any) (_ T) {
- t.Helper()
- _, ok := got.(T)
- require.True(t, ok, msgAndArgs...)
- return got.(T)
-}
diff --git a/internal/utils/testing/log.go b/internal/utils/testing/log.go
deleted file mode 100644
index bf662dbf..00000000
--- a/internal/utils/testing/log.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package expect
-
-import "github.com/rs/zerolog"
-
-func init() {
- if isTest {
- zerolog.SetGlobalLevel(zerolog.DebugLevel)
- }
-}
diff --git a/internal/utils/testing/testing.go b/internal/utils/testing/testing.go
deleted file mode 100644
index 13411c3f..00000000
--- a/internal/utils/testing/testing.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package expect
-
-import (
- "testing"
-
- "github.com/stretchr/testify/require"
-)
-
-func ExpectNoError(t *testing.T, err error) {
- t.Helper()
- require.NoError(t, err)
-}
-
-func ExpectHasError(t *testing.T, err error) {
- t.Helper()
- require.Error(t, err)
-}
-
-func ExpectError(t *testing.T, expected error, err error) {
- t.Helper()
- require.ErrorIs(t, err, expected)
-}
-
-func ExpectErrorT[T error](t *testing.T, err error) {
- t.Helper()
- var errAs T
- require.ErrorAs(t, err, &errAs)
-}
-
-func ExpectEqual[T any](t *testing.T, got T, want T) {
- t.Helper()
- require.EqualValues(t, want, got)
-}
-
-func ExpectContains[T any](t *testing.T, got T, wants []T) {
- t.Helper()
- require.Contains(t, wants, got)
-}
-
-func ExpectTrue(t *testing.T, got bool) {
- t.Helper()
- require.True(t, got)
-}
-
-func ExpectFalse(t *testing.T, got bool) {
- t.Helper()
- require.False(t, got)
-}
-
-func ExpectType[T any](t *testing.T, got any) (_ T) {
- t.Helper()
- _, ok := got.(T)
- require.True(t, ok)
- return got.(T)
-}
diff --git a/internal/watcher/config_file_watcher.go b/internal/watcher/config_file_watcher.go
index b31c3ea7..86cb9c8d 100644
--- a/internal/watcher/config_file_watcher.go
+++ b/internal/watcher/config_file_watcher.go
@@ -4,7 +4,7 @@ import (
"sync"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/task"
+ "github.com/yusing/goutils/task"
)
var (
diff --git a/internal/watcher/directory_watcher.go b/internal/watcher/directory_watcher.go
index 53ab758b..d491ac81 100644
--- a/internal/watcher/directory_watcher.go
+++ b/internal/watcher/directory_watcher.go
@@ -9,9 +9,9 @@ import (
"github.com/fsnotify/fsnotify"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
- "github.com/yusing/godoxy/internal/gperr"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/watcher/events"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
type DirWatcher struct {
diff --git a/internal/watcher/docker_watcher.go b/internal/watcher/docker_watcher.go
index 7c5c49eb..7a8a8fc2 100644
--- a/internal/watcher/docker_watcher.go
+++ b/internal/watcher/docker_watcher.go
@@ -10,8 +10,8 @@ import (
"github.com/docker/docker/client"
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/docker"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/watcher/events"
+ gperr "github.com/yusing/goutils/errs"
)
type (
diff --git a/internal/watcher/events/event_queue.go b/internal/watcher/events/event_queue.go
index eea1fbca..40002c47 100644
--- a/internal/watcher/events/event_queue.go
+++ b/internal/watcher/events/event_queue.go
@@ -5,8 +5,8 @@ import (
"time"
"github.com/yusing/godoxy/internal/common"
- "github.com/yusing/godoxy/internal/gperr"
- "github.com/yusing/godoxy/internal/task"
+ gperr "github.com/yusing/goutils/errs"
+ "github.com/yusing/goutils/task"
)
type (
diff --git a/internal/watcher/events/events.go b/internal/watcher/events/events.go
index f20457a6..4fe137cd 100644
--- a/internal/watcher/events/events.go
+++ b/internal/watcher/events/events.go
@@ -72,7 +72,7 @@ var actionNameMap = func() (m map[Action]string) {
for k, v := range fileActionNameMap {
m[k] = v
}
- return
+ return m
}()
func (e Event) String() string {
diff --git a/internal/watcher/file_watcher.go b/internal/watcher/file_watcher.go
index 619f5376..c0563981 100644
--- a/internal/watcher/file_watcher.go
+++ b/internal/watcher/file_watcher.go
@@ -3,7 +3,7 @@ package watcher
import (
"context"
- "github.com/yusing/godoxy/internal/gperr"
+ gperr "github.com/yusing/goutils/errs"
)
type fileWatcher struct {
diff --git a/internal/watcher/health/monitor/agent_proxied.go b/internal/watcher/health/monitor/agent_proxied.go
index a38a3e96..ded29e9f 100644
--- a/internal/watcher/health/monitor/agent_proxied.go
+++ b/internal/watcher/health/monitor/agent_proxied.go
@@ -78,5 +78,5 @@ func (mon *AgentProxiedMonitor) CheckHealth() (result types.HealthCheckResult, e
// use godoxy to agent latency
result.Latency = endTime.Sub(startTime)
}
- return
+ return result, err
}
diff --git a/internal/watcher/health/monitor/monitor.go b/internal/watcher/health/monitor/monitor.go
index 3a5f019f..7cbc5e2c 100644
--- a/internal/watcher/health/monitor/monitor.go
+++ b/internal/watcher/health/monitor/monitor.go
@@ -11,12 +11,12 @@ import (
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/internal/common"
"github.com/yusing/godoxy/internal/docker"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/notif"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/types"
"github.com/yusing/godoxy/internal/utils/atomic"
+ gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
+ "github.com/yusing/goutils/task"
)
type (
diff --git a/internal/watcher/health/monitor/monitor_test.go b/internal/watcher/health/monitor/monitor_test.go
index 6206064c..6129cf6c 100644
--- a/internal/watcher/health/monitor/monitor_test.go
+++ b/internal/watcher/health/monitor/monitor_test.go
@@ -9,8 +9,8 @@ import (
"github.com/rs/zerolog"
"github.com/stretchr/testify/require"
"github.com/yusing/godoxy/internal/notif"
- "github.com/yusing/godoxy/internal/task"
"github.com/yusing/godoxy/internal/types"
+ "github.com/yusing/goutils/task"
)
// Test notification tracker
diff --git a/internal/watcher/watcher.go b/internal/watcher/watcher.go
index 45419e95..925d94ed 100644
--- a/internal/watcher/watcher.go
+++ b/internal/watcher/watcher.go
@@ -3,8 +3,8 @@ package watcher
import (
"context"
- "github.com/yusing/godoxy/internal/gperr"
"github.com/yusing/godoxy/internal/watcher/events"
+ gperr "github.com/yusing/goutils/errs"
)
type Event = events.Event
diff --git a/pkg/version.go b/pkg/version.go
index 7b42ee0b..8ca5e3b3 100644
--- a/pkg/version.go
+++ b/pkg/version.go
@@ -101,30 +101,30 @@ var versionRegex = regexp.MustCompile(`^v(\d+)\.(\d+)\.(\d+)(\-\w+)?$`)
func ParseVersion(v string) (ver Version) {
if v == "" {
- return
+ return ver
}
if !versionRegex.MatchString(v) { // likely feature branch (e.g. feat/some-feature)
- return
+ return ver
}
v = strings.Split(v, "-")[0]
v = strings.TrimPrefix(v, "v")
parts := strings.Split(v, ".")
if len(parts) != 3 {
- return
+ return ver
}
gen, err := strconv.Atoi(parts[0])
if err != nil {
- return
+ return ver
}
major, err := strconv.Atoi(parts[1])
if err != nil {
- return
+ return ver
}
minor, err := strconv.Atoi(parts[2])
if err != nil {
- return
+ return ver
}
return Ver(gen, major, minor)
}