Skip to content

Commit

Permalink
Improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
andyone committed Mar 18, 2024
1 parent 6069e1d commit dab9187
Show file tree
Hide file tree
Showing 7 changed files with 596 additions and 199 deletions.
317 changes: 317 additions & 0 deletions cli/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,317 @@
package cli

// ////////////////////////////////////////////////////////////////////////////////// //
// //
// Copyright (c) 2024 ESSENTIAL KAOS //
// Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> //
// //
// ////////////////////////////////////////////////////////////////////////////////// //

import (
"fmt"
"os"
"strconv"
"strings"

"github.com/essentialkaos/ek/v12/fmtc"
"github.com/essentialkaos/ek/v12/knf"
"github.com/essentialkaos/ek/v12/mathutil"
"github.com/essentialkaos/ek/v12/options"
"github.com/essentialkaos/ek/v12/pager"
"github.com/essentialkaos/ek/v12/terminal/tty"
"github.com/essentialkaos/ek/v12/usage"
"github.com/essentialkaos/ek/v12/usage/completion/bash"
"github.com/essentialkaos/ek/v12/usage/completion/fish"
"github.com/essentialkaos/ek/v12/usage/completion/zsh"
"github.com/essentialkaos/ek/v12/usage/man"
"github.com/essentialkaos/ek/v12/usage/update"

"github.com/essentialkaos/knfgen/support"
)

// ////////////////////////////////////////////////////////////////////////////////// //

const (
APP = "knfgen"
VER = "1.0.0"
DESC = "Utility for generating Golang const code for KNF configuration files"
)

const (
OPT_SEPARATORS = "S:separators"
OPT_UNITED = "U:united"
OPT_NO_COLOR = "nc:no-color"
OPT_HELP = "h:help"
OPT_VER = "v:version"

OPT_VERB_VER = "vv:verbose-version"
OPT_COMPLETION = "completion"
OPT_GENERATE_MAN = "generate-man"
)

// ////////////////////////////////////////////////////////////////////////////////// //

var optMap = options.Map{
OPT_SEPARATORS: {Type: options.BOOL},
OPT_UNITED: {Type: options.BOOL},
OPT_NO_COLOR: {Type: options.BOOL},
OPT_HELP: {Type: options.BOOL},
OPT_VER: {Type: options.BOOL},

OPT_VERB_VER: {Type: options.BOOL},
OPT_COMPLETION: {},
OPT_GENERATE_MAN: {Type: options.BOOL},
}

// color tags for app name and version
var colorTagApp, colorTagVer string

// tabSymbol contains tab symbol
var tabSymbol = "\t"

// ////////////////////////////////////////////////////////////////////////////////// //

// Run is main utility function
func Run(gitRev string, gomod []byte) {
preConfigureUI()

args, errs := options.Parse(optMap)

if len(errs) != 0 {
for _, err := range errs {
printError(err.Error())
}

os.Exit(1)
}

configureUI()

switch {
case options.Has(OPT_COMPLETION):
os.Exit(printCompletion())
case options.Has(OPT_GENERATE_MAN):
printMan()
os.Exit(0)
case options.GetB(OPT_VER):
genAbout(gitRev).Print(options.GetS(OPT_VER))
os.Exit(0)
case options.GetB(OPT_VERB_VER):
support.Print(APP, VER, gitRev, gomod)
os.Exit(0)
case options.GetB(OPT_HELP) || len(args) == 0:
genUsage().Print()
os.Exit(0)
}

process(args.Get(0).Clean().String())
}

// preConfigureUI preconfigures UI based on information about user terminal
func preConfigureUI() {
if !tty.IsTTY() {
fmtc.DisableColors = true
}

switch {
case fmtc.IsTrueColorSupported():
colorTagApp, colorTagVer = "{*}{#784FFF}", "{#784FFF}"
case fmtc.Is256ColorsSupported():
colorTagApp, colorTagVer = "{*}{#99}", "{#99}"
default:
colorTagApp, colorTagVer = "{*}{c}", "{c}"
}
}

// configureUI configures user interface
func configureUI() {
if options.GetB(OPT_NO_COLOR) {
fmtc.DisableColors = true
}

isTmux, _ := tty.IsTMUX()

if isTmux {
tabSymbol = " "
}
}

// process starts config processing
func process(file string) {
config, err := knf.Read(file)

if err != nil {
printError(err.Error())
os.Exit(1)
}

if pager.Setup() == nil {
defer pager.Complete()
}

renderConfig(config)

if options.GetB(OPT_UNITED) {
renderUnitedConfig(config)
}
}

// renderConfig renders config data
func renderConfig(config *knf.Config) {
var maxPropSize int

for _, section := range config.Sections() {
for _, prop := range config.Props(section) {
maxPropSize = mathutil.Max(maxPropSize, len(formatConstName(section, prop)))
}
}

formatString := getFormatString(maxPropSize)
sectionsTotal := len(config.Sections())

printSeparator()

fmtc.Println("{*}const{!} (")

for sectionIndex, section := range config.Sections() {
for _, prop := range config.Props(section) {
fmtc.Printf(
formatString,
formatConstName(section, prop),
section, prop,
)
}

if options.GetB(OPT_SEPARATORS) && sectionIndex < sectionsTotal-1 {
fmtc.NewLine()
}
}

fmt.Println(")")

printSeparator()
}

