From f48fffb7a52386c06ff49cc7072196b1b746a011 Mon Sep 17 00:00:00 2001 From: Sergey Bykov Date: Sat, 28 Mar 2026 14:38:34 +0300 Subject: [PATCH 1/4] Add --dir flag, Homebrew publishing, update tooling to Go 1.25 - Add --dir/-d flag to specify migrations directory independently from config file location - Add homebrew_casks config to .goreleaser.yaml for vmkteam/homebrew-tap - Pass HOMEBREW_TAP_TOKEN to goreleaser workflow - Upgrade golangci-lint to v2 config format with extended linter set - Replace goimports with golangci-lint fmt in Makefile - Bump Go version from 1.20 to 1.25 in go.mod and all CI workflows - Upgrade GitHub Actions to v6 (checkout, setup-go, goreleaser) - Fix linter issues: errorlint, perfsprint, funcorder, staticcheck, whitespace - Add Homebrew install instructions to README.md and README.ru.md - Remove outdated limitation about config file location from docs --- .github/workflows/go.yml | 6 +- .github/workflows/golangci-lint.yml | 34 +---- .github/workflows/goreleaser.yml | 9 +- .golangci.yml | 217 +++++++++++++++++++--------- .goreleaser.yaml | 11 ++ Makefile | 8 +- README.md | 16 +- README.ru.md | 16 +- go.mod | 30 ++-- go.sum | 38 +++++ main.go | 19 ++- pkg/app/app.go | 4 +- pkg/migrator/migrator.go | 6 +- pkg/migrator/migrator_test.go | 11 +- pkg/migrator/model.go | 16 +- 15 files changed, 287 insertions(+), 154 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 42dfb1f..de063b2 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -16,12 +16,12 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v6 with: - go-version: '1.20.x' + go-version: '1.25.x' - name: Build run: go build -v ./... diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 768b11d..462edef 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -5,42 +5,22 @@ on: - v* branches: - master - - main pull_request: + permissions: contents: read - # Optional: allow read access to pull request. Use with `only-new-issues` option. pull-requests: read + jobs: golangci: name: lint runs-on: ubuntu-latest steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v6 with: - go-version: '1.20.x' - - uses: actions/checkout@v4 + go-version: '1.25.x' + - uses: actions/checkout@v6 - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v9 with: - # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version - version: v1.54.2 - - # Optional: working directory, useful for monorepos - # working-directory: somedir - - # Optional: golangci-lint command line arguments. - # args: --issues-exit-code=0 - - # Optional: show only new issues if it's a pull request. The default value is `false`. - # only-new-issues: true - - # Optional: if set to true then the all caching functionality will be complete disabled, - # takes precedence over all other caching options. - # skip-cache: true - - # Optional: if set to true then the action don't cache or restore ~/go/pkg. - # skip-pkg-cache: true - - # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. - # skip-build-cache: true + version: v2.8.0 diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml index 68bb655..9de985d 100644 --- a/.github/workflows/goreleaser.yml +++ b/.github/workflows/goreleaser.yml @@ -14,20 +14,21 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v6 with: - go-version: '1.20.x' + go-version: '1.25.x' - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v4 + uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser version: latest args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} diff --git a/.golangci.yml b/.golangci.yml index 3be6dec..d90826b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,82 +1,159 @@ -run: - # default concurrency is a available CPU number - concurrency: 4 - - # timeout for analysis, e.g. 30s, 5m, default is 1m - deadline: 30m - - # exit code when at least one issue was found, default is 1 - issues-exit-code: 1 - - # include test files or not, default is true - tests: true - - # skip files - skip-files: - - ".*\\_gen\\.go$" - -output: - # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" - format: colored-line-number - - # print lines of code with issue, default is true - print-issued-lines: true - - # print linter name in the end of issue text, default is true - print-linter-name: true - -linters-settings: - goimports: - # put imports beginning with prefix after 3rd-party packages; - # it's a comma-separated list of prefixes - local-prefixes: github.com/vmkteam/zenrpc - gocritic: - # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint` run to see all tags and checks. - # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". - enabled-checks: - - appendAssign - - appendCombine - - assignOp - - badCond - - boolExprSimplify - - captLocal - - caseOrder - - defaultCaseOrder - - dupArg - - dupBranchBody - - dupCase - - dupSubExpr - - elseif - - emptyFallthrough - - emptyStringTest - - equalFold - - exitAfterDefer - - flagName - - hexLiteral - - indexAlloc - - nilValReturn - - offBy1 - - regexpMust - - sloppyLen - - switchTrue - - wrapperFunc - - yodaStyleExpr +version: "2" linters: - enable-all: false - disable-all: true enable: + - asasalint + - asciicheck + - bidichk - bodyclose - - dogsled + - canonicalheader + - copyloopvar + - cyclop - dupl + - durationcheck + - errcheck + - errname + - errorlint + - exhaustive + - exptostd + - fatcontext + #- forbidigo + - funcorder + - funlen + - gocheckcompilerdirectives + - gochecknoinits + - gochecksumtype + - gocognit - goconst - - gofmt - - goimports - - gosimple - gocritic + - gocyclo + - goprintffuncname - govet + - iface - ineffassign + - intrange + - loggercheck + - makezero + - mirror + - nestif + - nilerr + - nilnesserr + - noctx + - nosprintfhostport + - perfsprint + - predeclared + - promlinter + - protogetter + - recvcheck + - rowserrcheck + - sloglint + - spancheck + - sqlclosecheck - staticcheck - - typecheck + - testableexamples + - testifylint + - tparallel - unconvert + - unparam - unused + - usestdlibvars + - usetesting + - wastedassign + - whitespace + - decorder + - ginkgolinter + - goheader + - inamedparam + - interfacebloat + - prealloc + - zerologlint + settings: + cyclop: + max-complexity: 30 + package-average: 10.0 + + errcheck: + check-type-assertions: true + + exhaustive: + check: + - switch + - map + + funcorder: + struct-method: false + + funlen: + lines: 100 + statements: 50 + + gochecksumtype: + default-signifies-exhaustive: false + + gocognit: + min-complexity: 32 + + gocritic: + settings: + captLocal: + paramsOnly: false + underef: + skipRecvDeref: false + + govet: + enable-all: true + disable: + - fieldalignment + settings: + shadow: + strict: false + + inamedparam: + skip-single-param: true + + nakedret: + max-func-lines: 0 + + perfsprint: + strconcat: false + + staticcheck: + checks: + - all + - -ST1000 + - -ST1016 + - -QF1008 + + usetesting: + os-temp-dir: true + + exclusions: + warn-unused: false + presets: + - std-error-handling + - common-false-positives + rules: + - source: 'TODO' + linters: [ godot ] + - path: '_test\.go' + linters: + - bodyclose + - dupl + - errcheck + - funlen + - goconst + - noctx + +formatters: + enable: + - gci + settings: + gci: + sections: + - standard + - localmodule + - default + no-inline-comments: true + no-prefix-comments: true + custom-order: true + no-lex-order: true diff --git a/.goreleaser.yaml b/.goreleaser.yaml index b56851b..22621c8 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -5,3 +5,14 @@ builds: - linux - windows - darwin + +homebrew_casks: + - name: pgmigrator + binaries: + - pgmigrator + homepage: "https://github.com/vmkteam/pgmigrator" + description: "Command-line tool for PostgreSQL migrations" + repository: + owner: vmkteam + name: homebrew-tap + token: "{{ .Env.HOMEBREW_TAP_TOKEN }}" diff --git a/Makefile b/Makefile index 671d930..c4bb28f 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,14 @@ PKG := `go list -f {{.Dir}} ./...` +LINT_VERSION := v2.8.0 + fmt: - @goimports -local "github.com/vmkteam/pgmigrator" -l -w $(PKG) + @golangci-lint fmt lint: - @golangci-lint run -c .golangci.yml + @golangci-lint version + @golangci-lint config verify + @golangci-lint run test: @go test -v ./... diff --git a/README.md b/README.md index 4bc41b0..898453c 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,6 @@ Limitations * Migrations filename mask: `YYYYY-MM-DDD-.sql` / `YYYYY-MM-DD--NONTR.sql` * Migration types: UP only * Algorithm: applies sorted migrations files that are in the folder and fit the file mask, except for what is already applied in the database -* The program works only with the configuration file located in the folder with migrations. - - FAQ -- Q: Why only up migrations?
@@ -89,6 +86,7 @@ Run Flags: -c, --config string configuration file (default "pgmigrator.toml") + -d, --dir string path to migrations directory -h, --help help for pgmigrator -v, --version version for pgmigrator @@ -97,7 +95,7 @@ Run Any command supports an argument in the form of a number. For `last` it is the number of last migrations (default is 5). For all others - the number of the file from `plan` to which to apply migrations. If no argument is passed, there are no restrictions (or default ones are used). The base directory for migrations is the one where the configuration file is located. -That is, you can call `pgmigrator --config docs/patches/pgmigrator.toml plan` and it will take all migrations from the `docs/patches` folder. +You can override it with `--dir` flag: `pgmigrator --config pgmigrator.toml --dir docs/patches plan`. ## Commands @@ -208,6 +206,14 @@ It is recommended to have a different migrations table for each schema. * transactional - transactional flag (false для NONTR migrations) * md5sum - md5 hash of migration file -### Docker images +### Install + +#### Homebrew +```bash +brew tap vmkteam/tap +brew install pgmigrator +``` + +#### Docker images - [Docker Hub](https://hub.docker.com/r/vmkteam/pgmigrator) - Packages Tab in this repo diff --git a/README.ru.md b/README.ru.md index 28c4481..d29523e 100644 --- a/README.ru.md +++ b/README.ru.md @@ -17,9 +17,6 @@ pgmigrator очень простая утилита, предназначенн * Маска файлов миграций: `YYYY-MM-DDD-.sql` / `YYYY-MM-DD--NONTR.sql` * Типы миграций: только UP * Алгоритм: применяем к базе данных отсортированные файлы с миграциями, которые есть в папке и подходят по маске файла, кроме тех, которые уже применены к базе -* Программа работает только с конфигурационным файлом, расположенным в папке с миграциями. - - FAQ -- Q: Почему только up миграции?
@@ -91,6 +88,7 @@ A: Цель - простая утилита, которая работает с Flags: -c, --config string configuration file (default "pgmigrator.toml") + -d, --dir string path to migrations directory -h, --help help for pgmigrator -v, --version version for pgmigrator @@ -99,7 +97,7 @@ A: Цель - простая утилита, которая работает с Любая команда поддерживает аргумент в виде числа. Для `last` - это количество последних миграций (по умолчанию 5). Для всех остальных – номер файла из `plan`, до которого применять миграции. Если аргумент не передан, то ограничений нет (или используется значение по умолчанию). Базовая директория для миграций - та, в которой расположен файл конфигурации. -То есть можно вызвать `pgmigrator --config docs/patches/pgmigrator.toml plan` - и он возьмет все миграции из папки `docs/patches`. +Можно переопределить через флаг `--dir`: `pgmigrator --config pgmigrator.toml --dir docs/patches plan`. ### Plan @@ -224,6 +222,14 @@ A: Цель - простая утилита, которая работает с При обновлении из гита можно вызвать `pgmigrator plan` из `docs/patches` и посмотреть новые патчи. Внедрять можно на любой стадии проекта. -### Docker образы +### Установка + +#### Homebrew +```bash +brew tap vmkteam/tap +brew install pgmigrator +``` + +#### Docker образы - [Docker Hub](https://hub.docker.com/vmkteam/pgmigrator) - Вкладка Packages в этом репозитории diff --git a/go.mod b/go.mod index 1156def..1cf3ca9 100644 --- a/go.mod +++ b/go.mod @@ -1,32 +1,32 @@ module github.com/vmkteam/pgmigrator -go 1.20 +go 1.25.0 require ( - github.com/BurntSushi/toml v1.3.2 - github.com/fatih/color v1.15.0 - github.com/go-pg/pg/v10 v10.11.1 - github.com/rodaine/table v1.1.0 + github.com/BurntSushi/toml v1.6.0 + github.com/fatih/color v1.19.0 + github.com/go-pg/pg/v10 v10.15.0 + github.com/rodaine/table v1.3.1 github.com/smartystreets/goconvey v1.8.1 - github.com/spf13/cobra v1.7.0 + github.com/spf13/cobra v1.10.2 ) require ( github.com/go-pg/zerochecker v0.2.0 // indirect - github.com/gopherjs/gopherjs v1.17.2 // indirect + github.com/gopherjs/gopherjs v1.20.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect - github.com/smarty/assertions v1.15.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/smarty/assertions v1.16.0 // indirect + github.com/spf13/pflag v1.0.10 // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/vmihailenco/bufpool v0.1.11 // indirect - github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - golang.org/x/crypto v0.1.0 // indirect - golang.org/x/sys v0.6.0 // indirect - mellium.im/sasl v0.3.1 // indirect + golang.org/x/crypto v0.49.0 // indirect + golang.org/x/sys v0.42.0 // indirect + mellium.im/sasl v0.3.2 // indirect ) diff --git a/go.sum b/go.sum index 3d1a0d3..a81c7df 100644 --- a/go.sum +++ b/go.sum @@ -2,9 +2,12 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= +github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -12,11 +15,16 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= +github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/go-pg/pg/v10 v10.11.1 h1:vYwbFpqoMpTDphnzIPshPPepdy3VpzD8qo29OFKp4vo= github.com/go-pg/pg/v10 v10.11.1/go.mod h1:ExJWndhDNNftBdw1Ow83xqpSf4WMSJK8urmXD5VXS1I= +github.com/go-pg/pg/v10 v10.15.0 h1:6DQwbaxJz/e4wvgzbxBkBLiL/Uuk87MGgHhkURtzx24= +github.com/go-pg/pg/v10 v10.15.0/go.mod h1:FIn/x04hahOf9ywQ1p68rXqaDVbTRLYlu4MQR0lhoB8= github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -41,6 +49,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= +github.com/gopherjs/gopherjs v1.20.1 h1:22uLWFvVcxhJ+j3dJ99NNfwGyHynxCmjhYsrcwqbY60= +github.com/gopherjs/gopherjs v1.20.1/go.mod h1:h+FTmmLgbXMmmtuZFp9bUqXciN429Wx0sJEJuMnpyfM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -54,9 +64,13 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= @@ -76,15 +90,25 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rodaine/table v1.1.0 h1:/fUlCSdjamMY8VifdQRIu3VWZXYLY7QHFkVorS8NTr4= github.com/rodaine/table v1.1.0/go.mod h1:Qu3q5wi1jTQD6B6HsP6szie/S4w1QUQ8pq22pz9iL8g= +github.com/rodaine/table v1.3.1 h1:jBVgg1bEu5EzEdYSrwUUlQpayDtkvtTmgFS0FPAxOq8= +github.com/rodaine/table v1.3.1/go.mod h1:VYCJRCHa2DpD25uFALcB6hi5ECF3eEJQVhCXRjHgXc4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= +github.com/smarty/assertions v1.16.0 h1:EvHNkdRA4QHMrn75NZSoUQ/mAUXAYWfatfB01yTCzfY= +github.com/smarty/assertions v1.16.0/go.mod h1:duaaFdCS0K9dnoM50iyek/eYINOZ64gbh1Xlf6LG7AI= github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= 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/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -96,17 +120,24 @@ github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6cz github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= github.com/vmihailenco/msgpack/v5 v5.3.4 h1:qMKAwOV+meBw2Y8k9cVwAy7qErtYCwBzZ2ellBfvnqc= github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -125,6 +156,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -148,6 +180,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -157,6 +191,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -167,6 +202,7 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -202,3 +238,5 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= +mellium.im/sasl v0.3.2 h1:PT6Xp7ccn9XaXAnJ03FcEjmAn7kK1x7aoXV6F+Vmrl0= +mellium.im/sasl v0.3.2/go.mod h1:NKXDi1zkr+BlMHLQjY3ofYuU4KSPFxknb8mfEu6SveY= diff --git a/main.go b/main.go index a58671b..4b1da5a 100644 --- a/main.go +++ b/main.go @@ -7,19 +7,24 @@ import ( "path/filepath" "runtime/debug" + "github.com/vmkteam/pgmigrator/pkg/app" + "github.com/vmkteam/pgmigrator/pkg/migrator" + "github.com/BurntSushi/toml" "github.com/go-pg/pg/v10" "github.com/spf13/cobra" - "github.com/vmkteam/pgmigrator/pkg/app" - "github.com/vmkteam/pgmigrator/pkg/migrator" ) -var cfgFile string +var ( + cfgFile string + migrationsDir string +) func main() { log.SetFlags(0) rootCmd := newRootCmd() rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", app.DefaultConfigFile, "configuration file") + rootCmd.PersistentFlags().StringVarP(&migrationsDir, "dir", "d", "", "path to migrations directory") rootCmd.InitDefaultVersionFlag() rootCmd.InitDefaultHelpFlag() exitOnErr(rootCmd.ParseFlags(os.Args)) @@ -41,7 +46,13 @@ func main() { cfg.ConfigFile, err = filepath.Abs(cfgFile) exitOnErr(err) - mg = migrator.NewMigrator(pg.Connect(cfg.Database), cfg.App, filepath.Dir(cfg.ConfigFile)) + rootDir := filepath.Dir(cfg.ConfigFile) + if migrationsDir != "" { + rootDir, err = filepath.Abs(migrationsDir) + exitOnErr(err) + } + + mg = migrator.NewMigrator(pg.Connect(cfg.Database), cfg.App, rootDir) } // create app and run diff --git a/pkg/app/app.go b/pkg/app/app.go index 8800175..3a94ef7 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -11,13 +11,13 @@ import ( "sync" "time" + "github.com/vmkteam/pgmigrator/pkg/migrator" + "github.com/BurntSushi/toml" "github.com/fatih/color" "github.com/go-pg/pg/v10" "github.com/rodaine/table" "github.com/spf13/cobra" - - "github.com/vmkteam/pgmigrator/pkg/migrator" ) const ( diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go index df2384f..f67d23c 100644 --- a/pkg/migrator/migrator.go +++ b/pkg/migrator/migrator.go @@ -176,7 +176,7 @@ func finishTxOnErr(tx *pg.Tx, err error) error { } if er != nil { - err = fmt.Errorf("failed to finish transation er=%v: %w", er, err) + err = fmt.Errorf("failed to finish transaction er=%w: %w", er, err) } return err @@ -350,7 +350,7 @@ func (m *Migrator) skipMigrations(ctx context.Context, mm Migrations, chCurrentF func alwaysRollbackTx(tx *pg.Tx, err error) error { if er := tx.Rollback(); er != nil { - err = fmt.Errorf("failed to finish transation er=%v: %w", er, err) + err = fmt.Errorf("failed to finish transation er=%w: %w", er, err) } return err @@ -429,7 +429,7 @@ func (m *Migrator) Redo(ctx context.Context, chCurrentFile chan string) (*PgMigr var pm PgMigration if err := m.db.ModelContext(ctx, &pm).Order(`id desc`).Limit(1).Select(); err != nil { if errors.Is(err, pg.ErrNoRows) { - return nil, fmt.Errorf(`applied migrations were not found`) + return nil, errors.New(`applied migrations were not found`) } return nil, fmt.Errorf(`fetch last migration failed: %w`, err) } diff --git a/pkg/migrator/migrator_test.go b/pkg/migrator/migrator_test.go index 0824827..cd326ea 100644 --- a/pkg/migrator/migrator_test.go +++ b/pkg/migrator/migrator_test.go @@ -10,7 +10,7 @@ import ( ) var ( - testDb *pg.DB + testDB *pg.DB testConfig Config testMigrator *Migrator dbConn = env("DB_CONN", "postgres://postgres:postgres@localhost:5432/pgmigrator?sslmode=disable") @@ -33,9 +33,9 @@ func NewTestDB() *pg.DB { } func TestMain(m *testing.M) { - testDb = NewTestDB() + testDB = NewTestDB() testConfig = NewDefaultConfig() - testMigrator = NewMigrator(testDb, testConfig, "testdata") + testMigrator = NewMigrator(testDB, testConfig, "testdata") os.Exit(m.Run()) } @@ -115,7 +115,6 @@ func TestNewMigration(t *testing.T) { Transactional: true, }) }) - } func TestMigrator_prepareMigrationsToRun(t *testing.T) { @@ -275,7 +274,7 @@ func TestMigrator_Redo(t *testing.T) { err = execRun(ctx, t) So(err, ShouldBeNil) - _, err = testDb.Exec("DROP TABLE tags CASCADE;") + _, err = testDB.Exec("DROP TABLE tags CASCADE;") So(err, ShouldBeNil) ch := make(chan string) @@ -500,6 +499,6 @@ func readFromCh(ch chan string, t *testing.T) { } func recreateSchema() error { - _, err := testDb.Exec("DROP SCHEMA public CASCADE; CREATE SCHEMA PUBLIC;") + _, err := testDB.Exec("DROP SCHEMA public CASCADE; CREATE SCHEMA PUBLIC;") return err } diff --git a/pkg/migrator/model.go b/pkg/migrator/model.go index 994b7e9..49bf416 100644 --- a/pkg/migrator/model.go +++ b/pkg/migrator/model.go @@ -42,14 +42,6 @@ type Migration struct { Transactional bool } -func (m *Migration) ToDB() *PgMigration { - return &PgMigration{ - Filename: m.Filename, - Transactional: m.Transactional, - Md5sum: m.Md5Sum, - } -} - func NewMigration(rootDir, filename string) (Migration, error) { f, err := os.ReadFile(filepath.Join(rootDir, filename)) if err != nil { @@ -66,6 +58,14 @@ func NewMigration(rootDir, filename string) (Migration, error) { return m, nil } +func (m *Migration) ToDB() *PgMigration { + return &PgMigration{ + Filename: m.Filename, + Transactional: m.Transactional, + Md5sum: m.Md5Sum, + } +} + type Migrations []Migration func (mm Migrations) FirstNonTransactional() (*Migration, bool) { From aa7389513b20aba99f2274fc45f8c18d9457c31e Mon Sep 17 00:00:00 2001 From: Sergey Bykov Date: Sat, 28 Mar 2026 15:00:18 +0300 Subject: [PATCH 2/4] Replace goconvey with testify, fix error handling and minor issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace goconvey with testify assert/require using t.Run for BDD style - Remove goconvey, gopherjs, jtolds/gls, smarty/assertions dependencies - Fix log.Fatal in runCmd/dryRunCmd/skipCmd to return error consistently - Fix typo "transation" → "transaction" in alwaysRollbackTx - Compile FileMask regex once in NewMigrator instead of per readAllFiles call - Use os.Stat instead of full file read for existence check in Redo - Remove dead "main" branch trigger from go.yml workflow --- .github/workflows/go.yml | 1 - go.mod | 9 +- go.sum | 182 +--------- pkg/app/app.go | 6 +- pkg/migrator/migrator.go | 24 +- pkg/migrator/migrator_test.go | 648 ++++++++++++++++------------------ 6 files changed, 340 insertions(+), 530 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index de063b2..1353df5 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -5,7 +5,6 @@ on: - v* branches: - master - - main pull_request: permissions: diff --git a/go.mod b/go.mod index 1cf3ca9..4f312a2 100644 --- a/go.mod +++ b/go.mod @@ -7,19 +7,19 @@ require ( github.com/fatih/color v1.19.0 github.com/go-pg/pg/v10 v10.15.0 github.com/rodaine/table v1.3.1 - github.com/smartystreets/goconvey v1.8.1 github.com/spf13/cobra v1.10.2 + github.com/stretchr/testify v1.11.1 ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/go-pg/zerochecker v0.2.0 // indirect - github.com/gopherjs/gopherjs v1.20.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/smarty/assertions v1.16.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/vmihailenco/bufpool v0.1.11 // indirect @@ -28,5 +28,6 @@ require ( github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect golang.org/x/crypto v0.49.0 // indirect golang.org/x/sys v0.42.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect mellium.im/sasl v0.3.2 // indirect ) diff --git a/go.sum b/go.sum index a81c7df..f09a7eb 100644 --- a/go.sum +++ b/go.sum @@ -1,242 +1,90 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY= +github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= -github.com/go-pg/pg/v10 v10.11.1 h1:vYwbFpqoMpTDphnzIPshPPepdy3VpzD8qo29OFKp4vo= -github.com/go-pg/pg/v10 v10.11.1/go.mod h1:ExJWndhDNNftBdw1Ow83xqpSf4WMSJK8urmXD5VXS1I= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/go-pg/pg/v10 v10.15.0 h1:6DQwbaxJz/e4wvgzbxBkBLiL/Uuk87MGgHhkURtzx24= github.com/go-pg/pg/v10 v10.15.0/go.mod h1:FIn/x04hahOf9ywQ1p68rXqaDVbTRLYlu4MQR0lhoB8= github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= -github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= -github.com/gopherjs/gopherjs v1.20.1 h1:22uLWFvVcxhJ+j3dJ99NNfwGyHynxCmjhYsrcwqbY60= -github.com/gopherjs/gopherjs v1.20.1/go.mod h1:h+FTmmLgbXMmmtuZFp9bUqXciN429Wx0sJEJuMnpyfM= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.21 h1:jJKAZiQH+2mIinzCJIaIG9Be1+0NR+5sz/lYEEjdM8w= +github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= 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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rodaine/table v1.1.0 h1:/fUlCSdjamMY8VifdQRIu3VWZXYLY7QHFkVorS8NTr4= -github.com/rodaine/table v1.1.0/go.mod h1:Qu3q5wi1jTQD6B6HsP6szie/S4w1QUQ8pq22pz9iL8g= github.com/rodaine/table v1.3.1 h1:jBVgg1bEu5EzEdYSrwUUlQpayDtkvtTmgFS0FPAxOq8= github.com/rodaine/table v1.3.1/go.mod h1:VYCJRCHa2DpD25uFALcB6hi5ECF3eEJQVhCXRjHgXc4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= -github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= -github.com/smarty/assertions v1.16.0 h1:EvHNkdRA4QHMrn75NZSoUQ/mAUXAYWfatfB01yTCzfY= -github.com/smarty/assertions v1.16.0/go.mod h1:duaaFdCS0K9dnoM50iyek/eYINOZ64gbh1Xlf6LG7AI= -github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= -github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= -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/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94= github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= -github.com/vmihailenco/msgpack/v5 v5.3.4 h1:qMKAwOV+meBw2Y8k9cVwAy7qErtYCwBzZ2ellBfvnqc= -github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 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-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 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.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= -mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= mellium.im/sasl v0.3.2 h1:PT6Xp7ccn9XaXAnJ03FcEjmAn7kK1x7aoXV6F+Vmrl0= mellium.im/sasl v0.3.2/go.mod h1:NKXDi1zkr+BlMHLQjY3ofYuU4KSPFxknb8mfEu6SveY= diff --git a/pkg/app/app.go b/pkg/app/app.go index 3a94ef7..3a2a1ef 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -206,7 +206,7 @@ If applied, applies only migrations from plan. By default: 5`, // calculate count cnt, err := count(args) if err != nil { - log.Fatal("invalid argument") + return errors.New("invalid argument") } else if cnt > len(mm) { cnt = len(mm) } @@ -245,7 +245,7 @@ If applied, runs only migrations. By default: 5`, // calculate count cnt, err := count(args) if err != nil { - log.Fatal("invalid argument") + return errors.New("invalid argument") } else if cnt > len(mm) { cnt = len(mm) } @@ -285,7 +285,7 @@ If applied, marks only first migrations displayed in plan. Defau // calculate count cnt, err := count(args) if err != nil { - log.Fatal("invalid argument") + return errors.New("invalid argument") } else if cnt > len(mm) { cnt = len(mm) } diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go index f67d23c..2f52081 100644 --- a/pkg/migrator/migrator.go +++ b/pkg/migrator/migrator.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "os" + "path/filepath" "regexp" "sort" "strings" @@ -15,16 +16,18 @@ import ( ) type Migrator struct { - db *pg.DB - cfg Config - rootDir string // patches + db *pg.DB + cfg Config + rootDir string // patches + fileMask *regexp.Regexp } func NewMigrator(db *pg.DB, cfg Config, rootDir string) *Migrator { m := &Migrator{ - db: db, - cfg: cfg, - rootDir: rootDir, + db: db, + cfg: cfg, + rootDir: rootDir, + fileMask: regexp.MustCompile(cfg.FileMask), } if db != nil { @@ -61,9 +64,8 @@ func (m *Migrator) readAllFiles() ([]string, error) { } var filenames []string - var namesToExecRegex = regexp.MustCompile(m.cfg.FileMask) for _, f := range files { - if f.IsDir() || !namesToExecRegex.MatchString(f.Name()) { + if f.IsDir() || !m.fileMask.MatchString(f.Name()) { continue } else if strings.HasSuffix(f.Name(), "MANUAL.sql") { // skip manual migrations @@ -350,7 +352,7 @@ func (m *Migrator) skipMigrations(ctx context.Context, mm Migrations, chCurrentF func alwaysRollbackTx(tx *pg.Tx, err error) error { if er := tx.Rollback(); er != nil { - err = fmt.Errorf("failed to finish transation er=%w: %w", er, err) + err = fmt.Errorf("failed to finish transaction er=%w: %w", er, err) } return err @@ -434,8 +436,8 @@ func (m *Migrator) Redo(ctx context.Context, chCurrentFile chan string) (*PgMigr return nil, fmt.Errorf(`fetch last migration failed: %w`, err) } - // create and check if exists - if _, err := NewMigration(m.rootDir, pm.Filename); err != nil { + // check if migration file exists + if _, err := os.Stat(filepath.Join(m.rootDir, pm.Filename)); err != nil { return nil, fmt.Errorf(`find migration file "%s" failed: %w`, pm.Filename, err) } diff --git a/pkg/migrator/migrator_test.go b/pkg/migrator/migrator_test.go index cd326ea..53d05bd 100644 --- a/pkg/migrator/migrator_test.go +++ b/pkg/migrator/migrator_test.go @@ -6,7 +6,8 @@ import ( "testing" "github.com/go-pg/pg/v10" - . "github.com/smartystreets/goconvey/convey" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( @@ -42,67 +43,60 @@ func TestMain(m *testing.M) { func TestMigrator_Plan(t *testing.T) { ctx := context.Background() - Convey("TestMigrator_Plan", t, func() { - err := recreateSchema() - So(err, ShouldBeNil) + err := recreateSchema() + require.NoError(t, err) - want := []string{ - "2022-12-12-01-create-table-statuses.sql", - "2022-12-12-02-create-table-news.sql", - "2022-12-12-03-add-comments-news-NONTR.sql", - "2022-12-13-01-create-categories-table.sql", - "2022-12-13-02-create-tags-table.sql", - } - got, err := testMigrator.Plan(ctx) - So(err, ShouldBeNil) - So(got, ShouldResemble, want) - }) + want := []string{ + "2022-12-12-01-create-table-statuses.sql", + "2022-12-12-02-create-table-news.sql", + "2022-12-12-03-add-comments-news-NONTR.sql", + "2022-12-13-01-create-categories-table.sql", + "2022-12-13-02-create-tags-table.sql", + } + got, err := testMigrator.Plan(ctx) + require.NoError(t, err) + assert.Equal(t, want, got) } func TestMigrator_readFiles(t *testing.T) { - Convey("TestMigrator_readFiles", t, func() { - want := []string{ - "2022-12-12-01-create-table-statuses.sql", - "2022-12-12-02-create-table-news.sql", - "2022-12-12-03-add-comments-news-NONTR.sql", - "2022-12-13-01-create-categories-table.sql", - "2022-12-13-02-create-tags-table.sql", - } + want := []string{ + "2022-12-12-01-create-table-statuses.sql", + "2022-12-12-02-create-table-news.sql", + "2022-12-12-03-add-comments-news-NONTR.sql", + "2022-12-13-01-create-categories-table.sql", + "2022-12-13-02-create-tags-table.sql", + } - filenames, err := testMigrator.readAllFiles() - So(err, ShouldBeNil) - So(filenames, ShouldResemble, want) - }) + filenames, err := testMigrator.readAllFiles() + require.NoError(t, err) + assert.Equal(t, want, filenames) } func TestMigrator_compareFilenames(t *testing.T) { - Convey("TestMigrator_compareFilenames", t, func() { - dirFiles := []string{ - "2022-12-12-01-create-table-statuses.sql", - "2022-12-12-02-create-table-news.sql", - "2022-12-12-03-add-comments-news-NONTR.sql", - "2022-12-13-01-create-categories-table.sql", - "2022-12-13-02-create-tags-table.sql", - } - completedFiles := []string{"2022-12-12-01-create-table-statuses.sql"} - want := []string{ - "2022-12-12-02-create-table-news.sql", - "2022-12-12-03-add-comments-news-NONTR.sql", - "2022-12-13-01-create-categories-table.sql", - "2022-12-13-02-create-tags-table.sql", - } - res := testMigrator.removeCompleted(dirFiles, completedFiles) - So(res, ShouldResemble, want) - }) + dirFiles := []string{ + "2022-12-12-01-create-table-statuses.sql", + "2022-12-12-02-create-table-news.sql", + "2022-12-12-03-add-comments-news-NONTR.sql", + "2022-12-13-01-create-categories-table.sql", + "2022-12-13-02-create-tags-table.sql", + } + completedFiles := []string{"2022-12-12-01-create-table-statuses.sql"} + want := []string{ + "2022-12-12-02-create-table-news.sql", + "2022-12-12-03-add-comments-news-NONTR.sql", + "2022-12-13-01-create-categories-table.sql", + "2022-12-13-02-create-tags-table.sql", + } + res := testMigrator.removeCompleted(dirFiles, completedFiles) + assert.Equal(t, want, res) } func TestNewMigration(t *testing.T) { - Convey("TestMigrator_compareFilenames", t, func() { - res, err := NewMigration(testMigrator.rootDir, "2022-12-12-01-create-table-statuses.sql") - So(err, ShouldBeNil) - So(res, ShouldResemble, Migration{ - Filename: "2022-12-12-01-create-table-statuses.sql", - Data: []byte(`CREATE TABLE "statuses" + res, err := NewMigration(testMigrator.rootDir, "2022-12-12-01-create-table-statuses.sql") + require.NoError(t, err) + assert.Equal(t, Migration{ + Filename: "2022-12-12-01-create-table-statuses.sql", + Data: []byte(`CREATE TABLE "statuses" ( "statusId" SERIAL NOT NULL, "title" varchar(255) NOT NULL, @@ -111,105 +105,83 @@ func TestNewMigration(t *testing.T) { CONSTRAINT "statuses_alias_key" UNIQUE ("alias") ); `), - Md5Sum: "463fe73a85e13dd55fe210904ec19d7c", - Transactional: true, - }) - }) + Md5Sum: "463fe73a85e13dd55fe210904ec19d7c", + Transactional: true, + }, res) } func TestMigrator_prepareMigrationsToRun(t *testing.T) { - Convey("TestMigrator_prepareMigrationsToRun", t, func() { - dirFiles := []string{ - "2022-12-12-01-create-table-statuses.sql", - "2022-12-12-02-create-table-news.sql", - "2022-12-12-03-add-comments-news-NONTR.sql", - "2022-12-13-01-create-categories-table.sql", - "2022-12-13-02-create-tags-table.sql", - } - want := []Migration{ - { - Filename: "2022-12-12-01-create-table-statuses.sql", - Transactional: true, - }, - { - Filename: "2022-12-12-02-create-table-news.sql", - Transactional: true, - }, - { - Filename: "2022-12-12-03-add-comments-news-NONTR.sql", - Transactional: false, - }, - { - Filename: "2022-12-13-01-create-categories-table.sql", - Transactional: true, - }, - { - Filename: "2022-12-13-02-create-tags-table.sql", - Transactional: true, - }, - } + dirFiles := []string{ + "2022-12-12-01-create-table-statuses.sql", + "2022-12-12-02-create-table-news.sql", + "2022-12-12-03-add-comments-news-NONTR.sql", + "2022-12-13-01-create-categories-table.sql", + "2022-12-13-02-create-tags-table.sql", + } + want := []Migration{ + {Filename: "2022-12-12-01-create-table-statuses.sql", Transactional: true}, + {Filename: "2022-12-12-02-create-table-news.sql", Transactional: true}, + {Filename: "2022-12-12-03-add-comments-news-NONTR.sql", Transactional: false}, + {Filename: "2022-12-13-01-create-categories-table.sql", Transactional: true}, + {Filename: "2022-12-13-02-create-tags-table.sql", Transactional: true}, + } - res, err := testMigrator.newMigrations(dirFiles) - So(err, ShouldBeNil) - So(res, ShouldHaveLength, len(want)) + res, err := testMigrator.newMigrations(dirFiles) + require.NoError(t, err) + require.Len(t, res, len(want)) - for i, m := range res { - So(m.Filename, ShouldEqual, want[i].Filename) - So(m.Transactional, ShouldEqual, want[i].Transactional) - } - }) + for i, m := range res { + assert.Equal(t, want[i].Filename, m.Filename) + assert.Equal(t, want[i].Transactional, m.Transactional) + } } func TestMigrator_applyNonTransactionalMigration(t *testing.T) { t.Skip() ctx := context.Background() - Convey("TestMigrator_applyNonTransactionalMigration", t, func() { - err := recreateSchema() - So(err, ShouldBeNil) - _, err = testMigrator.db.ExecContext(ctx, `create table news (id text);`) - So(err, ShouldBeNil) - mg, err := NewMigration(testMigrator.rootDir, "2022-12-12-03-add-comments-news-NONTR.sql") - So(err, ShouldBeNil) + err := recreateSchema() + require.NoError(t, err) - err = testMigrator.applyNonTransactionalMigration(ctx, mg) - So(err, ShouldBeNil) + _, err = testMigrator.db.ExecContext(ctx, `create table news (id text);`) + require.NoError(t, err) - var pm PgMigration - err = testMigrator.db.ModelContext(ctx, &pm).Where(`"filename" = ?`, mg.Filename).Select() - So(err, ShouldBeNil) - So(pm, ShouldNotBeNil) - So(pm.FinishedAt, ShouldNotBeEmpty) - }) + mg, err := NewMigration(testMigrator.rootDir, "2022-12-12-03-add-comments-news-NONTR.sql") + require.NoError(t, err) + + err = testMigrator.applyNonTransactionalMigration(ctx, mg) + require.NoError(t, err) + + var pm PgMigration + err = testMigrator.db.ModelContext(ctx, &pm).Where(`"filename" = ?`, mg.Filename).Select() + require.NoError(t, err) + assert.NotEmpty(t, pm.FinishedAt) } func TestMigrator_applyMigration(t *testing.T) { t.Skip() ctx := context.Background() - Convey("TestMigrator_applyMigration", t, func() { - mg, err := NewMigration(testMigrator.rootDir, "2022-12-12-01-create-table-statuses.sql") - So(err, ShouldBeNil) - err = testMigrator.applyMigration(ctx, mg) - So(err, ShouldBeNil) + mg, err := NewMigration(testMigrator.rootDir, "2022-12-12-01-create-table-statuses.sql") + require.NoError(t, err) - var pm PgMigration - err = testMigrator.db.ModelContext(ctx, &pm).Where(`"filename" = ?`, mg.Filename).Select() - So(err, ShouldBeNil) - So(pm, ShouldNotBeNil) - So(pm.FinishedAt, ShouldNotBeEmpty) - }) + err = testMigrator.applyMigration(ctx, mg) + require.NoError(t, err) + + var pm PgMigration + err = testMigrator.db.ModelContext(ctx, &pm).Where(`"filename" = ?`, mg.Filename).Select() + require.NoError(t, err) + assert.NotEmpty(t, pm.FinishedAt) } func TestMigrator_Run(t *testing.T) { ctx := context.Background() - Convey("TestMigrator_Run", t, func() { - err := recreateSchema() - So(err, ShouldBeNil) - err = execRun(ctx, t) - So(err, ShouldBeNil) - }) + err := recreateSchema() + require.NoError(t, err) + + err = execRun(ctx, t) + require.NoError(t, err) } func execRun(ctx context.Context, t *testing.T) error { @@ -226,269 +198,257 @@ func execRun(ctx context.Context, t *testing.T) error { func TestMigrator_Last(t *testing.T) { ctx := context.Background() - Convey("TestMigrator_Last", t, func() { - Convey("check empty list", func() { - err := recreateSchema() - So(err, ShouldBeNil) - - list, err := testMigrator.Last(ctx, 5) - So(err, ShouldBeNil) - So(list, ShouldHaveLength, 0) - }) - Convey("check all applied list", func() { - err := recreateSchema() - So(err, ShouldBeNil) - err = execRun(ctx, t) - So(err, ShouldBeNil) - - list, err := testMigrator.Last(ctx, 5) - So(err, ShouldBeNil) - So(list, ShouldHaveLength, 5) - }) - Convey("check 3 last migrations", func() { - list, err := testMigrator.Last(ctx, 3) - So(err, ShouldBeNil) - So(list, ShouldHaveLength, 3) - }) + + t.Run("empty list", func(t *testing.T) { + err := recreateSchema() + require.NoError(t, err) + + list, err := testMigrator.Last(ctx, 5) + require.NoError(t, err) + assert.Empty(t, list) + }) + + t.Run("all applied", func(t *testing.T) { + err := recreateSchema() + require.NoError(t, err) + err = execRun(ctx, t) + require.NoError(t, err) + + list, err := testMigrator.Last(ctx, 5) + require.NoError(t, err) + assert.Len(t, list, 5) + }) + + t.Run("3 last migrations", func(t *testing.T) { + list, err := testMigrator.Last(ctx, 3) + require.NoError(t, err) + assert.Len(t, list, 3) }) } func TestMigrator_Redo(t *testing.T) { ctx := context.Background() - Convey("TestMigrator_Redo", t, func() { - Convey("check if migrations wasn't applied", func() { - err := recreateSchema() - So(err, ShouldBeNil) - - ch := make(chan string) - go readFromCh(ch, t) - - pm, err := testMigrator.Redo(ctx, ch) - So(err.Error(), ShouldEqual, "applied migrations were not found") - So(pm, ShouldBeNil) - }) - Convey("redo last applied", func() { - err := recreateSchema() - So(err, ShouldBeNil) - - err = execRun(ctx, t) - So(err, ShouldBeNil) - - _, err = testDB.Exec("DROP TABLE tags CASCADE;") - So(err, ShouldBeNil) - - ch := make(chan string) - go readFromCh(ch, t) - - pm, err := testMigrator.Redo(ctx, ch) - So(err, ShouldBeNil) - So(pm, ShouldResemble, &PgMigration{ - ID: pm.ID, - Filename: "2022-12-13-02-create-tags-table.sql", - StartedAt: pm.StartedAt, - FinishedAt: pm.FinishedAt, - Transactional: true, - Md5sum: "d10bca7f78e847d3d4e71003b31a54a6", - }) - }) + + t.Run("no applied migrations", func(t *testing.T) { + err := recreateSchema() + require.NoError(t, err) + + ch := make(chan string) + go readFromCh(ch, t) + + pm, err := testMigrator.Redo(ctx, ch) + require.EqualError(t, err, "applied migrations were not found") + assert.Nil(t, pm) + }) + + t.Run("redo last applied", func(t *testing.T) { + err := recreateSchema() + require.NoError(t, err) + + err = execRun(ctx, t) + require.NoError(t, err) + + _, err = testDB.Exec("DROP TABLE tags CASCADE;") + require.NoError(t, err) + + ch := make(chan string) + go readFromCh(ch, t) + + pm, err := testMigrator.Redo(ctx, ch) + require.NoError(t, err) + assert.Equal(t, &PgMigration{ + ID: pm.ID, + Filename: "2022-12-13-02-create-tags-table.sql", + StartedAt: pm.StartedAt, + FinishedAt: pm.FinishedAt, + Transactional: true, + Md5sum: "d10bca7f78e847d3d4e71003b31a54a6", + }, pm) }) } func TestMigrator_dryRunMigrations(t *testing.T) { ctx := context.Background() - Convey("TestMigrator_prepareMigrationsToDryRun", t, func() { + + err := recreateSchema() + require.NoError(t, err) + err = testMigrator.createMigratorTable(ctx) + require.NoError(t, err) + + dirFiles := []string{ + "2022-12-12-01-create-table-statuses.sql", + "2022-12-12-02-create-table-news.sql", + } + mm, err := testMigrator.newMigrations(dirFiles) + require.NoError(t, err) + + ch := make(chan string) + go readFromCh(ch, t) + err = testMigrator.dryRunMigrations(ctx, mm, ch) + require.NoError(t, err) +} + +func TestMigrator_DryRun(t *testing.T) { + ctx := context.Background() + + t.Run("transactional migrations", func(t *testing.T) { err := recreateSchema() - So(err, ShouldBeNil) - err = testMigrator.createMigratorTable(ctx) - So(err, ShouldBeNil) + require.NoError(t, err) dirFiles := []string{ "2022-12-12-01-create-table-statuses.sql", "2022-12-12-02-create-table-news.sql", } - mm, err := testMigrator.newMigrations(dirFiles) - So(err, ShouldBeNil) ch := make(chan string) go readFromCh(ch, t) - err = testMigrator.dryRunMigrations(ctx, mm, ch) - So(err, ShouldBeNil) - }) -} -func TestMigrator_DryRun(t *testing.T) { - ctx := context.Background() - Convey("TestMigrator_DryRun", t, func() { - Convey("check transactional migrations to dry run", func() { - err := recreateSchema() - So(err, ShouldBeNil) - - dirFiles := []string{ - "2022-12-12-01-create-table-statuses.sql", - "2022-12-12-02-create-table-news.sql", - } - - ch := make(chan string) - go readFromCh(ch, t) - - err = testMigrator.DryRun(ctx, dirFiles, ch) - So(err, ShouldBeNil) - }) - - Convey("check with non transactional migrations to dry run", func() { - err := recreateSchema() - So(err, ShouldBeNil) - dirFiles := []string{ - "2022-12-12-01-create-table-statuses.sql", - "2022-12-12-02-create-table-news.sql", - "2022-12-12-03-add-comments-news-NONTR.sql", - "2022-12-13-01-create-categories-table.sql", - "2022-12-13-02-create-tags-table.sql", - } - - ch := make(chan string) - go readFromCh(ch, t) - - err = testMigrator.DryRun(ctx, dirFiles, ch) - So(err.Error(), ShouldEqual, `non transactional migration found "2022-12-12-03-add-comments-news-NONTR.sql", run all migrations before it, please`) - }) + err = testMigrator.DryRun(ctx, dirFiles, ch) + require.NoError(t, err) }) -} -func TestMigrator_skipMigrations(t *testing.T) { - ctx := context.Background() - Convey("TestMigrator_skipMigrations", t, func() { + t.Run("with non transactional migrations", func(t *testing.T) { err := recreateSchema() - So(err, ShouldBeNil) - err = testMigrator.createMigratorTable(ctx) - So(err, ShouldBeNil) + require.NoError(t, err) dirFiles := []string{ "2022-12-12-01-create-table-statuses.sql", "2022-12-12-02-create-table-news.sql", + "2022-12-12-03-add-comments-news-NONTR.sql", + "2022-12-13-01-create-categories-table.sql", + "2022-12-13-02-create-tags-table.sql", } - mm, err := testMigrator.newMigrations(dirFiles) - So(err, ShouldBeNil) ch := make(chan string) go readFromCh(ch, t) - err = testMigrator.skipMigrations(ctx, mm, ch) - So(err, ShouldBeNil) - - for _, mg := range mm { - var pm PgMigration - err = testMigrator.db.ModelContext(ctx, &pm).Where(`"filename" = ?`, mg.Filename).Select() - So(err, ShouldBeNil) - So(pm, ShouldNotBeNil) - So(pm.FinishedAt, ShouldNotBeEmpty) - } + + err = testMigrator.DryRun(ctx, dirFiles, ch) + assert.EqualError(t, err, `non transactional migration found "2022-12-12-03-add-comments-news-NONTR.sql", run all migrations before it, please`) }) } +func TestMigrator_skipMigrations(t *testing.T) { + ctx := context.Background() + + err := recreateSchema() + require.NoError(t, err) + err = testMigrator.createMigratorTable(ctx) + require.NoError(t, err) + + dirFiles := []string{ + "2022-12-12-01-create-table-statuses.sql", + "2022-12-12-02-create-table-news.sql", + } + mm, err := testMigrator.newMigrations(dirFiles) + require.NoError(t, err) + + ch := make(chan string) + go readFromCh(ch, t) + err = testMigrator.skipMigrations(ctx, mm, ch) + require.NoError(t, err) + + for _, mg := range mm { + var pm PgMigration + err = testMigrator.db.ModelContext(ctx, &pm).Where(`"filename" = ?`, mg.Filename).Select() + require.NoError(t, err) + assert.NotEmpty(t, pm.FinishedAt) + } +} + func TestMigrator_Skip(t *testing.T) { ctx := context.Background() - Convey("TestMigrator_Skip", t, func() { - err := recreateSchema() - So(err, ShouldBeNil) - filenames, err := testMigrator.Plan(ctx) - So(err, ShouldBeNil) - ch := make(chan string) - go readFromCh(ch, t) - err = testMigrator.Skip(ctx, filenames, ch) - So(err, ShouldBeNil) - }) + + err := recreateSchema() + require.NoError(t, err) + + filenames, err := testMigrator.Plan(ctx) + require.NoError(t, err) + + ch := make(chan string) + go readFromCh(ch, t) + err = testMigrator.Skip(ctx, filenames, ch) + require.NoError(t, err) } func TestMigrator_compareMD5Sum(t *testing.T) { - Convey("TestMigrator_compareMD5Sum", t, func() { - Convey("check correct", func() { - filenames := []string{ - "2022-12-12-01-create-table-statuses.sql", - "2022-12-12-02-create-table-news.sql", - } - mm, err := testMigrator.newMigrations(filenames) - So(err, ShouldBeNil) - fileMigrations := mm.ToDB() - dbMigrations := []PgMigration{ - { - Filename: "2022-12-12-01-create-table-statuses.sql", - Md5sum: "463fe73a85e13dd55fe210904ec19d7c", - }, - { - Filename: "2022-12-12-02-create-table-news.sql", - Md5sum: "6158555b3ceb1a216b0cb365cb97fc71", - }, - } - - invalid := testMigrator.compareMD5Sum(fileMigrations, dbMigrations) - So(invalid, ShouldHaveLength, 0) - }) - Convey("check invalid", func() { - filenames := []string{ - "2022-12-12-01-create-table-statuses.sql", - "2022-12-12-02-create-table-news.sql", - } - mm, err := testMigrator.newMigrations(filenames) - So(err, ShouldBeNil) - fileMigrations := mm.ToDB() - - dbMigrations := []PgMigration{ - { - Filename: "2022-12-12-01-create-table-statuses.sql", - Md5sum: "463fe73a85e13dd55fe210904ec19d7c", - }, - { - Filename: "2022-12-12-02-create-table-news.sql", - Md5sum: "invalid!!!", - }, - } - - invalid := testMigrator.compareMD5Sum(fileMigrations, dbMigrations) - So(invalid, ShouldHaveLength, 1) - So(invalid[0].Filename, ShouldEqual, "2022-12-12-02-create-table-news.sql") - }) + t.Run("correct checksums", func(t *testing.T) { + filenames := []string{ + "2022-12-12-01-create-table-statuses.sql", + "2022-12-12-02-create-table-news.sql", + } + mm, err := testMigrator.newMigrations(filenames) + require.NoError(t, err) + + fileMigrations := mm.ToDB() + dbMigrations := []PgMigration{ + {Filename: "2022-12-12-01-create-table-statuses.sql", Md5sum: "463fe73a85e13dd55fe210904ec19d7c"}, + {Filename: "2022-12-12-02-create-table-news.sql", Md5sum: "6158555b3ceb1a216b0cb365cb97fc71"}, + } + + invalid := testMigrator.compareMD5Sum(fileMigrations, dbMigrations) + assert.Empty(t, invalid) + }) + + t.Run("invalid checksum", func(t *testing.T) { + filenames := []string{ + "2022-12-12-01-create-table-statuses.sql", + "2022-12-12-02-create-table-news.sql", + } + mm, err := testMigrator.newMigrations(filenames) + require.NoError(t, err) + + fileMigrations := mm.ToDB() + dbMigrations := []PgMigration{ + {Filename: "2022-12-12-01-create-table-statuses.sql", Md5sum: "463fe73a85e13dd55fe210904ec19d7c"}, + {Filename: "2022-12-12-02-create-table-news.sql", Md5sum: "invalid!!!"}, + } + + invalid := testMigrator.compareMD5Sum(fileMigrations, dbMigrations) + require.Len(t, invalid, 1) + assert.Equal(t, "2022-12-12-02-create-table-news.sql", invalid[0].Filename) }) } func TestMigrator_Verify(t *testing.T) { ctx := context.Background() - Convey("TestMigrator_Verify", t, func() { - Convey("check from empty table", func() { - err := recreateSchema() - So(err, ShouldBeNil) - - invalid, err := testMigrator.Verify(ctx) - So(err, ShouldBeNil) - So(invalid, ShouldHaveLength, 0) - }) - Convey("check from correct migrations", func() { - err := recreateSchema() - So(err, ShouldBeNil) - - err = execRun(ctx, t) - So(err, ShouldBeNil) - - invalid, err := testMigrator.Verify(ctx) - So(err, ShouldBeNil) - So(invalid, ShouldHaveLength, 0) - }) - Convey("check from invalid migrations", func() { - err := recreateSchema() - So(err, ShouldBeNil) - - err = execRun(ctx, t) - So(err, ShouldBeNil) - - invalidFilename := "2022-12-13-01-create-categories-table.sql" - pm := PgMigration{Md5sum: "invalid!!!"} - _, err = testMigrator.db.ModelContext(ctx, &pm).Column("md5sum").Where(`"filename" = ?`, invalidFilename).Update() - So(err, ShouldBeNil) - - invalid, err := testMigrator.Verify(ctx) - So(err, ShouldBeNil) - So(invalid, ShouldHaveLength, 1) - So(invalid[0].Filename, ShouldEqual, invalidFilename) - }) + + t.Run("empty table", func(t *testing.T) { + err := recreateSchema() + require.NoError(t, err) + + invalid, err := testMigrator.Verify(ctx) + require.NoError(t, err) + assert.Empty(t, invalid) + }) + + t.Run("correct migrations", func(t *testing.T) { + err := recreateSchema() + require.NoError(t, err) + + err = execRun(ctx, t) + require.NoError(t, err) + + invalid, err := testMigrator.Verify(ctx) + require.NoError(t, err) + assert.Empty(t, invalid) + }) + + t.Run("invalid migrations", func(t *testing.T) { + err := recreateSchema() + require.NoError(t, err) + + err = execRun(ctx, t) + require.NoError(t, err) + + invalidFilename := "2022-12-13-01-create-categories-table.sql" + pm := PgMigration{Md5sum: "invalid!!!"} + _, err = testMigrator.db.ModelContext(ctx, &pm).Column("md5sum").Where(`"filename" = ?`, invalidFilename).Update() + require.NoError(t, err) + + invalid, err := testMigrator.Verify(ctx) + require.NoError(t, err) + require.Len(t, invalid, 1) + assert.Equal(t, invalidFilename, invalid[0].Filename) }) } From 24d8f7e8efe2087fb3aee81806b10e5fe0c0da9f Mon Sep 17 00:00:00 2001 From: Sergey Bykov Date: Sat, 28 Mar 2026 15:03:46 +0300 Subject: [PATCH 3/4] Add version: 2 to goreleaser config --- .goreleaser.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 22621c8..9f7fb81 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,3 +1,5 @@ +version: 2 + builds: - env: - CGO_ENABLED=0 From fd3360da69df033a42411d5e49c922c74de48f2b Mon Sep 17 00:00:00 2001 From: Sergey Bykov Date: Sat, 28 Mar 2026 15:11:02 +0300 Subject: [PATCH 4/4] Fix goreleaser homebrew config and add multi-arch builds - Use homebrew_casks with correct token env mapping (HOMEBREW_TAP_GITHUB_TOKEN) - Add goarch amd64/arm64 for multi-architecture builds --- .github/workflows/goreleaser.yml | 2 +- .goreleaser.yaml | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml index 9de985d..39a7dac 100644 --- a/.github/workflows/goreleaser.yml +++ b/.github/workflows/goreleaser.yml @@ -31,4 +31,4 @@ jobs: args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} + HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 9f7fb81..fa7511a 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -7,6 +7,9 @@ builds: - linux - windows - darwin + goarch: + - amd64 + - arm64 homebrew_casks: - name: pgmigrator @@ -17,4 +20,4 @@ homebrew_casks: repository: owner: vmkteam name: homebrew-tap - token: "{{ .Env.HOMEBREW_TAP_TOKEN }}" + token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"