master > master: code - go project hinzugefügt
This commit is contained in:
parent
37dea15b2b
commit
f4287dfd8f
15
code/golang/go.mod
Normal file
15
code/golang/go.mod
Normal file
@ -0,0 +1,15 @@
|
||||
module ads
|
||||
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/akamensky/argparse v1.3.1
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/lithammer/dedent v1.1.0
|
||||
github.com/pmezard/go-difflib v1.0.0
|
||||
github.com/slongfield/pyfmt v0.0.0-20180124071345-020a7cb18bca
|
||||
github.com/stretchr/objx v0.1.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
golang.org/x/tools v0.1.7
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
)
|
116
code/golang/internal/core/logging/logging.go
Normal file
116
code/golang/internal/core/logging/logging.go
Normal file
@ -0,0 +1,116 @@
|
||||
package logging
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"ads/internal/core/utils"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* GLOBAL VARIABLES
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
var quietmode bool = false
|
||||
var debugmode bool = false
|
||||
var ansimode bool = true
|
||||
var loggingPrefix string = ""
|
||||
var force bool = false
|
||||
var tagAll bool = false
|
||||
|
||||
func GetQuietMode() bool {
|
||||
return quietmode
|
||||
}
|
||||
|
||||
func SetQuietMode(mode bool) {
|
||||
quietmode = mode
|
||||
}
|
||||
|
||||
func GetDebugMode() bool {
|
||||
return debugmode
|
||||
}
|
||||
|
||||
func SetDebugMode(mode bool) {
|
||||
debugmode = mode
|
||||
}
|
||||
|
||||
func GetAnsiMode() bool {
|
||||
return ansimode
|
||||
}
|
||||
|
||||
func SetAnsiMode(mode bool) {
|
||||
ansimode = mode
|
||||
}
|
||||
|
||||
func GetForce() bool {
|
||||
return force
|
||||
}
|
||||
|
||||
func SetForce(mode bool) {
|
||||
force = mode
|
||||
}
|
||||
|
||||
func SetTagAll(mode bool) {
|
||||
tagAll = mode
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHOD logging
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func logGeneric(tag string, lines ...interface{}) {
|
||||
if !force && quietmode {
|
||||
return
|
||||
}
|
||||
if !(tag == "") {
|
||||
tag = tag + " "
|
||||
}
|
||||
for _, line := range lines {
|
||||
_line := fmt.Sprintf("%[1]s%[2]s%[3]v", loggingPrefix, tag, line)
|
||||
if !ansimode {
|
||||
_line = utils.StripAnsi(_line)
|
||||
}
|
||||
fmt.Println(_line)
|
||||
if !tagAll {
|
||||
tag = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func LogPlain(lines ...interface{}) {
|
||||
SetTagAll(false)
|
||||
logGeneric("", lines...)
|
||||
}
|
||||
|
||||
func LogInfo(lines ...interface{}) {
|
||||
SetTagAll(true)
|
||||
logGeneric("[\033[94;1mINFO\033[0m]", lines...)
|
||||
}
|
||||
|
||||
func LogDebug(lines ...interface{}) {
|
||||
if !debugmode {
|
||||
return
|
||||
}
|
||||
SetTagAll(true)
|
||||
logGeneric("[\033[96;1mDEBUG\033[0m]", lines...)
|
||||
}
|
||||
|
||||
func LogWarn(lines ...interface{}) {
|
||||
SetTagAll(false)
|
||||
logGeneric("[\033[93;1mWARNING\033[0m]", lines...)
|
||||
}
|
||||
|
||||
func LogError(lines ...interface{}) {
|
||||
SetTagAll(false)
|
||||
logGeneric("[\033[91;1mERROR\033[0m]", lines...)
|
||||
}
|
||||
|
||||
func LogFatal(lines ...interface{}) {
|
||||
SetTagAll(false)
|
||||
logGeneric("[\033[91;1mFATAL\033[0m]", lines...)
|
||||
os.Exit(1)
|
||||
}
|
85
code/golang/internal/core/utils/utils_arrays.go
Normal file
85
code/golang/internal/core/utils/utils_arrays.go
Normal file
@ -0,0 +1,85 @@
|
||||
package utils
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHOD array contains
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func ArrayContains(x interface{}, elem interface{}) bool {
|
||||
xAsArray := reflect.ValueOf(x)
|
||||
if xAsArray.Kind() == reflect.Slice {
|
||||
for i := 0; i < xAsArray.Len(); i++ {
|
||||
if xAsArray.Index(i).Interface() == elem {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// func ListComprehension(x interface{}, cond (interface{}) bool) bool {
|
||||
// xAsArray := reflect.ValueOf(x)
|
||||
// if xAsArray.Kind() == reflect.Slice {
|
||||
// for i := 0; i < xAsArray.Len(); i++ {
|
||||
// if xAsArray.Index(i).Interface() == elem {
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHOD array contains
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func UniqueListOfStrings(X []string) []string {
|
||||
var ok bool
|
||||
m := map[string]bool{}
|
||||
X_unique := []string{}
|
||||
for _, x := range X {
|
||||
if _, ok = m[x]; !ok {
|
||||
X_unique = append(X_unique, x)
|
||||
}
|
||||
}
|
||||
return X_unique
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHOD get value from array of unknown length
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func GetArrayStringValue(arr *[]string, index int, Default string) string {
|
||||
if arr != nil && len(*arr) > index {
|
||||
return (*arr)[index]
|
||||
}
|
||||
return Default
|
||||
}
|
||||
|
||||
func GetArrayBoolValue(arr *[]bool, index int, Default bool) bool {
|
||||
if arr != nil && len(*arr) > index {
|
||||
return (*arr)[index]
|
||||
}
|
||||
return Default
|
||||
}
|
||||
|
||||
func GetArrayIntValue(arr *[]int, index int, Default int) int {
|
||||
if arr != nil && len(*arr) > index {
|
||||
return (*arr)[index]
|
||||
}
|
||||
return Default
|
||||
}
|
||||
|
||||
func GetArrayInterfaceValue(arr *[](interface{}), index int, Default interface{}) interface{} {
|
||||
if arr != nil && len(*arr) > index {
|
||||
return (*arr)[index]
|
||||
}
|
||||
return Default
|
||||
}
|
96
code/golang/internal/core/utils/utils_strings.go
Normal file
96
code/golang/internal/core/utils/utils_strings.go
Normal file
@ -0,0 +1,96 @@
|
||||
package utils
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/lithammer/dedent"
|
||||
"github.com/slongfield/pyfmt"
|
||||
|
||||
"ads/pkg/re"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHOD format strings with dictionary substitution
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func FormatPythonString(text string, arguments map[string]interface{}) string {
|
||||
var (
|
||||
err error
|
||||
key string
|
||||
value interface{}
|
||||
kind reflect.Kind
|
||||
refValue reflect.Value
|
||||
)
|
||||
// force compatibility of expressions with python
|
||||
for key, value = range arguments {
|
||||
kind = reflect.TypeOf(value).Kind()
|
||||
switch kind {
|
||||
case reflect.Ptr:
|
||||
refValue = reflect.ValueOf(value)
|
||||
if refValue.IsNil() {
|
||||
arguments[key] = "None"
|
||||
}
|
||||
case reflect.Bool:
|
||||
arguments[key] = strings.Title(fmt.Sprintf(`%v`, value))
|
||||
}
|
||||
}
|
||||
text, err = pyfmt.Fmt(text, arguments)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHOD dedent textblock and expand escaped symbols
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func DedentIgnoreEmptyLines(text string) string {
|
||||
return dedent.Dedent(text)
|
||||
}
|
||||
|
||||
func DedentIgnoreFirstAndLast(text string) string {
|
||||
text = re.Sub(`^\s*[\n\r]|[\n\r]\s*$`, ``, text)
|
||||
return DedentIgnoreEmptyLines(text)
|
||||
}
|
||||
|
||||
func DedentAndExpand(text string) string {
|
||||
var err error
|
||||
var result []string
|
||||
result = []string{}
|
||||
text = dedent.Dedent(text)
|
||||
lines := strings.Split(text, "\n")
|
||||
for _, line := range lines {
|
||||
line = fmt.Sprintf(`"%s"`, line)
|
||||
line, err = strconv.Unquote(line)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
result = append(result, line)
|
||||
}
|
||||
return strings.Join(result, "\n")
|
||||
}
|
||||
|
||||
func FormatTextBlockAsList(text string, options ...bool) []string {
|
||||
var unindent bool = GetArrayBoolValue(&options, 0, true)
|
||||
if unindent {
|
||||
text = DedentIgnoreFirstAndLast(text)
|
||||
}
|
||||
return re.Split(`\n`, text)
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHODS ansi
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func StripAnsi(text string) string {
|
||||
return re.Sub(`\x1b[^m]*m`, ``, text)
|
||||
}
|
34
code/golang/internal/endpoints/endpoints_print.go
Normal file
34
code/golang/internal/endpoints/endpoints_print.go
Normal file
@ -0,0 +1,34 @@
|
||||
package endpoints
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
import (
|
||||
"ads/internal/core/logging"
|
||||
"ads/internal/setup"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* ENDPOINT version
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func Version() {
|
||||
logging.SetForce(true)
|
||||
logging.LogPlain(setup.Version())
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* ENDPOINT help
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func Help() {
|
||||
logging.SetForce(true)
|
||||
logging.LogPlain(
|
||||
"",
|
||||
setup.Logo(),
|
||||
// cli.Parser.Usage(nil),
|
||||
setup.Help(),
|
||||
"",
|
||||
)
|
||||
}
|
20
code/golang/internal/endpoints/endpoints_run.go
Normal file
20
code/golang/internal/endpoints/endpoints_run.go
Normal file
@ -0,0 +1,20 @@
|
||||
package endpoints
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
import (
|
||||
"ads/internal/core/logging"
|
||||
"ads/internal/setup"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* ENDPOINT run
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func Run(fnameConfig string) error {
|
||||
logging.LogPlain(setup.Logo())
|
||||
logging.LogWarn("Die Go-Implementierung ist noch unter Arbeit.")
|
||||
return nil
|
||||
}
|
66
code/golang/internal/setup/cli/cli.go
Normal file
66
code/golang/internal/setup/cli/cli.go
Normal file
@ -0,0 +1,66 @@
|
||||
package cli
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
import (
|
||||
"github.com/akamensky/argparse"
|
||||
|
||||
"ads/internal/types"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* GLOBAL VARIABLES
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
var Parser *argparse.Parser
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* LOCAL VARIABLES / CONSTANTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
var optionsQuiet = argparse.Options{
|
||||
Help: "Blendet alle Konsole-Messages aus.",
|
||||
Required: false,
|
||||
Default: false,
|
||||
}
|
||||
|
||||
var optionsDebug = argparse.Options{
|
||||
Help: "Blendet die Debugging-Befehle ein.",
|
||||
Required: false,
|
||||
Default: false,
|
||||
}
|
||||
|
||||
var optionsColour = argparse.Options{
|
||||
Help: "Ob Logging färblich angezeigt wird (default=true).",
|
||||
Required: false,
|
||||
// NOTE: no `Boolean` option available!
|
||||
Default: "true",
|
||||
}
|
||||
|
||||
var optionsConfigFile = argparse.Options{
|
||||
Help: "Pfad zur Configdatei (nur für run Endpunkt).",
|
||||
Required: false,
|
||||
Default: "code/config.yml",
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHODS parse cli
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func ParseCli(args []string) (*types.CliArguments, error) {
|
||||
var err error
|
||||
Parser = argparse.NewParser("cli parser", "Liest Optionen + Flags von Kommandozeile.")
|
||||
arguments := types.CliArguments{
|
||||
Help: Parser.NewCommand("help", ""),
|
||||
Version: Parser.NewCommand("version", "Ruft Endpunkt auf, der die Version anzeigt."),
|
||||
Run: Parser.NewCommand("run", "Ruft Endpunkt auf, der die Algorithmen laufen lässt."),
|
||||
Quiet: Parser.Flag("q", "quiet", &optionsQuiet),
|
||||
Debug: Parser.Flag("", "debug", &optionsDebug),
|
||||
Colour: Parser.String("", "colour", &optionsColour),
|
||||
ConfigFile: Parser.String("", "config", &optionsConfigFile),
|
||||
}
|
||||
err = Parser.Parse(args)
|
||||
return &arguments, err
|
||||
}
|
56
code/golang/internal/setup/setup_assets.go
Normal file
56
code/golang/internal/setup/setup_assets.go
Normal file
@ -0,0 +1,56 @@
|
||||
package setup
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"ads/internal/core/utils"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* GLOBAL VARIABLES
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
var Res embed.FS
|
||||
var Assets map[string]string
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHOD read assets
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func ReadAsset(key string) string {
|
||||
var found bool
|
||||
if _, found = Assets[key]; !found {
|
||||
log.Fatal(fmt.Sprintf("Key \033[1m%s\033[0m not found in dictionary!", key))
|
||||
}
|
||||
data, err := Res.ReadFile(Assets[key])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
text := string(data)
|
||||
return text
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHODS templates
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func Help() string {
|
||||
contents := ReadAsset("help")
|
||||
return utils.DedentAndExpand(contents)
|
||||
}
|
||||
|
||||
func Logo() string {
|
||||
contents := ReadAsset("logo")
|
||||
return utils.DedentAndExpand(contents)
|
||||
}
|
||||
|
||||
func Version() string {
|
||||
return strings.Trim(ReadAsset("version"), "\n")
|
||||
}
|
45
code/golang/internal/types/types_cli.go
Normal file
45
code/golang/internal/types/types_cli.go
Normal file
@ -0,0 +1,45 @@
|
||||
package types
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/akamensky/argparse"
|
||||
|
||||
"ads/pkg/re"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* TYPES
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
type CliArguments struct {
|
||||
Help *argparse.Command
|
||||
Version *argparse.Command
|
||||
Run *argparse.Command
|
||||
Quiet *bool
|
||||
Debug *bool
|
||||
Colour *string
|
||||
ConfigFile *string
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHODS convert string option to boolean
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func IsTrue(text string) bool {
|
||||
text = strings.TrimSpace(text)
|
||||
return re.Matches(`(?i)(^(true|t|yes|y|1|\+|\+1)$)`, text)
|
||||
}
|
||||
|
||||
func IsFalse(text string) bool {
|
||||
text = strings.TrimSpace(text)
|
||||
return re.Matches(`(?i)(^(false|f|no|n|0|-|-1)$)`, text)
|
||||
}
|
||||
|
||||
func (arguments *CliArguments) ShowColour() bool {
|
||||
return !IsFalse(*arguments.Colour)
|
||||
}
|
68
code/golang/main.go
Normal file
68
code/golang/main.go
Normal file
@ -0,0 +1,68 @@
|
||||
package main
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"os"
|
||||
|
||||
"ads/internal/core/logging"
|
||||
"ads/internal/endpoints"
|
||||
"ads/internal/setup"
|
||||
"ads/internal/setup/cli"
|
||||
"ads/internal/types"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* GLOBAL VARIABLES
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
var (
|
||||
// !!! NOTE: do not remove the following "comment", as it is a preprocessing instruction !!!
|
||||
//go:embed assets/*
|
||||
res embed.FS
|
||||
assets = map[string]string{
|
||||
"version": "assets/VERSION",
|
||||
"logo": "assets/LOGO",
|
||||
"help": "assets/HELP",
|
||||
}
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHOD main
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
var arguments *types.CliArguments
|
||||
|
||||
// set assets
|
||||
setup.Res = res
|
||||
setup.Assets = assets
|
||||
|
||||
// parse cli arguments
|
||||
arguments, err = cli.ParseCli(os.Args)
|
||||
|
||||
// initialise logging options
|
||||
if err == nil {
|
||||
logging.SetQuietMode(*arguments.Quiet)
|
||||
logging.SetDebugMode(*arguments.Debug)
|
||||
logging.SetAnsiMode(arguments.ShowColour())
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
if arguments.Version.Happened() {
|
||||
endpoints.Version()
|
||||
} else if arguments.Run.Happened() {
|
||||
err = endpoints.Run(*arguments.ConfigFile)
|
||||
} else { // } else if arguments.Help.Happened() {
|
||||
endpoints.Help()
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logging.LogFatal(err)
|
||||
}
|
||||
}
|
62
code/golang/pkg/re/re.go
Normal file
62
code/golang/pkg/re/re.go
Normal file
@ -0,0 +1,62 @@
|
||||
package re
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* IMPORTS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* GLOBAL VARIABLES
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
type Reader struct {
|
||||
regex *regexp.Regexp
|
||||
lastpattern *string
|
||||
}
|
||||
|
||||
var defaultReader Reader = Reader{}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHODS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func Matches(pattern string, text string) bool {
|
||||
return defaultReader.Matches(pattern, text)
|
||||
}
|
||||
|
||||
func Sub(pattern string, substitute string, text string) string {
|
||||
return defaultReader.Sub(pattern, substitute, text)
|
||||
}
|
||||
|
||||
func Split(pattern string, text string) []string {
|
||||
return defaultReader.Split(pattern, text)
|
||||
}
|
||||
|
||||
func (r *Reader) Matches(pattern string, text string) bool {
|
||||
r.setReader(pattern)
|
||||
return r.regex.MatchString(text)
|
||||
}
|
||||
|
||||
func (r *Reader) Sub(pattern string, substitute string, text string) string {
|
||||
r.setReader(pattern)
|
||||
return r.regex.ReplaceAllString(text, substitute)
|
||||
}
|
||||
|
||||
func (r *Reader) Split(pattern string, text string) []string {
|
||||
r.setReader(pattern)
|
||||
return r.regex.Split(text, -1)
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* PRIVATE MEHODS
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func (r *Reader) setReader(pattern string) {
|
||||
if r.regex == nil || r.lastpattern == nil || *r.lastpattern != pattern {
|
||||
r.lastpattern = &pattern
|
||||
r.regex = regexp.MustCompile(pattern)
|
||||
}
|
||||
}
|
6
code/golang/requirements
Normal file
6
code/golang/requirements
Normal file
@ -0,0 +1,6 @@
|
||||
github.com/akamensky/argparse@v1.3.1
|
||||
github.com/lithammer/dedent@v1.1.0
|
||||
github.com/slongfield/pyfmt@v0.0.0-20180124071345-020a7cb18bca
|
||||
github.com/stretchr/testify@v1.7.0
|
||||
golang.org/x/tools
|
||||
gopkg.in/yaml.v3@v3.0.0-20210107192922-496545a6307b
|
Loading…
Reference in New Issue
Block a user