func renderUnitedConfig(config *knf.Config) {
fmtc.Println(`{s-}// addExtraOptions adds extra options{!}`)
fmtc.Println(`{*}func{!} {b}addExtraOptions{!}({&}m{!} {*}options.Map{!}) {`)

for _, section := range config.Sections() {
for _, prop := range config.Props(section) {
fmtc.Printf(
tabSymbol+"m.{r*}Set{!}({r*}knfu.O{!}(%s), &options.{*}V{!}{s}{}{!})\n",
formatConstName(section, prop),
)
}
}

fmt.Println("}\n")

fmtc.Println(`{s-}// combineConfigs combines knf cofiguration with options and environment variables{!}`)
fmtc.Println(`{*}func{!} {b}combineConfigs{!}() {`)
fmtc.Println(tabSymbol + "knfu.{r*}Combine{!}(")

for _, section := range config.Sections() {
for _, prop := range config.Props(section) {
fmtc.Printf(
tabSymbol+tabSymbol+"knfu.{r*}Simple{!}(%s),\n",
formatConstName(section, prop),
)
}
}

fmt.Println(tabSymbol + ")")
fmt.Println("}")

printSeparator()
}

// formatConstName returns const name
func formatConstName(section, prop string) string {
fs := strings.ToUpper(section)
fp := strings.ToUpper(prop)

fs = strings.ReplaceAll(fs, "-", "_")
fp = strings.ReplaceAll(fp, "-", "_")

return fs + "_" + fp
}

// printSeparator prints separator
func printSeparator() {
fmtc.Printf("\n{s-}// %s //{!}\n\n", strings.Repeat("/", 72))
}

// getFormatString returns format string
func getFormatString(maxSize int) string {
return tabSymbol + "%-" + strconv.Itoa(maxSize) + "s = {y}\"%s:%s\"{!}\n"
}

// printError prints error message to console
func printError(f string, a ...interface{}) {
fmtc.Fprintf(os.Stderr, "{r}"+f+"{!}\n", a...)
}

// ////////////////////////////////////////////////////////////////////////////////// //

// printCompletion prints completion for given shell
func printCompletion() int {
info := genUsage()

switch options.GetS(OPT_COMPLETION) {
case "bash":
fmt.Print(bash.Generate(info, "atlassian-cloud-backuper"))
case "fish":
fmt.Print(fish.Generate(info, "atlassian-cloud-backuper"))
case "zsh":
fmt.Print(zsh.Generate(info, optMap, "atlassian-cloud-backuper"))
default:
return 1
}

return 0
}

// printMan prints man page
func printMan() {
fmt.Println(man.Generate(genUsage(), genAbout("")))
}

// genUsage generates usage info
func genUsage() *usage.Info {
info := usage.NewInfo("", "file")

info.AddOption(OPT_SEPARATORS, "Add new lines between sections")
info.AddOption(OPT_UNITED, "Generate code for united configuration")
info.AddOption(OPT_NO_COLOR, "Disable colors in output")
info.AddOption(OPT_HELP, "Show this help message")
info.AddOption(OPT_VER, "Show version")

info.AddExample("app.knf", "Generate copy-paste code for app.knf")

return info
}

// genAbout generates info about version
func genAbout(gitRev string) *usage.About {
about := &usage.About{
App: APP,
Version: VER,
Desc: DESC,
Year: 2006,
Owner: "ESSENTIAL KAOS",

AppNameColorTag: colorTagApp,
VersionColorTag: colorTagVer,
DescSeparator: "{s}—{!}",

License: "Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0>",
UpdateChecker: usage.UpdateChecker{"essentialkaos/knfgen", update.GitHubChecker},
}

if gitRev != "" {
about.Build = "git:" + gitRev
}

return about
}
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ module github.com/essentialkaos/knfgen

go 1.19

require github.com/essentialkaos/ek/v12 v12.107.0
require (
github.com/essentialkaos/depsy v1.1.0
github.com/essentialkaos/ek/v12 v12.107.0
)

require golang.org/x/sys v0.18.0 // indirect
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
github.com/essentialkaos/check v1.4.0 h1:kWdFxu9odCxUqo1NNFNJmguGrDHgwi3A8daXX1nkuKk=
github.com/essentialkaos/depsy v1.1.0 h1:U6dp687UkQwXlZU17Hg2KMxbp3nfZAoZ8duaeUFYvJI=
github.com/essentialkaos/depsy v1.1.0/go.mod h1:kpiTAV17dyByVnrbNaMcZt2jRwvuXClUYOzpyJQwtG8=
github.com/essentialkaos/ek/v12 v12.107.0 h1:wNUuFXJRPb6iGJEBDvU8pOV7l3a5yzUj5gt7ZR29vew=
github.com/essentialkaos/ek/v12 v12.107.0/go.mod h1:exBTL3OE3dm4vjHihE4ZhQ3onJq7C8q2r+OTZmpCO6s=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
Expand Down
Loading

0 comments on commit dab9187

Please sign in to comment.