diff --git a/go.mod b/go.mod index facc8b5c5..04c6212b2 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/andybalholm/brotli v1.2.0 github.com/cenkalti/backoff/v4 v4.3.0 github.com/charmbracelet/bubbles v0.18.0 - github.com/charmbracelet/bubbletea v0.25.0 + github.com/charmbracelet/bubbletea v1.3.6 github.com/charmbracelet/glamour v0.9.1 github.com/charmbracelet/lipgloss v1.1.0 github.com/containerd/errdefs v1.0.0 @@ -96,13 +96,12 @@ require ( github.com/charithe/durationcheck v0.0.10 // indirect github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect github.com/charmbracelet/harmonica v0.2.0 // indirect - github.com/charmbracelet/x/ansi v0.8.0 // indirect + github.com/charmbracelet/x/ansi v0.9.3 // indirect github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect github.com/charmbracelet/x/term v0.2.1 // indirect github.com/chavacava/garif v0.1.0 // indirect github.com/ckaznocha/intrange v0.3.1 // indirect github.com/cloudflare/circl v1.6.1 // indirect - github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containers/storage v1.59.1 // indirect github.com/curioswitch/go-reassign v0.3.0 // indirect @@ -122,6 +121,7 @@ require ( github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect github.com/ecies/go/v2 v2.0.11 // indirect github.com/emirpasic/gods v1.18.1 // indirect + github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/ethereum/go-ethereum v1.15.8 // indirect github.com/ettle/strcase v0.2.0 // indirect github.com/fatih/color v1.18.0 // indirect @@ -234,7 +234,7 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/moricho/tparallel v0.3.2 // indirect github.com/morikuni/aec v1.0.0 // indirect - github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect + github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.16.0 // indirect github.com/nakabonne/nestif v0.3.1 // indirect diff --git a/go.sum b/go.sum index 610a0cb7a..879f02547 100644 --- a/go.sum +++ b/go.sum @@ -159,8 +159,8 @@ github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iy github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= -github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= -github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= +github.com/charmbracelet/bubbletea v1.3.6 h1:VkHIxPJQeDt0aFJIsVxw8BQdh/F/L2KKZGsK6et5taU= +github.com/charmbracelet/bubbletea v1.3.6/go.mod h1:oQD9VCRQFF8KplacJLo28/jofOI2ToOfGYeFgBBxHOc= github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= github.com/charmbracelet/glamour v0.9.1 h1:11dEfiGP8q1BEqvGoIjivuc2rBk+5qEXdPtaQ2WoiCM= @@ -169,8 +169,8 @@ github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= -github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE= -github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q= +github.com/charmbracelet/x/ansi v0.9.3 h1:BXt5DHS/MKF+LjuK4huWrC6NCvHtexww7dMayh6GXd0= +github.com/charmbracelet/x/ansi v0.9.3/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30= @@ -191,8 +191,6 @@ github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 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.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= -github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= @@ -271,6 +269,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF 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= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= +github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/ethereum/go-ethereum v1.15.8 h1:H6NilvRXFVoHiXZ3zkuTqKW5XcxjLZniV5UjxJt1GJU= github.com/ethereum/go-ethereum v1.15.8/go.mod h1:+S9k+jFzlyVTNcYGvqFhzN/SFhI6vA+aOY4T5tLSPL0= @@ -725,8 +725,8 @@ github.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKH github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34= -github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= @@ -1282,6 +1282,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1289,7 +1290,6 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc 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= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/db/pull/pull.go b/internal/db/pull/pull.go index 9c302e61b..3363ce7a6 100644 --- a/internal/db/pull/pull.go +++ b/internal/db/pull/pull.go @@ -44,9 +44,7 @@ func Run(ctx context.Context, schema []string, config pgconn.Config, name string // 2. Pull schema timestamp := utils.GetCurrentTimestamp() path := new.GetMigrationPath(timestamp, name) - if err := utils.RunProgram(ctx, func(p utils.Program, ctx context.Context) error { - return run(p, ctx, schema, path, conn, fsys) - }); err != nil { + if err := run(ctx, schema, path, conn, fsys); err != nil { return err } // 3. Insert a row to `schema_migrations` @@ -59,12 +57,12 @@ func Run(ctx context.Context, schema []string, config pgconn.Config, name string return nil } -func run(p utils.Program, ctx context.Context, schema []string, path string, conn *pgx.Conn, fsys afero.Fs) error { +func run(ctx context.Context, schema []string, path string, conn *pgx.Conn, fsys afero.Fs) error { config := conn.Config().Config // 1. Assert `supabase/migrations` and `schema_migrations` are in sync. if err := assertRemoteInSync(ctx, conn, fsys); errors.Is(err, errMissing) { // Not passing down schemas to avoid pulling in managed schemas - if err = dumpRemoteSchema(p, ctx, path, config, fsys); err == nil { + if err = dumpRemoteSchema(ctx, path, config, fsys); err == nil { utils.CmdSuggestion = suggestExtraPull } return err @@ -80,16 +78,16 @@ func run(p utils.Program, ctx context.Context, schema []string, path string, con return err } } - err := diffRemoteSchema(p, ctx, schema, path, config, fsys) + err := diffRemoteSchema(ctx, schema, path, config, fsys) if defaultSchema && (err == nil || errors.Is(err, errInSync)) { utils.CmdSuggestion = suggestExtraPull } return err } -func dumpRemoteSchema(p utils.Program, ctx context.Context, path string, config pgconn.Config, fsys afero.Fs) error { +func dumpRemoteSchema(ctx context.Context, path string, config pgconn.Config, fsys afero.Fs) error { // Special case if this is the first migration - p.Send(utils.StatusMsg("Dumping schema from remote database...")) + fmt.Fprintln(os.Stderr, "Dumping schema from remote database...") if err := utils.MkdirIfNotExistFS(fsys, filepath.Dir(path)); err != nil { return err } @@ -101,10 +99,9 @@ func dumpRemoteSchema(p utils.Program, ctx context.Context, path string, config return migration.DumpSchema(ctx, config, f, dump.DockerExec) } -func diffRemoteSchema(p utils.Program, ctx context.Context, schema []string, path string, config pgconn.Config, fsys afero.Fs) error { - w := utils.StatusWriter{Program: p} +func diffRemoteSchema(ctx context.Context, schema []string, path string, config pgconn.Config, fsys afero.Fs) error { // Diff remote db (source) & shadow db (target) and write it as a new migration. - output, err := diff.DiffDatabase(ctx, schema, config, w, fsys, diff.DiffSchemaMigra) + output, err := diff.DiffDatabase(ctx, schema, config, os.Stderr, fsys, diff.DiffSchemaMigra) if err != nil { return err } diff --git a/internal/db/pull/pull_test.go b/internal/db/pull/pull_test.go index d156db9b0..33e1d849f 100644 --- a/internal/db/pull/pull_test.go +++ b/internal/db/pull/pull_test.go @@ -70,9 +70,7 @@ func TestPullSchema(t *testing.T) { conn.Query(migration.LIST_MIGRATION_VERSION). Reply("SELECT 0") // Run test - err := utils.RunProgram(context.Background(), func(p utils.Program, ctx context.Context) error { - return run(p, ctx, nil, "0_test.sql", conn.MockClient(t), fsys) - }) + err := run(context.Background(), nil, "0_test.sql", conn.MockClient(t), fsys) // Check error assert.NoError(t, err) assert.Empty(t, apitest.ListUnmatchedRequests()) @@ -94,9 +92,7 @@ func TestPullSchema(t *testing.T) { Query(migration.ListSchemas, migration.ManagedSchemas). ReplyError(pgerrcode.DuplicateTable, `relation "test" already exists`) // Run test - err := utils.RunProgram(context.Background(), func(p utils.Program, ctx context.Context) error { - return run(p, ctx, nil, "", conn.MockClient(t), fsys) - }) + err := run(context.Background(), nil, "", conn.MockClient(t), fsys) // Check error assert.ErrorContains(t, err, `ERROR: relation "test" already exists (SQLSTATE 42P07)`) }) @@ -118,9 +114,7 @@ func TestPullSchema(t *testing.T) { conn.Query(migration.LIST_MIGRATION_VERSION). Reply("SELECT 1", []interface{}{"0"}) // Run test - err := utils.RunProgram(context.Background(), func(p utils.Program, ctx context.Context) error { - return run(p, ctx, []string{"public"}, "", conn.MockClient(t), fsys) - }) + err := run(context.Background(), []string{"public"}, "", conn.MockClient(t), fsys) // Check error assert.ErrorContains(t, err, "network error") assert.Empty(t, apitest.ListUnmatchedRequests()) diff --git a/internal/start/start.go b/internal/start/start.go index f922addf3..e985c3405 100644 --- a/internal/start/start.go +++ b/internal/start/start.go @@ -51,16 +51,14 @@ func Run(ctx context.Context, fsys afero.Fs, excludedContainers []string, ignore } } - if err := utils.RunProgram(ctx, func(p utils.Program, ctx context.Context) error { - dbConfig := pgconn.Config{ - Host: utils.DbId, - Port: 5432, - User: "postgres", - Password: utils.Config.Db.Password, - Database: "postgres", - } - return run(p, ctx, fsys, excludedContainers, dbConfig) - }); err != nil { + dbConfig := pgconn.Config{ + Host: utils.DbId, + Port: 5432, + User: "postgres", + Password: utils.Config.Db.Password, + Database: "postgres", + } + if err := run(ctx, fsys, excludedContainers, dbConfig); err != nil { if ignoreHealthCheck && start.IsUnhealthyError(err) { fmt.Fprintln(os.Stderr, err) } else { @@ -139,7 +137,7 @@ var ( var serviceTimeout = 30 * time.Second -func run(p utils.Program, ctx context.Context, fsys afero.Fs, excludedContainers []string, dbConfig pgconn.Config, options ...func(*pgx.ConnConfig)) error { +func run(ctx context.Context, fsys afero.Fs, excludedContainers []string, dbConfig pgconn.Config, options ...func(*pgx.ConnConfig)) error { excluded := make(map[string]bool) for _, name := range excludedContainers { excluded[name] = true @@ -151,9 +149,8 @@ func run(p utils.Program, ctx context.Context, fsys afero.Fs, excludedContainers } // Start Postgres. - w := utils.StatusWriter{Program: p} if dbConfig.Host == utils.DbId { - if err := start.StartDatabase(ctx, "", fsys, w, options...); err != nil { + if err := start.StartDatabase(ctx, "", fsys, os.Stderr, options...); err != nil { return err } } @@ -162,7 +159,7 @@ func run(p utils.Program, ctx context.Context, fsys afero.Fs, excludedContainers var isStorageEnabled = utils.Config.Storage.Enabled && !isContainerExcluded(utils.Config.Storage.Image, excluded) var isImgProxyEnabled = utils.Config.Storage.ImageTransformation != nil && utils.Config.Storage.ImageTransformation.Enabled && !isContainerExcluded(utils.Config.Storage.ImgProxyImage, excluded) - p.Send(utils.StatusMsg("Starting containers...")) + fmt.Fprintln(os.Stderr, "Starting containers...") // Start Logflare if utils.Config.Analytics.Enabled && !isContainerExcluded(utils.Config.Analytics.Image, excluded) { @@ -1110,7 +1107,7 @@ EOF started = append(started, utils.PoolerId) } - p.Send(utils.StatusMsg("Waiting for health checks...")) + fmt.Fprintln(os.Stderr, "Waiting for health checks...") if utils.NoBackupVolume && utils.SliceContains(started, utils.StorageId) { if err := start.WaitForHealthyService(ctx, serviceTimeout, utils.StorageId); err != nil { return err diff --git a/internal/start/start_test.go b/internal/start/start_test.go index d52bc4590..99df75378 100644 --- a/internal/start/start_test.go +++ b/internal/start/start_test.go @@ -200,9 +200,7 @@ func TestDatabaseStart(t *testing.T) { Reply(http.StatusOK). JSON([]storage.BucketResponse{}) // Run test - err := utils.RunProgram(context.Background(), func(p utils.Program, ctx context.Context) error { - return run(p, context.Background(), fsys, []string{}, pgconn.Config{Host: utils.DbId}, conn.Intercept) - }) + err := run(context.Background(), fsys, []string{}, pgconn.Config{Host: utils.DbId}, conn.Intercept) // Check error assert.NoError(t, err) assert.Empty(t, apitest.ListUnmatchedRequests()) @@ -246,9 +244,7 @@ func TestDatabaseStart(t *testing.T) { // Run test exclude := ExcludableContainers() exclude = append(exclude, "invalid", exclude[0]) - err := utils.RunProgram(context.Background(), func(p utils.Program, ctx context.Context) error { - return run(p, context.Background(), fsys, exclude, pgconn.Config{Host: utils.DbId}) - }) + err := run(context.Background(), fsys, exclude, pgconn.Config{Host: utils.DbId}) // Check error assert.NoError(t, err) assert.Empty(t, apitest.ListUnmatchedRequests())