Skip to content

Commit

Permalink
feat: make config file optional (#3103)
Browse files Browse the repository at this point in the history
* feat: make config file optional

* chore: update unit tests
  • Loading branch information
sweatybridge authored Feb 7, 2025
1 parent e2b04d0 commit 9142412
Show file tree
Hide file tree
Showing 12 changed files with 48 additions and 56 deletions.
10 changes: 0 additions & 10 deletions internal/db/branch/switch_/switch__test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package switch_
import (
"context"
"net/http"
"os"
"path/filepath"
"testing"

Expand Down Expand Up @@ -63,15 +62,6 @@ func TestSwitchCommand(t *testing.T) {
assert.Equal(t, []byte(branch), contents)
})

t.Run("throws error on missing config", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
// Run test
err := Run(context.Background(), "target", fsys)
// Check error
assert.ErrorIs(t, err, os.ErrNotExist)
})

t.Run("throws error on malformed config", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
Expand Down
23 changes: 21 additions & 2 deletions internal/db/diff/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,14 @@ func TestRun(t *testing.T) {
assert.Equal(t, []byte(diff), contents)
})

t.Run("throws error on missing config", func(t *testing.T) {
t.Run("throws error on malformed config", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fsys, utils.ConfigPath, []byte("malformed"), 0644))
// Run test
err := Run(context.Background(), []string{"public"}, "", pgconn.Config{}, DiffSchemaMigra, fsys)
// Check error
assert.ErrorIs(t, err, os.ErrNotExist)
assert.ErrorContains(t, err, "toml: expected = after a key, but the document ends there")
})

