Skip to content

Commit

Permalink
config is parsed correctly now
Browse files Browse the repository at this point in the history
  • Loading branch information
nxy7 committed Jun 21, 2023
1 parent 2bd7144 commit d4094ae
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 73 deletions.
37 changes: 5 additions & 32 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,20 @@ var rootCmd = &cobra.Command{
Long: `Optimus is opinionated but extensible monorepo framework that can work with most web app workflows: standalone services, docker-compose projects and kubernetes clusters. It's easy to extend optimus to do most monorepo tasks using your favourite shell language.`,
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {

AppConfig = config.LoadConfig()
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}

func init() {
// parse config
// config := config.Config {}
AppConfig = config.LoadConfig()

for name, command := range AppConfig.AdditionalCommands {
rootCmd.AddCommand(&cobra.Command{
Use: name,
Use: name,
Short: command.Description,
Run: func(cmd *cobra.Command, args []string) {
e := exec.Command("bash", "-c", command.Run)
e.Stdout = os.Stdout
Expand All @@ -48,32 +43,10 @@ func init() {
})
}

for name, svc := range AppConfig.Services {
svcCmd := &cobra.Command{
Use: name,
Short: name + " commands",
}
allCmds := svc.AdditionalCommands
allCmds["build"] = svc.Build
allCmds["dev"] = svc.Dev
allCmds["start"] = svc.Start

for k, c := range allCmds {
svcCmd.AddCommand(&cobra.Command{
Use: k,
Short: k + " command",
Run: func(cmd *cobra.Command, args []string) {
e := exec.Command("bash", "-c", c.Run)
e.Stdout = os.Stdout

e.Run()

},
})

}
for _, svc := range AppConfig.Services {
svcCmd := svc.ToCobraCommand()

rootCmd.AddCommand(svcCmd)
rootCmd.AddCommand(&svcCmd)
}

rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
Expand Down
89 changes: 64 additions & 25 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package config

import (
"fmt"
"log"
"optimus/utils"
"strings"

"github.com/spf13/viper"
)

type Config struct {
Global Global
BuildCmd Cmd
PushCmd Cmd
E2eTests Cmd
Services map[string]Service
AdditionalCommands map[string]Cmd
Global *Global
BuildCmd *Cmd
PushCmd *Cmd
E2eTests *Cmd
Services map[string]*Service
AdditionalCommands map[string]*Cmd
}

type E2eTests struct {
Expand All @@ -23,12 +23,18 @@ type E2eTests struct {

func LoadConfig() Config {
p := utils.ProjectRoot()

conf := LoadConfigFromPath(p)
conf.MergeConfigs(DefaultConfig())

return conf
}

func LoadConfigFromPath(p string) Config {
conf := DefaultConfig()
conf := Config{
Services: make(map[string]*Service),
AdditionalCommands: make(map[string]*Cmd),
}
v := viper.New()
v.SetConfigType("yaml")
v.SetConfigName("optimus")
Expand All @@ -45,6 +51,7 @@ func LoadConfigFromPath(p string) Config {
panic(err)
}

include := make([]string, 0)
for k, v2 := range c {
if k == "include" {
strv2, o := v2.([]any)
Expand All @@ -53,34 +60,66 @@ func LoadConfigFromPath(p string) Config {
}

for _, v3 := range strv2 {
v3str, o := v3.(string)
includePath, o := v3.(string)
if !o {
panic("include only accepts strings")
}
_ = LoadConfigFromPath(v3str)
includePath = strings.Replace(includePath, "./", "/", 1)
include = append(include, includePath)
}
} else if k == "global" {
g := ParseGlobal(v2)
conf.Global = &g
} else if k == "e2e_tests" {
c := ParseCmd(v2)
conf.E2eTests = &c
} else if k == "services" {
servicesAny, o := v2.(map[string]any)
if !o {
panic("Unexpected services format")
}
for svcName, svcAny := range servicesAny {
s := ParseService(svcName, svcAny)
conf.Services[svcName] = &s
}
} else {
cmd := ParseCmd(v2)
conf.AdditionalCommands[k] = &cmd
}

}

for _, v2 := range include {
c2 := LoadConfigFromPath(p + v2)
conf.MergeConfigs(c2)
}

return conf
}

func (c1 *Config) MergeConfigs(c2 Config) {
if c1.Global == nil && c2.Global != nil {
c1.Global = c2.Global
}

if c1.E2eTests == nil && c2.E2eTests != nil {
c1.E2eTests = c2.E2eTests
}

for k, s := range c2.Services {
c1.Services[k] = s
}

// if c1.Global{}
}

func DefaultConfig() Config {
return Config{
Global: Global{ShellCmd: "bash -c"},
BuildCmd: Cmd{},
PushCmd: Cmd{},
E2eTests: Cmd{},
Services: map[string]Service{
"frontend": Service{
AdditionalCommands: make(map[string]Cmd),
},
},
AdditionalCommands: map[string]Cmd{
"testcmd": Cmd{
Description: "Gówno",
Run: "echo 2",
},
},
Global: &Global{ShellCmd: "bash -c"},
BuildCmd: nil,
PushCmd: nil,
E2eTests: nil,
Services: make(map[string]*Service),
AdditionalCommands: make(map[string]*Cmd),
}
}
7 changes: 6 additions & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package config

import (
"encoding/json"
"fmt"
"testing"
)

func TestLoadConfig(t *testing.T) {
c := LoadConfig()
fmt.Printf("c: %v\n", c)
j, err := json.Marshal(c)
if err != nil {
panic("could not jsonify")
}
fmt.Printf("c: %v\n", string(j))
}
5 changes: 3 additions & 2 deletions config/optimus.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ services:
backend:
root: ./backend
dev:
cmd: zsh -c
file: ./start_dev.sh
shell: zsh -c
run: |
echo 2
another_command: |
echo "testing"
83 changes: 77 additions & 6 deletions config/service.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,88 @@
package config

import (
"os"
"os/exec"

"github.com/spf13/cobra"
)

type Service struct {
Name string

// in the future I'd like to be automatically get service version from package.json/cargo.toml and other files, so it can be used to tag images
// Version string
// Language string
Root string
Start Cmd
Build Cmd
Dev Cmd
PostDev Cmd
AdditionalCommands map[string]Cmd
Test TestCmd
Start *Cmd
Build *Cmd
Dev *Cmd
PostDev *Cmd
AdditionalCommands map[string]*Cmd
Test *TestCmd
DirHash string
}

func ParseService(name string, a any) Service {
// fmt.Println("Parsing service")
s := Service{
Name: name,
}

amap, o := a.(map[string]any)
if !o {
panic("Invalid service format")
}

for k, v := range amap {
if k == "dev" {
c := ParseCmd(v)
s.Dev = &c
} else if k == "build" {
c := ParseCmd(v)
s.Build = &c
} else if k == "root" {
str := v.(string)
s.Root = str
}
}

// fmt.Println(s)
return s
}

func (s *Service) ToCobraCommand() cobra.Command {
svcCmd := cobra.Command{
Use: s.Name,
Short: "Commands related to " + s.Name + " service.",
}
allCmds := s.AdditionalCommands
if allCmds == nil {
allCmds = make(map[string]*Cmd)
}
if s.Build != nil {
allCmds["build"] = s.Build
}
if s.Dev != nil {
allCmds["dev"] = s.Dev
}
if s.Test != nil {
allCmds["test"] = &s.Test.Cmd
}

for k, c := range allCmds {
svcCmd.AddCommand(&cobra.Command{
Use: k,
Short: k + " command",
Run: func(cmd *cobra.Command, args []string) {
e := exec.Command("bash", "-c", c.Run)
e.Stdout = os.Stdout

e.Run()

},
})
}

return svcCmd
}
17 changes: 10 additions & 7 deletions optimus.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# global:
# shell_cmd: bash -c
global:
shell_cmd: nu -c

include:
- ./config

# script that initializes your dev environment
# init:
# description: |
# Start the application
# run: |
# docker compose -f compose.yml -f compose.dev.yml up -d
start:
description: |
Start the application
run: |
docker compose -f compose.yml -f compose.dev.yml up -d
# script that runs e2e tests
Expand All @@ -27,3 +27,6 @@ services:
shell: nu -c
run: |
pnpm i; pnpm dev;
someCmd: |
echo "some command"

0 comments on commit d4094ae

Please sign in to comment.