Skip to content

Commit

Permalink
Completed basic kev init + kev genyml CLI commands. (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
ezodude authored Jun 10, 2020
1 parent 9d2e964 commit b2252f8
Show file tree
Hide file tree
Showing 611 changed files with 220,545 additions and 1 deletion.
41 changes: 41 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
### Generated App Definitions ###
.kev/*

### IDEs ###
.idea/*
/bin/

### Git meld ###
*.orig

### Mac OS ###
*.DS_Store

### Go ###
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.o
*.a
*.so
*.dylib
# Test binary, build with 'go test -c'
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out

### Vim ###
# swap
.sw[a-p]
.*.sw[a-p]
# session
Session.vim
# temporary
.netrwhist
# auto-generated tag files
tags

### VisualStudioCode ###
.vscode/*
.history
90 changes: 90 additions & 0 deletions cmd/kev/cmd/genyml.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* Copyright 2020 Appvia Ltd <[email protected]>
*
* 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 cmd

import (
"os"

"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
)

var genymlCmd = &cobra.Command{
Use: "genyml",
Short: "Spikes generating yml with comments & more.",
RunE: runGenYamlCmd,
}

type App struct {
Name string `yaml:"name"`
// Services []yaml.Node `yaml:"services"`
Services *yaml.Node `yaml:"services,omitempty"`
}

type Doc struct {
App *App `yaml:"app"`
}

func runGenYamlCmd(cmd *cobra.Command, _ []string) error {
out, _ := cmd.Flags().GetString("out")
doc := &Doc{
App: &App{
Name: "hello-world",
Services: &yaml.Node{
HeadComment: "Start, expected app services",
Kind: yaml.SequenceNode,
Content: []*yaml.Node{
{
Kind: yaml.ScalarNode,
Value: "[placeholder]",
LineComment: "add service name",
},
{
Kind: yaml.ScalarNode,
Value: "[placeholder]",
LineComment: "add service name",
},
},
},
},
}

outFile, err := os.Create(out)
if err != nil {
return err
}
defer outFile.Close()

enc := yaml.NewEncoder(outFile)
enc.SetIndent(2)
return enc.Encode(doc)
}

func init() {
flags := genymlCmd.Flags()
flags.SortFlags = false

flags.StringP(
"out",
"o",
"",
"Output destination file",
)
_ = genymlCmd.MarkFlagRequired("out")

rootCmd.AddCommand(genymlCmd)
}
157 changes: 157 additions & 0 deletions cmd/kev/cmd/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/**
* Copyright 2020 Appvia Ltd <[email protected]>
*
* 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 cmd

import (
"fmt"
"io/ioutil"
"os"
"path"

"github.com/compose-spec/compose-go/loader"
compose "github.com/compose-spec/compose-go/types"
"github.com/disiqueira/gotree"
"github.com/goccy/go-yaml"
"github.com/spf13/cobra"
)

// BaseDir is a top level directory for Kev files
const BaseDir = ".kev"

var initLongDesc = `(init) reuses one or more docker-compose files to initialise a cloud native app.
Examples:
# Initialise an app definition with a single docker-compose file
$ kev init -n <myapp> -e <production> -c docker-compose.yaml
# Initialise an app definition with multiple docker-compose files.
# These will be interpreted as one file.
$ kev init -n <myapp> -e <production> -c docker-compose.yaml -c docker-compose.other.yaml`

var initCmd = &cobra.Command{
Use: "init",
Short: "Reuses project docker-compose file(s) to initialise an app definition.",
Long: initLongDesc,
RunE: runInitCmd,
}

func init() {
flags := initCmd.Flags()
flags.SortFlags = false

flags.StringP(
"name",
"n",
"",
"Application name",
)
initCmd.MarkFlagRequired("name")

flags.StringSliceP(
"compose-file",
"c",
[]string{},
"Compose file to use as application base - use multiple flags for additional files",
)
initCmd.MarkFlagRequired("compose-file")

flags.StringP(
"environment",
"e",
"",
"Target environment in addition to application base (optional) ",
)

rootCmd.AddCommand(initCmd)
}

func runInitCmd(cmd *cobra.Command, args []string) error {
appName, _ := cmd.Flags().GetString("name")
composeFiles, _ := cmd.Flags().GetStringSlice("compose-file")

config, err := load(composeFiles)
if err != nil {
return err
}

defSource := gotree.New("\n\nSource compose file(s)")
for _, e := range composeFiles {
defSource.Add(e)
}
fmt.Println(defSource.Print())

appDir := path.Join(BaseDir, appName)
if err := os.MkdirAll(appDir, os.ModePerm); err != nil {
return err
}

bytes, err := yaml.Marshal(config)
if err != nil {
return err
}

appBaseComposeFile := "compose.yaml"
appBaseComposePath := path.Join(appDir, appBaseComposeFile)
ioutil.WriteFile(appBaseComposePath, bytes, os.ModePerm)
if err != nil {
return err
}

appBaseConfigFile := "config.yaml"
appBaseConfigPath := path.Join(appDir, appBaseConfigFile)
var appTempConfigContent = fmt.Sprintf(`app:
name: %s
description: new app.
`, appName)
ioutil.WriteFile(appBaseConfigPath, []byte(appTempConfigContent), os.ModePerm)
if err != nil {
return err
}

fmt.Println("🚀 App initialised")
defTree := gotree.New(BaseDir)
node2 := defTree.Add(appName)
node2.Add(appBaseComposeFile)
node2.Add(appBaseConfigFile)
fmt.Println(defTree.Print())

return nil
}

func load(paths []string) (*compose.Config, error) {
var configFiles []compose.ConfigFile

for _, path := range paths {
b, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}

config, err := loader.ParseYAML(b)
if err != nil {
return nil, err
}

configFiles = append(configFiles, compose.ConfigFile{Filename: path, Config: config})
}

return loader.Load(compose.ConfigDetails{
WorkingDir: path.Dir(paths[0]),
ConfigFiles: configFiles,
})
}
62 changes: 62 additions & 0 deletions cmd/kev/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright 2020 Appvia Ltd <[email protected]>
*
* 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 cmd

import (
"errors"
"fmt"
"os"

"github.com/spf13/cobra"
)

const banner = `
o
| /
OO o-o o o
| \ |-' \ /
o o o-o o `

var silentErr = errors.New("silentErr")
var rootCmd = &cobra.Command{
Use: "kev",
Short: "Reuse and run your Docker Compose applications on Kubernetes",
Long: `(kev) transforms your Docker Compose applications
into Cloud Native applications you can run on Kubernetes.`,
SilenceErrors: true,
SilenceUsage: true,
}

func init() {
fmt.Print(banner)

// This is required to help with error handling from RunE , https://github.com/spf13/cobra/issues/914#issuecomment-548411337
rootCmd.SetFlagErrorFunc(func(cmd *cobra.Command, err error) error {
cmd.Println(err)
cmd.Println(cmd.UsageString())
return silentErr
})
}

func Execute() {
if err := rootCmd.Execute(); err != nil {
if err != silentErr {
fmt.Fprintln(os.Stderr, err)
}
os.Exit(1)
}
}
25 changes: 25 additions & 0 deletions cmd/kev/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright 2020 Appvia Ltd <[email protected]>
*
* 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 main

import (
"github.com/appvia/kube-devx/cmd/kev/cmd"
)

func main() {
cmd.Execute()
}
Loading

0 comments on commit b2252f8

Please sign in to comment.