Skip to content

Commit

Permalink
Validate application names so that API calls and Docker build doesn't… (
Browse files Browse the repository at this point in the history
#296)

* Validate application names so that API calls and Docker build doesn't fail later
  • Loading branch information
janelletavares authored Apr 4, 2022
1 parent 1636a89 commit 110bf8b
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
27 changes: 26 additions & 1 deletion cmd/meroxa/root/apps/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"errors"
"fmt"
"os/exec"
"regexp"
"strings"

"github.com/meroxa/cli/cmd/meroxa/builder"
turbineCLI "github.com/meroxa/cli/cmd/meroxa/turbine_cli"
Expand Down Expand Up @@ -84,11 +86,34 @@ func (i *Init) GitInit(ctx context.Context, path string) error {
return nil
}

func validateAppName(name string) (string, error) {
var err error

// must be lowercase because of reusing the name for the Docker image
name = strings.ToLower(name)

// Platform API requires the first character be a letter and
// that the whole name be alphanumeric except for '-' as separators.
r := regexp.MustCompile(`^([a-z][a-z0-9-]*)$`)
matches := r.FindStringSubmatch(name)
if len(matches) == 0 {
err = fmt.Errorf(
"invalid application name: %s;"+
" should start with a letter, be alphanumeric, and only have dashes as separators",
name)
}
return name, err
}

func (i *Init) Execute(ctx context.Context) error {
name := i.args.appName
lang := i.flags.Lang

var err error
name, err := validateAppName(name)
if err != nil {
return err
}

i.path, err = turbineCLI.GetPath(i.flags.Path)
if err != nil {
return err
Expand Down
56 changes: 56 additions & 0 deletions cmd/meroxa/root/apps/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package apps
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -205,3 +206,58 @@ func TestGoInit(t *testing.T) {
})
}
}

func TestAppNameValidation(t *testing.T) {
tests := []struct {
desc string
inputName string
outputName string
err error
}{
{
desc: "Valid app name",
inputName: "perfect-name",
outputName: "perfect-name",
err: nil,
},
{
desc: "Valid capitalized app name",
inputName: "Perfect-name",
outputName: "perfect-name",
err: nil,
},
{
desc: "Invalid app name - leading number",
inputName: "3otherwisegoodname",
outputName: "",
err: fmt.Errorf("invalid application name: %s; should start with a letter, be alphanumeric,"+
" and only have dashes as separators", "3otherwisegoodname"),
},
{
desc: "Invalid app name - invalid characters",
inputName: "!ch@os",
outputName: "",
err: fmt.Errorf("invalid application name: %s; should start with a letter, be alphanumeric,"+
" and only have dashes as separators", "!ch@os"),
},
}

for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
output, err := validateAppName(tt.inputName)
if err != nil {
if tt.err == nil {
t.Fatalf("unexpected error \"%s\"", err)
} else if tt.err.Error() != err.Error() {
t.Fatalf("expected \"%s\" got \"%s\"", tt.err, err)
}
}

if err == nil && tt.err == nil {
if output != tt.outputName {
t.Fatalf("expected \"%s\" got \"%s\"", tt.outputName, output)
}
}
})
}
}

0 comments on commit 110bf8b

Please sign in to comment.