Skip to content

Commit

Permalink
meroxa apps run initial spike
Browse files Browse the repository at this point in the history
  • Loading branch information
brettgoulder authored and raulb committed Feb 10, 2022
1 parent 4760ff0 commit 9158939
Show file tree
Hide file tree
Showing 5 changed files with 290 additions and 0 deletions.
55 changes: 55 additions & 0 deletions cmd/meroxa/root/apps/apps.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
Copyright © 2022 Meroxa Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package apps

import (
"github.com/meroxa/cli/cmd/meroxa/builder"
"github.com/spf13/cobra"
)

type Apps struct{}

var (
_ builder.CommandWithDocs = (*Apps)(nil)
_ builder.CommandWithAliases = (*Apps)(nil)
_ builder.CommandWithSubCommands = (*Apps)(nil)
_ builder.CommandWithHidden = (*Apps)(nil)
)

func (*Apps) Aliases() []string {
return []string{"app"}
}

func (*Apps) Usage() string {
return "apps"
}

func (*Apps) Hidden() bool {
return true
}

func (*Apps) Docs() builder.Docs {
return builder.Docs{
Short: "Manage Meroxa Data Applications",
}
}

func (*Apps) SubCommands() []*cobra.Command {
return []*cobra.Command{
builder.BuildCobraCommand(&Run{}),
}
}
26 changes: 26 additions & 0 deletions cmd/meroxa/root/apps/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package apps

import (
"context"
"os/exec"

"github.com/meroxa/cli/log"
)

