diff --git a/.gitignore b/.gitignore index 4c78ead7..2a5970e3 100644 --- a/.gitignore +++ b/.gitignore @@ -61,7 +61,6 @@ out/ .idea/ local/data/ portainer-data/ -.env .husky/pre-commit # Logs @@ -138,13 +137,6 @@ web_modules/ # Yarn Integrity file .yarn-integrity -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - # parcel-bundler cache (https://parceljs.org/) .cache .parcel-cache diff --git a/Makefile b/Makefile index 94aaab39..ddd873f7 100644 --- a/Makefile +++ b/Makefile @@ -85,6 +85,28 @@ lint: @./scripts/lint.sh order_service @./scripts/lint.sh pkg +# https://github.com/golang-migrate/migrate/blob/856ea12df9d230b0145e23d951b7dbd6b86621cb/database/postgres/TUTORIAL.md +# https://github.com/golang-migrate/migrate/blob/856ea12df9d230b0145e23d951b7dbd6b86621cb/GETTING_STARTED.md +# https://github.com/golang-migrate/migrate/blob/856ea12df9d230b0145e23d951b7dbd6b86621cb/MIGRATIONS.md +# https://github.com/golang-migrate/migrate/tree/856ea12df9d230b0145e23d951b7dbd6b86621cb/cmd/migrate#usage +.PHONY: go-migrate +go-migrate: + @./scripts/go-migrate.sh -p ./internal/services/catalog_write_service/db/migrations/go-migrate -c create -n create_product_table + @./scripts/go-migrate.sh -p ./internal/services/catalog_write_service/db/migrations/go-migrate -c up -o postgres://postgres:postgres@localhost:5432/catalogs_service?sslmode=disable + @./scripts/go-migrate.sh -p ./internal/services/catalog_write_service/db/migrations/go-migrate -c down -o postgres://postgres:postgres@localhost:5432/catalogs_service?sslmode=disable + +# https://github.com/pressly/goose#usage +.PHONY: goose-migrate +goose-migrate: + @./scripts/goose-migrate.sh -p ./internal/services/catalog_write_service/db/migrations/goose-migrate -c create -n create_product_table + @./scripts/goose-migrate.sh -p ./internal/services/catalog_write_service/db/migrations/goose-migrate -c up -o "user=postgres password=postgres dbname=catalogs_service sslmode=disable" + @./scripts/goose-migrate.sh -p ./internal/services/catalog_write_service/db/migrations/goose-migrate -c down -o "user=postgres password=postgres dbname=catalogs_service sslmode=disable" + +# https://atlasgo.io/guides/orms/gorm +.PHONY: atlas +atlas: + @./scripts/atlas-migrate.sh -c gorm-sync -p "./internal/services/catalog_write_service" + @./scripts/atlas-migrate.sh -c apply -p "./internal/services/catalog_write_service" -o "postgres://postgres:postgres@localhost:5432/catalogs_service?sslmode=disable" #.PHONY: c4 #c4: diff --git a/internal/pkg/config/config_helper.go b/internal/pkg/config/config_helper.go index d70f8a88..9a83a632 100644 --- a/internal/pkg/config/config_helper.go +++ b/internal/pkg/config/config_helper.go @@ -30,9 +30,11 @@ func BindConfigKey[T any](configKey string, environments ...environemnt.Environm } // https://articles.wesionary.team/environment-variable-configuration-in-your-golang-project-using-viper-4e8289ef664d - configPathFromEnv := viper.Get(constants.ConfigPath) - if configPathFromEnv != nil { - configPath = configPathFromEnv.(string) + // when we `Set` a viper with string value, we should get it from viper with `viper.GetString`, elsewhere we get empty string + // load `config path` from environment variable or viper internal registry + configPathFromEnv := viper.GetString(constants.ConfigPath) + if configPathFromEnv != "" { + configPath = configPathFromEnv } else { // https://stackoverflow.com/questions/31873396/is-it-possible-to-get-the-current-root-of-package-structure-as-a-string-in-golan // https://stackoverflow.com/questions/18537257/how-to-get-the-directory-of-the-currently-running-file diff --git a/internal/pkg/config/configfx.go b/internal/pkg/config/configfx.go index 219bf9b7..b17ea753 100644 --- a/internal/pkg/config/configfx.go +++ b/internal/pkg/config/configfx.go @@ -19,7 +19,7 @@ var ModuleFunc = func(e environemnt.Environment) fx.Option { return fx.Module( "configfx", fx.Provide(func() environemnt.Environment { - return e + return environemnt.ConfigAppEnv(e) }), ) } diff --git a/internal/pkg/config/environemnt/environment.go b/internal/pkg/config/environemnt/environment.go index 9d337c2e..651d1f1d 100644 --- a/internal/pkg/config/environemnt/environment.go +++ b/internal/pkg/config/environemnt/environment.go @@ -3,10 +3,13 @@ package environemnt import ( "log" "os" + "path/filepath" + "strings" "syscall" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/constants" + "emperror.dev/errors" "github.com/joho/godotenv" "github.com/spf13/viper" ) @@ -32,11 +35,13 @@ func ConfigAppEnv(environments ...Environment) Environment { // https://articles.wesionary.team/environment-variable-configuration-in-your-golang-project-using-viper-4e8289ef664d // load environment variables form .env files to system environment variables, it just find `.env` file in our current `executing working directory` in our app for example `catalogs_service` - err := godotenv.Load() + err := loadEnvFilesRecursive() if err != nil { - log.Println(".env file cannot be found.") + log.Printf(".env file cannot be found, err: %v", err) } + setRootWorkingDirectoryEnvironment() + manualEnv := os.Getenv(constants.AppEnv) if manualEnv != "" { @@ -64,3 +69,69 @@ func EnvString(key, fallback string) string { } return fallback } + +func loadEnvFilesRecursive() error { + // Start from the current working directory + dir, err := os.Getwd() + if err != nil { + return err + } + + // Keep traversing up the directory hierarchy until you find an ".env" file + for { + envFilePath := filepath.Join(dir, ".env") + err := godotenv.Load(envFilePath) + + if err == nil { + // .env file found and loaded + return nil + } + + // Move up one directory level + parentDir := filepath.Dir(dir) + if parentDir == dir { + // Reached the root directory, stop searching + break + } + + dir = parentDir + } + + return errors.New(".env file not found in the project hierarchy") +} + +func setRootWorkingDirectoryEnvironment() { + // https://articles.wesionary.team/environment-variable-configuration-in-your-golang-project-using-viper-4e8289ef664d + // when we `Set` a viper with string value, we should get it from viper with `viper.GetString`, elsewhere we get empty string + // viper will get it from `os env` or a .env file + pn := viper.GetString(constants.PROJECT_NAME_ENV) + if pn == "" { + log.Fatalf( + "can't find environment variable `%s` in the system environment variables or a .env file", + constants.PROJECT_NAME_ENV, + ) + } + + // set root working directory of our app in the viper + // https://stackoverflow.com/a/47785436/581476 + wd, _ := os.Getwd() + + for !strings.HasSuffix(wd, pn) { + wd = filepath.Dir(wd) + } + + absoluteRootWorkingDirectory, _ := filepath.Abs(wd) + + // when we `Set` a viper with string value, we should get it from viper with `viper.GetString`, elsewhere we get empty string + viper.Set(constants.AppRootPath, absoluteRootWorkingDirectory) + + configPath := viper.GetString(constants.ConfigPath) + + // check for existing `CONFIG_PATH` variable in system environment variables - we can set it directly in .env file or system environments + if configPath == "" { + configPath := filepath.Join(absoluteRootWorkingDirectory, "config") + + // when we `Set` a viper with string value, we should get it from viper with `viper.GetString`, elsewhere we get empty string + viper.Set(constants.ConfigPath, configPath) + } +} diff --git a/internal/pkg/fxapp/application_builder.go b/internal/pkg/fxapp/application_builder.go index df8c845e..af0ca4c8 100644 --- a/internal/pkg/fxapp/application_builder.go +++ b/internal/pkg/fxapp/application_builder.go @@ -1,12 +1,7 @@ package fxapp import ( - "os" - "path/filepath" - "strings" - "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/config/environemnt" - "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/constants" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/fxapp/contracts" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger" loggerConfig "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger/config" @@ -14,7 +9,6 @@ import ( "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger/models" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger/zap" - "github.com/spf13/viper" "go.uber.org/fx" ) @@ -29,8 +23,6 @@ type applicationBuilder struct { func NewApplicationBuilder(environments ...environemnt.Environment) contracts.ApplicationBuilder { env := environemnt.ConfigAppEnv(environments...) - setConfigPath() - var logger logger.Logger logoption, err := loggerConfig.ProvideLogConfig(env) if err != nil || logoption == nil { @@ -44,31 +36,6 @@ func NewApplicationBuilder(environments ...environemnt.Environment) contracts.Ap return &applicationBuilder{logger: logger, environment: env} } -func setConfigPath() { - // https://stackoverflow.com/a/47785436/581476 - wd, _ := os.Getwd() - - // https://articles.wesionary.team/environment-variable-configuration-in-your-golang-project-using-viper-4e8289ef664d - // get from `os env` or viper `internal registry` - pn := viper.Get(constants.PROJECT_NAME_ENV) - if pn == nil { - return - } - for !strings.HasSuffix(wd, pn.(string)) { - wd = filepath.Dir(wd) - } - - // Get the absolute path of the executed project directory - absCurrentDir, _ := filepath.Abs(wd) - - viper.Set(constants.AppRootPath, absCurrentDir) - - // Get the path to the "config" folder within the project directory - configPath := filepath.Join(absCurrentDir, "config") - - viper.Set(constants.ConfigPath, configPath) -} - func (a *applicationBuilder) ProvideModule(module fx.Option) { a.options = append(a.options, module) } diff --git a/internal/pkg/fxapp/contracts/application_builder.go b/internal/pkg/fxapp/contracts/application_builder.go index 331632c7..c138a8a2 100644 --- a/internal/pkg/fxapp/contracts/application_builder.go +++ b/internal/pkg/fxapp/contracts/application_builder.go @@ -8,7 +8,9 @@ import ( ) type ApplicationBuilder interface { + // ProvideModule register modules directly instead and modules should not register with `provided` function ProvideModule(module fx.Option) + // Provide register functions constructors as dependency resolver Provide(constructors ...interface{}) Decorate(constructors ...interface{}) Build() Application diff --git a/internal/pkg/fxapp/test/test_application.go b/internal/pkg/fxapp/test/test_application.go index 17fee1fa..706de421 100644 --- a/internal/pkg/fxapp/test/test_application.go +++ b/internal/pkg/fxapp/test/test_application.go @@ -2,11 +2,14 @@ package test import ( "context" + "os" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/config/environemnt" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/constants" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/fxapp/contracts" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger" + "github.com/spf13/viper" "go.uber.org/fx" "go.uber.org/fx/fxtest" ) @@ -61,16 +64,8 @@ func (a *testApplication) RegisterHook(function interface{}) { } func (a *testApplication) Run() { - // build phase of container will do in this stage, containing provides and invokes but app not started yet and will be started in the future with `fxApp.Register` - fxTestApp := CreateFxTestApp( - a.tb, - a.provides, - a.decorates, - a.invokes, - a.options, - a.logger, - a.env, - ) + fxTestApp := a.createFxTest() + // running phase will do in this stage and all register event hooks like OnStart and OnStop // instead of run for handling start and stop and create a ctx and cancel we can handle them manually with appconfigfx.start and appconfigfx.stop // https://github.com/uber-go/fx/blob/v1.20.0/app.go#L573 @@ -79,10 +74,9 @@ func (a *testApplication) Run() { func (a *testApplication) Start(ctx context.Context) error { // build phase of container will do in this stage, containing provides and invokes but app not started yet and will be started in the future with `fxApp.Register` - fxApp := CreateFxTestApp(a.tb, a.provides, a.decorates, a.invokes, a.options, a.logger, a.env) - a.fxtestApp = fxApp + fxTestApp := a.createFxTest() - return fxApp.Start(ctx) + return fxTestApp.Start(ctx) } func (a *testApplication) Stop(ctx context.Context) error { @@ -98,3 +92,34 @@ func (a *testApplication) Wait() <-chan fx.ShutdownSignal { } return a.fxtestApp.Wait() } + +func (a *testApplication) createFxTest() *fxtest.App { + a.fixTestEnvironmentWorkingDirectory() + + // build phase of container will do in this stage, containing provides and invokes but app not started yet and will be started in the future with `fxApp.Register` + fxTestApp := CreateFxTestApp( + a.tb, + a.provides, + a.decorates, + a.invokes, + a.options, + a.logger, + a.env, + ) + a.fxtestApp = fxTestApp + + return fxTestApp +} + +func (a *testApplication) fixTestEnvironmentWorkingDirectory() { + currentWD, _ := os.Getwd() + a.logger.Infof("Current test working directory is: %s", currentWD) + + rootDir := viper.GetString(constants.AppRootPath) + if rootDir != "" { + _ = os.Chdir(rootDir) + + newWD, _ := os.Getwd() + a.logger.Infof("New test working directory is: %s", newWD) + } +} diff --git a/internal/pkg/go.mod b/internal/pkg/go.mod index 2d190e09..ffb1bcb7 100644 --- a/internal/pkg/go.mod +++ b/internal/pkg/go.mod @@ -11,6 +11,7 @@ require ( github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de github.com/avast/retry-go v3.0.0+incompatible github.com/caarlos0/env/v8 v8.0.0 + github.com/docker/docker v24.0.5+incompatible github.com/docker/go-connections v0.4.0 github.com/doug-martin/goqu/v9 v9.18.0 github.com/elastic/go-elasticsearch/v8 v8.9.0 @@ -33,11 +34,13 @@ require ( github.com/lib/pq v1.10.9 github.com/mcuadros/go-defaults v1.2.0 github.com/mehdihadeli/go-mediatr v1.1.10 + github.com/michaelklishin/rabbit-hole v1.5.0 github.com/mitchellh/mapstructure v1.5.0 github.com/nolleh/caption_json_formatter v0.2.2 github.com/orlangure/gnomock v0.30.0 github.com/ory/dockertest/v3 v3.10.0 github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 + github.com/pressly/goose/v3 v3.15.0 github.com/prometheus/client_golang v1.16.0 github.com/rabbitmq/amqp091-go v1.8.1 github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 @@ -90,7 +93,6 @@ require ( github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/docker/cli v24.0.5+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v24.0.5+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect github.com/elastic/elastic-transport-go/v8 v8.3.0 // indirect github.com/fatih/color v1.15.0 // indirect @@ -137,6 +139,7 @@ require ( github.com/moby/term v0.5.0 // indirect github.com/montanaflynn/stats v0.7.1 // indirect github.com/morikuni/aec v1.0.0 // indirect + github.com/nxadm/tail v1.4.8 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc4 // indirect github.com/opencontainers/runc v1.1.9 // indirect @@ -157,6 +160,7 @@ require ( github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/streadway/amqp v1.1.0 // indirect github.com/stretchr/objx v0.5.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect diff --git a/internal/pkg/go.sum b/internal/pkg/go.sum index bc8b8569..fb555b42 100644 --- a/internal/pkg/go.sum +++ b/internal/pkg/go.sum @@ -154,6 +154,8 @@ github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD github.com/doug-martin/goqu/v9 v9.18.0 h1:/6bcuEtAe6nsSMVK/M+fOiXUNfyFF3yYtE07DBPFMYY= github.com/doug-martin/goqu/v9 v9.18.0/go.mod h1:nf0Wc2/hV3gYK9LiyqIrzBEVGlI8qW3GuDCEobC4wBQ= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/elastic-transport-go/v8 v8.0.0-20230329154755-1a3c63de0db6/go.mod h1:87Tcz8IVNe6rVSLdBux1o/PEItLtyabHU3naC7IoqKI= github.com/elastic/elastic-transport-go/v8 v8.3.0 h1:DJGxovyQLXGr62e9nDMPSxRyWION0Bh6d9eCFBriiHo= github.com/elastic/elastic-transport-go/v8 v8.3.0/go.mod h1:87Tcz8IVNe6rVSLdBux1o/PEItLtyabHU3naC7IoqKI= @@ -173,6 +175,7 @@ github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= @@ -218,8 +221,9 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keL github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-migrate/migrate/v4 v4.16.2 h1:8coYbMKUyInrFk1lfGfRovTLAW7PhWp8qQDT2iKfuoA= github.com/golang-migrate/migrate/v4 v4.16.2/go.mod h1:pfcJX4nPHaVdc5nmdCikFBWtm+UBpiZjRNNsyBbp0/o= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -383,6 +387,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kamva/mgm/v3 v3.5.0 h1:/2mNshpqwAC9spdzJZ0VR/UZ/SY/PsNTrMjT111KQjM= github.com/kamva/mgm/v3 v3.5.0/go.mod h1:F4J1hZnXQMkqL3DZgR7Z7BOuiTqQG/JTic3YzliG4jk= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -444,6 +450,8 @@ github.com/mcuadros/go-defaults v1.2.0 h1:FODb8WSf0uGaY8elWJAkoLL0Ri6AlZ1bFlenk5 github.com/mcuadros/go-defaults v1.2.0/go.mod h1:WEZtHEVIGYVDqkKSWBdWKUVdRyKlMfulPaGDWIVeCWY= github.com/mehdihadeli/go-mediatr v1.1.10 h1:NAzg4065c90lgYeb+Vzbd2WKH0tUFpxzL0mpx6hkU/A= github.com/mehdihadeli/go-mediatr v1.1.10/go.mod h1:lwgZl7qVL/RKomObBblhG3uEte/r4nJDV95Vd+nGrMw= +github.com/michaelklishin/rabbit-hole v1.5.0 h1:Bex27BiFDsijCM9D0ezSHqyy0kehpYHuNKaPqq/a4RM= +github.com/michaelklishin/rabbit-hole v1.5.0/go.mod h1:vvI1uOitYZi0O5HEGXhaWC1XT80Gy+HvFheJ+5Krlhk= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= @@ -463,9 +471,15 @@ github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nolleh/caption_json_formatter v0.2.2 h1:EKsOr/fCllNQF2ZoajfbSDlV73BNV1bDu1aTTSRrlN0= github.com/nolleh/caption_json_formatter v0.2.2/go.mod h1:5FYofZA8NAej/eFxa12FvyQKosU1LfyKizZPlY0JojU= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -502,6 +516,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pressly/goose/v3 v3.15.0 h1:6tY5aDqFknY6VZkorFGgZtWygodZQxfmmEF4rqyJW9k= +github.com/pressly/goose/v3 v3.15.0/go.mod h1:LlIo3zGccjb/YUgG+Svdb9Er14vefRdlDI7URCDrwYo= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -520,6 +536,8 @@ github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnA github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= @@ -563,6 +581,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/streadway/amqp v1.1.0 h1:py12iX8XSyI7aN/3dUT8DFIDJazNJsVJdxNVEpnQTZM= +github.com/streadway/amqp v1.1.0/go.mod h1:WYSrTEYHOXHd0nwFeUXAe2G2hRnQT+deZJJf88uS9Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -845,6 +865,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1099,6 +1120,7 @@ gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8 gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1125,8 +1147,28 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= +lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= +modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= +modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= +modernc.org/ccgo/v3 v3.16.14 h1:af6KNtFgsVmnDYrWk3PQCS9XT6BXe7o3ZFJKkIKvXNQ= +modernc.org/ccgo/v3 v3.16.14/go.mod h1:mPDSujUIaTNWQSG4eqKw+atqLOEbma6Ncsa94WbC9zo= +modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM= +modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o= +modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA= +modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU= +modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/internal/pkg/migrate/migration_config.go b/internal/pkg/migrate/migration_config.go deleted file mode 100644 index 321e82ea..00000000 --- a/internal/pkg/migrate/migration_config.go +++ /dev/null @@ -1,14 +0,0 @@ -package migrate - -type MigrationConfig struct { - Host string `mapstructure:"host"` - Port int `mapstructure:"port"` - User string `mapstructure:"user"` - DBName string `mapstructure:"dbName"` - SSLMode bool `mapstructure:"sslMode"` - Password string `mapstructure:"password"` - VersionTable string `mapstructure:"versionTable"` - MigrationsDir string `mapstructure:"migrationsDir"` - TargetVersion uint `mapstructure:"targetVersion"` - SkipMigration bool `mapstructure:"skipMigration"` -} diff --git a/internal/pkg/migrate/mongo.go b/internal/pkg/migrate/mongo.go deleted file mode 100644 index cdfd0861..00000000 --- a/internal/pkg/migrate/mongo.go +++ /dev/null @@ -1,78 +0,0 @@ -package migrate - -import ( - "context" - "fmt" - "path/filepath" - "runtime" - - mongodb2 "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/mongodb" - - "emperror.dev/errors" - "github.com/golang-migrate/migrate/v4" - "github.com/golang-migrate/migrate/v4/database/mongodb" - "go.uber.org/zap" -) - -func (config *MigrationConfig) Migrate(ctx context.Context) error { - if config.SkipMigration { - zap.L().Info("database migration skipped") - return nil - } - - if config.DBName == "" { - return errors.New("DBName is required in the config.") - } - - db, err := mongodb2.NewMongoDB(&mongodb2.MongoDbOptions{ - Host: config.Host, - Port: config.Port, - User: config.User, - Password: config.Password, - Database: config.DBName, - UseAuth: false, - }) - if err != nil { - return err - } - - driver, err := mongodb.WithInstance( - db, - &mongodb.Config{DatabaseName: config.DBName, MigrationsCollection: config.VersionTable}, - ) - if err != nil { - return fmt.Errorf("failed to initialize migrator: %w", err) - } - - // determine the project's root path - _, callerPath, _, _ := runtime.Caller(1) // nolint:dogsled - - // look for migrations source starting from project's root dir - sourceURL := fmt.Sprintf( - "file://%s/../../%s", - filepath.ToSlash(filepath.Dir(callerPath)), - filepath.ToSlash(config.MigrationsDir), - ) - - mig, err := migrate.NewWithDatabaseInstance(sourceURL, config.DBName, driver) - if err != nil { - return fmt.Errorf("failed to initialize migrator: %w", err) - } - - if config.TargetVersion == 0 { - err = mig.Up() - } else { - err = mig.Migrate(config.TargetVersion) - } - - if err == migrate.ErrNoChange { - return nil - } - - zap.L().Info("migration finished") - if err != nil { - return fmt.Errorf("failed to migrate database: %w", err) - } - - return nil -} diff --git a/internal/pkg/migrate/postgres.go b/internal/pkg/migrate/postgres.go deleted file mode 100644 index 72820b7d..00000000 --- a/internal/pkg/migrate/postgres.go +++ /dev/null @@ -1,139 +0,0 @@ -package migrate - -import ( - "context" - "database/sql" - "fmt" - "path/filepath" - "runtime" - - "emperror.dev/errors" - "github.com/golang-migrate/migrate/v4" - "github.com/golang-migrate/migrate/v4/database/postgres" - "github.com/jackc/pgx/v4/pgxpool" - "go.uber.org/zap" -) - -// Up executes all migrations found at the given source path against the -// database specified by given DSN. -func Up(config *MigrationConfig) error { - if config.SkipMigration { - zap.L().Info("database migration skipped") - return nil - } - - if config.DBName == "" { - return errors.New("DBName is required in the config.") - } - - err := createDB(config, context.Background()) - if err != nil { - return err - } - - datasource := fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=disable", - config.User, - config.Password, - config.Host, - config.Port, - config.DBName, - ) - - db, err := sql.Open("postgres", datasource) - if err != nil { - return err - } - - driver, err := postgres.WithInstance(db, &postgres.Config{ - MigrationsTable: config.VersionTable, - DatabaseName: config.DBName, - }) - if err != nil { - return fmt.Errorf("failed to initialize migrator: %w", err) - } - - // determine the project's root path - _, callerPath, _, _ := runtime.Caller(1) // nolint:dogsled - - // look for migrations source starting from project's root dir - sourceURL := fmt.Sprintf( - "file://%s/../../%s", - filepath.ToSlash(filepath.Dir(callerPath)), - filepath.ToSlash(config.MigrationsDir), - ) - - migration, err := migrate.NewWithDatabaseInstance( - sourceURL, - config.DBName, - driver, - ) - if err != nil { - return fmt.Errorf("failed to initialize migrator: %w", err) - } - - if config.TargetVersion == 0 { - err = migration.Up() - } else { - err = migration.Migrate(config.TargetVersion) - } - - if err == migrate.ErrNoChange { - return nil - } - if err != nil { - return fmt.Errorf("failed to migrate database: %w", err) - } - zap.L().Info("migration finished") - - return nil -} - -func createDB(cfg *MigrationConfig, ctx context.Context) error { - // we should choose a default database in the connection, but because we don't have a database yet we specify postgres default database 'postgres' - datasource := fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=disable", - cfg.User, - cfg.Password, - cfg.Host, - cfg.Port, - "postgres", - ) - - poolCfg, err := pgxpool.ParseConfig(datasource) - if err != nil { - return err - } - - connPool, err := pgxpool.ConnectConfig(ctx, poolCfg) - if err != nil { - return errors.WrapIf(err, "pgx.ConnectConfig") - } - - var exists int - rows, err := connPool.Query( - context.Background(), - fmt.Sprintf("SELECT 1 FROM pg_catalog.pg_database WHERE datname='%s'", cfg.DBName), - ) - if err != nil { - return err - } - - if rows.Next() { - err = rows.Scan(&exists) - if err != nil { - return err - } - } - - if exists == 1 { - return nil - } - - _, err = connPool.Exec(context.Background(), fmt.Sprintf("CREATE DATABASE %s", cfg.DBName)) - if err != nil { - return err - } - - defer connPool.Close() - - return nil -} diff --git a/internal/pkg/migration/contracts/migration_runner.go b/internal/pkg/migration/contracts/migration_runner.go new file mode 100644 index 00000000..f2052531 --- /dev/null +++ b/internal/pkg/migration/contracts/migration_runner.go @@ -0,0 +1,8 @@ +package contracts + +import "context" + +type PostgresMigrationRunner interface { + Up(ctx context.Context, version uint) error + Down(ctx context.Context, version uint) error +} diff --git a/internal/pkg/migration/gomigrate/gomigrate_fx.go b/internal/pkg/migration/gomigrate/gomigrate_fx.go new file mode 100644 index 00000000..97b9874c --- /dev/null +++ b/internal/pkg/migration/gomigrate/gomigrate_fx.go @@ -0,0 +1,21 @@ +package gomigrate + +import ( + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/migration" + + "go.uber.org/fx" +) + +var ( + // Module provided to fxlog + // https://uber-go.github.io/fx/modules.html + Module = fx.Module( //nolint:gochecknoglobals + "gomigratefx", + mongoProviders, + ) + + mongoProviders = fx.Provide( //nolint:gochecknoglobals + migration.ProvideConfig, + NewGoMigratorPostgres, + ) +) diff --git a/internal/pkg/migration/gomigrate/postgres.go b/internal/pkg/migration/gomigrate/postgres.go new file mode 100644 index 00000000..8d71d44a --- /dev/null +++ b/internal/pkg/migration/gomigrate/postgres.go @@ -0,0 +1,136 @@ +package gomigrate + +// https://github.com/golang-migrate/migrate/blob/856ea12df9d230b0145e23d951b7dbd6b86621cb/database/postgres/TUTORIAL.md#optional-run-migrations-within-your-go-app + +import ( + "context" + "database/sql" + "fmt" + + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/migration" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/migration/contracts" + + "emperror.dev/errors" + "github.com/golang-migrate/migrate/v4" + + _ "github.com/golang-migrate/migrate/v4/database/postgres" + _ "github.com/golang-migrate/migrate/v4/source/file" +) + +type goMigratePostgresMigrator struct { + config *migration.MigrationOptions + db *sql.DB + datasource string + logger logger.Logger + migration *migrate.Migrate +} + +func NewGoMigratorPostgres( + config *migration.MigrationOptions, + db *sql.DB, + logger logger.Logger, +) (contracts.PostgresMigrationRunner, error) { + if config.DBName == "" { + return nil, errors.New("DBName is required in the config.") + } + + datasource := fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=disable", + config.User, + config.Password, + config.Host, + config.Port, + config.DBName, + ) + + // In test environment, ewe need a fix for applying application working directory correctly. we will apply this in our environment setup process in `config/environment` file + migration, err := migrate.New(fmt.Sprintf("file://%s", config.MigrationsDir), datasource) + if err != nil { + return nil, errors.WrapIf(err, "failed to initialize migrator") + } + + return &goMigratePostgresMigrator{ + config: config, + db: db, + datasource: datasource, + logger: logger, + migration: migration, + }, nil +} + +func (m *goMigratePostgresMigrator) Up(_ context.Context, version uint) error { + if m.config.SkipMigration { + m.logger.Info("database migration skipped") + + return nil + } + + err := m.executeCommand(migration.Up, version) + + if errors.Is(err, migrate.ErrNoChange) { + return nil + } + + if errors.Is(err, migrate.ErrNoChange) { + return nil + } + + if err != nil { + return errors.WrapIf(err, "failed to migrate database") + } + + m.logger.Info("migration finished") + + return nil +} + +func (m *goMigratePostgresMigrator) Down(_ context.Context, version uint) error { + if m.config.SkipMigration { + m.logger.Info("database migration skipped") + + return nil + } + + err := m.executeCommand(migration.Up, version) + + if errors.Is(err, migrate.ErrNoChange) { + return nil + } + + if err != nil { + return errors.WrapIf(err, "failed to migrate database") + } + + m.logger.Info("migration finished") + + return nil +} + +func (m *goMigratePostgresMigrator) executeCommand(command migration.CommandType, version uint) error { + var err error + switch command { + case migration.Up: + if version == 0 { + err = m.migration.Up() + } else { + err = m.migration.Migrate(version) + } + case migration.Down: + if version == 0 { + err = m.migration.Down() + } else { + err = m.migration.Migrate(version) + } + default: + err = errors.New("invalid migration direction") + } + + if err == migrate.ErrNoChange { + return nil + } + if err != nil { + return errors.WrapIf(err, "failed to migrate database") + } + + return nil +} diff --git a/internal/pkg/migration/goose/goose_fx.go b/internal/pkg/migration/goose/goose_fx.go new file mode 100644 index 00000000..6f1547d2 --- /dev/null +++ b/internal/pkg/migration/goose/goose_fx.go @@ -0,0 +1,21 @@ +package goose + +import ( + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/migration" + + "go.uber.org/fx" +) + +var ( + // Module provided to fxlog + // https://uber-go.github.io/fx/modules.html + Module = fx.Module( //nolint:gochecknoglobals + "goosefx", + mongoProviders, + ) + + mongoProviders = fx.Provide( //nolint:gochecknoglobals + migration.ProvideConfig, + NewGoosePostgres, + ) +) diff --git a/internal/pkg/migration/goose/postgres.go b/internal/pkg/migration/goose/postgres.go new file mode 100644 index 00000000..91e3d0c3 --- /dev/null +++ b/internal/pkg/migration/goose/postgres.go @@ -0,0 +1,64 @@ +package goose + +// https://github.com/pressly/goose#embedded-sql-migrations + +import ( + "context" + "database/sql" + "errors" + "strconv" + + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger" + migration "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/migration" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/migration/contracts" + + "github.com/pressly/goose/v3" +) + +type goosePostgresMigrator struct { + config *migration.MigrationOptions + db *sql.DB + logger logger.Logger +} + +func NewGoosePostgres( + config *migration.MigrationOptions, + db *sql.DB, + logger logger.Logger, +) contracts.PostgresMigrationRunner { + goose.SetBaseFS(nil) + + return &goosePostgresMigrator{config: config, db: db, logger: logger} +} + +func (m *goosePostgresMigrator) Up(_ context.Context, version uint) error { + err := m.executeCommand(migration.Up, version) + + return err +} + +func (m *goosePostgresMigrator) Down(_ context.Context, version uint) error { + err := m.executeCommand(migration.Down, version) + + return err +} + +func (m *goosePostgresMigrator) executeCommand(command migration.CommandType, version uint) error { + switch command { + case migration.Up: + if version == 0 { + // In test environment, ewe need a fix for applying application working directory correctly. we will apply this in our environment setup process in `config/environment` file + return goose.Run("up", m.db, m.config.MigrationsDir) + } + + return goose.Run("up-to VERSION ", m.db, m.config.MigrationsDir, strconv.FormatUint(uint64(version), 10)) + case migration.Down: + if version == 0 { + return goose.Run("down", m.db, m.config.MigrationsDir) + } + + return goose.Run("down-to VERSION ", m.db, m.config.MigrationsDir, strconv.FormatUint(uint64(version), 10)) + default: + return errors.New("invalid migration direction") + } +} diff --git a/internal/pkg/migration/migration_options.go b/internal/pkg/migration/migration_options.go new file mode 100644 index 00000000..99997a0e --- /dev/null +++ b/internal/pkg/migration/migration_options.go @@ -0,0 +1,34 @@ +package migration + +import ( + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/config" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/config/environemnt" + typeMapper "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/reflection/type_mappper" + + "github.com/iancoleman/strcase" +) + +type CommandType string + +const ( + Up CommandType = "up" + Down CommandType = "down" +) + +type MigrationOptions struct { + Host string `mapstructure:"host"` + Port int `mapstructure:"port"` + User string `mapstructure:"user"` + DBName string `mapstructure:"dbName"` + SSLMode bool `mapstructure:"sslMode"` + Password string `mapstructure:"password"` + VersionTable string `mapstructure:"versionTable"` + MigrationsDir string `mapstructure:"migrationsDir"` + SkipMigration bool `mapstructure:"skipMigration"` +} + +func ProvideConfig(environment environemnt.Environment) (*MigrationOptions, error) { + optionName := strcase.ToLowerCamel(typeMapper.GetTypeNameByT[MigrationOptions]()) + + return config.BindConfigKey[*MigrationOptions](optionName, environment) +} diff --git a/internal/pkg/mongodb/mongo_options.go b/internal/pkg/mongodb/mongo_options.go index 3d218cd4..46ba2f6b 100644 --- a/internal/pkg/mongodb/mongo_options.go +++ b/internal/pkg/mongodb/mongo_options.go @@ -8,8 +8,6 @@ import ( "github.com/iancoleman/strcase" ) -var optionName = strcase.ToLowerCamel(typeMapper.GetTypeNameByT[MongoDbOptions]()) - type MongoDbOptions struct { Host string `mapstructure:"host"` Port int `mapstructure:"port"` @@ -20,5 +18,6 @@ type MongoDbOptions struct { } func provideConfig(environment environemnt.Environment) (*MongoDbOptions, error) { + optionName := strcase.ToLowerCamel(typeMapper.GetTypeNameByT[MongoDbOptions]()) return config.BindConfigKey[*MongoDbOptions](optionName, environment) } diff --git a/internal/pkg/test/containers/contracts/rabbitmq_container.go b/internal/pkg/test/containers/contracts/rabbitmq_container.go index 268ef396..5f012fa5 100644 --- a/internal/pkg/test/containers/contracts/rabbitmq_container.go +++ b/internal/pkg/test/containers/contracts/rabbitmq_container.go @@ -2,6 +2,7 @@ package contracts import ( "context" + "fmt" "testing" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/core/serializer" @@ -23,6 +24,14 @@ type RabbitMQContainerOptions struct { Tag string } +func (h *RabbitMQContainerOptions) AmqpEndPoint() string { + return fmt.Sprintf("amqp://%s:%s@%s:%d", h.UserName, h.Password, h.Host, h.HostPort) +} + +func (h *RabbitMQContainerOptions) HttpEndPoint() string { + return fmt.Sprintf("http://%s:%d", h.Host, h.HttpPort) +} + type RabbitMQContainer interface { Start(ctx context.Context, t *testing.T, diff --git a/internal/pkg/test/containers/testcontainer/rabbitmq/rabbitmq_container.go b/internal/pkg/test/containers/testcontainer/rabbitmq/rabbitmq_container.go index 5baf874a..9c3af822 100644 --- a/internal/pkg/test/containers/testcontainer/rabbitmq/rabbitmq_container.go +++ b/internal/pkg/test/containers/testcontainer/rabbitmq/rabbitmq_container.go @@ -18,6 +18,7 @@ import ( "emperror.dev/errors" "github.com/docker/docker/api/types/container" "github.com/docker/go-connections/nat" + rabbithole "github.com/michaelklishin/rabbit-hole" "github.com/rabbitmq/amqp091-go" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" @@ -79,7 +80,10 @@ func (g *rabbitmqTestContainers) CreatingContainerOptions( }) // get a free random host port for rabbitmq `Tcp Port` - hostPort, err := dbContainer.MappedPort(ctx, nat.Port(g.defaultOptions.Ports[0])) + hostPort, err := dbContainer.MappedPort( + ctx, + nat.Port(g.defaultOptions.Ports[0]), + ) if err != nil { return nil, err } @@ -88,7 +92,10 @@ func (g *rabbitmqTestContainers) CreatingContainerOptions( // https://github.com/michaelklishin/rabbit-hole/issues/74 // get a free random host port for rabbitmq UI `Http Port` - uiHttpPort, err := dbContainer.MappedPort(ctx, nat.Port(g.defaultOptions.Ports[1])) + uiHttpPort, err := dbContainer.MappedPort( + ctx, + nat.Port(g.defaultOptions.Ports[1]), + ) if err != nil { return nil, err } @@ -136,7 +143,9 @@ func (g *rabbitmqTestContainers) Start( rabbitHostOptions.AmqpEndPoint(), ) - rabbitmqConfig := &config.RabbitmqOptions{RabbitmqHostOptions: rabbitHostOptions} + rabbitmqConfig := &config.RabbitmqOptions{ + RabbitmqHostOptions: rabbitHostOptions, + } conn, err := types.NewRabbitMQConnection(rabbitmqConfig) if err != nil { return nil, err @@ -189,9 +198,15 @@ func (g *rabbitmqTestContainers) getRunOptions( } } containerReq := testcontainers.ContainerRequest{ - Image: fmt.Sprintf("%s:%s", g.defaultOptions.ImageName, g.defaultOptions.Tag), + Image: fmt.Sprintf( + "%s:%s", + g.defaultOptions.ImageName, + g.defaultOptions.Tag, + ), ExposedPorts: g.defaultOptions.Ports, - WaitingFor: wait.ForListeningPort(nat.Port(g.defaultOptions.Ports[0])), + WaitingFor: wait.ForListeningPort( + nat.Port(g.defaultOptions.Ports[0]), + ), HostConfigModifier: func(hostConfig *container.HostConfig) { hostConfig.AutoRemove = true }, @@ -205,12 +220,19 @@ func (g *rabbitmqTestContainers) getRunOptions( return containerReq } -func IsConnectable(logger logger.Logger, options *contracts.RabbitMQContainerOptions) bool { - conn, err := amqp091.Dial( - fmt.Sprintf("amqp://%s:%s@%s:%d", options.UserName, options.Password, options.Host, options.HostPort), - ) +func IsConnectable( + logger logger.Logger, + options *contracts.RabbitMQContainerOptions, +) bool { + conn, err := amqp091.Dial(options.AmqpEndPoint()) if err != nil { - logError(logger, options.UserName, options.Password, options.Host, options.HostPort) + logError( + logger, + options.UserName, + options.Password, + options.Host, + options.HostPort, + ) return false } @@ -218,10 +240,33 @@ func IsConnectable(logger logger.Logger, options *contracts.RabbitMQContainerOpt defer conn.Close() if err != nil || (conn != nil && conn.IsClosed()) { - logError(logger, options.UserName, options.Password, options.Host, options.HostPort) + logError( + logger, + options.UserName, + options.Password, + options.Host, + options.HostPort, + ) return false } + + // https://github.com/michaelklishin/rabbit-hole + rmqc, err := rabbithole.NewClient( + options.HttpEndPoint(), + options.UserName, + options.Password, + ) + _, err = rmqc.ListExchanges() + if err != nil { + logger.Errorf( + "Error in creating rabbitmq connection with http host: %s", + options.HttpEndPoint(), + ) + + return false + } + logger.Infof( "Opened rabbitmq connection on host: amqp://%s:%s@%s:%d", options.UserName, @@ -233,9 +278,19 @@ func IsConnectable(logger logger.Logger, options *contracts.RabbitMQContainerOpt return true } -func logError(logger logger.Logger, userName string, password string, host string, hostPort int) { +func logError( + logger logger.Logger, + userName string, + password string, + host string, + hostPort int, +) { // we should not use `t.Error` or `t.Errorf` for logging errors because it will `fail` our test at the end and, we just should use logs without error like log.Error (not log.Fatal) logger.Errorf( - "Error in creating rabbitmq connection with host: amqp://%s:%s@%s:%d", userName, password, host, hostPort, + "Error in creating rabbitmq connection with amqp host: amqp://%s:%s@%s:%d", + userName, + password, + host, + hostPort, ) } diff --git a/internal/services/catalog_read_service/.env b/internal/services/catalog_read_service/.env new file mode 100644 index 00000000..c307987a --- /dev/null +++ b/internal/services/catalog_read_service/.env @@ -0,0 +1 @@ +PROJECT_NAME=catalog_read_service diff --git a/internal/services/catalog_read_service/Makefile b/internal/services/catalog_read_service/Makefile index 67393c12..8bdee48d 100644 --- a/internal/services/catalog_read_service/Makefile +++ b/internal/services/catalog_read_service/Makefile @@ -16,8 +16,8 @@ lint: .PHONY: format format: - goimports-reviser -company-prefixes "github.com/mehdihadeli" -project-name "github.com/mehdihadeli/go-ecommerce-microservices" -imports-order "std,general,company,project" -recursive ./... golines -m 120 -w --ignore-generated . + gci write --skip-generated -s standard -s "prefix(github.com/mehdihadeli/go-ecommerce-microservices)" -s default -s blank -s dot --custom-order . gofumpt -l -w . .PHONY: test diff --git a/internal/services/catalog_read_service/cmd/app/main.go b/internal/services/catalog_read_service/cmd/app/main.go index 20bc9250..65c67c0f 100644 --- a/internal/services/catalog_read_service/cmd/app/main.go +++ b/internal/services/catalog_read_service/cmd/app/main.go @@ -5,6 +5,8 @@ import ( "github.com/mehdihadeli/go-ecommerce-microservices/internal/services/catalogreadservice/internal/shared/app" + "github.com/pterm/pterm" + "github.com/pterm/pterm/putils" "github.com/spf13/cobra" ) @@ -26,6 +28,11 @@ var rootCmd = &cobra.Command{ // @version 1.0 // @description Catalogs Read-Service Api. func main() { + pterm.DefaultBigText.WithLetters( + putils.LettersFromStringWithStyle("Catalogs", pterm.FgLightGreen.ToStyle()), + putils.LettersFromStringWithStyle(" Read Service", pterm.FgLightMagenta.ToStyle())). + Render() + err := rootCmd.Execute() if err != nil { os.Exit(1) diff --git a/internal/services/catalog_read_service/go.mod b/internal/services/catalog_read_service/go.mod index 5b9a9988..e3343eb9 100644 --- a/internal/services/catalog_read_service/go.mod +++ b/internal/services/catalog_read_service/go.mod @@ -15,11 +15,11 @@ require ( github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg v0.0.0-20230831075934-be8df319f588 github.com/mehdihadeli/go-mediatr v1.1.10 github.com/michaelklishin/rabbit-hole v1.5.0 + github.com/pterm/pterm v0.12.69 github.com/redis/go-redis/v9 v9.0.5 github.com/satori/go.uuid v1.2.0 github.com/smartystreets/goconvey v1.8.1 github.com/spf13/cobra v1.7.0 - github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 github.com/swaggo/echo-swagger v1.4.1 github.com/swaggo/swag v1.16.2 @@ -31,13 +31,15 @@ require ( ) require ( + atomicgo.dev/cursor v0.2.0 // indirect + atomicgo.dev/keyboard v0.2.9 // indirect + atomicgo.dev/schedule v0.1.0 // indirect dario.cat/mergo v1.0.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/EventStore/EventStore-Client-Go v1.0.2 // indirect github.com/KyleBanks/depth v1.2.1 // indirect github.com/Masterminds/squirrel v1.5.4 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2 // indirect github.com/ahmetb/go-linq/v3 v3.2.0 // indirect github.com/ajg/form v1.5.1 // indirect @@ -48,12 +50,11 @@ require ( github.com/caarlos0/env/v8 v8.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/containerd/console v1.0.3 // indirect github.com/containerd/containerd v1.7.5 // indirect - github.com/containerd/continuity v0.4.2 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/docker/cli v24.0.5+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.5+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect @@ -81,14 +82,13 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.1 // indirect + github.com/gookit/color v1.5.4 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect github.com/imkira/go-interpol v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect @@ -112,10 +112,12 @@ require ( github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/leodido/go-urn v1.2.4 // indirect + github.com/lithammer/fuzzysearch v1.1.8 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mcuadros/go-defaults v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -130,7 +132,6 @@ require ( github.com/opencontainers/image-spec v1.1.0-rc4 // indirect github.com/opencontainers/runc v1.1.9 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect - github.com/ory/dockertest/v3 v3.10.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -141,6 +142,7 @@ require ( github.com/rabbitmq/amqp091-go v1.8.1 // indirect github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/samber/lo v1.38.1 // indirect github.com/sergi/go-diff v1.2.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect @@ -149,6 +151,7 @@ require ( github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.16.0 // indirect github.com/streadway/amqp v1.1.0 // indirect github.com/stretchr/objx v0.5.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect @@ -168,6 +171,7 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect github.com/yudai/gojsondiff v1.0.0 // indirect @@ -190,6 +194,7 @@ require ( golang.org/x/net v0.15.0 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.12.0 // indirect + golang.org/x/term v0.12.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.13.0 // indirect diff --git a/internal/services/catalog_read_service/go.sum b/internal/services/catalog_read_service/go.sum index a88926a8..861a54b6 100644 --- a/internal/services/catalog_read_service/go.sum +++ b/internal/services/catalog_read_service/go.sum @@ -1,3 +1,11 @@ +atomicgo.dev/assert v0.0.2 h1:FiKeMiZSgRrZsPo9qn/7vmr7mCsh5SZyXY4YGYiYwrg= +atomicgo.dev/assert v0.0.2/go.mod h1:ut4NcI3QDdJtlmAxQULOmA13Gz6e2DWbSAS8RUOmNYQ= +atomicgo.dev/cursor v0.2.0 h1:H6XN5alUJ52FZZUkI7AlJbUc1aW38GWZalpYRPpoPOw= +atomicgo.dev/cursor v0.2.0/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU= +atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8= +atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ= +atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs= +atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU= bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -59,6 +67,15 @@ github.com/EventStore/EventStore-Client-Go v1.0.2 h1:onM2TIInLhWUJwUQ/5a/8blNrrb github.com/EventStore/EventStore-Client-Go v1.0.2/go.mod h1:NOqSOtNxqGizr1Qnf7joGGLK6OkeoLV/QEI893A43H0= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= +github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= +github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= +github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k= +github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI= +github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c= +github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE= +github.com/MarvinJWendt/testza v0.5.2 h1:53KDo64C1z/h/d/stCYCPY69bt/OSwjq5KpFNwi+zB4= +github.com/MarvinJWendt/testza v0.5.2/go.mod h1:xu53QFE5sCdjtMCKk8YMQ2MnymimEctc4n3EjyIYvEY= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= @@ -81,6 +98,7 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/ github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -116,6 +134,8 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWH github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.7.5 h1:i9T9XpAWMe11BHMN7pu1BZqOGjXaKTPyz2v+KYOZgkY= github.com/containerd/containerd v1.7.5/go.mod h1:ieJNCSzASw2shSGYLHx8NAE7WsZ/gEigo5fQ78W5Zvw= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -212,7 +232,6 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator v9.31.0+incompatible h1:UA72EPEogEnq76ehGdEDp4Mit+3FDh548oRqwVgNsHA= github.com/go-playground/validator v9.31.0+incompatible/go.mod h1:yrEkQXlcI+PugkyDjY2bRrL/UBU4f3rvrgkN3V8JEig= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -306,6 +325,10 @@ github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= +github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= +github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= +github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e h1:XmA6L9IPRdUr28a+SK/oMchGgQy159wvzXA5tJ7l+40= github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e/go.mod h1:AFIo+02s+12CEg8Gzz9kzhCbmbq6JcKNrhHffCGA9z4= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= @@ -409,6 +432,11 @@ github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8 github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -440,6 +468,8 @@ github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= +github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -461,6 +491,9 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -538,6 +571,15 @@ github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdO github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI= +github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg= +github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE= +github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU= +github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= +github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= +github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= +github.com/pterm/pterm v0.12.69 h1:fBCKnB8dSLAl8FlYRQAWYGp2WTI/Xm/tKJ21Hyo9USw= +github.com/pterm/pterm v0.12.69/go.mod h1:wl06ko9MHnqxz4oDV++IORDpjCzw6+mfrvf0MPj6fdk= github.com/rabbitmq/amqp091-go v1.8.1 h1:RejT1SBUim5doqcL6s7iN6SBmsQqyTgXb1xMlH0h1hA= github.com/rabbitmq/amqp091-go v1.8.1/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc= github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho= @@ -546,6 +588,9 @@ github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnAfVjZNvfJTYfPetfZk5yoSTLaQ= github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= @@ -665,6 +710,9 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= @@ -804,6 +852,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -871,6 +920,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -932,8 +982,10 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -945,8 +997,12 @@ golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -958,6 +1014,7 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1025,6 +1082,7 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/services/catalog_read_service/internal/shared/app/test/test_application_builder.go b/internal/services/catalog_read_service/internal/shared/app/test/test_application_builder.go index 9fcc3c1b..44c2576a 100644 --- a/internal/services/catalog_read_service/internal/shared/app/test/test_application_builder.go +++ b/internal/services/catalog_read_service/internal/shared/app/test/test_application_builder.go @@ -1,12 +1,9 @@ package test import ( - "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/constants" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/fxapp/contracts" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/fxapp/test" - constants2 "github.com/mehdihadeli/go-ecommerce-microservices/internal/services/catalogreadservice/internal/shared/constants" - "github.com/spf13/viper" "go.uber.org/fx/fxtest" ) @@ -16,9 +13,6 @@ type CatalogsReadTestApplicationBuilder struct { } func NewCatalogsReadTestApplicationBuilder(tb fxtest.TB) *CatalogsReadTestApplicationBuilder { - // set viper internal registry, in real app we read it from `.env` file in current `executing working directory` for example `catalogs_service` - viper.Set(constants.PROJECT_NAME_ENV, constants2.PROJECT_NAME) - return &CatalogsReadTestApplicationBuilder{ ApplicationBuilder: test.NewTestApplicationBuilder(tb), tb: tb, diff --git a/internal/services/catalog_read_service/internal/shared/constants/constants.go b/internal/services/catalog_read_service/internal/shared/constants/constants.go deleted file mode 100644 index 83ffce79..00000000 --- a/internal/services/catalog_read_service/internal/shared/constants/constants.go +++ /dev/null @@ -1,5 +0,0 @@ -package constants - -const ( - PROJECT_NAME = "catalog_read_service" -) diff --git a/internal/services/catalog_read_service/internal/shared/test_fixture/integration/integration_test_fixture.go b/internal/services/catalog_read_service/internal/shared/test_fixture/integration/integration_test_fixture.go index 93501cca..2dbb824a 100644 --- a/internal/services/catalog_read_service/internal/shared/test_fixture/integration/integration_test_fixture.go +++ b/internal/services/catalog_read_service/internal/shared/test_fixture/integration/integration_test_fixture.go @@ -2,7 +2,6 @@ package integration import ( "context" - "fmt" "testing" "time" @@ -21,7 +20,6 @@ import ( "github.com/brianvoe/gofakeit/v6" rabbithole "github.com/michaelklishin/rabbit-hole" uuid "github.com/satori/go.uuid" - "github.com/stretchr/testify/require" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "go.opentelemetry.io/otel/trace" @@ -43,16 +41,19 @@ type IntegrationTestSharedFixture struct { Tracer trace.Tracer } -func NewIntegrationTestSharedFixture(t *testing.T) *IntegrationTestSharedFixture { +func NewIntegrationTestSharedFixture( + t *testing.T, +) *IntegrationTestSharedFixture { result := test.NewTestApp().Run(t) // https://github.com/michaelklishin/rabbit-hole rmqc, err := rabbithole.NewClient( - fmt.Sprintf(result.RabbitmqOptions.RabbitmqHostOptions.HttpEndPoint()), + result.RabbitmqOptions.RabbitmqHostOptions.HttpEndPoint(), result.RabbitmqOptions.RabbitmqHostOptions.UserName, result.RabbitmqOptions.RabbitmqHostOptions.Password) - - require.NoError(t, err) + if err != nil { + result.Logger.Error(errors.WrapIf(err, "error in creating rabbithole client")) + } shared := &IntegrationTestSharedFixture{ Log: result.Logger, @@ -78,8 +79,9 @@ func (i *IntegrationTestSharedFixture) InitializeTest() { // seed data in each test res, err := seedData(i.mongoClient, i.MongoOptions.Database) if err != nil { - i.Log.Fatal(err) + i.Log.Error(errors.WrapIf(err, "error in seeding mongodb data")) } + i.Items = res } @@ -88,15 +90,18 @@ func (i *IntegrationTestSharedFixture) DisposeTest() { // cleanup test containers with their hooks if err := i.cleanupRabbitmqData(); err != nil { - i.Log.Fatal(err) + i.Log.Error(errors.WrapIf(err, "error in cleanup rabbitmq data")) } if err := i.cleanupMongoData(); err != nil { - i.Log.Fatal(err) + i.Log.Error(errors.WrapIf(err, "error in cleanup mongodb data")) } } -func seedData(db *mongo.Client, databaseName string) ([]*models.Product, error) { +func seedData( + db *mongo.Client, + databaseName string, +) ([]*models.Product, error) { ctx := context.Background() products := []*models.Product{ @@ -119,13 +124,18 @@ func seedData(db *mongo.Client, databaseName string) ([]*models.Product, error) } //// https://go.dev/doc/faq#convert_slice_of_interface - data := make([]interface{}, len(products)) + productsData := make([]interface{}, len(products)) + for i, v := range products { - data[i] = v + productsData[i] = v } collection := db.Database(databaseName).Collection("products") - _, err := collection.InsertMany(context.Background(), data, &options.InsertManyOptions{}) + _, err := collection.InsertMany( + context.Background(), + productsData, + &options.InsertManyOptions{}, + ) if err != nil { return nil, errors.WrapIf(err, "error in seed database") } @@ -136,13 +146,16 @@ func seedData(db *mongo.Client, databaseName string) ([]*models.Product, error) collection, nil, ) + return result.Items, nil } func (i *IntegrationTestSharedFixture) cleanupRabbitmqData() error { // https://github.com/michaelklishin/rabbit-hole // Get all queues - queues, err := i.RabbitmqCleaner.ListQueuesIn(i.rabbitmqOptions.RabbitmqHostOptions.VirtualHost) + queues, err := i.RabbitmqCleaner.ListQueuesIn( + i.rabbitmqOptions.RabbitmqHostOptions.VirtualHost, + ) if err != nil { return err } @@ -153,6 +166,7 @@ func (i *IntegrationTestSharedFixture) cleanupRabbitmqData() error { i.rabbitmqOptions.RabbitmqHostOptions.VirtualHost, queue.Name, ) + return err } @@ -161,11 +175,20 @@ func (i *IntegrationTestSharedFixture) cleanupRabbitmqData() error { func (i *IntegrationTestSharedFixture) cleanupMongoData() error { collections := []string{"products"} - err := cleanupCollections(i.mongoClient, collections, i.MongoOptions.Database) + err := cleanupCollections( + i.mongoClient, + collections, + i.MongoOptions.Database, + ) + return err } -func cleanupCollections(db *mongo.Client, collections []string, databaseName string) error { +func cleanupCollections( + db *mongo.Client, + collections []string, + databaseName string, +) error { database := db.Database(databaseName) ctx := context.Background() diff --git a/internal/services/catalog_read_service/test/integration/products/features/deleting_product/v1/commands/delete_product_test.go b/internal/services/catalog_read_service/test/integration/products/features/deleting_product/v1/commands/delete_product_test.go index d8464dfb..7deae9de 100644 --- a/internal/services/catalog_read_service/test/integration/products/features/deleting_product/v1/commands/delete_product_test.go +++ b/internal/services/catalog_read_service/test/integration/products/features/deleting_product/v1/commands/delete_product_test.go @@ -17,7 +17,9 @@ import ( ) func TestDeleteProduct(t *testing.T) { - integrationTestSharedFixture := integration.NewIntegrationTestSharedFixture(t) + integrationTestSharedFixture := integration.NewIntegrationTestSharedFixture( + t, + ) Convey("Deleting Product Feature", t, func() { ctx := context.Background() @@ -27,7 +29,9 @@ func TestDeleteProduct(t *testing.T) { // scenario Convey("Deleting an existing product from the database", func() { Convey("Given an existing product in the mongo database", func() { - productId, err := uuid.FromString(integrationTestSharedFixture.Items[0].ProductId) + productId, err := uuid.FromString( + integrationTestSharedFixture.Items[0].ProductId, + ) So(err, ShouldBeNil) command, err := commands.NewDeleteProduct(productId) @@ -39,18 +43,24 @@ func TestDeleteProduct(t *testing.T) { command, ) - Convey("Then the product should be deleted successfully in mongo database", func() { - So(err, ShouldBeNil) - So(result, ShouldNotBeNil) + Convey( + "Then the product should be deleted successfully in mongo database", + func() { + So(err, ShouldBeNil) + So(result, ShouldNotBeNil) - Convey("And the product should no longer exist in the system", func() { - deletedProduct, _ := integrationTestSharedFixture.ProductRepository.GetProductById( - ctx, - productId.String(), + Convey( + "And the product should no longer exist in the system", + func() { + deletedProduct, _ := integrationTestSharedFixture.ProductRepository.GetProductByProductId( + ctx, + productId.String(), + ) + So(deletedProduct, ShouldBeNil) + }, ) - So(deletedProduct, ShouldBeNil) - }) - }) + }, + ) }) }) }) diff --git a/internal/services/catalog_read_service/test/integration/products/features/updating_product/v1/events/product_updated_test.go b/internal/services/catalog_read_service/test/integration/products/features/updating_product/v1/events/product_updated_test.go index 6f7186ac..37282c39 100644 --- a/internal/services/catalog_read_service/test/integration/products/features/updating_product/v1/events/product_updated_test.go +++ b/internal/services/catalog_read_service/test/integration/products/features/updating_product/v1/events/product_updated_test.go @@ -23,7 +23,9 @@ import ( func TestProductUpdatedConsumer(t *testing.T) { // Setup and initialization code here. - integrationTestSharedFixture := integration.NewIntegrationTestSharedFixture(t) + integrationTestSharedFixture := integration.NewIntegrationTestSharedFixture( + t, + ) // in test mode we set rabbitmq `AutoStart=false` in configuration in rabbitmqOptions, so we should run rabbitmq bus manually integrationTestSharedFixture.Bus.Start(context.Background()) // wait for consumers ready to consume before publishing messages, preparation background workers takes a bit time (for preventing messages lost) @@ -52,62 +54,94 @@ func TestProductUpdatedConsumer(t *testing.T) { } Convey("When a ProductUpdated event consumed", func() { - err := integrationTestSharedFixture.Bus.PublishMessage(ctx, fakeUpdateProduct, nil) + err := integrationTestSharedFixture.Bus.PublishMessage( + ctx, + fakeUpdateProduct, + nil, + ) So(err, ShouldBeNil) - Convey("Then it should consume the ProductUpdated event", func() { - hypothesis.Validate(ctx, "there is no consumed message", 30*time.Second) - }) + Convey( + "Then it should consume the ProductUpdated event", + func() { + hypothesis.Validate( + ctx, + "there is no consumed message", + 30*time.Second, + ) + }, + ) }) }) // https://specflow.org/learn/gherkin/#learn-gherkin // scenario - Convey("Update product in mongo database when a ProductDeleted event consumed", func() { - fakeUpdateProduct := &externalEvents.ProductUpdatedV1{ - Message: types.NewMessage(uuid.NewV4().String()), - ProductId: integrationTestSharedFixture.Items[0].ProductId, - Name: gofakeit.Name(), - Price: gofakeit.Price(100, 1000), - Description: gofakeit.EmojiDescription(), - UpdatedAt: time.Now(), - } - - Convey("When a ProductUpdated event consumed", func() { - err := integrationTestSharedFixture.Bus.PublishMessage(ctx, fakeUpdateProduct, nil) - So(err, ShouldBeNil) - - Convey("It should update product in the mongo database", func() { - ctx := context.Background() - productUpdated := &externalEvents.ProductUpdatedV1{ - Message: types.NewMessage(uuid.NewV4().String()), - ProductId: integrationTestSharedFixture.Items[0].ProductId, - Name: gofakeit.Name(), - Description: gofakeit.AdjectiveDescriptive(), - Price: gofakeit.Price(150, 6000), - UpdatedAt: time.Now(), - } - - err := integrationTestSharedFixture.Bus.PublishMessage(ctx, productUpdated, nil) + Convey( + "Update product in mongo database when a ProductDeleted event consumed", + func() { + fakeUpdateProduct := &externalEvents.ProductUpdatedV1{ + Message: types.NewMessage(uuid.NewV4().String()), + ProductId: integrationTestSharedFixture.Items[0].ProductId, + Name: gofakeit.Name(), + Price: gofakeit.Price(100, 1000), + Description: gofakeit.EmojiDescription(), + UpdatedAt: time.Now(), + } + + Convey("When a ProductUpdated event consumed", func() { + err := integrationTestSharedFixture.Bus.PublishMessage( + ctx, + fakeUpdateProduct, + nil, + ) So(err, ShouldBeNil) - var product *models.Product - - err = testUtils.WaitUntilConditionMet(func() bool { - product, err = integrationTestSharedFixture.ProductRepository.GetProductByProductId( - ctx, - integrationTestSharedFixture.Items[0].ProductId, - ) - - return product != nil && product.Name == productUpdated.Name - }) - - So(err, ShouldBeNil) - So(product, ShouldNotBeNil) - So(productUpdated.ProductId, ShouldEqual, product.ProductId) + Convey( + "Then It should update product in the mongo database", + func() { + ctx := context.Background() + productUpdated := &externalEvents.ProductUpdatedV1{ + Message: types.NewMessage( + uuid.NewV4().String(), + ), + ProductId: integrationTestSharedFixture.Items[0].ProductId, + Name: gofakeit.Name(), + Description: gofakeit.AdjectiveDescriptive(), + Price: gofakeit.Price(150, 6000), + UpdatedAt: time.Now(), + } + + err := integrationTestSharedFixture.Bus.PublishMessage( + ctx, + productUpdated, + nil, + ) + So(err, ShouldBeNil) + + var product *models.Product + + err = testUtils.WaitUntilConditionMet(func() bool { + product, err = integrationTestSharedFixture.ProductRepository.GetProductByProductId( + ctx, + integrationTestSharedFixture.Items[0].ProductId, + ) + + return product != nil && + product.Name == productUpdated.Name + }) + + So(err, ShouldBeNil) + So(product, ShouldNotBeNil) + So( + productUpdated.ProductId, + ShouldEqual, + product.ProductId, + ) + }, + ) }) - }) - }) + }, + ) integrationTestSharedFixture.DisposeTest() }) diff --git a/internal/services/catalog_write_service/.env b/internal/services/catalog_write_service/.env new file mode 100644 index 00000000..aa77c30f --- /dev/null +++ b/internal/services/catalog_write_service/.env @@ -0,0 +1 @@ +PROJECT_NAME=catalog_write_service diff --git a/internal/services/catalog_write_service/Makefile b/internal/services/catalog_write_service/Makefile index 9ddf2347..36a764ff 100644 --- a/internal/services/catalog_write_service/Makefile +++ b/internal/services/catalog_write_service/Makefile @@ -20,11 +20,10 @@ lint: .PHONY: format format: - goimports-reviser -company-prefixes "github.com/mehdihadeli" -project-name "github.com/mehdihadeli/go-ecommerce-microservices" -imports-order "std,general,company,project" -recursive ./... golines -m 120 -w --ignore-generated . + gci write --skip-generated -s standard -s "prefix(github.com/mehdihadeli/go-ecommerce-microservices)" -s default -s blank -s dot --custom-order . gofumpt -l -w . - .PHONY: update update: @go get -u @@ -87,19 +86,3 @@ create_db: .PHONY: drop_db drop_db: docker exec -it postgres dropdb -U $(DB_USER) $(DB_NAME) - -.PHONY: force_db -force_db: - migrate -database postgres://postgres:postgres@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?sslmode=$(SSL_MODE) -verbose -path migrations force 1 - -.PHONY: version_db -version_db: - migrate -database postgres://postgres:postgres@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?sslmode=$(SSL_MODE) -verbose -path migrations version - -.PHONY: migrate_up -migrate_up: - migrate -database postgres://postgres:postgres@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?sslmode=$(SSL_MODE) -verbose -path migrations up - -.PHONY: migrate_down -migrate_down: - migrate -database postgres://postgres:postgres@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?sslmode=$(SSL_MODE) -verbose -path migrations down diff --git a/internal/services/catalog_write_service/atlas.hcl b/internal/services/catalog_write_service/atlas.hcl new file mode 100644 index 00000000..c2befff1 --- /dev/null +++ b/internal/services/catalog_write_service/atlas.hcl @@ -0,0 +1,40 @@ +#https://atlasgo.io/atlas-schema/projects + +data "external_schema" "gorm" { + program = [ + "go", + "run", + "-mod=mod", + "ariga.io/atlas-provider-gorm", + "load", + "--path", "./internal/products/models", + "--dialect", "postgres", + ] +} + +env "gorm" { + src = data.external_schema.gorm.url + dev = "postgres://postgres:postgres@localhost:5432/catalogs_service?sslmode=disable" + migration { + dir = "file://db/migrations/atlas" + } + format { + migrate { + diff = "{{ sql . \" \" }}" + } + } +} + +env "go-migrate" { + src = "file://db/migrations/go-migrate/schema.sql" + dev = "postgres://postgres:postgres@localhost:5432/catalogs_service?sslmode=disable" + migration { + dir = "file://db/migrations/go-migrate" + format = golang-migrate + } + format { + migrate { + diff = "{{ sql . \" \" }}" + } + } +} diff --git a/internal/services/catalog_write_service/cmd/app/main.go b/internal/services/catalog_write_service/cmd/app/main.go index 646a1ac5..e49d95fa 100644 --- a/internal/services/catalog_write_service/cmd/app/main.go +++ b/internal/services/catalog_write_service/cmd/app/main.go @@ -5,6 +5,8 @@ import ( "github.com/mehdihadeli/go-ecommerce-microservices/internal/services/catalogwriteservice/internal/shared/app" + "github.com/pterm/pterm" + "github.com/pterm/pterm/putils" "github.com/spf13/cobra" ) @@ -26,6 +28,11 @@ var rootCmd = &cobra.Command{ // @version 1.0 // @description Catalogs Write-Service Api. func main() { + pterm.DefaultBigText.WithLetters( + putils.LettersFromStringWithStyle("Catalogs", pterm.FgLightGreen.ToStyle()), + putils.LettersFromStringWithStyle(" Write Service", pterm.FgLightMagenta.ToStyle())). + Render() + err := rootCmd.Execute() if err != nil { os.Exit(1) diff --git a/internal/services/catalog_write_service/cmd/migration/.gitkeep b/internal/services/catalog_write_service/cmd/migration/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/internal/services/catalog_write_service/cmd/migration/main.go b/internal/services/catalog_write_service/cmd/migration/main.go new file mode 100644 index 00000000..216fd3f4 --- /dev/null +++ b/internal/services/catalog_write_service/cmd/migration/main.go @@ -0,0 +1,115 @@ +package main + +import ( + "context" + "os" + + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/config" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/config/environemnt" + gormPostgres "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/gorm_postgres" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger" + defaultLogger "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger/default_logger" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger/external/fxlog" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger/zap" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/migration" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/migration/contracts" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/migration/goose" + appconfig "github.com/mehdihadeli/go-ecommerce-microservices/internal/services/catalogwriteservice/config" + + "github.com/spf13/cobra" + "go.uber.org/fx" +) + +func init() { + // Add flags to specify the version + cmdUp.Flags().Uint("version", 0, "Migration version") + cmdDown.Flags().Uint("version", 0, "Migration version") + + // Add commands to the root command + rootCmd.AddCommand(cmdUp) + rootCmd.AddCommand(cmdDown) +} + +var ( + rootCmd = &cobra.Command{ //nolint:gochecknoglobals + Use: "migration", + Short: "A tool for running migrations", + Run: func(cmd *cobra.Command, args []string) { + // Execute the "up" subcommand when no subcommand is specified + if len(args) == 0 { + cmd.SetArgs([]string{"up"}) + if err := cmd.Execute(); err != nil { + defaultLogger.Logger.Error(err) + os.Exit(1) + } + } + }, + } + + cmdDown = &cobra.Command{ //nolint:gochecknoglobals + Use: "down", + Short: "Run a down migration", + Run: func(cmd *cobra.Command, args []string) { + executeMigration(cmd, migration.Down) + }, + } + + cmdUp = &cobra.Command{ //nolint:gochecknoglobals + Use: "up", + Short: "Run an up migration", + Run: func(cmd *cobra.Command, args []string) { + executeMigration(cmd, migration.Up) + }, + } +) + +func executeMigration(cmd *cobra.Command, commandType migration.CommandType) { + version, err := cmd.Flags().GetUint("version") + if err != nil { + defaultLogger.Logger.Fatal(err) + } + + app := fx.New( + config.ModuleFunc(environemnt.Development), + zap.Module, + fxlog.FxLogger, + gormPostgres.Module, + appconfig.Module, + //// use go-migrate library for migration + //gomigrate.Module, + // use go-migrate library for migration + goose.Module, + fx.Invoke(func(migrationRunner contracts.PostgresMigrationRunner, logger logger.Logger) { + logger.Info("Migration process started...") + switch commandType { + case migration.Up: + err = migrationRunner.Up(context.Background(), version) + case migration.Down: + err = migrationRunner.Down(context.Background(), version) + } + if err != nil { + logger.Fatalf("migration failed, err: %s", err) + } + logger.Info("Migration completed...") + }), + ) + + err = app.Start(context.Background()) + if err != nil { + defaultLogger.Logger.Fatal(err) + } + + err = app.Stop(context.Background()) + if err != nil { + defaultLogger.Logger.Fatal(err) + } +} + +func main() { + defaultLogger.SetupDefaultLogger() + + if err := rootCmd.Execute(); err != nil { + defaultLogger.Logger.Error(err) + os.Exit(1) + } +} diff --git a/internal/services/catalog_write_service/config/config.development.json b/internal/services/catalog_write_service/config/config.development.json index 60f99676..1a49c752 100644 --- a/internal/services/catalog_write_service/config/config.development.json +++ b/internal/services/catalog_write_service/config/config.development.json @@ -29,18 +29,6 @@ "logType": 0, "callerEnabled": false }, - "postgresPxgOptions": { - "host": "localhost", - "port": 5432, - "user": "postgres", - "password": "postgres", - "dbName": "catalogs_service", - "sslMode": false, - "migrations": { - "migrationsDir": "migrations", - "skipMigration": true - } - }, "gormOptions": { "host": "localhost", "port": 5432, @@ -60,7 +48,7 @@ "httpPort": 15672 } }, - "OpenTelemetryOptions": { + "openTelemetryOptions": { "enable": true, "serviceName": "catalogs-write-service", "instrumentationName": "github.com/mehdihadeli/go-ecommerce-microservices/internal/services/catalogwriteservice", @@ -81,5 +69,15 @@ }, "eventStoreDbOptions": { "connectionString": "esdb://localhost:2113?tls=false" + }, + "migrationOptions": { + "host": "localhost", + "port": 5432, + "user": "postgres", + "password": "postgres", + "dbName": "catalogs_service", + "sslMode": false, + "migrationsDir": "db/migrations/goose-migrate", + "skipMigration": false } } diff --git a/internal/services/catalog_write_service/config/config.test.json b/internal/services/catalog_write_service/config/config.test.json index 1eccec5d..58a80583 100644 --- a/internal/services/catalog_write_service/config/config.test.json +++ b/internal/services/catalog_write_service/config/config.test.json @@ -29,18 +29,6 @@ "logType": 0, "callerEnabled": false }, - "postgresPxgOptions": { - "host": "localhost", - "port": 5432, - "user": "postgres", - "password": "postgres", - "dbName": "catalogs_service", - "sslMode": false, - "migrations": { - "migrationsDir": "migrations", - "skipMigration": true - } - }, "gormOptions": { "host": "localhost", "port": 5432, @@ -60,7 +48,7 @@ "httpPort": 15672 } }, - "OpenTelemetryOptions": { + "openTelemetryOptions": { "enable": true, "serviceName": "catalogs-write-service", "instrumentationName": "github.com/mehdihadeli/go-ecommerce-microservices/internal/services/catalogwriteservice", @@ -81,5 +69,15 @@ }, "eventStoreDbOptions": { "connectionString": "esdb://localhost:2113?tls=false" + }, + "migrationOptions": { + "host": "localhost", + "port": 5432, + "user": "postgres", + "password": "postgres", + "dbName": "catalogs_service", + "sslMode": false, + "migrationsDir": "db/migrations/goose-migrate", + "skipMigration": false } } diff --git a/internal/services/catalog_write_service/db/migrations/000001_catalogs_service_tables_init.down.sql b/internal/services/catalog_write_service/db/migrations/000001_catalogs_service_tables_init.down.sql deleted file mode 100644 index 5f202047..00000000 --- a/internal/services/catalog_write_service/db/migrations/000001_catalogs_service_tables_init.down.sql +++ /dev/null @@ -1,4 +0,0 @@ - --- https://github.com/golang-migrate/migrate/blob/master/MIGRATIONS.md -DROP TABLE IF EXISTS products CASCADE; -DROP EXTENSION IF EXISTS citext CASCADE; \ No newline at end of file diff --git a/internal/services/catalog_write_service/db/migrations/000001_catalogs_service_tables_init.up.sql b/internal/services/catalog_write_service/db/migrations/000001_catalogs_service_tables_init.up.sql deleted file mode 100644 index b7ecc8a4..00000000 --- a/internal/services/catalog_write_service/db/migrations/000001_catalogs_service_tables_init.up.sql +++ /dev/null @@ -1,17 +0,0 @@ --- https://github.com/golang-migrate/migrate/blob/master/MIGRATIONS.md ---https://dev.to/techschoolguru/how-to-write-run-database-migration-in-golang-5h6g -CREATE EXTENSION IF NOT EXISTS citext; -CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -DROP TABLE IF EXISTS products CASCADE; - - -CREATE TABLE products -( - product_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), - name VARCHAR(250) NOT NULL CHECK ( name <> '' ), - description VARCHAR(5000) NOT NULL CHECK ( description <> '' ), - price NUMERIC NOT NULL, - created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -); - diff --git a/internal/services/catalog_write_service/db/migrations/atlas/20230919170700.sql b/internal/services/catalog_write_service/db/migrations/atlas/20230919170700.sql new file mode 100644 index 00000000..09475fba --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/atlas/20230919170700.sql @@ -0,0 +1,10 @@ +-- Create "products" table +CREATE TABLE "public"."products" ( + "product_id" text NOT NULL, + "name" text NULL, + "description" text NULL, + "price" numeric NULL, + "created_at" timestamptz NULL, + "updated_at" timestamptz NULL, + PRIMARY KEY ("product_id") +); diff --git a/internal/services/catalog_write_service/db/migrations/atlas/atlas.sum b/internal/services/catalog_write_service/db/migrations/atlas/atlas.sum new file mode 100644 index 00000000..7ef3c671 --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/atlas/atlas.sum @@ -0,0 +1,2 @@ +h1:STL9Gt6US7g2EZozDIQ2fkT0eGROAhTsnDSZhY6rNRI= +20230919170700.sql h1:Z2PYRNbeYrwt9xmOI44evGjjj/jmpShqWYVexvUXWI8= diff --git a/internal/services/catalog_write_service/db/migrations/atlas/goose/00001_enable_uuid_extension.sql b/internal/services/catalog_write_service/db/migrations/atlas/goose/00001_enable_uuid_extension.sql new file mode 100644 index 00000000..c941cb36 --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/atlas/goose/00001_enable_uuid_extension.sql @@ -0,0 +1 @@ +CREATE EXTENSION "uuid-ossp"; diff --git a/internal/services/catalog_write_service/db/migrations/atlas/goose/00002_create_products_table.sql b/internal/services/catalog_write_service/db/migrations/atlas/goose/00002_create_products_table.sql new file mode 100644 index 00000000..3cd15971 --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/atlas/goose/00002_create_products_table.sql @@ -0,0 +1,9 @@ +CREATE TABLE IF NOT EXISTS products +( + product_id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), + name text, + description text, + price numeric, + created_at timestamp with time zone, + updated_at timestamp with time zone +); diff --git a/internal/services/catalog_write_service/db/migrations/atlas/goose/atlas.sum b/internal/services/catalog_write_service/db/migrations/atlas/goose/atlas.sum new file mode 100644 index 00000000..d462e2a2 --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/atlas/goose/atlas.sum @@ -0,0 +1,3 @@ +h1:tTCE9gdplT14q9qkT5Awu+3A/Y+Xjl8AoJhkH6e4tpE= +00001_enable_uuid_extension.sql h1:8nvgTOQQ91UoPUqGRpVIc0TFZ225YmCOblX7yEObv2I= +00002_create_products_table.sql h1:u5k/Xihi+GiziFZALx3cJa+v7x2b450ycezB3lVweBc= diff --git a/internal/services/catalog_write_service/db/migrations/atlas/readme.md b/internal/services/catalog_write_service/db/migrations/atlas/readme.md new file mode 100644 index 00000000..e49933b8 --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/atlas/readme.md @@ -0,0 +1,6 @@ +# Migration Using Atlas +- [Automatic migration planning for GORM](https://atlasgo.io/guides/orms/gorm) +- [Automatic migration planning for golang-migrate](https://atlasgo.io/guides/migration-tools/golang-migrate) +- [Importing a Goose project to Atlas](https://atlasgo.io/guides/migration-tools/goose-import) + +# Sync Grom with Atlas Here diff --git a/internal/services/catalog_write_service/db/migrations/go-migrate/000001_enable_uuid_extension.down.sql b/internal/services/catalog_write_service/db/migrations/go-migrate/000001_enable_uuid_extension.down.sql new file mode 100644 index 00000000..8ca954c0 --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/go-migrate/000001_enable_uuid_extension.down.sql @@ -0,0 +1 @@ +DROP EXTENSION IF EXISTS "uuid-ossp"; diff --git a/internal/services/catalog_write_service/db/migrations/go-migrate/000001_enable_uuid_extension.up.sql b/internal/services/catalog_write_service/db/migrations/go-migrate/000001_enable_uuid_extension.up.sql new file mode 100644 index 00000000..c941cb36 --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/go-migrate/000001_enable_uuid_extension.up.sql @@ -0,0 +1 @@ +CREATE EXTENSION "uuid-ossp"; diff --git a/internal/services/catalog_write_service/db/migrations/go-migrate/000002_create_products_table.down.sql b/internal/services/catalog_write_service/db/migrations/go-migrate/000002_create_products_table.down.sql new file mode 100644 index 00000000..39a3c0ed --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/go-migrate/000002_create_products_table.down.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS products; diff --git a/internal/services/catalog_write_service/db/migrations/go-migrate/000002_create_products_table.up.sql b/internal/services/catalog_write_service/db/migrations/go-migrate/000002_create_products_table.up.sql new file mode 100644 index 00000000..3cd15971 --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/go-migrate/000002_create_products_table.up.sql @@ -0,0 +1,9 @@ +CREATE TABLE IF NOT EXISTS products +( + product_id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), + name text, + description text, + price numeric, + created_at timestamp with time zone, + updated_at timestamp with time zone +); diff --git a/internal/services/catalog_write_service/db/migrations/go-migrate/atlas.sum b/internal/services/catalog_write_service/db/migrations/go-migrate/atlas.sum new file mode 100644 index 00000000..49961eab --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/go-migrate/atlas.sum @@ -0,0 +1,6 @@ +h1:tpPUeCB+6hZZFR/Q7kF3UyQU0jggMPFUrcHVSeXxD6M= +000001_enable_uuid_extension.down.sql h1:gtXVYVcdHUgztryvvV/3OSCpegzalBV2afyVKJD2Umw= +000001_enable_uuid_extension.up.sql h1:AwRwKu3SfgU4x2WRaGwuVp9B+NZ0xFzH4/q3TCqwMbU= +000002_create_products_table.down.sql h1:BxLX2d7QPf2y7uuw7O401p6Bg2mBNQVdEyWIfkEEo4U= +000002_create_products_table.up.sql h1:dqSmpveIQ7ez6EgR5oq2jGjbhKWpQ+IU5StOz/hfbPw= +schema.sql h1:sYZljxAdKwrdvhSf9OppA2UPUI0VaDZxyiiJ8ifJhlI= diff --git a/internal/services/catalog_write_service/db/migrations/go-migrate/readme.md b/internal/services/catalog_write_service/db/migrations/go-migrate/readme.md new file mode 100644 index 00000000..0adcf4d3 --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/go-migrate/readme.md @@ -0,0 +1,16 @@ +# Migration Using Go-Migrate +- [migrate CLI](https://github.com/golang-migrate/migrate/tree/master/cmd/migrate) +- [Getting started](https://github.com/golang-migrate/migrate/blob/856ea12df9d230b0145e23d951b7dbd6b86621cb/GETTING_STARTED.md) +- [Migration Filename Format](https://github.com/golang-migrate/migrate/blob/856ea12df9d230b0145e23d951b7dbd6b86621cb/MIGRATIONS.md) +- [PostgreSQL tutorial for beginners](https://github.com/golang-migrate/migrate/blob/856ea12df9d230b0145e23d951b7dbd6b86621cb/database/postgres/TUTORIAL.md) + +# Atlas Go-Migrate +[https://atlasgo.io/guides/migration-tools/golang-migrate](https://atlasgo.io/guides/migration-tools/golang-migrate) + +```bash +atlas migrate hash --env go-migrate +``` + +```bash +atlas schema inspect --env go-migrate --url "file://db/migrations/go-migrate" --format "{{ sql . \" \" }}" > ./db/migrations/go-migrate/schema.sql +``` diff --git a/internal/services/catalog_write_service/db/migrations/go-migrate/schema.sql b/internal/services/catalog_write_service/db/migrations/go-migrate/schema.sql new file mode 100644 index 00000000..879b57f2 --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/go-migrate/schema.sql @@ -0,0 +1,14 @@ +-- Add new schema named "public" +CREATE SCHEMA IF NOT EXISTS "public"; +-- Set comment to schema: "public" +COMMENT ON SCHEMA "public" IS 'standard public schema'; +-- Create "products" table +CREATE TABLE "public"."products" ( + "product_id" uuid NOT NULL DEFAULT uuid_generate_v4(), + "name" text NULL, + "description" text NULL, + "price" numeric NULL, + "created_at" timestamptz NULL, + "updated_at" timestamptz NULL, + PRIMARY KEY ("product_id") +); diff --git a/internal/services/catalog_write_service/db/migrations/goose-migrate/00001_enable_uuid_extension.sql b/internal/services/catalog_write_service/db/migrations/goose-migrate/00001_enable_uuid_extension.sql new file mode 100644 index 00000000..30826f0f --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/goose-migrate/00001_enable_uuid_extension.sql @@ -0,0 +1,9 @@ +-- +goose Up +-- +goose StatementBegin +CREATE EXTENSION "uuid-ossp"; +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +DROP EXTENSION "uuid-ossp"; +-- +goose StatementEnd diff --git a/internal/services/catalog_write_service/db/migrations/goose-migrate/00002_create_products_table.sql b/internal/services/catalog_write_service/db/migrations/goose-migrate/00002_create_products_table.sql new file mode 100644 index 00000000..f7ed379b --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/goose-migrate/00002_create_products_table.sql @@ -0,0 +1,17 @@ +-- +goose Up +-- +goose StatementBegin +CREATE TABLE IF NOT EXISTS products +( + product_id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), + name text, + description text, + price numeric, + created_at timestamp with time zone, + updated_at timestamp with time zone +); +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +DROP TABLE products; +-- +goose StatementEnd diff --git a/internal/services/catalog_write_service/db/migrations/goose-migrate/readme.md b/internal/services/catalog_write_service/db/migrations/goose-migrate/readme.md new file mode 100644 index 00000000..ac7d5e07 --- /dev/null +++ b/internal/services/catalog_write_service/db/migrations/goose-migrate/readme.md @@ -0,0 +1,9 @@ +# Migration Using Goose +- [Goose Usage](https://github.com/pressly/goose#usage) + +# Atlas Goose +- [Importing a Goose project to Atlas](https://atlasgo.io/guides/migration-tools/goose-import) + +```bash +atlas migrate import --from file://db/migrations/goose-migrate?format=goose --to file://db/migrations/atlas/goose +``` diff --git a/internal/services/catalog_write_service/db/migrations/readme.md b/internal/services/catalog_write_service/db/migrations/readme.md deleted file mode 100644 index 99d3d298..00000000 --- a/internal/services/catalog_write_service/db/migrations/readme.md +++ /dev/null @@ -1,5 +0,0 @@ -## Create Migration File - -``` cmd -migrate create -ext .sql -seq catalogs_service_tables_init -``` \ No newline at end of file diff --git a/internal/services/catalog_write_service/go.mod b/internal/services/catalog_write_service/go.mod index d0d290d4..4be37c64 100644 --- a/internal/services/catalog_write_service/go.mod +++ b/internal/services/catalog_write_service/go.mod @@ -20,9 +20,9 @@ require ( github.com/michaelklishin/rabbit-hole v1.5.0 github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.27.10 + github.com/pterm/pterm v0.12.69 github.com/satori/go.uuid v1.2.0 github.com/spf13/cobra v1.7.0 - github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 github.com/swaggo/echo-swagger v1.4.1 github.com/swaggo/swag v1.16.2 @@ -36,6 +36,9 @@ require ( ) require ( + atomicgo.dev/cursor v0.2.0 // indirect + atomicgo.dev/keyboard v0.2.9 // indirect + atomicgo.dev/schedule v0.1.0 // indirect dario.cat/mergo v1.0.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/ClickHouse/ch-go v0.58.2 // indirect @@ -53,6 +56,7 @@ require ( github.com/avast/retry-go v3.0.0+incompatible // indirect github.com/caarlos0/env/v8 v8.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/containerd/console v1.0.3 // indirect github.com/containerd/containerd v1.7.5 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -86,6 +90,7 @@ require ( github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.3.1 // indirect + github.com/gookit/color v1.5.4 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/imkira/go-interpol v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -110,9 +115,12 @@ require ( github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/leodido/go-urn v1.2.4 // indirect + github.com/lithammer/fuzzysearch v1.1.8 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mcuadros/go-defaults v1.2.0 // indirect github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect @@ -130,16 +138,19 @@ require ( github.com/pierrec/lz4/v4 v4.1.18 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pressly/goose/v3 v3.15.0 // indirect github.com/prometheus/common v0.44.0 // indirect github.com/rabbitmq/amqp091-go v1.8.1 // indirect github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 // indirect github.com/redis/go-redis/v9 v9.0.5 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/samber/lo v1.38.1 // indirect github.com/segmentio/asm v1.2.0 // indirect - github.com/sergi/go-diff v1.0.0 // indirect + github.com/sergi/go-diff v1.2.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/spf13/viper v1.16.0 // indirect github.com/streadway/amqp v1.1.0 // indirect github.com/stretchr/objx v0.5.1 // indirect github.com/swaggo/files/v2 v2.0.0 // indirect @@ -158,6 +169,7 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect github.com/yudai/gojsondiff v1.0.0 // indirect @@ -181,6 +193,7 @@ require ( golang.org/x/net v0.15.0 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.12.0 // indirect + golang.org/x/term v0.12.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.13.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect diff --git a/internal/services/catalog_write_service/go.sum b/internal/services/catalog_write_service/go.sum index 572b8516..b75314c5 100644 --- a/internal/services/catalog_write_service/go.sum +++ b/internal/services/catalog_write_service/go.sum @@ -1,3 +1,11 @@ +atomicgo.dev/assert v0.0.2 h1:FiKeMiZSgRrZsPo9qn/7vmr7mCsh5SZyXY4YGYiYwrg= +atomicgo.dev/assert v0.0.2/go.mod h1:ut4NcI3QDdJtlmAxQULOmA13Gz6e2DWbSAS8RUOmNYQ= +atomicgo.dev/cursor v0.2.0 h1:H6XN5alUJ52FZZUkI7AlJbUc1aW38GWZalpYRPpoPOw= +atomicgo.dev/cursor v0.2.0/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU= +atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8= +atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ= +atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs= +atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU= bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -63,6 +71,15 @@ github.com/EventStore/EventStore-Client-Go v1.0.2 h1:onM2TIInLhWUJwUQ/5a/8blNrrb github.com/EventStore/EventStore-Client-Go v1.0.2/go.mod h1:NOqSOtNxqGizr1Qnf7joGGLK6OkeoLV/QEI893A43H0= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= +github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= +github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= +github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k= +github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI= +github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c= +github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE= +github.com/MarvinJWendt/testza v0.5.2 h1:53KDo64C1z/h/d/stCYCPY69bt/OSwjq5KpFNwi+zB4= +github.com/MarvinJWendt/testza v0.5.2/go.mod h1:xu53QFE5sCdjtMCKk8YMQ2MnymimEctc4n3EjyIYvEY= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= @@ -87,6 +104,7 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/ github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -122,6 +140,8 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWH github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.7.5 h1:i9T9XpAWMe11BHMN7pu1BZqOGjXaKTPyz2v+KYOZgkY= github.com/containerd/containerd v1.7.5/go.mod h1:ieJNCSzASw2shSGYLHx8NAE7WsZ/gEigo5fQ78W5Zvw= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -162,6 +182,8 @@ github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD github.com/doug-martin/goqu/v9 v9.18.0 h1:/6bcuEtAe6nsSMVK/M+fOiXUNfyFF3yYtE07DBPFMYY= github.com/doug-martin/goqu/v9 v9.18.0/go.mod h1:nf0Wc2/hV3gYK9LiyqIrzBEVGlI8qW3GuDCEobC4wBQ= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -248,8 +270,9 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keL github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-migrate/migrate/v4 v4.16.2 h1:8coYbMKUyInrFk1lfGfRovTLAW7PhWp8qQDT2iKfuoA= github.com/golang-migrate/migrate/v4 v4.16.2/go.mod h1:pfcJX4nPHaVdc5nmdCikFBWtm+UBpiZjRNNsyBbp0/o= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -328,6 +351,10 @@ github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= +github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= +github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= +github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e h1:XmA6L9IPRdUr28a+SK/oMchGgQy159wvzXA5tJ7l+40= github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e/go.mod h1:AFIo+02s+12CEg8Gzz9kzhCbmbq6JcKNrhHffCGA9z4= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= @@ -421,6 +448,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/kamva/mgm/v3 v3.5.0 h1:/2mNshpqwAC9spdzJZ0VR/UZ/SY/PsNTrMjT111KQjM= github.com/kamva/mgm/v3 v3.5.0/go.mod h1:F4J1hZnXQMkqL3DZgR7Z7BOuiTqQG/JTic3YzliG4jk= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/khaiql/dbcleaner v2.3.0+incompatible h1:VU/ZnMcs0Dx6s4XELYfZMMyib2hyrnJ0Xk1/2aZQIqg= github.com/khaiql/dbcleaner v2.3.0+incompatible/go.mod h1:NUURNSEp3cHXCm37Ljb/IWAdp2/qYv/HAW+1BdnEbps= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -429,6 +458,11 @@ github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8 github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -460,6 +494,8 @@ github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= +github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -481,9 +517,12 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= -github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= +github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mcuadros/go-defaults v1.2.0 h1:FODb8WSf0uGaY8elWJAkoLL0Ri6AlZ1bFlenk56oZtc= @@ -558,6 +597,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pressly/goose/v3 v3.15.0 h1:6tY5aDqFknY6VZkorFGgZtWygodZQxfmmEF4rqyJW9k= +github.com/pressly/goose/v3 v3.15.0/go.mod h1:LlIo3zGccjb/YUgG+Svdb9Er14vefRdlDI7URCDrwYo= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -567,6 +608,15 @@ github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdO github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI= +github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg= +github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE= +github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU= +github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= +github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= +github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= +github.com/pterm/pterm v0.12.69 h1:fBCKnB8dSLAl8FlYRQAWYGp2WTI/Xm/tKJ21Hyo9USw= +github.com/pterm/pterm v0.12.69/go.mod h1:wl06ko9MHnqxz4oDV++IORDpjCzw6+mfrvf0MPj6fdk= github.com/rabbitmq/amqp091-go v1.8.1 h1:RejT1SBUim5doqcL6s7iN6SBmsQqyTgXb1xMlH0h1hA= github.com/rabbitmq/amqp091-go v1.8.1/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc= github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho= @@ -575,6 +625,11 @@ github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnAfVjZNvfJTYfPetfZk5yoSTLaQ= github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= @@ -592,8 +647,9 @@ github.com/savsgio/gotils v0.0.0-20210617111740-97865ed5a873/go.mod h1:dmPawKuiA github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= @@ -695,6 +751,9 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= @@ -835,6 +894,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -902,6 +962,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -963,8 +1024,10 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -976,8 +1039,12 @@ golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -989,6 +1056,7 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1056,6 +1124,7 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1167,6 +1236,7 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -1209,8 +1279,28 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= +lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= +modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= +modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= +modernc.org/ccgo/v3 v3.16.14 h1:af6KNtFgsVmnDYrWk3PQCS9XT6BXe7o3ZFJKkIKvXNQ= +modernc.org/ccgo/v3 v3.16.14/go.mod h1:mPDSujUIaTNWQSG4eqKw+atqLOEbma6Ncsa94WbC9zo= +modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM= +modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o= +modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA= +modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU= +modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e/go.mod h1:nejbQVfXh96n9dSF6cH3Jsk/QI1Z2oEL7sSI2ifXFNA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/internal/services/catalog_write_service/internal/shared/app/test/test_app.go b/internal/services/catalog_write_service/internal/shared/app/test/test_app.go index 5652148a..b3ff7249 100644 --- a/internal/services/catalog_write_service/internal/shared/app/test/test_app.go +++ b/internal/services/catalog_write_service/internal/shared/app/test/test_app.go @@ -11,6 +11,8 @@ import ( "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/grpc" config3 "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/http/custom_echo/config" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/logger" + contracts2 "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/migration/contracts" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/migration/goose" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/rabbitmq/bus" config2 "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/rabbitmq/config" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/test/containers/testcontainer/gorm" @@ -27,18 +29,19 @@ import ( type TestApp struct{} type TestAppResult struct { - Cfg *config.AppOptions - Bus bus.RabbitmqBus - Container contracts.Container - Logger logger.Logger - RabbitmqOptions *config2.RabbitmqOptions - EchoHttpOptions *config3.EchoHttpOptions - GormOptions *gormPostgres.GormOptions - CatalogUnitOfWorks data.CatalogUnitOfWork - ProductRepository data.ProductRepository - Gorm *gorm2.DB - ProductServiceClient productsService.ProductsServiceClient - GrpcClient grpc.GrpcClient + Cfg *config.AppOptions + Bus bus.RabbitmqBus + Container contracts.Container + Logger logger.Logger + RabbitmqOptions *config2.RabbitmqOptions + EchoHttpOptions *config3.EchoHttpOptions + GormOptions *gormPostgres.GormOptions + CatalogUnitOfWorks data.CatalogUnitOfWork + ProductRepository data.ProductRepository + Gorm *gorm2.DB + ProductServiceClient productsService.ProductsServiceClient + GrpcClient grpc.GrpcClient + PostgresMigrationRunner contracts2.PostgresMigrationRunner } func NewTestApp() *TestApp { @@ -51,6 +54,7 @@ func (a *TestApp) Run(t *testing.T) (result *TestAppResult) { // ref: https://github.com/uber-go/fx/blob/master/app_test.go appBuilder := NewCatalogsWriteTestApplicationBuilder(t) appBuilder.ProvideModule(catalogs.CatalogsServiceModule) + appBuilder.ProvideModule(goose.Module) appBuilder.Decorate(rabbitmq.RabbitmqContainerOptionsDecorator(t, lifetimeCtx)) appBuilder.Decorate(gorm.GormContainerOptionsDecorator(t, lifetimeCtx)) @@ -72,20 +76,22 @@ func (a *TestApp) Run(t *testing.T) (result *TestAppResult) { gorm *gorm2.DB, echoOptions *config3.EchoHttpOptions, grpcClient grpc.GrpcClient, + postgresMigrationRunner contracts2.PostgresMigrationRunner, ) { grpcConnection := grpcClient.GetGrpcConnection() result = &TestAppResult{ - Bus: bus, - Cfg: cfg, - Container: testApp, - Logger: logger, - RabbitmqOptions: rabbitmqOptions, - GormOptions: gormOptions, - ProductRepository: productRepository, - CatalogUnitOfWorks: catalogUnitOfWorks, - Gorm: gorm, - EchoHttpOptions: echoOptions, + Bus: bus, + Cfg: cfg, + Container: testApp, + Logger: logger, + RabbitmqOptions: rabbitmqOptions, + GormOptions: gormOptions, + ProductRepository: productRepository, + CatalogUnitOfWorks: catalogUnitOfWorks, + Gorm: gorm, + EchoHttpOptions: echoOptions, + PostgresMigrationRunner: postgresMigrationRunner, ProductServiceClient: productsService.NewProductsServiceClient( grpcConnection, ), diff --git a/internal/services/catalog_write_service/internal/shared/app/test/test_application_builder.go b/internal/services/catalog_write_service/internal/shared/app/test/test_application_builder.go index 1481b7cd..601ae4d2 100644 --- a/internal/services/catalog_write_service/internal/shared/app/test/test_application_builder.go +++ b/internal/services/catalog_write_service/internal/shared/app/test/test_application_builder.go @@ -1,12 +1,9 @@ package test import ( - "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/constants" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/fxapp/contracts" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/fxapp/test" - constants2 "github.com/mehdihadeli/go-ecommerce-microservices/internal/services/catalogwriteservice/internal/shared/constants" - "github.com/spf13/viper" "go.uber.org/fx/fxtest" ) @@ -16,9 +13,6 @@ type CatalogsWriteTestApplicationBuilder struct { } func NewCatalogsWriteTestApplicationBuilder(tb fxtest.TB) *CatalogsWriteTestApplicationBuilder { - // set viper internal registry, in real app we read it from `.env` file in current `executing working directory` for example `catalogs_service` - viper.Set(constants.PROJECT_NAME_ENV, constants2.PROJECT_NAME) - return &CatalogsWriteTestApplicationBuilder{ ApplicationBuilder: test.NewTestApplicationBuilder(tb), tb: tb, diff --git a/internal/services/catalog_write_service/internal/shared/configurations/catalogs/catalogs_configurator_migration.go b/internal/services/catalog_write_service/internal/shared/configurations/catalogs/catalogs_configurator_migration.go index b5d440b5..c79f8ba9 100644 --- a/internal/services/catalog_write_service/internal/shared/configurations/catalogs/catalogs_configurator_migration.go +++ b/internal/services/catalog_write_service/internal/shared/configurations/catalogs/catalogs_configurator_migration.go @@ -1,17 +1,18 @@ package catalogs import ( - "github.com/mehdihadeli/go-ecommerce-microservices/internal/services/catalogwriteservice/internal/products/models" - "gorm.io/gorm" ) func (ic *CatalogsServiceConfigurator) migrateCatalogs(gorm *gorm.DB) error { - // or we could use `gorm.Migrate()` - err := gorm.AutoMigrate(&models.Product{}) - if err != nil { - return err - } + // - for complex migration and ability to back-track to specific migration revision it is better we use `goose`, but if we want to use built-in gorm migration we can also sync gorm with `atlas` integration migration versioning for getting migration history from grom changes + // - here I used goose for migration, with using cmd/migration file + // https://atlasgo.io/guides/orms/gorm + + //err := gorm.AutoMigrate(&models.Product{}) + //if err != nil { + // return err + //} return nil } diff --git a/internal/services/catalog_write_service/internal/shared/constants/constants.go b/internal/services/catalog_write_service/internal/shared/constants/constants.go deleted file mode 100644 index 56d33346..00000000 --- a/internal/services/catalog_write_service/internal/shared/constants/constants.go +++ /dev/null @@ -1,5 +0,0 @@ -package constants - -const ( - PROJECT_NAME = "catalog_write_service" -) diff --git a/internal/services/catalog_write_service/internal/shared/test_fixtures/integration/integration_test_fixture.go b/internal/services/catalog_write_service/internal/shared/test_fixtures/integration/integration_test_fixture.go index 857de410..5eb2ced3 100644 --- a/internal/services/catalog_write_service/internal/shared/test_fixtures/integration/integration_test_fixture.go +++ b/internal/services/catalog_write_service/internal/shared/test_fixtures/integration/integration_test_fixture.go @@ -2,7 +2,6 @@ package integration import ( "context" - "fmt" "testing" "time" @@ -23,7 +22,6 @@ import ( "github.com/brianvoe/gofakeit/v6" rabbithole "github.com/michaelklishin/rabbit-hole" uuid "github.com/satori/go.uuid" - "github.com/stretchr/testify/require" "gopkg.in/khaiql/dbcleaner.v2" "gorm.io/gorm" @@ -46,16 +44,21 @@ type IntegrationTestSharedFixture struct { ProductServiceClient productsService.ProductsServiceClient } -func NewIntegrationTestSharedFixture(t *testing.T) *IntegrationTestSharedFixture { +func NewIntegrationTestSharedFixture( + t *testing.T, +) *IntegrationTestSharedFixture { result := test.NewTestApp().Run(t) // https://github.com/michaelklishin/rabbit-hole rmqc, err := rabbithole.NewClient( - fmt.Sprintf(result.RabbitmqOptions.RabbitmqHostOptions.HttpEndPoint()), + result.RabbitmqOptions.RabbitmqHostOptions.HttpEndPoint(), result.RabbitmqOptions.RabbitmqHostOptions.UserName, result.RabbitmqOptions.RabbitmqHostOptions.Password) - - require.NoError(t, err) + if err != nil { + result.Logger.Error( + errors.WrapIf(err, "error in creating rabbithole client"), + ) + } shared := &IntegrationTestSharedFixture{ Log: result.Logger, @@ -71,6 +74,8 @@ func NewIntegrationTestSharedFixture(t *testing.T) *IntegrationTestSharedFixture ProductServiceClient: result.ProductServiceClient, } + migrateDatabase(result) + return shared } @@ -80,8 +85,9 @@ func (i *IntegrationTestSharedFixture) InitializeTest() { // seed data in each test res, err := seedData(i.Gorm) if err != nil { - i.Log.Fatal(err) + i.Log.Error(errors.WrapIf(err, "error in seeding data in postgres")) } + i.Items = res } @@ -90,18 +96,20 @@ func (i *IntegrationTestSharedFixture) DisposeTest() { // cleanup test containers with their hooks if err := i.cleanupRabbitmqData(); err != nil { - i.Log.Fatal(err) + i.Log.Error(errors.WrapIf(err, "error in cleanup rabbitmq data")) } if err := i.cleanupPostgresData(); err != nil { - i.Log.Fatal(err) + i.Log.Error(errors.WrapIf(err, "error in cleanup postgres data")) } } func (i *IntegrationTestSharedFixture) cleanupRabbitmqData() error { // https://github.com/michaelklishin/rabbit-hole // Get all queues - queues, err := i.RabbitmqCleaner.ListQueuesIn(i.rabbitmqOptions.RabbitmqHostOptions.VirtualHost) + queues, err := i.RabbitmqCleaner.ListQueuesIn( + i.rabbitmqOptions.RabbitmqHostOptions.VirtualHost, + ) if err != nil { return err } @@ -112,6 +120,7 @@ func (i *IntegrationTestSharedFixture) cleanupRabbitmqData() error { i.rabbitmqOptions.RabbitmqHostOptions.VirtualHost, queue.Name, ) + return err } @@ -123,8 +132,10 @@ func (i *IntegrationTestSharedFixture) cleanupPostgresData() error { // Iterate over the tables and delete all records for _, table := range tables { err := i.Gorm.Exec("DELETE FROM " + table).Error + return err } + return nil } @@ -152,6 +163,7 @@ func seedData(gormDB *gorm.DB) ([]*models.Product, error) { if err != nil { return nil, errors.Wrap(err, "error in seed database") } + return products, nil } @@ -203,3 +215,10 @@ func seedAndMigration(gormDB *gorm.DB) ([]*models.Product, error) { ) return result.Items, nil } + +func migrateDatabase(result *test.TestAppResult) { + err := result.PostgresMigrationRunner.Up(context.Background(), 0) + if err != nil { + result.Logger.Fatalf("error in catalog_service migration, err: %s", err) + } +} diff --git a/internal/services/order_service/.env b/internal/services/order_service/.env new file mode 100644 index 00000000..d883e79f --- /dev/null +++ b/internal/services/order_service/.env @@ -0,0 +1 @@ +PROJECT_NAME=order_service diff --git a/internal/services/order_service/Makefile b/internal/services/order_service/Makefile index c1628ca8..8499116d 100644 --- a/internal/services/order_service/Makefile +++ b/internal/services/order_service/Makefile @@ -25,8 +25,8 @@ lint: .PHONY: format format: - goimports-reviser -company-prefixes "github.com/mehdihadeli" -project-name "github.com/mehdihadeli/go-ecommerce-microservices" -imports-order "std,general,company,project" -recursive ./... golines -m 120 -w --ignore-generated . + gci write --skip-generated -s standard -s "prefix(github.com/mehdihadeli/go-ecommerce-microservices)" -s default -s blank -s dot --custom-order . gofumpt -l -w . .PHONY: update diff --git a/internal/services/order_service/cmd/app/main.go b/internal/services/order_service/cmd/app/main.go index dd943202..030212f9 100644 --- a/internal/services/order_service/cmd/app/main.go +++ b/internal/services/order_service/cmd/app/main.go @@ -5,6 +5,8 @@ import ( "github.com/mehdihadeli/go-ecommerce-microservices/internal/services/orderservice/internal/shared/app" + "github.com/pterm/pterm" + "github.com/pterm/pterm/putils" "github.com/spf13/cobra" ) @@ -26,6 +28,11 @@ var rootCmd = &cobra.Command{ // @version 1.0 // @description Orders Service Api func main() { + pterm.DefaultBigText.WithLetters( + putils.LettersFromStringWithStyle("Orders", pterm.FgLightGreen.ToStyle()), + putils.LettersFromStringWithStyle(" Service", pterm.FgLightMagenta.ToStyle())). + Render() + err := rootCmd.Execute() if err != nil { os.Exit(1) diff --git a/internal/services/order_service/go.mod b/internal/services/order_service/go.mod index d625a7b7..776edaf6 100644 --- a/internal/services/order_service/go.mod +++ b/internal/services/order_service/go.mod @@ -20,9 +20,9 @@ require ( github.com/michaelklishin/rabbit-hole v1.5.0 github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.27.10 + github.com/pterm/pterm v0.12.69 github.com/satori/go.uuid v1.2.0 github.com/spf13/cobra v1.7.0 - github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 github.com/swaggo/echo-swagger v1.4.1 github.com/swaggo/swag v1.16.2 @@ -36,6 +36,9 @@ require ( ) require ( + atomicgo.dev/cursor v0.2.0 // indirect + atomicgo.dev/keyboard v0.2.9 // indirect + atomicgo.dev/schedule v0.1.0 // indirect dario.cat/mergo v1.0.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/KyleBanks/depth v1.2.1 // indirect @@ -52,6 +55,7 @@ require ( github.com/caarlos0/env/v8 v8.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/containerd/console v1.0.3 // indirect github.com/containerd/containerd v1.7.5 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -86,6 +90,7 @@ require ( github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.3.1 // indirect + github.com/gookit/color v1.5.4 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -112,10 +117,12 @@ require ( github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/leodido/go-urn v1.2.4 // indirect + github.com/lithammer/fuzzysearch v1.1.8 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mcuadros/go-defaults v1.2.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect @@ -142,14 +149,16 @@ require ( github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 // indirect github.com/redis/go-redis/v9 v9.0.5 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/samber/lo v1.38.1 // indirect github.com/sanity-io/litter v1.5.5 // indirect - github.com/sergi/go-diff v1.0.0 // indirect + github.com/sergi/go-diff v1.2.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.16.0 // indirect github.com/streadway/amqp v1.1.0 // indirect github.com/stretchr/objx v0.5.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect @@ -169,6 +178,7 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect github.com/yudai/gojsondiff v1.0.0 // indirect @@ -191,6 +201,7 @@ require ( golang.org/x/net v0.15.0 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.12.0 // indirect + golang.org/x/term v0.12.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.13.0 // indirect diff --git a/internal/services/order_service/go.sum b/internal/services/order_service/go.sum index 21d6d331..3d8dbc97 100644 --- a/internal/services/order_service/go.sum +++ b/internal/services/order_service/go.sum @@ -1,3 +1,11 @@ +atomicgo.dev/assert v0.0.2 h1:FiKeMiZSgRrZsPo9qn/7vmr7mCsh5SZyXY4YGYiYwrg= +atomicgo.dev/assert v0.0.2/go.mod h1:ut4NcI3QDdJtlmAxQULOmA13Gz6e2DWbSAS8RUOmNYQ= +atomicgo.dev/cursor v0.2.0 h1:H6XN5alUJ52FZZUkI7AlJbUc1aW38GWZalpYRPpoPOw= +atomicgo.dev/cursor v0.2.0/go.mod h1:Lr4ZJB3U7DfPPOkbH7/6TOtJ4vFGHlgj1nc+n900IpU= +atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8= +atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ= +atomicgo.dev/schedule v0.1.0 h1:nTthAbhZS5YZmgYbb2+DH8uQIZcTlIrd4eYr3UQxEjs= +atomicgo.dev/schedule v0.1.0/go.mod h1:xeUa3oAkiuHYh8bKiQBRojqAMq3PXXbJujjb0hw8pEU= bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -59,6 +67,15 @@ github.com/EventStore/EventStore-Client-Go v1.0.2 h1:onM2TIInLhWUJwUQ/5a/8blNrrb github.com/EventStore/EventStore-Client-Go v1.0.2/go.mod h1:NOqSOtNxqGizr1Qnf7joGGLK6OkeoLV/QEI893A43H0= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= +github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= +github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= +github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k= +github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI= +github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c= +github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE= +github.com/MarvinJWendt/testza v0.5.2 h1:53KDo64C1z/h/d/stCYCPY69bt/OSwjq5KpFNwi+zB4= +github.com/MarvinJWendt/testza v0.5.2/go.mod h1:xu53QFE5sCdjtMCKk8YMQ2MnymimEctc4n3EjyIYvEY= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= @@ -83,6 +100,7 @@ github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhP github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -118,6 +136,8 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWH github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.7.5 h1:i9T9XpAWMe11BHMN7pu1BZqOGjXaKTPyz2v+KYOZgkY= github.com/containerd/containerd v1.7.5/go.mod h1:ieJNCSzASw2shSGYLHx8NAE7WsZ/gEigo5fQ78W5Zvw= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -314,6 +334,10 @@ github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= +github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= +github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= +github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e h1:XmA6L9IPRdUr28a+SK/oMchGgQy159wvzXA5tJ7l+40= github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e/go.mod h1:AFIo+02s+12CEg8Gzz9kzhCbmbq6JcKNrhHffCGA9z4= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= @@ -412,6 +436,11 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= +github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= +github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -443,6 +472,8 @@ github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= +github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -463,6 +494,9 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -546,6 +580,15 @@ github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdO github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI= +github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg= +github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE= +github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU= +github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= +github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= +github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= +github.com/pterm/pterm v0.12.69 h1:fBCKnB8dSLAl8FlYRQAWYGp2WTI/Xm/tKJ21Hyo9USw= +github.com/pterm/pterm v0.12.69/go.mod h1:wl06ko9MHnqxz4oDV++IORDpjCzw6+mfrvf0MPj6fdk= github.com/rabbitmq/amqp091-go v1.8.1 h1:RejT1SBUim5doqcL6s7iN6SBmsQqyTgXb1xMlH0h1hA= github.com/rabbitmq/amqp091-go v1.8.1/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc= github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho= @@ -555,6 +598,9 @@ github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnA github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= @@ -571,8 +617,9 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= @@ -671,6 +718,9 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= @@ -810,6 +860,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -877,6 +928,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -937,10 +989,12 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -952,8 +1006,12 @@ golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -965,6 +1023,7 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1033,6 +1092,7 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1144,6 +1204,7 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/internal/services/order_service/internal/shared/app/test/test_application_builder.go b/internal/services/order_service/internal/shared/app/test/test_application_builder.go index 7f9edb0f..f0aaedd3 100644 --- a/internal/services/order_service/internal/shared/app/test/test_application_builder.go +++ b/internal/services/order_service/internal/shared/app/test/test_application_builder.go @@ -1,12 +1,9 @@ package test import ( - "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/constants" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/fxapp/contracts" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/fxapp/test" - constants2 "github.com/mehdihadeli/go-ecommerce-microservices/internal/services/orderservice/internal/shared/constants" - "github.com/spf13/viper" "go.uber.org/fx/fxtest" ) @@ -16,9 +13,6 @@ type OrdersTestApplicationBuilder struct { } func NewOrdersTestApplicationBuilder(tb fxtest.TB) *OrdersTestApplicationBuilder { - // set viper internal registry, in real app we read it from `.env` file in current `executing working directory` for example `catalogs_service` - viper.Set(constants.PROJECT_NAME_ENV, constants2.PROJECT_NAME) - return &OrdersTestApplicationBuilder{ ApplicationBuilder: test.NewTestApplicationBuilder(tb), tb: tb, diff --git a/internal/services/order_service/internal/shared/constants/constants.go b/internal/services/order_service/internal/shared/constants/constants.go deleted file mode 100644 index 96816208..00000000 --- a/internal/services/order_service/internal/shared/constants/constants.go +++ /dev/null @@ -1,5 +0,0 @@ -package constants - -const ( - PROJECT_NAME = "order_service" -) diff --git a/internal/services/order_service/internal/shared/test_fixtures/integration/integration_test_fixture.go b/internal/services/order_service/internal/shared/test_fixtures/integration/integration_test_fixture.go index 6161416f..91032d12 100644 --- a/internal/services/order_service/internal/shared/test_fixtures/integration/integration_test_fixture.go +++ b/internal/services/order_service/internal/shared/test_fixtures/integration/integration_test_fixture.go @@ -2,7 +2,6 @@ package integration import ( "context" - "fmt" "testing" "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/es/contracts/store" @@ -52,15 +51,21 @@ type IntegrationTestSharedFixture struct { OrdersServiceClient ordersService.OrdersServiceClient } -func NewIntegrationTestSharedFixture(t *testing.T) *IntegrationTestSharedFixture { +func NewIntegrationTestSharedFixture( + t *testing.T, +) *IntegrationTestSharedFixture { result := test.NewTestApp().Run(t) // https://github.com/michaelklishin/rabbit-hole - rmqc, _ := rabbithole.NewClient( - fmt.Sprintf(result.RabbitmqOptions.RabbitmqHostOptions.HttpEndPoint()), + rmqc, err := rabbithole.NewClient( + result.RabbitmqOptions.RabbitmqHostOptions.HttpEndPoint(), result.RabbitmqOptions.RabbitmqHostOptions.UserName, result.RabbitmqOptions.RabbitmqHostOptions.Password) - + if err != nil { + result.Logger.Error( + errors.WrapIf(err, "error in creating rabbithole client"), + ) + } shared := &IntegrationTestSharedFixture{ Log: result.Logger, Container: result.Container, @@ -86,7 +91,7 @@ func (i *IntegrationTestSharedFixture) InitializeTest() { // seed data in each test res, err := seedReadModelData(i.mongoClient, i.MongoDbOptions.Database) if err != nil { - i.Log.Fatal(err) + i.Log.Error(errors.WrapIf(err, "error in seeding mongodb data")) } i.Items = res } @@ -96,18 +101,20 @@ func (i *IntegrationTestSharedFixture) DisposeTest() { // cleanup test containers with their hooks if err := i.cleanupRabbitmqData(); err != nil { - i.Log.Fatal(err) + i.Log.Error(errors.WrapIf(err, "error in cleanup rabbitmq data")) } if err := i.cleanupMongoData(); err != nil { - i.Log.Fatal(err) + i.Log.Error(errors.WrapIf(err, "error in cleanup mongodb data")) } } func (i *IntegrationTestSharedFixture) cleanupRabbitmqData() error { // https://github.com/michaelklishin/rabbit-hole // Get all queues - queues, err := i.RabbitmqCleaner.ListQueuesIn(i.rabbitmqOptions.RabbitmqHostOptions.VirtualHost) + queues, err := i.RabbitmqCleaner.ListQueuesIn( + i.rabbitmqOptions.RabbitmqHostOptions.VirtualHost, + ) if err != nil { return err } @@ -126,11 +133,19 @@ func (i *IntegrationTestSharedFixture) cleanupRabbitmqData() error { func (i *IntegrationTestSharedFixture) cleanupMongoData() error { collections := []string{orderCollection} - err := cleanupCollections(i.mongoClient, collections, i.MongoDbOptions.Database) + err := cleanupCollections( + i.mongoClient, + collections, + i.MongoDbOptions.Database, + ) return err } -func cleanupCollections(db *mongo.Client, collections []string, databaseName string) error { +func cleanupCollections( + db *mongo.Client, + collections []string, + databaseName string, +) error { database := db.Database(databaseName) ctx := context.Background() @@ -196,7 +211,11 @@ func seedReadModelData( } collection := db.Database(databaseName).Collection("orders") - _, err := collection.InsertMany(context.Background(), data, &options.InsertManyOptions{}) + _, err := collection.InsertMany( + context.Background(), + data, + &options.InsertManyOptions{}, + ) if err != nil { return nil, errors.WrapIf(err, "error in seed database") } diff --git a/scripts/atlas-migrate.sh b/scripts/atlas-migrate.sh new file mode 100644 index 00000000..3b8b9dcd --- /dev/null +++ b/scripts/atlas-migrate.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +# https://github.com/golang-migrate/migrate/tree/856ea12df9d230b0145e23d951b7dbd6b86621cb/cmd/migrate#usage + +echo "Running go migrate command..." +while getopts ":p:c:n:o:" opt; do + case $opt in + p) + path="$OPTARG" + ;; + c) + command="$OPTARG" + ;; + n) + name="$OPTARG" + ;; + o) + connection="$OPTARG" + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + exit 1 + ;; + esac +done + +if [ "$command" == "gorm-sync" ]; then + # shellcheck disable=SC2164 + # atlas migrate diff -h + cd "$path" + atlas migrate diff --env gorm --config "file://atlas.hcl" +elif [ "$command" == "apply" ]; then + # shellcheck disable=SC2164 + # atlas migrate apply -h + cd "$path" + atlas migrate apply --dir "file://db/migrations/atlas" --url "$connection" +elif [ "$command" == "down" ]; then + echo "Running down command..." +else + echo "Invalid command. Supported commands: create, up, down." +fi diff --git a/scripts/go-migrate.sh b/scripts/go-migrate.sh new file mode 100644 index 00000000..69b0a9f1 --- /dev/null +++ b/scripts/go-migrate.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# https://github.com/golang-migrate/migrate/tree/856ea12df9d230b0145e23d951b7dbd6b86621cb/cmd/migrate#usage + +echo "Running go migrate command..." +while getopts ":p:c:n:o:" opt; do + case $opt in + p) + path="$OPTARG" + ;; + c) + command="$OPTARG" + ;; + n) + name="$OPTARG" + ;; + o) + connection="$OPTARG" + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + exit 1 + ;; + esac +done + +if [ "$command" == "create" ]; then + migrate create -ext sql -dir "$path" -seq "$name" +elif [ "$command" == "up" ]; then + migrate -database "$connection" -verbose -path "$path" up +elif [ "$command" == "down" ]; then + migrate -database "$connection" -verbose -path "$path" down +else + echo "Invalid command. Supported commands: create, up, down." +fi diff --git a/scripts/goose-migrate.sh b/scripts/goose-migrate.sh new file mode 100644 index 00000000..883ecd2f --- /dev/null +++ b/scripts/goose-migrate.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +#!/bin/bash + + +echo "Running go migrate command..." +while getopts ":p:c:n:o:" opt; do + case $opt in + p) + path="$OPTARG" + ;; + c) + command="$OPTARG" + ;; + n) + name="$OPTARG" + ;; + o) + connection="$OPTARG" + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + exit 1 + ;; + esac +done + +if [ "$command" == "create" ]; then + goose -s -v -dir "$path" create "$name" sql +elif [ "$command" == "up" ]; then + goose -s -v -dir "$path" postgres "$connection" up +elif [ "$command" == "down" ]; then + goose -s -v -dir "$path" postgres "$connection" down +else + echo "Invalid command. Supported commands: create, up, down." +fi diff --git a/scripts/install-tools.sh b/scripts/install-tools.sh index 9c8cf3a7..e6f4c72d 100644 --- a/scripts/install-tools.sh +++ b/scripts/install-tools.sh @@ -1,5 +1,7 @@ #!/bin/bash +# https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md + # In a bash script, set -e is a command that enables the "exit immediately" option. When this option is set, the script will terminate immediately if any command within the script exits with a non-zero status (indicating an error). set -e @@ -35,6 +37,10 @@ go install google.golang.org/protobuf/proto@latest go install github.com/golang/protobuf/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest +# migration tools +go install github.com/pressly/goose/v3/cmd/goose@latest +go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest + # https://github.com/swaggo/swag/ # https://github.com/swaggo/swag/issues/817 # swag cli v1.8.3 - upper versions have some problems with generic types @@ -72,9 +78,14 @@ if [[ "$OS" == "Linux" ]]; then sudo apt-get install k6 sudo apt install diffutils + # Install atlas on linux + curl -sSf https://atlasgo.sh | sh + # https://grpc.io/docs/protoc-installation/ apt install -y protobuf-compiler elif [[ "$OS" == "MINGW"* || "$OS" == "MSYS"* ]]; then + # https://github.com/actions/runner-images/blob/main/images/win/Windows2022-Readme.md + # https://github.com/bufbuild/buf echo "Installing Buff on Windows..." # Windows installation commands @@ -89,6 +100,7 @@ elif [[ "$OS" == "MINGW"* || "$OS" == "MSYS"* ]]; then # https://community.chocolatey.org/packages/protoc # https://grpc.io/docs/protoc-installation/ + # choco is available on github windows-server choco install protoc choco install diffutils