generated from TBD54566975/tbd-project-template
-
Notifications
You must be signed in to change notification settings - Fork 5
/
cmd_dev.go
89 lines (75 loc) 路 2.69 KB
/
cmd_dev.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package main
import (
"context"
"errors"
"time"
"golang.org/x/sync/errgroup"
"github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect"
"github.com/TBD54566975/ftl/buildengine"
"github.com/TBD54566975/ftl/common/projectconfig"
"github.com/TBD54566975/ftl/internal/log"
"github.com/TBD54566975/ftl/internal/rpc"
"github.com/TBD54566975/ftl/lsp"
)
type devCmd struct {
Parallelism int `short:"j" help:"Number of modules to build in parallel." default:"${numcpu}"`
Dirs []string `arg:"" help:"Base directories containing modules." type:"existingdir" optional:""`
External []string `help:"Directories for libraries that require FTL module stubs." type:"existingdir" optional:""`
Watch time.Duration `help:"Watch template directory at this frequency and regenerate on change." default:"500ms"`
NoServe bool `help:"Do not start the FTL server." default:"false"`
Lsp bool `help:"Run the language server." default:"false"`
ServeCmd serveCmd `embed:""`
languageServer *lsp.Server
}
func (d *devCmd) Run(ctx context.Context, projConfig projectconfig.Config) error {
if len(d.Dirs) == 0 && len(d.External) == 0 {
d.Dirs = projConfig.ModuleDirs
d.External = projConfig.ExternalDirs
}
if len(d.Dirs) == 0 && len(d.External) == 0 {
return errors.New("no directories specified")
}
client := rpc.ClientFromContext[ftlv1connect.ControllerServiceClient](ctx)
g, ctx := errgroup.WithContext(ctx)
if d.NoServe && d.ServeCmd.Stop {
logger := log.FromContext(ctx)
return KillBackgroundServe(logger)
}
if !d.NoServe {
if d.ServeCmd.Stop {
err := d.ServeCmd.Run(ctx)
if err != nil {
return err
}
d.ServeCmd.Stop = false
}
if d.ServeCmd.isRunning(ctx, client) {
return errors.New(ftlRunningErrorMsg)
}
g.Go(func() error { return d.ServeCmd.Run(ctx) })
}
g.Go(func() error {
err := waitForControllerOnline(ctx, d.ServeCmd.StartupTimeout, client)
if err != nil {
return err
}
opts := []buildengine.Option{buildengine.Parallelism(d.Parallelism)}
if d.Lsp {
d.languageServer = lsp.NewServer(ctx)
opts = append(opts, buildengine.WithListener(buildengine.BuildStartedListenerFunc(d.OnBuildStarted)))
ctx = log.ContextWithLogger(ctx, log.FromContext(ctx).AddSink(lsp.NewLogSink(d.languageServer)))
g.Go(func() error {
return d.languageServer.Run()
})
}
engine, err := buildengine.New(ctx, client, d.Dirs, d.External, opts...)
if err != nil {
return err
}
return engine.Dev(ctx, d.Watch, projConfig.Commands)
})
return g.Wait()
}
func (d *devCmd) OnBuildStarted(project buildengine.Project) {
d.languageServer.BuildStarted(project.Config().Dir)
}