From 52eead3bf5a075062ed00f9ac74710b0f9c2cfab Mon Sep 17 00:00:00 2001 From: krau <71133316+krau@users.noreply.github.com> Date: Thu, 18 Dec 2025 17:42:20 +0800 Subject: [PATCH] feat: refactor database dialect handling and add stubs for unsupported features --- Dockerfile.micro | 40 ++++++++++++++++++++++++++++ Dockerfile.pico | 35 ++++++++++++++++++++++++ client/bot/bot.go | 4 +-- client/user/userclient.go | 3 +-- common/i18n/i18n.go | 2 ++ database/db.go | 4 +-- database/driver.go | 13 +++++++++ database/driver_glebarez.go | 12 +++++++++ go.mod | 5 +--- go.sum | 44 +++++++++++++++---------------- parsers/js/api.go | 2 ++ parsers/js/api_playwright.go | 2 ++ parsers/js/api_playwright_stub.go | 2 +- parsers/js/js.go | 2 ++ parsers/js/js_stub.go | 16 +++++++++++ parsers/js/plugin.go | 2 ++ storage/minio/client.go | 2 ++ storage/minio/client_stub.go | 41 ++++++++++++++++++++++++++++ 18 files changed, 197 insertions(+), 34 deletions(-) create mode 100644 Dockerfile.micro create mode 100644 Dockerfile.pico create mode 100644 database/driver.go create mode 100644 database/driver_glebarez.go create mode 100644 parsers/js/js_stub.go create mode 100644 storage/minio/client_stub.go diff --git a/Dockerfile.micro b/Dockerfile.micro new file mode 100644 index 0000000..c4f1d8b --- /dev/null +++ b/Dockerfile.micro @@ -0,0 +1,40 @@ +FROM golang:alpine AS builder + +ARG VERSION="dev" +ARG GitCommit="Unknown" +ARG BuildTime="Unknown" + +WORKDIR /app + +COPY go.mod go.sum ./ +RUN --mount=type=cache,target=/go/pkg/mod \ + go mod download + +COPY . . +RUN --mount=type=cache,target=/root/.cache/go-build \ + --mount=type=cache,target=/go/pkg \ + CGO_ENABLED=0 \ + go build -trimpath \ + -tags=no_jsparser,no_minio \ + -ldflags=" \ + -s -w \ + -X 'github.com/krau/SaveAny-Bot/config.Version=${VERSION}' \ + -X 'github.com/krau/SaveAny-Bot/config.GitCommit=${GitCommit}' \ + -X 'github.com/krau/SaveAny-Bot/config.BuildTime=${BuildTime}' \ + " \ + -o saveany-bot . + +FROM alpine:latest + +RUN apk add --no-cache curl + +WORKDIR /app + +COPY --from=builder /app/saveany-bot . +COPY entrypoint.sh . + +RUN chmod +x /app/saveany-bot && \ + chmod +x /app/entrypoint.sh + +ENTRYPOINT ["/app/entrypoint.sh"] + diff --git a/Dockerfile.pico b/Dockerfile.pico new file mode 100644 index 0000000..64ee780 --- /dev/null +++ b/Dockerfile.pico @@ -0,0 +1,35 @@ +# pico is the minimum build of SaveAnyBot, which disables all the optional features like JS parsing and MinIO support. +FROM golang:alpine AS builder + +ARG VERSION="dev" +ARG GitCommit="Unknown" +ARG BuildTime="Unknown" + +WORKDIR /app + +COPY go.mod go.sum ./ +RUN --mount=type=cache,target=/go/pkg/mod \ + go mod download + +COPY . . +RUN --mount=type=cache,target=/root/.cache/go-build \ + --mount=type=cache,target=/go/pkg \ + CGO_ENABLED=0 \ + go build -trimpath \ + -tags=no_jsparser,no_minio,sqlite_glebarez \ + -ldflags=" \ + -s -w \ + -X 'github.com/krau/SaveAny-Bot/config.Version=${VERSION}' \ + -X 'github.com/krau/SaveAny-Bot/config.GitCommit=${GitCommit}' \ + -X 'github.com/krau/SaveAny-Bot/config.BuildTime=${BuildTime}' \ + " \ + -o saveany-bot . + +FROM scratch + +WORKDIR /app + +COPY --from=builder /app/saveany-bot . +RUN chmod +x /app/saveany-bot + +ENTRYPOINT ["/app/saveany-bot"] diff --git a/client/bot/bot.go b/client/bot/bot.go index a465b21..4f41727 100644 --- a/client/bot/bot.go +++ b/client/bot/bot.go @@ -14,7 +14,7 @@ import ( "github.com/krau/SaveAny-Bot/client/middleware" "github.com/krau/SaveAny-Bot/common/utils/tgutil" "github.com/krau/SaveAny-Bot/config" - "github.com/ncruces/go-sqlite3/gormlite" + "github.com/krau/SaveAny-Bot/database" ) func Init(ctx context.Context) <-chan struct{} { @@ -39,7 +39,7 @@ func Init(ctx context.Context) <-chan struct{} { config.C().Telegram.AppHash, gotgproto.ClientTypeBot(config.C().Telegram.Token), &gotgproto.ClientOpts{ - Session: sessionMaker.SqlSession(gormlite.Open(config.C().DB.Session)), + Session: sessionMaker.SqlSession(database.GetDialect(config.C().DB.Session)), DisableCopyright: true, Middlewares: middleware.NewDefaultMiddlewares(ctx, 5*time.Minute), Resolver: resolver, diff --git a/client/user/userclient.go b/client/user/userclient.go index a5653ce..0556707 100644 --- a/client/user/userclient.go +++ b/client/user/userclient.go @@ -17,7 +17,6 @@ import ( "github.com/krau/SaveAny-Bot/common/utils/tgutil" "github.com/krau/SaveAny-Bot/config" "github.com/krau/SaveAny-Bot/database" - "github.com/ncruces/go-sqlite3/gormlite" ) var uc *gotgproto.Client @@ -64,7 +63,7 @@ func Login(ctx context.Context) (*gotgproto.Client, error) { config.C().Telegram.AppHash, gotgproto.ClientTypePhone(""), &gotgproto.ClientOpts{ - Session: sessionMaker.SqlSession(gormlite.Open(config.C().Telegram.Userbot.Session)), + Session: sessionMaker.SqlSession(database.GetDialect(config.C().Telegram.Userbot.Session)), AuthConversator: &terminalAuthConversator{}, Context: ctx, DisableCopyright: true, diff --git a/common/i18n/i18n.go b/common/i18n/i18n.go index fe587c0..f89fcbc 100644 --- a/common/i18n/i18n.go +++ b/common/i18n/i18n.go @@ -1,3 +1,5 @@ +// [TODO] complete the i18n support + package i18n import ( diff --git a/database/db.go b/database/db.go index 5800c5c..d948052 100644 --- a/database/db.go +++ b/database/db.go @@ -9,8 +9,6 @@ import ( "github.com/charmbracelet/log" "github.com/krau/SaveAny-Bot/config" - _ "github.com/ncruces/go-sqlite3/embed" - "github.com/ncruces/go-sqlite3/gormlite" "gorm.io/gorm" glogger "gorm.io/gorm/logger" ) @@ -23,7 +21,7 @@ func Init(ctx context.Context) { logger.Fatal("Failed to create data directory: ", err) } var err error - db, err = gorm.Open(gormlite.Open(config.C().DB.Path), &gorm.Config{ + db, err = gorm.Open(GetDialect(config.C().DB.Path), &gorm.Config{ Logger: glogger.New(logger, glogger.Config{ Colorful: true, SlowThreshold: time.Second * 5, diff --git a/database/driver.go b/database/driver.go new file mode 100644 index 0000000..004c501 --- /dev/null +++ b/database/driver.go @@ -0,0 +1,13 @@ +//go:build !sqlite_glebarez + +package database + +import ( + _ "github.com/ncruces/go-sqlite3/embed" + "github.com/ncruces/go-sqlite3/gormlite" + "gorm.io/gorm" +) + +func GetDialect(dsn string) gorm.Dialector { + return gormlite.Open(dsn) +} diff --git a/database/driver_glebarez.go b/database/driver_glebarez.go new file mode 100644 index 0000000..7e38b8e --- /dev/null +++ b/database/driver_glebarez.go @@ -0,0 +1,12 @@ +//go:build sqlite_glebarez + +package database + +import ( + "github.com/glebarez/sqlite" + "gorm.io/gorm" +) + +func GetDialect(dsn string) gorm.Dialector { + return sqlite.Open(dsn) +} diff --git a/go.mod b/go.mod index eed076f..316b79b 100644 --- a/go.mod +++ b/go.mod @@ -27,9 +27,6 @@ require ( require ( github.com/AnimeKaizoku/cacher v1.0.3 // indirect - github.com/aws/aws-sdk-go-v2 v1.40.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.19.3 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0 // indirect github.com/aws/smithy-go v1.24.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -110,7 +107,7 @@ require ( github.com/dop251/goja v0.0.0-20251008123653-cf18d89f3cf6 github.com/duke-git/lancet/v2 v2.3.7 github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/glebarez/sqlite v1.11.0 // indirect + github.com/glebarez/sqlite v1.11.0 github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/compress v1.18.2 // indirect github.com/mitchellh/mapstructure v1.5.0 diff --git a/go.sum b/go.sum index 3f7e6eb..782a34e 100644 --- a/go.sum +++ b/go.sum @@ -4,30 +4,30 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/aws/aws-sdk-go-v2 v1.40.1 h1:difXb4maDZkRH0x//Qkwcfpdg1XQVXEAEs2DdXldFFc= -github.com/aws/aws-sdk-go-v2 v1.40.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4= -github.com/aws/aws-sdk-go-v2/credentials v1.19.3 h1:01Ym72hK43hjwDeJUfi1l2oYLXBAOR8gNSZNmXmvuas= -github.com/aws/aws-sdk-go-v2/credentials v1.19.3/go.mod h1:55nWF/Sr9Zvls0bGnWkRxUdhzKqj9uRNlPvgV1vgxKc= +github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM= +github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 h1:zAybnyUQXIZ5mok5Jqwlf58/TFE7uvd3IAsa1aF9cXs= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10/go.mod h1:qqvMj6gHLR/EXWZw4ZbqlPbQUyenf4h82UQUlKc+l14= +github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM= +github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.75 h1:S61/E3N01oral6B3y9hZ2E1iFDqCZPPOBoBQretCnBI= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.75/go.mod h1:bDMQbkI1vJbNjnvJYpPTSNYBkI/VIv18ngWb/K84tkk= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.15 h1:Y5YXgygXwDI5P4RkteB5yF7v35neH7LfJKBG+hzIons= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.15/go.mod h1:K+/1EpG42dFSY7CBj+Fruzm8PsCGWTXJ3jdeJ659oGQ= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.15 h1:AvltKnW9ewxX2hFmQS0FyJH93aSvJVUEFvXfU+HWtSE= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.15/go.mod h1:3I4oCdZdmgrREhU74qS1dK9yZ62yumob+58AbFR4cQA= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.15 h1:NLYTEyZmVZo0Qh183sC8nC+ydJXOOeIL/qI/sS3PdLY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.15/go.mod h1:Z803iB3B0bc8oJV8zH2PERLRfQUJ2n2BXISpsA4+O1M= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.6 h1:P1MU/SuhadGvg2jtviDXPEejU3jBNhoeeAlRadHzvHI= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.6/go.mod h1:5KYaMG6wmVKMFBSfWoyG/zH8pWwzQFnKgpoSRlXHKdQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.15 h1:3/u/4yZOffg5jdNk1sDpOQ4Y+R6Xbh+GzpDrSZjuy3U= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.15/go.mod h1:4Zkjq0FKjE78NKjabuM4tRXKFzUJWXgP0ItEZK8l7JU= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.15 h1:wsSQ4SVz5YE1crz0Ap7VBZrV4nNqZt4CIBBT8mnwoNc= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.15/go.mod h1:I7sditnFGtYMIqPRU1QoHZAUrXkGp4SczmlLwrNPlD0= -github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0 h1:IrbE3B8O9pm3lsg96AXIN5MXX4pECEuExh/A0Du3AuI= -github.com/aws/aws-sdk-go-v2/service/s3 v1.93.0/go.mod h1:/sJLzHtiiZvs6C1RbxS/anSAFwZD6oC6M/kotQzOiLw= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 h1:ZNTqv4nIdE/DiBfUUfXcLZ/Spcuz+RjeziUtNJackkM= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34/go.mod h1:zf7Vcd1ViW7cPqYWEHLHJkS50X0JS2IKz9Cgaj6ugrs= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.1 h1:4nm2G6A4pV9rdlWzGMPv4BNtQp22v1hg3yrtkYpeLl8= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.1/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 h1:moLQUoVq91LiqT1nbvzDukyqAlCv89ZmwaHw/ZFlFZg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15/go.mod h1:ZH34PJUc8ApjBIfgQCFvkWcUDBtl/WTD+uiYHjd8igA= +github.com/aws/aws-sdk-go-v2/service/s3 v1.79.3 h1:BRXS0U76Z8wfF+bnkilA2QwpIch6URlm++yPUt9QPmQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.79.3/go.mod h1:bNXKFFyaiVvWuR6O16h/I1724+aXe/tAkA9/QS01t5k= github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk= github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= diff --git a/parsers/js/api.go b/parsers/js/api.go index c99f70e..6cd28ae 100644 --- a/parsers/js/api.go +++ b/parsers/js/api.go @@ -1,3 +1,5 @@ +//go:build !no_jsparser + package js import ( diff --git a/parsers/js/api_playwright.go b/parsers/js/api_playwright.go index fbd04ff..68a41cd 100644 --- a/parsers/js/api_playwright.go +++ b/parsers/js/api_playwright.go @@ -1,3 +1,5 @@ +//go:build !no_jsparser && !no_playwright + package js import ( diff --git a/parsers/js/api_playwright_stub.go b/parsers/js/api_playwright_stub.go index 2a2b7c0..7b27cd0 100644 --- a/parsers/js/api_playwright_stub.go +++ b/parsers/js/api_playwright_stub.go @@ -1,4 +1,4 @@ -//go:build no_playwright +//go:build no_playwright && !no_jsparser package js diff --git a/parsers/js/js.go b/parsers/js/js.go index 0bc1570..32629cb 100644 --- a/parsers/js/js.go +++ b/parsers/js/js.go @@ -1,3 +1,5 @@ +//go:build !no_jsparser + package js import ( diff --git a/parsers/js/js_stub.go b/parsers/js/js_stub.go new file mode 100644 index 0000000..21eae10 --- /dev/null +++ b/parsers/js/js_stub.go @@ -0,0 +1,16 @@ +//go:build no_jsparser + +package js + +import ( + "context" + "errors" +) + +func LoadPlugins(ctx context.Context, dir string) error { + return errors.New("JS parser plugins are not supported in this build") +} + +func AddPlugin(ctx context.Context, code string, name string) error { + return errors.New("JS parser plugins are not supported in this build") +} diff --git a/parsers/js/plugin.go b/parsers/js/plugin.go index 404429d..71f4d23 100644 --- a/parsers/js/plugin.go +++ b/parsers/js/plugin.go @@ -1,3 +1,5 @@ +//go:build !no_jsparser + package js import "github.com/blang/semver" diff --git a/storage/minio/client.go b/storage/minio/client.go index 22ac9d9..c3811b6 100644 --- a/storage/minio/client.go +++ b/storage/minio/client.go @@ -1,3 +1,5 @@ +//go:build !no_minio + package minio import ( diff --git a/storage/minio/client_stub.go b/storage/minio/client_stub.go new file mode 100644 index 0000000..0c6601b --- /dev/null +++ b/storage/minio/client_stub.go @@ -0,0 +1,41 @@ +//go:build no_minio + +package minio + +import ( + "context" + "fmt" + "io" + "path" + "strings" + + config "github.com/krau/SaveAny-Bot/config/storage" + storenum "github.com/krau/SaveAny-Bot/pkg/enums/storage" +) + +type Minio struct { +} + +func (m *Minio) Init(_ context.Context, _ config.StorageConfig) error { + return fmt.Errorf("minio storage is not supported in this build") +} + +func (m *Minio) Type() storenum.StorageType { + return storenum.Minio +} + +func (m *Minio) Name() string { + return "" +} + +func (m *Minio) JoinStoragePath(p string) string { + return strings.TrimPrefix(path.Join("", p), "/") +} + +func (m *Minio) Save(_ context.Context, _ io.Reader, _ string) error { + return fmt.Errorf("minio storage is not supported in this build") +} + +func (m *Minio) Exists(_ context.Context, _ string) bool { + return false +}