func buildGoApp(ctx context.Context, l log.Logger, appPath, appName string, platform bool) error {
var cmd *exec.Cmd
if platform {
cmd = exec.Command("go", "build", "--tags", "platform", "-o", "./"+appPath, "./"+appPath+"/...") //nolint:gosec
} else {
cmd = exec.Command("go", "build", "-o", appName, "./...")
}
cmd.Dir = appPath

stdout, err := cmd.CombinedOutput()
if err != nil {
l.Error(ctx, string(stdout))
return err
}

return nil
}
162 changes: 162 additions & 0 deletions cmd/meroxa/root/apps/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/*
Copyright © 2022 Meroxa Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package apps

import (
"context"
"encoding/json"
"fmt"
"os"
"os/exec"
"path"

"github.com/meroxa/cli/cmd/meroxa/builder"
"github.com/meroxa/cli/log"
)

type Run struct {
flags struct {
// `--lang` is not required unless language is not specified via app.json
Lang string `long:"lang" short:"l" usage:"language to use (go | js)"`
Path string `long:"path" usage:"path of application to run"`
}

logger log.Logger
}

var (
_ builder.CommandWithDocs = (*Run)(nil)
_ builder.CommandWithFlags = (*Run)(nil)
_ builder.CommandWithExecute = (*Run)(nil)
_ builder.CommandWithLogger = (*Run)(nil)
)

type AppConfig struct {
Language string
}

func (*Run) Usage() string {
return "run"
}

func (*Run) Docs() builder.Docs {
return builder.Docs{
Short: "Execute a Meroxa Data Application locally",
Long: "meroxa apps run will build your app locally to then run it\n" +
"locally on --path.",
Example: "meroxa apps run # assumes you run it from the app directory\n" +
"meroxa apps run --path ../js-demo --lang js # in case you didn't specify lang on your app.json" +
"meroxa apps run --path ../go-demo # it'll use lang defined in your app.json",
}
}

func (r *Run) Flags() []builder.Flag {
return builder.BuildFlags(&r.flags)
}

func (r *Run) buildGoApp(ctx context.Context, appPath string) error {
// grab current location to use it as project name
appName := path.Base(appPath)

// building is a requirement prior to running for go apps
err := buildGoApp(ctx, r.logger, appPath, appName, false)
if err != nil {
return err
}

err = os.Chdir(appPath)
if err != nil {
return err
}

cmd := exec.Command("./" + appName) //nolint:gosec

out, err := cmd.CombinedOutput()
if err != nil {
r.logger.Error(ctx, err.Error())
}

r.logger.Info(ctx, string(out))
return nil
}

func (r *Run) buildJSApp(ctx context.Context) error {
// TODO: Handle the requirement of https://github.com/meroxa/turbine-js.git being installed
// cd into the path first
cmd := exec.Command("npx", "turbine", "test")
stdout, err := cmd.CombinedOutput()
if err != nil {
return err
}
r.logger.Info(ctx, string(stdout))
return nil
}

func (r *Run) readConfigFile() (AppConfig, error) {
var appConfig AppConfig

appPath := r.flags.Path
appConfigPath := path.Join(appPath, "app.json")
appConfigBytes, err := os.ReadFile(appConfigPath)
if err != nil {
return appConfig, fmt.Errorf("%v\n"+
"Applications to run require an app.json file", err)
}
if err := json.Unmarshal(appConfigBytes, &appConfig); err != nil {
return appConfig, err
}

return appConfig, nil
}

func (r *Run) Execute(ctx context.Context) error {
var appPath string

switch {
case r.flags.Path != "":
appPath = r.flags.Path
default:
appPath = "."
}

appConfig, err := r.readConfigFile()
if err != nil {
return err
}

lang := appConfig.Language

if lang == "" {
if r.flags.Lang == "" {
return fmt.Errorf("flag --lang is required unless lang is specified in your app.json")
}
lang = r.flags.Lang
}

switch lang {
case "go", "golang":
return r.buildGoApp(ctx, appPath)
case "js", "javascript", "nodejs":
return r.buildJSApp(ctx)
default:
return fmt.Errorf("language %q not supported. Currently, we support \"javascript\" and \"go\"", lang)
}
}

func (r *Run) Logger(logger log.Logger) {
r.logger = logger
}
45 changes: 45 additions & 0 deletions cmd/meroxa/root/apps/run_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package apps

import (
"testing"

"github.com/meroxa/cli/cmd/meroxa/builder"
"github.com/meroxa/cli/utils"
)

func TestRunAppFlags(t *testing.T) {
expectedFlags := []struct {
name string
required bool
shorthand string
hidden bool
}{
{name: "lang", shorthand: "l"},
{name: "path", required: false},
}

c := builder.BuildCobraCommand(&Run{})

for _, f := range expectedFlags {
cf := c.Flags().Lookup(f.name)
if cf == nil {
t.Fatalf("expected flag \"%s\" to be present", f.name)
}

if f.shorthand != cf.Shorthand {
t.Fatalf("expected shorthand \"%s\" got \"%s\" for flag \"%s\"", f.shorthand, cf.Shorthand, f.name)
}

if f.required && !utils.IsFlagRequired(cf) {
t.Fatalf("expected flag \"%s\" to be required", f.name)
}

if cf.Hidden != f.hidden {
if cf.Hidden {
t.Fatalf("expected flag \"%s\" not to be hidden", f.name)
} else {
t.Fatalf("expected flag \"%s\" to be hidden", f.name)
}
}
}
}
2 changes: 2 additions & 0 deletions cmd/meroxa/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/meroxa/cli/cmd/meroxa/global"

"github.com/meroxa/cli/cmd/meroxa/root/api"
"github.com/meroxa/cli/cmd/meroxa/root/apps"
"github.com/meroxa/cli/cmd/meroxa/root/auth"
"github.com/meroxa/cli/cmd/meroxa/root/billing"
"github.com/meroxa/cli/cmd/meroxa/root/config"
Expand Down Expand Up @@ -80,6 +81,7 @@ meroxa resources list --types

cmd.AddCommand(builder.BuildCobraCommand(&api.API{}))
cmd.AddCommand(builder.BuildCobraCommand(&auth.Auth{}))
cmd.AddCommand(builder.BuildCobraCommand(&apps.Apps{}))
cmd.AddCommand(builder.BuildCobraCommand(&billing.Billing{}))
cmd.AddCommand(builder.BuildCobraCommand(&config.Config{}))
cmd.AddCommand(builder.BuildCobraCommand(&connectors.Connect{}))
Expand Down

0 comments on commit 9158939

Please sign in to comment.