master > master: code go - fügte settings hinzu

This commit is contained in:
RD 2021-11-03 18:43:13 +01:00
parent f55677ed8b
commit f7ef295ec8
11 changed files with 208 additions and 66 deletions

View File

@ -1,5 +1,9 @@
package maxsubsum package maxsubsum
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import ( import (
"fmt" "fmt"
@ -7,10 +11,6 @@ import (
"ads/internal/setup" "ads/internal/setup"
) )
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- * /* ---------------------------------------------------------------- *
* GLOBAL VARIABLES/CONSTANTS * GLOBAL VARIABLES/CONSTANTS
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */

View File

@ -26,6 +26,7 @@ var ansimode bool = true
var loggingPrefix string = "" var loggingPrefix string = ""
var force bool = false var force bool = false
var tagAll bool = false var tagAll bool = false
var promptSymb string = ">"
func GetQuietMode() bool { func GetQuietMode() bool {
return quietmode return quietmode
@ -131,7 +132,7 @@ func Prompt(lines ...interface{}) (string, bool, error) {
logGeneric(pipe, "", lines...) logGeneric(pipe, "", lines...)
logGeneric(pipe, "", "") logGeneric(pipe, "", "")
} }
fmt.Fprint(pipe, "$ ") fmt.Fprintf(pipe, "%s ", promptSymb)
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
line, err := reader.ReadString('\n') line, err := reader.ReadString('\n')
line = re.Sub(`\s+$`, "", line) line = re.Sub(`\s+$`, "", line)

View File

@ -5,6 +5,8 @@ package endpoints
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
import ( import (
"fmt"
"ads/internal/core/logging" "ads/internal/core/logging"
"ads/internal/menus" "ads/internal/menus"
"ads/internal/setup" "ads/internal/setup"
@ -40,22 +42,74 @@ var menuMain = menus.Menu{
PromptMessages: []string{ PromptMessages: []string{
"Option wählen", "Option wählen",
}, },
Options: []menus.MenuOption{ Options: [][]menus.MenuOption{
{
{Label: "Einstellungen", Submenu: &menuSettings},
{Label: "Version des Programms anzeigen", Action: actionShowVersion}, {Label: "Version des Programms anzeigen", Action: actionShowVersion},
}, {
{Label: "Programm auf config Datei ausführen.", Action: actionRunOnConfig}, {Label: "Programm auf config Datei ausführen.", Action: actionRunOnConfig},
}, {
{Label: "Suchalgorithmen", Submenu: &menuSearchAlgorithms}, {Label: "Suchalgorithmen", Submenu: &menuSearchAlgorithms},
{Label: "Summenalgorithmen", Submenu: &menuSumAlgorithms}, {Label: "Summenalgorithmen", Submenu: &menuSumAlgorithms},
}, },
DefaultOption: -1, },
Default: -1,
}
var menuSettings = menus.Menu{
Path: []string{"Hauptmenü", "Einstellungen"},
PromptMessages: []string{
"Option wählen",
},
Options: [][]menus.MenuOption{
{
{Label: "Aktueller Zustand", Action: actionShowSettings},
{Label: "Farbenmodus", Submenu: &menuColourMode},
{Label: "Debugmodus", Submenu: &menuDebugMode},
},
},
Default: -1,
}
var menuColourMode = menus.Menu{
ForceReturn: true,
Path: []string{"Hauptmenü", "Einstellungen", "Farbenmodus"},
PromptMessages: []string{
"Soll Console-Output mit Formattierung dargestellt werden?",
"Option für den Farbenmodus wählen:",
},
Options: [][]menus.MenuOption{
{
{Label: "ein", Action: actionColourModeOn},
{Label: "aus", Action: actionColourModeOff},
},
},
Default: 0,
}
var menuDebugMode = menus.Menu{
ForceReturn: true,
Path: []string{"Hauptmenü", "Einstellungen", "Debugmodus"},
PromptMessages: []string{
"Sollen Infos zu jedem Schritt der Algorithmen angezeigt werden?",
"Option für den Debugmodus wählen:",
},
Options: [][]menus.MenuOption{
{
{Label: "ein", Action: actionDebugModeOn},
{Label: "aus", Action: actionDebugModeOff},
},
},
Default: 1,
} }
var menuSearchAlgorithms = menus.Menu{ var menuSearchAlgorithms = menus.Menu{
IsRoot: false, Path: []string{"Hauptmenü", "Suchalgorithmen"},
Path: []string{"Hauptmenü", "Suchalgorithmus"},
PromptMessages: []string{ PromptMessages: []string{
"Algorithmus wählen", "Algorithmus wählen",
}, },
Options: []menus.MenuOption{ Options: [][]menus.MenuOption{
{
{Label: "Binärsuchalgorithmus", Action: actionAlgorithmSearchBinary}, {Label: "Binärsuchalgorithmus", Action: actionAlgorithmSearchBinary},
{Label: "Interpolationsalgorithmus", Action: actionAlgorithmSearchInterpolation}, {Label: "Interpolationsalgorithmus", Action: actionAlgorithmSearchInterpolation},
{Label: "Suche i. kleinstes Element", Action: actionAlgorithmSearchIthElement}, {Label: "Suche i. kleinstes Element", Action: actionAlgorithmSearchIthElement},
@ -66,20 +120,22 @@ var menuSearchAlgorithms = menus.Menu{
{Label: "Giftsuche", SubLabel: "optimiert", Action: actionAlgorithmSearchPoisonFast}, {Label: "Giftsuche", SubLabel: "optimiert", Action: actionAlgorithmSearchPoisonFast},
{Label: "Sequentiellsuchalgorithmus", Action: actionAlgorithmSearchSequential}, {Label: "Sequentiellsuchalgorithmus", Action: actionAlgorithmSearchSequential},
}, },
DefaultOption: -1, },
Default: -1,
} }
var menuSumAlgorithms = menus.Menu{ var menuSumAlgorithms = menus.Menu{
IsRoot: false, Path: []string{"Hauptmenü", "Summenalgorithmen"},
Path: []string{"Hauptmenü", "Suchalgorithmus"},
PromptMessages: []string{ PromptMessages: []string{
"Algorithmus wählen", "Algorithmus wählen",
}, },
Options: []menus.MenuOption{ Options: [][]menus.MenuOption{
{
{Label: "Maximale Teilsumme", SubLabel: "brute force", Action: actionAlgorithmSumMaxsub}, {Label: "Maximale Teilsumme", SubLabel: "brute force", Action: actionAlgorithmSumMaxsub},
{Label: "Maximale Teilsumme", SubLabel: "D & C", Action: actionAlgorithmSumMaxsubDc}, {Label: "Maximale Teilsumme", SubLabel: "D & C", Action: actionAlgorithmSumMaxsubDc},
}, },
DefaultOption: -1, },
Default: -1,
} }
/* ---------------------------------------------------------------- * /* ---------------------------------------------------------------- *
@ -92,6 +148,41 @@ func actionShowVersion() (bool, error) {
return false, nil return false, nil
} }
func actionShowSettings() (bool, error) {
var state string
state = "aus"
if logging.GetAnsiMode() {
state = "ein"
}
logging.LogInfo(fmt.Sprintf("Farbenmodus: %s", state))
state = "aus"
if logging.GetDebugMode() {
state = "ein"
}
logging.LogInfo(fmt.Sprintf("Debugmodus: %s", state))
return false, nil
}
func actionColourModeOn() (bool, error) {
logging.SetAnsiMode(true)
return false, nil
}
func actionColourModeOff() (bool, error) {
logging.SetAnsiMode(false)
return false, nil
}
func actionDebugModeOn() (bool, error) {
logging.SetDebugMode(true)
return false, nil
}
func actionDebugModeOff() (bool, error) {
logging.SetDebugMode(false)
return false, nil
}
/* ---------------------------------------------------------------- * /* ---------------------------------------------------------------- *
* ACTIONS - Algorithmen * ACTIONS - Algorithmen
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */

View File

@ -5,8 +5,6 @@ package endpoints
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
import ( import (
"ads/internal/setup"
"ads/internal/types"
"fmt" "fmt"
algorithm_search_binary "ads/internal/algorithms/search/binary" algorithm_search_binary "ads/internal/algorithms/search/binary"
@ -17,6 +15,8 @@ import (
algorithm_search_sequential "ads/internal/algorithms/search/sequential" algorithm_search_sequential "ads/internal/algorithms/search/sequential"
algorithm_sum_maxsubsum "ads/internal/algorithms/sum/maxsubsum" algorithm_sum_maxsubsum "ads/internal/algorithms/sum/maxsubsum"
"ads/internal/core/logging" "ads/internal/core/logging"
"ads/internal/setup"
"ads/internal/types"
) )
/* ---------------------------------------------------------------- * /* ---------------------------------------------------------------- *

View File

@ -15,6 +15,14 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
/* ---------------------------------------------------------------- *
* METHOD menu class methods
* ---------------------------------------------------------------- */
func (menu *Menu) SetDefault(index int) {
menu.Default = index
}
/* ---------------------------------------------------------------- * /* ---------------------------------------------------------------- *
* METHOD show menu * METHOD show menu
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
@ -29,7 +37,8 @@ func (menu Menu) ShowMenu() (bool, error) {
err error err error
) )
var promptMessages []string var promptMessages []string
var options [][2]string var optionsFlattened []MenuOption
var optionsKeyValue [][2]string
var defaultOption string var defaultOption string
var breaks []int var breaks []int
@ -40,22 +49,32 @@ func (menu Menu) ShowMenu() (bool, error) {
promptMessages = append([]string{head}, promptMessages...) promptMessages = append([]string{head}, promptMessages...)
// Zurück-Option einfügen // Zurück-Option einfügen
defaultOption = fmt.Sprintf("%v", menu.DefaultOption) defaultOption = ""
options = []([2]string){} if menu.Default >= 0 {
for i, opt := range menu.Options { defaultOption = fmt.Sprintf("%v", menu.Default+1)
key := fmt.Sprintf("%v", i+1) }
breaks = []int{}
optionsFlattened = []MenuOption{}
optionsKeyValue = []([2]string){}
index = 0
for _, suboptions := range menu.Options {
for _, opt := range suboptions {
optionsFlattened = append(optionsFlattened, opt)
key := fmt.Sprintf("%v", index+1)
subLabel := opt.SubLabel subLabel := opt.SubLabel
label := opt.Label label := opt.Label
if !(subLabel == "") { if !(subLabel == "") {
label = fmt.Sprintf("%v (\033[2m%v\033[0m)", opt.Label, subLabel) label = fmt.Sprintf("%v (\033[2m%v\033[0m)", opt.Label, subLabel)
} }
options = append(options, [2]string{key, label}) optionsKeyValue = append(optionsKeyValue, [2]string{key, label})
index++
}
breaks = append(breaks, index-1)
} }
breaks = []int{len(menu.Options) - 1}
if !menu.IsRoot { if !menu.IsRoot {
options = append(options, [2]string{"z", "Zurück zum vorherigen Menü"}) optionsKeyValue = append(optionsKeyValue, [2]string{"z", "Zurück zum vorherigen Menü"})
} }
options = append(options, [2]string{"q", "Programm schließen"}) optionsKeyValue = append(optionsKeyValue, [2]string{"q", "Programm schließen"})
// User Response immer abfragen und abarbeiten, bis quit/return. // User Response immer abfragen und abarbeiten, bis quit/return.
performClearScreen := !menu.IsRoot performClearScreen := !menu.IsRoot
@ -65,7 +84,7 @@ func (menu Menu) ShowMenu() (bool, error) {
} }
performClearScreen = true performClearScreen = true
choice, meta = PromptListOfOptions(promptMessages, options, breaks, defaultOption) choice, meta = promptListOfOptions(promptMessages, optionsKeyValue, breaks, defaultOption)
// Falls quit wählt, -> quit: // Falls quit wählt, -> quit:
if (menu.IsRoot && meta) || choice == "q" { if (menu.IsRoot && meta) || choice == "q" {
@ -80,8 +99,8 @@ func (menu Menu) ShowMenu() (bool, error) {
// sonst führe die assoziierte Methode aus // sonst führe die assoziierte Methode aus
index64, _ := strconv.ParseInt(choice, 10, 64) index64, _ := strconv.ParseInt(choice, 10, 64)
index = int(index64) - 1 index = int(index64) - 1
if 0 <= index && index < len(menu.Options) { if 0 <= index && index < len(optionsFlattened) {
opt := menu.Options[index] opt := optionsFlattened[index]
// Entweder Untermenü öffnen oder Action ausführen // Entweder Untermenü öffnen oder Action ausführen
if opt.Submenu != nil { if opt.Submenu != nil {
quit, err = opt.Submenu.ShowMenu() quit, err = opt.Submenu.ShowMenu()
@ -93,14 +112,20 @@ func (menu Menu) ShowMenu() (bool, error) {
if err != nil { if err != nil {
logging.LogError(err) logging.LogError(err)
} }
// Falls ForceReturn, dann nach Ausführung der Action, -> return
if menu.ForceReturn {
return false, nil
} else {
// Falls während der Action der User Meta+D klickt, -> return:
if cancel { if cancel {
continue continue
} }
quit := logging.PromptAnyKeyToContinue() quit := logging.PromptAnyKeyToContinue()
// Falls während der Action der User Meta+D klickt, -> quit: // Falls nach der Action der User Meta+D klickt, -> quit:
if quit { if quit {
return true, nil return true, nil
} }
}
} else { } else {
logging.LogWarn("Option noch nicht implementiert.") logging.LogWarn("Option noch nicht implementiert.")
quit := logging.PromptAnyKeyToContinue() quit := logging.PromptAnyKeyToContinue()

View File

@ -6,6 +6,7 @@ package menus
import ( import (
"fmt" "fmt"
"strings"
"ads/internal/core/logging" "ads/internal/core/logging"
"ads/internal/core/utils" "ads/internal/core/utils"
@ -16,7 +17,7 @@ import (
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
// Zeigt Prompt mit Liste von Optionen an // Zeigt Prompt mit Liste von Optionen an
func PromptListOfOptions(messages []string, options [][2]string, breaks []int, defaultChoice string) (string, bool) { func promptListOfOptions(messages []string, options [][2]string, breaks []int, defaultChoice string) (string, bool) {
var n = len(options) var n = len(options)
var ( var (
choice string choice string
@ -32,6 +33,8 @@ func PromptListOfOptions(messages []string, options [][2]string, breaks []int, d
lines = append(lines, message) lines = append(lines, message)
} }
lines = append(lines, "") lines = append(lines, "")
textbar := fmt.Sprintf(" \033[93m+%s+\033[0m", strings.Repeat("-", 40))
lines = append(lines, textbar)
for i, obj := range options { for i, obj := range options {
key := obj[0] key := obj[0]
label := obj[1] label := obj[1]
@ -42,13 +45,14 @@ func PromptListOfOptions(messages []string, options [][2]string, breaks []int, d
lines = append(lines, fmt.Sprintf(" \033[93;1m%v)\033[0m %v", key, label)) lines = append(lines, fmt.Sprintf(" \033[93;1m%v)\033[0m %v", key, label))
} }
if i < n-1 && utils.ArrayContains(breaks, i) { if i < n-1 && utils.ArrayContains(breaks, i) {
lines = append(lines, " \033[93m--------\033[0m") lines = append(lines, " \033[93m+----\033[0m")
} }
i++ i++
} }
if !(defaultChoice == "" || defaultChoice == "-1") { lines = append(lines, textbar)
if !(defaultChoice == "") {
lines = append(lines, "") lines = append(lines, "")
lines = append(lines, "\033[91;2m*\033[0m\033[2m = Default\033[0m") lines = append(lines, " \033[91;2m*\033[0m\033[2m = Default\033[0m")
} }
// Wiederhole Prompt, bis gültige Eingabe erreicht // Wiederhole Prompt, bis gültige Eingabe erreicht

View File

@ -19,10 +19,11 @@ type MenuOption struct {
type Menu struct { type Menu struct {
IsRoot bool IsRoot bool
ForceReturn bool
Path []string Path []string
PromptMessages []string PromptMessages []string
Options []MenuOption Options [][]MenuOption
DefaultOption int Default int
} }
/* ---------------------------------------------------------------- * /* ---------------------------------------------------------------- *

View File

@ -5,9 +5,12 @@ package cli
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
import ( import (
"fmt"
"github.com/akamensky/argparse" "github.com/akamensky/argparse"
"ads/internal/types" "ads/internal/types"
"ads/pkg/re"
) )
/* ---------------------------------------------------------------- * /* ---------------------------------------------------------------- *
@ -62,6 +65,7 @@ var optionsConfigFile = argparse.Options{
* METHODS parse cli * METHODS parse cli
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
// Parst cli flags.
func ParseCli(args []string) (*types.CliArguments, error) { func ParseCli(args []string) (*types.CliArguments, error) {
var err error var err error
Parser = argparse.NewParser("cli parser", "Liest Optionen + Flags von Kommandozeile.") Parser = argparse.NewParser("cli parser", "Liest Optionen + Flags von Kommandozeile.")
@ -79,3 +83,9 @@ func ParseCli(args []string) (*types.CliArguments, error) {
err = Parser.Parse(args) err = Parser.Parse(args)
return &arguments, err return &arguments, err
} }
// Prüft, ob der Parser nur deshalb fehlschlägt, weil ein Command fehlt.
func ParseCliCommandMissing(err error) bool {
// FIXME: unschöne Lösung. Leider ist Error-Typ im Package versteckt
return re.Matches(`(?i)(command required)`, fmt.Sprintf("%v", err))
}

View File

@ -5,9 +5,9 @@ package setup
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
import ( import (
"ads/internal/types"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"ads/internal/types"
) )
/* ---------------------------------------------------------------- * /* ---------------------------------------------------------------- *

View File

@ -5,10 +5,11 @@ package setup
* ---------------------------------------------------------------- */ * ---------------------------------------------------------------- */
import ( import (
"ads/internal/types"
"io/ioutil" "io/ioutil"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"ads/internal/types"
) )
/* ---------------------------------------------------------------- * /* ---------------------------------------------------------------- *

View File

@ -45,10 +45,15 @@ func main() {
// cli arguments parsen // cli arguments parsen
arguments, err = cli.ParseCli(os.Args) arguments, err = cli.ParseCli(os.Args)
cmdMissing := cli.ParseCliCommandMissing(err)
// initialisiere basic optionen wie Logging // initialisiere basic optionen wie Logging
if err == nil { if err == nil {
logging.SetQuietMode(arguments.QuietModeOn()) quiet := arguments.QuietModeOn()
if arguments.InteractiveMode() {
quiet = false
}
logging.SetQuietMode(quiet)
logging.SetDebugMode(arguments.DebugModeOn()) logging.SetDebugMode(arguments.DebugModeOn())
logging.SetAnsiMode(arguments.ShowColour()) logging.SetAnsiMode(arguments.ShowColour())
} }
@ -71,9 +76,13 @@ func main() {
} else { } else {
err = endpoints.RunNonInteractive(arguments.GetConfigFile()) err = endpoints.RunNonInteractive(arguments.GetConfigFile())
} }
} else { // } else if arguments.Help.Happened() { } else if arguments.ModeHelp.Happened() {
endpoints.Help() endpoints.Help()
} else {
err = endpoints.RunInteractive()
} }
} else if cmdMissing {
err = endpoints.RunInteractive()
} }
if err != nil { if err != nil {