Skip to content

Commit

Permalink
feat(cmd): allow the baseDir to be passed as an argument (grafana#6)
Browse files Browse the repository at this point in the history
The baseDir is the most important directory, because it directly affects JPATH
resolution.

It was assumed as the pwd so far. However, it is handy in scripts to specify it
on the command line. This behaviour switches to specify only.

BREAKING: You must specify the baseDir on the command line. To mimic the old
behaviour, use `tk show .`
  • Loading branch information
sh0rez authored Aug 6, 2019
1 parent 631d5fe commit 55adf80
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 76 deletions.
17 changes: 10 additions & 7 deletions cmd/tk/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package main

import (
"fmt"
"os"
"log"
"path/filepath"

"github.com/sh0rez/tanka/pkg/jpath"
Expand All @@ -21,18 +21,21 @@ func debugCmd() *cobra.Command {
func jpathCmd() *cobra.Command {
cmd := &cobra.Command{
Short: "print information about the jpath",
Use: "jpath",
RunE: func(cmd *cobra.Command, args []string) error {
pwd, err := os.Getwd()
Use: "jpath [directory]",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
pwd, err := filepath.Abs(args[0])
if err != nil {
return err
log.Fatalln(err)
}
path, base, root, err := jpath.Resolve(pwd)
if err != nil {
log.Fatalln("resolving jpath:", err)
}
path, base, root := jpath.Resolve(pwd)
fmt.Println("main:", filepath.Join(base, "main.jsonnet"))
fmt.Println("rootDir:", root)
fmt.Println("baseDir:", base)
fmt.Println("jpath:", path)
return nil
},
}
return cmd
Expand Down
36 changes: 15 additions & 21 deletions cmd/tk/jsonnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,53 @@ package main
import (
"encoding/json"
"fmt"
"os"
"log"
"path/filepath"

"github.com/pkg/errors"
"github.com/sh0rez/tanka/pkg/jpath"
"github.com/sh0rez/tanka/pkg/jsonnet"
"github.com/spf13/cobra"
)

func fmtCmd() *cobra.Command {
cmd := &cobra.Command{
Short: "format .jsonnet and .libsonnet files",
Use: "fmt",
}
cmd.Run = func(cmd *cobra.Command, args []string) {}
return cmd
}

func evalCmd() *cobra.Command {
cmd := &cobra.Command{
Short: "evaluate the jsonnet to json",
Use: "eval",
Use: "eval [directory]",
Args: cobra.ExactArgs(1),
}

cmd.RunE = func(cmd *cobra.Command, args []string) error {
json, err := eval()
cmd.Run = func(cmd *cobra.Command, args []string) {
json, err := eval(args[0])
if err != nil {
return err
log.Fatalln("evaluating:", err)
}
fmt.Print(json)
return nil
}

return cmd
}

func eval() (string, error) {
pwd, err := os.Getwd()
func eval(workdir string) (string, error) {
pwd, err := filepath.Abs(workdir)
if err != nil {
return "", err
}

_, baseDir, _ := jpath.Resolve(pwd)
_, baseDir, _, err := jpath.Resolve(pwd)
if err != nil {
return "", errors.Wrap(err, "resolving jpath")
}
json, err := jsonnet.EvaluateFile(filepath.Join(baseDir, "main.jsonnet"))
if err != nil {
return "", err
}
return json, nil
}

func evalDict() (map[string]interface{}, error) {
func evalDict(workdir string) (map[string]interface{}, error) {
var rawDict map[string]interface{}

raw, err := eval()
raw, err := eval(workdir)
if err != nil {
return nil, err
}
Expand Down
76 changes: 41 additions & 35 deletions cmd/tk/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package main

import (
"log"
"os"
"path/filepath"

"github.com/sh0rez/tanka/pkg/kubernetes"
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/sh0rez/tanka/pkg/config/v1alpha1"
"github.com/sh0rez/tanka/pkg/kubernetes"
)

// Version is the current version of the tk command.
Expand All @@ -34,8 +34,45 @@ func main() {
Short: "tanka <3 jsonnet",
Version: Version,
TraverseChildren: true,
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Help()
PersistentPreRun: func(cmd *cobra.Command, args []string) {
// Configuration parsing. Note this is using return to abort actions
viper.SetConfigName("spec")

// no args = no command that has a baseDir passed, abort
if len(args) == 0 {
return
}

// if the first arg is not a dir, abort
pwd, err := filepath.Abs(args[0])
if err != nil {
return
}
viper.AddConfigPath(pwd)

// handle deprecated ksonnet spec
for old, new := range deprecated {
viper.RegisterAlias(new, old)
}

// read it
if err := viper.ReadInConfig(); err != nil {
// just run fine without config. Provider features won't work (apply, show, diff)
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
return
}

log.Fatalln(err)
}
checkDeprecated()

if err := viper.Unmarshal(&config); err != nil {
log.Fatalln(err)
}

// Kubernetes
kube = kubernetes.New(config.Spec)

},
}
rootCmd.PersistentFlags().BoolP("verbose", "v", false, "")
Expand All @@ -54,43 +91,12 @@ func main() {
rootCmd.AddCommand(
evalCmd(),
initCmd(),
fmtCmd(),
debugCmd(),
)

// other commands
rootCmd.AddCommand(completionCommand(rootCmd))

// Configuration
viper.SetConfigName("spec")
viper.AddConfigPath(".")

// handle deprecated ksonnet spec
for old, new := range deprecated {
viper.RegisterAlias(new, old)
}

// Configuration
if err := viper.ReadInConfig(); err != nil {
// just run fine without config. Apply and Diff won't work
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
if err := rootCmd.Execute(); err != nil {
log.Fatalln("Ouch:", err)
}
os.Exit(1)
}

log.Fatalln("Reading config:", err)
}
checkDeprecated()

if err := viper.Unmarshal(&config); err != nil {
log.Fatalln("Parsing config:", err)
}

// Kubernetes
kube = kubernetes.New(config.Spec)

// Run!
if err := rootCmd.Execute(); err != nil {
log.Fatalln("Ouch:", rootCmd.Execute())
Expand Down
15 changes: 9 additions & 6 deletions cmd/tk/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import (

func applyCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "apply",
Use: "apply [directory]",
Short: "apply the configuration to the cluster",
Args: cobra.ExactArgs(1),
}
cmd.Run = func(cmd *cobra.Command, args []string) {
raw, err := evalDict()
raw, err := evalDict(args[0])
if err != nil {
log.Fatalln("Evaluating jsonnet:", err)
}
Expand All @@ -35,11 +36,12 @@ func applyCmd() *cobra.Command {

func diffCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "diff",
Use: "diff [directory]",
Short: "differences between the configuration and the cluster",
Args: cobra.ExactArgs(1),
}
cmd.Run = func(cmd *cobra.Command, args []string) {
raw, err := evalDict()
raw, err := evalDict(args[0])
if err != nil {
log.Fatalln("Evaluating jsonnet:", err)
}
Expand Down Expand Up @@ -67,11 +69,12 @@ func diffCmd() *cobra.Command {

func showCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "show",
Use: "show [directory]",
Short: "jsonnet as yaml",
Args: cobra.ExactArgs(1),
}
cmd.Run = func(cmd *cobra.Command, args []string) {
raw, err := evalDict()
raw, err := evalDict(args[0])
if err != nil {
log.Fatalln("Evaluating jsonnet:", err)
}
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ require (
github.com/alecthomas/chroma v0.6.6
github.com/fatih/color v1.7.0
github.com/google/go-jsonnet v0.13.0
github.com/mitchellh/mapstructure v1.1.2
github.com/pkg/errors v0.8.1
github.com/spf13/cobra v0.0.5
github.com/spf13/viper v1.4.0
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYX
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down
10 changes: 5 additions & 5 deletions pkg/jpath/jpath.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,22 @@ import (
// It then constructs a jPath with the base directory, vendor/ and lib/.
// This results in predictable imports, as it doesn't matter whether the user called
// called the command further down tree or not. A little bit like git.
func Resolve(workdir string) (path []string, base, root string) {
root, err := findParentFile("jsonnetfile.json", workdir, "/")
func Resolve(workdir string) (path []string, base, root string, err error) {
root, err = findParentFile("jsonnetfile.json", workdir, "/")
if err != nil {
panic(err)
return nil, "", "", err
}

base, err = findParentFile("main.jsonnet", workdir, root)
if err != nil {
panic(err)
return nil, "", "", err
}

return []string{
base,
filepath.Join(root, "vendor"),
filepath.Join(root, "lib"),
}, base, root
}, base, root, nil
}

// findParentFile traverses the parent directory tree for the given `file`,
Expand Down
6 changes: 5 additions & 1 deletion pkg/jsonnet/jsonnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"path/filepath"

jsonnet "github.com/google/go-jsonnet"
"github.com/pkg/errors"
"github.com/sh0rez/tanka/pkg/jpath"
"github.com/sh0rez/tanka/pkg/native"
)
Expand All @@ -16,7 +17,10 @@ func EvaluateFile(jsonnetFile string) (string, error) {
return "", err
}

jpath, _, _ := jpath.Resolve(filepath.Dir(jsonnetFile))
jpath, _, _, err := jpath.Resolve(filepath.Dir(jsonnetFile))
if err != nil {
return "", errors.Wrap(err, "resolving jpath")
}
return Evaluate(string(bytes), jpath)
}

Expand Down

0 comments on commit 55adf80

Please sign in to comment.