jx/cmd/cli/main.go
Matthew Rich 8feb7b8d56
Some checks failed
Lint / golangci-lint (push) Failing after 10m1s
Declarative Tests / test (push) Failing after 14s
add support of import search paths [doublejynx/jx#7]
2024-10-16 10:26:42 -07:00

217 lines
5.2 KiB
Go

// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
package main
import (
"context"
"decl/internal/data"
_ "decl/internal/config"
"decl/internal/folio"
_ "decl/internal/resource"
_ "decl/internal/fan"
"decl/internal/builtin"
_ "errors"
"flag"
"fmt"
_ "gopkg.in/yaml.v3"
"io"
"log/slog"
"os"
"decl/internal/client"
)
const (
FormatYaml = "yaml"
FormatJson = "json"
)
var (
version string
commit string
date string
)
var Client *client.App = client.NewClient()
var GlobalOformat *string
var GlobalOutput string
var GlobalQuiet *bool
var ImportMerge *bool
var ImportResource *string
var ApplyDelete *bool
var ConfigPath string
var ConfigDoc data.Document = folio.DocumentRegistry.NewDocument("")
var ctx context.Context = context.Background()
type RunCommand func(cmd *flag.FlagSet, output io.Writer) error
type SubCommand struct {
Name string
Run RunCommand
}
var jxSubCommands = []SubCommand{
{
Name: "diff",
Run: DiffSubCommand,
},
{
Name: "apply",
Run: ApplySubCommand,
},
{
Name: "import",
Run: ImportSubCommand,
},
{
Name: "config",
Run: ConfigSubCommand,
},
}
func VersionUsage() {
fmt.Println("jx")
fmt.Printf("version: %s\n", version)
fmt.Printf("commit: %s\n", commit)
fmt.Printf("date: %s\n", date)
}
func LoggerConfig() {
var programLevel = new(slog.LevelVar)
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel}))
slog.SetDefault(logger)
if debugLogging, ok := os.LookupEnv("JX_DEBUG"); ok && debugLogging != "" {
programLevel.Set(slog.LevelDebug)
} else {
programLevel.Set(slog.LevelError)
}
}
func ConfigSubCommand(cmd *flag.FlagSet, output io.Writer) (err error) {
if err = cmd.Parse(os.Args[2:]); err != nil {
return
}
if err = Client.SetOutput(GlobalOutput); err == nil {
if configErr := Client.SystemConfiguration(ConfigPath); configErr != nil {
slog.Info("Main.Import - SystemConfiguration", "config", ConfigPath, "error", configErr)
}
err = Client.ConfigCmd(cmd.Args(), true)
}
return
}
func ImportSubCommand(cmd *flag.FlagSet, output io.Writer) (err error) {
ImportResource = cmd.String("resource", "", "(uri) Add a resource to the document.")
ImportMerge = cmd.Bool("merge", false, "Merge resources into a single document.")
e := cmd.Parse(os.Args[2:])
if e != nil { // returns ErrHelp
return e
}
if err = Client.SetOutput(GlobalOutput); err == nil {
if configErr := Client.SystemConfiguration(ConfigPath); configErr != nil {
slog.Info("Main.Import - SystemConfiguration", "config", ConfigPath, "error", configErr)
}
err = Client.ImportCmd(ctx, cmd.Args(), *ImportResource, *GlobalQuiet, *ImportMerge)
}
return
}
func ApplySubCommand(cmd *flag.FlagSet, output io.Writer) (err error) {
ApplyDelete = cmd.Bool("delete", false, "Delete resources defined in the available documents.")
if e := cmd.Parse(os.Args[2:]); e != nil {
return e
}
if err = Client.SetOutput(GlobalOutput); err == nil {
if configErr := Client.SystemConfiguration(ConfigPath); configErr != nil {
slog.Info("Main.Import - SystemConfiguration", "config", ConfigPath, "error", configErr)
}
err = Client.ApplyCmd(ctx, cmd.Args(), *GlobalQuiet, *ApplyDelete)
}
return
}
func DiffSubCommand(cmd *flag.FlagSet, output io.Writer) (err error) {
if e := cmd.Parse(os.Args[2:]); e != nil {
return e
}
return Client.DiffCmd(cmd.Args())
}
func main() {
LoggerConfig()
if len(os.Args) < 2 {
fmt.Println("expected subcommands: diff, apply, import")
os.Exit(1)
}
DefaultConfigurations, configErr := builtin.BuiltInDocuments()
if configErr != nil {
slog.Warn("Failed loading default configuration", "error", configErr)
}
ConfigDoc.AppendConfigurations(DefaultConfigurations)
for _, subCmd := range jxSubCommands {
cmdFlagSet := flag.NewFlagSet(subCmd.Name, flag.ExitOnError)
cmdFlagSet.StringVar(&ConfigPath, "config", "/etc/jx/conf.d", "Config file path")
cmdFlagSet.StringVar(&ConfigPath, "c", "/etc/jx/conf.d", "Config file path")
GlobalOformat = cmdFlagSet.String("oformat", "yaml", "Output serialization format")
cmdFlagSet.StringVar(&GlobalOutput, "output", "-", "Output target (default stdout)")
cmdFlagSet.StringVar(&GlobalOutput, "o", "-", "Output target (default stdout)")
GlobalQuiet = cmdFlagSet.Bool("quiet", false, "Generate terse output.")
switch subCmd.Name {
case "diff":
cmdFlagSet.Usage = func() {
fmt.Println("jx diff source [source2]")
cmdFlagSet.PrintDefaults()
VersionUsage()
}
case "apply":
cmdFlagSet.Usage = func() {
fmt.Println("jx diff source [source2]")
cmdFlagSet.PrintDefaults()
VersionUsage()
}
case "import":
cmdFlagSet.Usage = func() {
fmt.Println("jx import source...")
cmdFlagSet.PrintDefaults()
VersionUsage()
}
case "config":
cmdFlagSet.Usage = func() {
fmt.Println("jx config source...")
cmdFlagSet.PrintDefaults()
VersionUsage()
}
}
slog.Info("CLI", "cmd", subCmd.Name)
if os.Args[1] == subCmd.Name {
if e := subCmd.Run(cmdFlagSet, os.Stdout); e != nil {
slog.Error("Failed running command", "command", os.Args[1], "error", e)
os.Exit(1)
}
return
}
}
flag.PrintDefaults()
VersionUsage()
os.Exit(1)
}