Skip to content

Commit

Permalink
refactor(deployment): remove spinner manager and replace with pin lib…
Browse files Browse the repository at this point in the history
…rary

This change simplifies deployment feedback by replacing the custom SpinnerManager with the pin library. It improves code maintainability and provides a more consistent user experience across the application.
  • Loading branch information
yarlson committed Feb 12, 2025
1 parent 70a8db6 commit 7cc5a9a
Show file tree
Hide file tree
Showing 14 changed files with 82 additions and 232 deletions.
19 changes: 2 additions & 17 deletions cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,25 +42,20 @@ func runBuild(cmd *cobra.Command, args []string) {

runner := local.NewRunner()
builder := build.NewBuild(runner)
sm := console.NewSpinnerManager()

ctx := context.Background()

if err := buildAndPushServices(ctx, cfg.Project.Name, cfg.Services, builder, skipPush, sm); err != nil {
if err := buildAndPushServices(ctx, cfg.Project.Name, cfg.Services, builder, skipPush); err != nil {
console.Error("Build process failed:", err)
return
}
}

// buildAndPushServices builds and pushes all services concurrently.
func buildAndPushServices(ctx context.Context, project string, services []config.Service, builder *build.Build, skipPush bool, sm *console.SpinnerManager) error {
func buildAndPushServices(ctx context.Context, project string, services []config.Service, builder *build.Build, skipPush bool) error {
var wg sync.WaitGroup
errChan := make(chan error, len(services))

// Start the spinner manager
sm.Start()
defer sm.Stop()

for _, svc := range services {
wg.Add(1)
go func(svc config.Service) {
Expand All @@ -71,32 +66,22 @@ func buildAndPushServices(ctx context.Context, project string, services []config
image = fmt.Sprintf("%s-%s", project, serviceName)
}

// Create build spinner
spinner := sm.AddSpinner(fmt.Sprintf("build-%s", serviceName), fmt.Sprintf("Building service %s", serviceName))

// Build service
if err := builder.Build(ctx, image, svc.Path); err != nil {
spinner.ErrorWithMessagef("Failed to build service %s: %v", serviceName, err)
errChan <- fmt.Errorf("failed to build service %s: %w", serviceName, err)
return
}
spinner.Complete()

// Skip push if requested or if using local image
if skipPush || svc.Image == "" {
return
}

// Create push spinner
spinner = sm.AddSpinner(fmt.Sprintf("push-%s", serviceName), fmt.Sprintf("Pushing service %s", serviceName))

// Push service
if err := builder.Push(ctx, svc.Image); err != nil {
spinner.ErrorWithMessagef("Failed to push service %s: %v", serviceName, err)
errChan <- fmt.Errorf("failed to push service %s: %w", serviceName, err)
return
}
spinner.Complete()
}(svc)
}

Expand Down
17 changes: 3 additions & 14 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,11 @@ func runDeploy(cmd *cobra.Command, args []string) {
return
}

sm := console.NewSpinnerManager()
sm.Start()

if err := deployToServer(cfg.Project.Name, cfg, cfg.Server, sm); err != nil {
sm.Stop()
if err := deployToServer(cfg.Project.Name, cfg, cfg.Server); err != nil {
console.Error("Deployment failed:", err)
return
}

sm.Stop()
console.Success("Deployment completed successfully")
}

Expand All @@ -63,24 +58,19 @@ func parseConfig(filename string) (*config.Config, error) {
return cfg, nil
}

func deployToServer(project string, cfg *config.Config, server config.Server, sm *console.SpinnerManager) error {
func deployToServer(project string, cfg *config.Config, server config.Server) error {
hostname := server.Host

// Connect to server
spinner := sm.AddSpinner(fmt.Sprintf("connect-%s", hostname), fmt.Sprintf("[%s] Connecting to server", hostname))
runner, err := connectToServer(server)
if err != nil {
spinner.ErrorWithMessagef("Failed to connect to server %s: %v", hostname, err)
return fmt.Errorf("failed to connect to server %s: %w", hostname, err)
}
defer runner.Close()
spinner.Complete()

// Create temp directory for docker sync
spinner = sm.AddSpinner(fmt.Sprintf("setup-%s", hostname), fmt.Sprintf("[%s] Setting up deployment", hostname))
localStore, err := os.MkdirTemp("", "dockersync-local")
if err != nil {
spinner.ErrorWithMessagef("Failed to create local store: %v", err)
return fmt.Errorf("failed to create local store: %w", err)
}

Expand All @@ -89,8 +79,7 @@ func deployToServer(project string, cfg *config.Config, server config.Server, sm
LocalStore: localStore,
MaxParallel: 1,
}, runner)
deploy := deployment.NewDeployment(runner, syncer, sm)
spinner.Complete()
deploy := deployment.NewDeployment(runner, syncer)

// Start deployment
ctx, cancel := context.WithCancel(context.Background())
Expand Down
45 changes: 20 additions & 25 deletions cmd/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

"github.com/spf13/cobra"
"github.com/yarlson/pin"

"github.com/yarlson/ftl/pkg/config"
"github.com/yarlson/ftl/pkg/console"
Expand All @@ -26,30 +27,28 @@ func init() {
}

func runSetup(cmd *cobra.Command, args []string) {
sm := console.NewSpinnerManager()
sm.Start()
defer sm.Stop()

spinner := sm.AddSpinner("config", "Parsing configuration")

pConfig := pin.New("Parsing configuration", pin.WithSpinnerColor(pin.ColorCyan))
cancelConfig := pConfig.Start(context.Background())
cfg, err := parseConfig("ftl.yaml")
if err != nil {
spinner.ErrorWithMessagef("Failed to parse config file: %v", err)
pConfig.Fail(fmt.Sprintf("Failed to parse config file: %v", err))
cancelConfig()
return
}
spinner.Complete()
pConfig.Stop("Configuration parsed")
cancelConfig()

// Get Docker credentials if needed
spinner = sm.AddSpinner("docker", "Checking Docker credentials")
pDocker := pin.New("Checking Docker credentials", pin.WithSpinnerColor(pin.ColorCyan))
cancelDocker := pDocker.Start(context.Background())
dockerCreds, err := getDockerCredentials(cfg.Services)
if err != nil {
spinner.ErrorWithMessagef("Failed to get Docker credentials: %v", err)
pDocker.Fail(fmt.Sprintf("Failed to get Docker credentials: %v", err))
cancelDocker()
return
}
spinner.Complete()
sm.Stop()
pDocker.Stop("Docker credentials obtained")
cancelDocker()

// Get user password
newUserPassword, err := getUserPassword()
if err != nil {
console.Error("Failed to read password:", err)
Expand All @@ -58,24 +57,20 @@ func runSetup(cmd *cobra.Command, args []string) {
console.ClearPreviousLine()
console.Success("Password set successfully")

sm = console.NewSpinnerManager()
sm.Start()
defer sm.Stop()

// Start server setup
pSetup := pin.New("Setting up server", pin.WithSpinnerColor(pin.ColorCyan))
cancelSetup := pSetup.Start(context.Background())
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()

if err := server.Setup(ctx, cfg, server.DockerCredentials{
Username: dockerCreds.Username,
Password: dockerCreds.Password,
}, newUserPassword, sm); err != nil {
sm.Stop()
console.Error("Setup failed:", err)
}, newUserPassword); err != nil {
pSetup.Fail(fmt.Sprintf("Setup failed: %v", err))
cancelSetup()
return
}

sm.Stop()
pSetup.Stop("Server setup completed successfully")
cancelSetup()

console.Success("Server setup completed successfully.")
}
Expand Down
23 changes: 12 additions & 11 deletions cmd/tunnels.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package cmd

import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
"time"

"github.com/spf13/cobra"
"github.com/yarlson/pin"

"github.com/yarlson/ftl/pkg/console"
"github.com/yarlson/ftl/pkg/tunnel"
Expand All @@ -26,21 +28,20 @@ func init() {
}

func runTunnels(cmd *cobra.Command, args []string) {
sm := console.NewSpinnerManager()
sm.Start()
defer sm.Stop()

spinner := sm.AddSpinner("tunnels", "Establishing SSH tunnels")
pTunnel := pin.New("Establishing SSH tunnels", pin.WithSpinnerColor(pin.ColorCyan), pin.WithTextColor(pin.ColorYellow))
cancelTunnel := pTunnel.Start(context.Background())

cfg, err := parseConfig("ftl.yaml")
if err != nil {
spinner.ErrorWithMessagef("Failed to parse config file: %v", err)
pTunnel.Fail(fmt.Sprintf("Failed to parse config file: %v", err))
cancelTunnel()
return
}

tunnels := tunnel.CollectDependencyTunnels(cfg)
if len(tunnels) == 0 {
spinner.ErrorWithMessage("No dependencies with ports found in the configuration.")
pTunnel.Fail("No dependencies with ports found in the configuration.")
cancelTunnel()
return
}

Expand All @@ -55,13 +56,13 @@ func runTunnels(cmd *cobra.Command, args []string) {
tunnels,
)
if err != nil {
spinner.ErrorWithMessagef("Failed to establish tunnels: %v", err)
pTunnel.Fail(fmt.Sprintf("Failed to establish tunnels: %v", err))
cancelTunnel()
return
}

// If no error arrived in 2 seconds, we assume success (like the original):
spinner.Complete()
sm.Stop()
pTunnel.Stop("SSH tunnels established")
cancelTunnel()

console.Success("SSH tunnels established. Press Ctrl+C to exit.")

Expand Down
29 changes: 13 additions & 16 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ toolchain go1.23.1

require (
github.com/bramvdbogaerde/go-scp v1.5.0
github.com/chelnak/ysmrr v0.5.0
github.com/docker/docker v27.4.1+incompatible
github.com/docker/docker v27.5.1+incompatible
github.com/docker/go-connections v0.5.0
github.com/go-playground/validator/v10 v10.23.0
github.com/go-playground/validator/v10 v10.24.0
github.com/joho/godotenv v1.5.1
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.10.0
github.com/testcontainers/testcontainers-go v0.35.0
golang.org/x/crypto v0.32.0
golang.org/x/term v0.28.0
github.com/yarlson/pin v0.7.1
golang.org/x/crypto v0.33.0
golang.org/x/term v0.29.0
gopkg.in/yaml.v3 v3.0.1
)

Expand All @@ -31,7 +31,6 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/go-logr/logr v1.4.2 // indirect
Expand All @@ -46,8 +45,6 @@ require (
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect
github.com/magiconair/properties v1.8.9 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/sys/sequential v0.6.0 // indirect
Expand All @@ -63,21 +60,21 @@ require (
github.com/shirou/gopsutil/v3 v3.24.5 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.9.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
go.opentelemetry.io/otel v1.33.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 // indirect
go.opentelemetry.io/otel/metric v1.33.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
go.opentelemetry.io/otel/trace v1.33.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/net v0.35.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/time v0.9.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 // indirect
Expand Down
Loading

0 comments on commit 7cc5a9a

Please sign in to comment.