t.Run("throws error on failure to load user schemas", func(t *testing.T) {
Expand Down Expand Up @@ -342,3 +343,21 @@ func TestDropStatements(t *testing.T) {
drops := findDropStatements("create table t(); drop table t; alter table t drop column c")
assert.Equal(t, []string{"drop table t", "alter table t drop column c"}, drops)
}

func TestLoadSchemas(t *testing.T) {
expected := []string{
filepath.Join(utils.SchemasDir, "comment", "model.sql"),
filepath.Join(utils.SchemasDir, "model.sql"),
filepath.Join(utils.SchemasDir, "reaction", "dislike", "model.sql"),
filepath.Join(utils.SchemasDir, "reaction", "like", "model.sql"),
}
fsys := afero.NewMemMapFs()
for _, fp := range expected {
require.NoError(t, afero.WriteFile(fsys, fp, nil, 0644))
}
// Run test
schemas, err := loadDeclaredSchemas(fsys)
// Check error
assert.NoError(t, err)
assert.ElementsMatch(t, expected, schemas)
}
6 changes: 3 additions & 3 deletions internal/db/pull/pull_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ var dbConfig = pgconn.Config{
}

func TestPullCommand(t *testing.T) {
t.Run("throws error on missing config", func(t *testing.T) {
t.Run("throws error on malformed config", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fsys, utils.ConfigPath, []byte("malformed"), 0644))
// Run test
err := Run(context.Background(), nil, pgconn.Config{}, "", fsys)
// Check error
assert.ErrorIs(t, err, os.ErrNotExist)
assert.Empty(t, apitest.ListUnmatchedRequests())
assert.ErrorContains(t, err, "toml: expected = after a key, but the document ends there")
})

t.Run("throws error on connect failure", func(t *testing.T) {
Expand Down
5 changes: 3 additions & 2 deletions internal/db/start/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,14 @@ func TestStartDatabase(t *testing.T) {
}

func TestStartCommand(t *testing.T) {
t.Run("throws error on missing config", func(t *testing.T) {
t.Run("throws error on malformed config", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fsys, utils.ConfigPath, []byte("malformed"), 0644))
// Run test
err := Run(context.Background(), "", fsys)
// Check error
assert.ErrorIs(t, err, os.ErrNotExist)
assert.ErrorContains(t, err, "toml: expected = after a key, but the document ends there")
})

t.Run("throws error on missing docker", func(t *testing.T) {
Expand Down
5 changes: 3 additions & 2 deletions internal/functions/serve/serve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,14 @@ func TestServeCommand(t *testing.T) {
assert.Empty(t, apitest.ListUnmatchedRequests())
})

t.Run("throws error on missing config", func(t *testing.T) {
t.Run("throws error on malformed config", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fsys, utils.ConfigPath, []byte("malformed"), 0644))
// Run test
err := Run(context.Background(), "", nil, "", RuntimeOption{}, fsys)
// Check error
assert.ErrorContains(t, err, "open supabase/config.toml: file does not exist")
assert.ErrorContains(t, err, "toml: expected = after a key, but the document ends there")
})

t.Run("throws error on missing db", func(t *testing.T) {
Expand Down
8 changes: 1 addition & 7 deletions internal/start/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"errors"
"net/http"
"os"
"regexp"
"testing"

Expand All @@ -25,12 +24,7 @@ import (
)

func TestStartCommand(t *testing.T) {
t.Run("throws error on missing config", func(t *testing.T) {
err := Run(context.Background(), afero.NewMemMapFs(), []string{}, false)
assert.ErrorIs(t, err, os.ErrNotExist)
})

t.Run("throws error on invalid config", func(t *testing.T) {
t.Run("throws error on malformed config", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fsys, utils.ConfigPath, []byte("malformed"), 0644))
Expand Down
8 changes: 1 addition & 7 deletions internal/status/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"errors"
"net/http"
"os"
"testing"

"github.com/docker/docker/api/types"
Expand Down Expand Up @@ -47,12 +46,7 @@ func TestStatusCommand(t *testing.T) {
assert.Empty(t, apitest.ListUnmatchedRequests())
})

t.Run("throws error on missing config", func(t *testing.T) {
err := Run(context.Background(), CustomName{}, utils.OutputPretty, afero.NewMemMapFs())
assert.ErrorIs(t, err, os.ErrNotExist)
})

t.Run("throws error on invalid config", func(t *testing.T) {
t.Run("throws error on malformed config", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fsys, utils.ConfigPath, []byte("malformed"), 0644))
Expand Down
6 changes: 3 additions & 3 deletions internal/stop/stop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"io"
"net/http"
"os"
"testing"

"github.com/docker/docker/api/types"
Expand Down Expand Up @@ -135,13 +134,14 @@ func TestStopCommand(t *testing.T) {
assert.Empty(t, apitest.ListUnmatchedRequests())
})

t.Run("throws error on invalid config", func(t *testing.T) {
t.Run("throws error on malformed config", func(t *testing.T) {
// Setup in-memory fs
fsys := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fsys, utils.ConfigPath, []byte("malformed"), 0644))
// Run test
err := Run(context.Background(), false, "", false, fsys)
// Check error
assert.ErrorIs(t, err, os.ErrNotExist)
assert.ErrorContains(t, err, "toml: expected = after a key, but the document ends there")
})

t.Run("throws error on stop failure", func(t *testing.T) {
Expand Down
7 changes: 0 additions & 7 deletions internal/utils/flags/config_path.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
package flags

import (
"fmt"
"os"

"github.com/go-errors/errors"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/utils"
)

func LoadConfig(fsys afero.Fs) error {
utils.Config.ProjectId = ProjectRef
if err := utils.Config.Load("", utils.NewRootFS(fsys)); err != nil {
if errors.Is(err, os.ErrNotExist) {
utils.CmdSuggestion = fmt.Sprintf("Have you set up the project with %s?", utils.Aqua("supabase init"))
}
return err
}
utils.UpdateDockerIds()
Expand Down
10 changes: 0 additions & 10 deletions internal/utils/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,16 +261,6 @@ func WriteFile(path string, contents []byte, fsys afero.Fs) error {
return nil
}

func AssertSupabaseCliIsSetUpFS(fsys afero.Fs) error {
if _, err := fsys.Stat(ConfigPath); errors.Is(err, os.ErrNotExist) {
return errors.Errorf("Cannot find %s in the current directory. Have you set up the project with %s?", Bold(ConfigPath), Aqua("supabase init"))
} else if err != nil {
return errors.Errorf("failed to read config file: %w", err)
}

return nil
}

func AssertProjectRefIsValid(projectRef string) error {
if !ProjectRefPattern.MatchString(projectRef) {
return errors.New(ErrInvalidRef)
Expand Down
8 changes: 5 additions & 3 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,8 @@ func (c *config) loadFromFile(filename string, fsys fs.FS) error {
v.SetConfigType("toml")
// Load default values
var buf bytes.Buffer
if err := initConfigTemplate.Option("missingkey=zero").Execute(&buf, c); err != nil {
return errors.Errorf("failed to initialise template config: %w", err)
if err := c.Eject(&buf); err != nil {
return err
} else if err := c.loadFromReader(v, &buf); err != nil {
return err
}
Expand All @@ -425,7 +425,9 @@ func (c *config) loadFromFile(filename string, fsys fs.FS) error {
v.SetConfigType(ext[1:])
}
f, err := fsys.Open(filename)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil
} else if err != nil {
return errors.Errorf("failed to read file config: %w", err)
}
defer f.Close()
Expand Down
8 changes: 8 additions & 0 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ func TestConfigParsing(t *testing.T) {
assert.NoError(t, config.Load("config.toml", fsys))
})

t.Run("optional config file", func(t *testing.T) {
config := NewConfig()
// Run test
err := config.Load("", fs.MapFS{})
// Check error
assert.NoError(t, err)
})

t.Run("config file with environment variables", func(t *testing.T) {
config := NewConfig()
// Setup in-memory fs
Expand Down

0 comments on commit 9142412

Please # to comment.