Skip to content

Commit

Permalink
fix: Handle relative paths for tb registry validate (#309)
Browse files Browse the repository at this point in the history
* Update goutils

* Fix tb registry validate having invalid registry name
  • Loading branch information
cszatmary authored Jan 21, 2022
1 parent f3de227 commit 0d3f2d2
Show file tree
Hide file tree
Showing 22 changed files with 170 additions and 171 deletions.
74 changes: 22 additions & 52 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
package cli

import (
"bytes"
"context"
"fmt"
"io"
"os"
"strings"
"sync"

"github.com/TouchBistro/goutils/log"
"github.com/TouchBistro/goutils/progress"
"github.com/TouchBistro/tb/engine"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -58,22 +59,10 @@ type Container struct {
Logger *Logger
}

// ExitError is used to signal that the CLI should exit with a given code and message.
type ExitError struct {
Code int
Message string
Err error
}

func (e *ExitError) Error() string {
return e.Message
}

// Logger that wraps a logrus.Logger and implements progress.OutputLogger.
// It writes to both stderr and a temp file.
// Logger is a logger that writes to both stderr and a temp file.
type Logger struct {
// Embed a logrus logger to automatically implement all the log methods.
*logrus.Logger
// Embed a logger to automatically implement all the log methods.
*log.Logger

f *os.File // temp file where all logs are written
h *loggerHook // hook for also logging to stderr
Expand All @@ -94,30 +83,23 @@ func NewLogger(verbose bool) (*Logger, error) {
return nil, fmt.Errorf("failed to create log file: %w", err)
}

logger := &logrus.Logger{
Out: f,
Formatter: &logrus.TextFormatter{
DisableColors: true,
},
Hooks: make(logrus.LevelHooks),
Level: logrus.DebugLevel,
}
logger := log.New(
log.WithOutput(f),
log.WithFormatter(&log.TextFormatter{}),
log.WithLevel(log.LevelDebug),
)
h := &loggerHook{
w: os.Stderr,
verbose: verbose,
formatter: &logrus.TextFormatter{
formatter: &log.TextFormatter{
Pretty: true,
DisableTimestamp: true,
ForceColors: true,
},
}
logger.AddHook(h)
return &Logger{logger, f, h}, nil
}

func (l *Logger) WithFields(fields progress.Fields) progress.Logger {
return progressLogger{l.Logger.WithFields(logrus.Fields(fields))}
}

func (l *Logger) Output() io.Writer {
// Use the hook's output, not the actual logger's
// since that is where stderr logs go.
Expand Down Expand Up @@ -159,40 +141,28 @@ func (l *Logger) Cleanup(remove bool) error {
return nil
}

// progressLogger is a simple wrapper for a logrus.FieldLogger that makes
// it implement progress.Logger.
type progressLogger struct {
logrus.FieldLogger
}

func (pl progressLogger) WithFields(fields progress.Fields) progress.Logger {
return progressLogger{pl.FieldLogger.WithFields(logrus.Fields(fields))}
}

// loggerHook is a logrus hook to writes to an io.Writer.
// loggerHook is a logger hook to writes to an io.Writer.
type loggerHook struct {
w io.Writer
verbose bool
mu sync.Mutex
formatter logrus.Formatter
formatter log.Formatter
buf bytes.Buffer
}

func (h *loggerHook) Levels() []logrus.Level {
// We want the hook to fire on all levels and then we will decide what to do.
return logrus.AllLevels
}

func (h *loggerHook) Fire(e *logrus.Entry) error {
if e.Level == logrus.DebugLevel && !h.verbose {
func (h *loggerHook) Run(e *log.Entry) error {
if e.Level == log.LevelDebug && !h.verbose {
// Ignore debug level if we aren't verbose
return nil
}
b, err := h.formatter.Format(e)

h.mu.Lock()
defer h.mu.Unlock()
h.buf.Reset()
b, err := h.formatter.Format(e, &h.buf)
if err != nil {
return err
}
h.mu.Lock()
defer h.mu.Unlock()
_, err = h.w.Write(b)
return err
}
7 changes: 4 additions & 3 deletions cli/commands/app/desktop/run.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package desktop

import (
"github.com/TouchBistro/goutils/fatal"
"github.com/TouchBistro/tb/cli"
"github.com/TouchBistro/tb/engine"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -33,9 +34,9 @@ Run the build for a specific branch:
Branch: opts.branch,
})
if err != nil {
return &cli.ExitError{
Message: "Failed to run desktop app",
Err: err,
return &fatal.Error{
Msg: "Failed to run desktop app",
Err: err,
}
}
c.Tracker.Info("✔ Launched desktop app")
Expand Down
10 changes: 6 additions & 4 deletions cli/commands/app/ios/logs.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package ios

import (
"errors"
"os"
"os/exec"

"github.com/TouchBistro/goutils/fatal"
"github.com/TouchBistro/tb/cli"
"github.com/TouchBistro/tb/engine"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -45,11 +47,11 @@ Displays the last 20 logs in an iOS 12.4 iPad Air 2 simulator:
tail.Stdout = os.Stdout
tail.Stderr = os.Stderr
if err := tail.Run(); err != nil {
code := tail.ProcessState.ExitCode()
if code == -1 {
code = 1
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
return &fatal.Error{Code: exitErr.ExitCode()}
}
os.Exit(code)
return &fatal.Error{Err: err}
}
return nil
},
Expand Down
7 changes: 4 additions & 3 deletions cli/commands/app/ios/run.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ios

import (
"github.com/TouchBistro/goutils/fatal"
"github.com/TouchBistro/tb/cli"
"github.com/TouchBistro/tb/engine"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -39,9 +40,9 @@ Run the build for specific branch in an iOS 12.3 iPad Air 2 simulator:
Branch: opts.branch,
})
if err != nil {
return &cli.ExitError{
Message: "Failed to run iOS app",
Err: err,
return &fatal.Error{
Msg: "Failed to run iOS app",
Err: err,
}
}
c.Tracker.Info("✔ Launched iOS app")
Expand Down
11 changes: 6 additions & 5 deletions cli/commands/clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"

"github.com/TouchBistro/goutils/errors"
"github.com/TouchBistro/goutils/fatal"
"github.com/TouchBistro/tb/cli"
"github.com/TouchBistro/tb/integrations/git"
"github.com/TouchBistro/tb/resource"
Expand All @@ -25,16 +26,16 @@ func newCloneCommand(c *cli.Container) *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
s, err := c.Engine.ResolveService(args[0])
if errors.Is(err, resource.ErrNotFound) {
return &cli.ExitError{
Message: "Try running `tb list` to see available services",
Err: err,
return &fatal.Error{
Msg: "Try running `tb list` to see available services",
Err: err,
}
} else if err != nil {
return err
}
if !s.HasGitRepo() {
return &cli.ExitError{
Message: fmt.Sprintf("%s does not have a repo", s.FullName()),
return &fatal.Error{
Msg: fmt.Sprintf("%s does not have a repo", s.FullName()),
}
}

Expand Down
23 changes: 12 additions & 11 deletions cli/commands/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/TouchBistro/goutils/command"
"github.com/TouchBistro/goutils/errors"
"github.com/TouchBistro/goutils/fatal"
"github.com/TouchBistro/tb/cli"
"github.com/TouchBistro/tb/engine"
"github.com/spf13/cobra"
Expand All @@ -31,9 +32,9 @@ func newDBCommand(c *cli.Container) *cobra.Command {
serviceName := args[0]
dbConf, err := getDbConf(c.Ctx, c, serviceName)
if err != nil {
return &cli.ExitError{
Message: "Could not retrieve database config for this service.",
Err: err,
return &fatal.Error{
Msg: "Could not retrieve database config for this service.",
Err: err,
}
}

Expand All @@ -52,14 +53,14 @@ func newDBCommand(c *cli.Container) *cobra.Command {
connArg = fmt.Sprintf("-U %s -P %s -S localhost -d %s", dbConf.user, dbConf.password, dbConf.name)
fmt.Println(connArg)
default:
return &cli.ExitError{
Message: fmt.Sprintf("DB_TYPE %s is not currently supported by tb db. Please consider making a pull request or let the maintainers know about your use case.", dbConf.dbType),
return &fatal.Error{
Msg: fmt.Sprintf("DB_TYPE %s is not currently supported by tb db. Please consider making a pull request or let the maintainers know about your use case.", dbConf.dbType),
}
}

if !command.IsAvailable(cliName) {
return &cli.ExitError{
Message: fmt.Sprintf("This command requires %s for %s, which uses a %s database.\n Please install it then run tb db.", cliName, serviceName, dbConf.dbType),
if !command.Exists(cliName) {
return &fatal.Error{
Msg: fmt.Sprintf("This command requires %s for %s, which uses a %s database.\n Please install it then run tb db.", cliName, serviceName, dbConf.dbType),
}
}

Expand All @@ -68,9 +69,9 @@ func newDBCommand(c *cli.Container) *cobra.Command {
err = command.New(command.WithStdin(os.Stdin), command.WithStdout(os.Stdout), command.WithStderr(os.Stderr)).
Exec(cliName, strings.Fields(connArg)...)
if err != nil {
return &cli.ExitError{
Message: fmt.Sprintf("could not start database client %s", cliName),
Err: err,
return &fatal.Error{
Msg: fmt.Sprintf("could not start database client %s", cliName),
Err: err,
}
}
return nil
Expand Down
7 changes: 4 additions & 3 deletions cli/commands/down.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package commands

import (
"github.com/TouchBistro/goutils/fatal"
"github.com/TouchBistro/tb/cli"
"github.com/TouchBistro/tb/engine"
"github.com/spf13/cobra"
Expand All @@ -27,9 +28,9 @@ Stop and remove on the postgres and redis containers:
RunE: func(cmd *cobra.Command, args []string) error {
err := c.Engine.Down(c.Ctx, engine.DownOptions{ServiceNames: args})
if err != nil {
return &cli.ExitError{
Message: "Failed to stop services",
Err: err,
return &fatal.Error{
Msg: "Failed to stop services",
Err: err,
}
}
c.Tracker.Info("✔ Stopped services")
Expand Down
8 changes: 4 additions & 4 deletions cli/commands/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"

"github.com/TouchBistro/goutils/fatal"
"github.com/TouchBistro/tb/cli"
"github.com/TouchBistro/tb/engine"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -46,11 +47,10 @@ Start an interactive bash shell in the core-database container:
if err != nil {
return err
}
if exitCode == -1 {
exitCode = 1
if exitCode != 0 {
// Match the exit code of the command
return &fatal.Error{Code: exitCode}
}
// Match the exit code of the command
os.Exit(exitCode)
return nil
},
}
Expand Down
17 changes: 9 additions & 8 deletions cli/commands/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/TouchBistro/goutils/errors"
"github.com/TouchBistro/goutils/fatal"
"github.com/TouchBistro/tb/cli"
dockerregistry "github.com/TouchBistro/tb/integrations/docker/registry"
"github.com/TouchBistro/tb/resource"
Expand Down Expand Up @@ -32,16 +33,16 @@ func newImagesCommand(c *cli.Container) *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
service, err := c.Engine.ResolveService(args[0])
if errors.Is(err, resource.ErrNotFound) {
return &cli.ExitError{
Message: "Try running `tb list` to see available services",
Err: err,
return &fatal.Error{
Msg: "Try running `tb list` to see available services",
Err: err,
}
} else if err != nil {
return err
}
if service.Remote.Image == "" {
return &cli.ExitError{
Message: fmt.Sprintf("%s is not available from a remote docker registry", service.FullName()),
return &fatal.Error{
Msg: fmt.Sprintf("%s is not available from a remote docker registry", service.FullName()),
}
}

Expand All @@ -54,9 +55,9 @@ func newImagesCommand(c *cli.Container) *cobra.Command {
imgs, err := dockerRegistry.FetchRepoImages(cmd.Context(), service.Remote.Image, opts.max)
c.Tracker.Stop()
if err != nil {
return &cli.ExitError{
Message: "Failed to fetch docker images",
Err: err,
return &fatal.Error{
Msg: "Failed to fetch docker images",
Err: err,
}
}
for _, img := range imgs {
Expand Down
Loading

0 comments on commit 0d3f2d2

Please sign in to comment.