Skip to content

Commit

Permalink
fix: require a project toml for ftl dev and ftl serve
Browse files Browse the repository at this point in the history
  • Loading branch information
safeer committed Jun 11, 2024
1 parent 170f267 commit c3d5da3
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 10 deletions.
7 changes: 5 additions & 2 deletions cmd/ftl/cmd_dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ func (d *devCmd) Run(ctx context.Context, projConfig projectconfig.Config) error
if len(d.Dirs) == 0 && len(d.External) == 0 {
return errors.New("no directories specified")
}
if len(projConfig.FilePaths()) == 0 {
return errors.New("configuration file not found, create an ftl-project.toml file or specify one with -C")
}

client := rpc.ClientFromContext[ftlv1connect.ControllerServiceClient](ctx)

Expand All @@ -45,7 +48,7 @@ func (d *devCmd) Run(ctx context.Context, projConfig projectconfig.Config) error
}
if !d.NoServe {
if d.ServeCmd.Stop {
err := d.ServeCmd.Run(ctx)
err := d.ServeCmd.Run(ctx, projConfig)
if err != nil {
return err
}
Expand All @@ -55,7 +58,7 @@ func (d *devCmd) Run(ctx context.Context, projConfig projectconfig.Config) error
return errors.New(ftlRunningErrorMsg)
}

g.Go(func() error { return d.ServeCmd.Run(ctx) })
g.Go(func() error { return d.ServeCmd.Run(ctx, projConfig) })
}

g.Go(func() error {
Expand Down
7 changes: 6 additions & 1 deletion cmd/ftl/cmd_serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/TBD54566975/ftl/backend/controller/sql/databasetesting"
ftlv1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1"
"github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect"
"github.com/TBD54566975/ftl/common/projectconfig"
"github.com/TBD54566975/ftl/internal/bind"
"github.com/TBD54566975/ftl/internal/container"
"github.com/TBD54566975/ftl/internal/log"
Expand All @@ -44,7 +45,11 @@ type serveCmd struct {
const ftlContainerName = "ftl-db-1"
const ftlRunningErrorMsg = "FTL is already running. Use 'ftl serve --stop' to stop it"

func (s *serveCmd) Run(ctx context.Context) error {
func (s *serveCmd) Run(ctx context.Context, projConfig projectconfig.Config) error {
if len(projConfig.FilePaths()) == 0 {
return errors.New("configuration file not found, create an ftl-project.toml file or specify one with -C")
}

logger := log.FromContext(ctx)
client := rpc.ClientFromContext[ftlv1connect.ControllerServiceClient](ctx)

Expand Down
2 changes: 1 addition & 1 deletion common/projectconfig/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
//
// Config is merged left to right, with later files taking precedence over earlier files.
func Merge(paths ...string) (Config, error) {
config := Config{}
config := Config{filePaths: paths}
for _, path := range paths {
partial, err := loadFile(path)
if err != nil {
Expand Down
12 changes: 8 additions & 4 deletions common/projectconfig/projectconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,17 @@ type Config struct {
Commands Commands `toml:"commands"`
FTLMinVersion string `toml:"ftl-min-version"`
absModuleDirs []string
filePaths []string
}

// AbsModuleDirsOrDefault returns the absolute path for the module-dirs field from the ftl-project.toml, unless
// that is not defined, in which case it defaults to the root directory.
func (c Config) AbsModuleDirsOrDefault() []string { return c.absModuleDirs }

// ConfigPaths returns the computed list of configuration paths to load.
// FilePaths returns the list of configuration files that generated this Config.
func (c Config) FilePaths() []string { return c.filePaths }

// ConfigPaths returns the computed list of configuration paths to load, or an empty list if none are found.
func ConfigPaths(input []string) []string {
if len(input) > 0 {
return input
Expand Down Expand Up @@ -80,7 +84,7 @@ func CreateDefaultFileIfNonexistent(ctx context.Context) error {
return err
}
logger.Debugf("Creating a new project config file at %q", path)
return Save(path, Config{})
return Save(path, Config{filePaths: []string{path}})
}

func LoadConfig(ctx context.Context, input []string) (Config, error) {
Expand Down Expand Up @@ -108,7 +112,7 @@ func LoadWritableConfig(ctx context.Context, input []string) (Config, error) {
logger := log.FromContext(ctx)
if _, err := os.Stat(target); errors.Is(err, os.ErrNotExist) {
logger.Debugf("Creating a new project config file at %q", target)
err = Save(target, Config{})
err = Save(target, Config{filePaths: []string{target}})
if err != nil {
return Config{}, err
}
Expand All @@ -120,7 +124,7 @@ func LoadWritableConfig(ctx context.Context, input []string) (Config, error) {

// Load project config from a file.
func loadFile(path string) (Config, error) {
config := Config{}
config := Config{filePaths: []string{path}}
md, err := toml.DecodeFile(path, &config)
if err != nil {
return Config{}, err
Expand Down
20 changes: 18 additions & 2 deletions common/projectconfig/projectconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestProjectConfig(t *testing.T) {
Commands: Commands{
Startup: []string{"echo 'Executing global pre-build command'"},
},
filePaths: []string{"testdata/ftl-project.toml"},
}

assert.Equal(t, expected, actual)
Expand All @@ -41,18 +42,33 @@ func TestProjectLoadConfig(t *testing.T) {
paths []string
err string
}{
{name: "AllValid", paths: []string{"testdata/ftl-project.toml"}},
{name: "SingleValid", paths: []string{"testdata/ftl-project.toml"}},
{name: "MultipleValid", paths: []string{"testdata/ftl-project.toml", "testdata/go/configs-ftl-project.toml"}},
{name: "IsNonExistent", paths: []string{"testdata/ftl-project-nonexistent.toml"}, err: "no such file or directory"},
{name: "ContainsNonExistent", paths: []string{"testdata/ftl-project.toml", "testdata/ftl-project-nonexistent.toml"}, err: "no such file or directory"},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
_, err := LoadConfig(log.ContextWithNewDefaultLogger(context.Background()), test.paths)
config, err := LoadConfig(log.ContextWithNewDefaultLogger(context.Background()), test.paths)
if test.err != "" {
assert.Error(t, err)
assert.Contains(t, err.Error(), test.err)
} else {
assert.NoError(t, err)

// Check that all test.paths exist in config.FilePaths
assert.Equal(t, len(test.paths), len(config.FilePaths()))
for _, path := range test.paths {
found := false
for _, configPath := range config.FilePaths() {
if path == configPath {
found = true
break
}
}
assert.True(t, found, "expected path %q not found in config.FilePaths", path)
}
}
})
}
Expand Down

0 comments on commit c3d5da3

Please sign in to comment.