Compare commits
No commits in common. "189755e69afdcdacce35a12dd7908fe1baa2c380" and "dccb8e8af2c6287f292c4264d01c1e44bf1a83fb" have entirely different histories.
189755e69a
...
dccb8e8af2
12
.env
12
.env
@ -1,12 +0,0 @@
|
||||
# General
|
||||
NAME_OF_APP="ads"
|
||||
REQUIREMENTS_PY="code/python/requirements"
|
||||
REQUIREMENTS_GO="code/golang/requirements"
|
||||
TEST_TIMEOUT="10s"
|
||||
|
||||
# Logging
|
||||
CONSOLE_OUT=/dev/stdout
|
||||
CONSOLE_ERR=/dev/stderr
|
||||
CONSOLE_VERBOSE=/dev/null
|
||||
CONSOLE_PATH_LOGS=logs
|
||||
CONSOLE_FILENAME_LOGS_DEBUG=debug.log
|
17
.gitignore
vendored
17
.gitignore
vendored
@ -5,7 +5,6 @@
|
||||
# MAIN FOLDER
|
||||
################################################################
|
||||
|
||||
!/.env
|
||||
!/README.md
|
||||
|
||||
################################################################
|
||||
@ -20,23 +19,11 @@
|
||||
!/protocol/README.md
|
||||
!/protocol/woche*.md
|
||||
|
||||
!/scripts
|
||||
!/scripts/*.sh
|
||||
|
||||
!/code
|
||||
!/code/**/
|
||||
!/code/python/**/*.py
|
||||
!/code/golang/**/*.go
|
||||
!/code/golang/go.mod
|
||||
!/code/*/requirements
|
||||
!/code/**/*.py
|
||||
!/code/requirements
|
||||
!/code/config.yml
|
||||
## nicht synchronisieren:
|
||||
/code/golang/go.sum
|
||||
/code/python/build
|
||||
/code/python/build/**
|
||||
|
||||
!/dist
|
||||
!/dist/VERSION
|
||||
|
||||
################################################################
|
||||
# ARTEFACTS
|
||||
|
73
README.md
73
README.md
@ -25,49 +25,16 @@ In diesem Repository findet man:
|
||||
|
||||
## Code ##
|
||||
|
||||
Im Unterordner [`code`](./code) kann man Codeprojekte in Python und Golang finden, in denen verschiedene Algorithmen implementiert werden
|
||||
(siehe insbes. [`code/python/src/algorithms`](./code/python//src/algorithms)
|
||||
und [`code/golang/pkg/algorithms`](./code/golang/pkg/algorithms)).
|
||||
Im Unterordner [`code`](./code) kann man ein Python-Projekt finden,
|
||||
in dem verschiedene Algorithmen implementiert werden
|
||||
(siehe insbes. [`code/algorithms`](./code/algorithms)).
|
||||
Man kann gerne den Code benutzen, in einer eigenen Repository verändern,
|
||||
und mit den in dem Kurs präsentierten Algorithmen herumexperimentieren.
|
||||
|
||||
### Systemvoraussetzungen ###
|
||||
|
||||
#### Bashscripts ####
|
||||
|
||||
Im Ordner [`scripts`](./scripts) sind mehrere Workflows als Bashscripts kodiert. (Man kann natürlich ohne sie arbeiten, insbesondere dann, wenn man einen guten IDE hat.)
|
||||
|
||||
Zunächst braucht man einen Bashterminal. Das kommt mit OSX (Terminal) und Linux. Für Windows-User braucht man [git-for-windows](https://gitforwindows.org) zu installieren, was auch bash mit installiert. (Und für diejenigen, die VSCode oder andere IDEs benutzen, lässt sich bash als integrierten Terminal im IDE selbst verwenden.)
|
||||
|
||||
Den Bashscripts benötigen Ausfuhrrechte. Hierfür führe man
|
||||
```bash
|
||||
chmod +x scripts/*.sh;
|
||||
```
|
||||
aus. Das muss danach nie wiederholt werden.
|
||||
|
||||
Jetzt können wir von dem Hauptordner des Repositorys Befehle wie
|
||||
```bash
|
||||
./scripts/build.sh
|
||||
./scripts/build.sh ---mode setup
|
||||
```
|
||||
usw. in der Bash-Console ausführen.
|
||||
|
||||
#### Für das Golang-Projekt ####
|
||||
|
||||
Man braucht [go](https://golang.org/dl/) Version **1.17.x**. (Man kann bestimmt bei späteren Releases höhere Versionen benutzen. Man muss lediglich dann in [`./code/golang/go.mod`](./code/golang/go.mod) die Version hochstellen und die Requirements nochmals installieren lassen.) Und einige Packages werden benötigen. Letztere lassen sich mittels
|
||||
```bash
|
||||
./scripts/build.sh --lang go --mode setup
|
||||
```
|
||||
installieren.
|
||||
|
||||
#### Für das Python-Projekt ####
|
||||
|
||||
Python version 3.x.x (idealerweise zumindest 3.9.5) plus einige Module (siehe [code/requirements](./code/requirements)). Letztere lassen sich mittels
|
||||
```bash
|
||||
./scripts/build.sh --lang python --mode setup
|
||||
## mit virtuellem Env:
|
||||
./scripts/build.sh --lang python --venv true --mode setup
|
||||
## alternative:
|
||||
python3 -m pip install -r code/requirements; # linux, osx
|
||||
py -3 -m pip install -r code/requirements; # Windows
|
||||
```
|
||||
@ -75,35 +42,17 @@ installieren.
|
||||
|
||||
### Ausführung ###
|
||||
|
||||
#### Für das Golang-Projekt ####
|
||||
|
||||
Zuerst den Artefakt kompilieren:
|
||||
Um den Python Code auszuführen, bspw. im Bash:
|
||||
```bash
|
||||
./scripts/build.sh --lang go --mode dist;
|
||||
## oder:
|
||||
go build -o "dist/ads" "code/golang/main.go";
|
||||
```
|
||||
und dann mit dem gebauten Artefakt arbeiten:
|
||||
```bash
|
||||
./dist/ads1 help; # zeigt Hilfsanleitung
|
||||
./dist/ads1 version; # zeigt Version
|
||||
./dist/ads1 run [--debug]; # führt code aus
|
||||
```
|
||||
|
||||
#### Für das Python-Projekt ####
|
||||
|
||||
```bash
|
||||
pushd code/python/src; ## <- auf Pfad mit main.py wechseln
|
||||
|
||||
## Anzeigen der Hilfsanleitung:
|
||||
python3 main.py -h; # linux, OSX
|
||||
py -3 main.py -h; # Windows
|
||||
python3 code/main.py -h; # linux, OSX
|
||||
py -3 code/main.py -h; # Windows
|
||||
## Ausführung der Testfälle in code/config.yml:
|
||||
python3 main.py run [--debug]; # linux, OSX
|
||||
py -3 main.py run [--debug]; # Windows
|
||||
## --debug Option benutzen, um Infos über Schritte zu zeigen.
|
||||
|
||||
popd; ## <- zum vorherigen Pfad zurückwechseln
|
||||
python3 code/main.py all; # linux, OSX
|
||||
py -3 code/main.py all; # Windows
|
||||
## Mit Infos über Schritte:
|
||||
python3 code/main.py --debug all; # linux, OSX
|
||||
py -3 code/main.py --debug all; # Windows
|
||||
```
|
||||
Oder man erstelle einen bash Skript wie `run.sh`, trage die Befehle da ein und führe
|
||||
```bash
|
||||
|
@ -5,5 +5,5 @@
|
||||
# EXPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.algorithms.search.exports import *;
|
||||
from src.algorithms.sum.exports import *;
|
||||
from code.algorithms.search.exports import *;
|
||||
from code.algorithms.sum.exports import *;
|
@ -7,8 +7,8 @@
|
||||
|
||||
import functools;
|
||||
|
||||
from src.core.log import *;
|
||||
from src.setup.display import *;
|
||||
from code.core.log import *;
|
||||
from code.setup.display import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# CLASSES
|
@ -5,11 +5,11 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.maths import *;
|
||||
from src.local.typing import *;
|
||||
from local.maths import *;
|
||||
from local.typing import *;
|
||||
|
||||
from src.core.log import *;
|
||||
from src.algorithms.methods import *;
|
||||
from code.core.log import *;
|
||||
from code.algorithms.methods import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES/CONSTANTS
|
16
code/algorithms/search/exports.py
Normal file
16
code/algorithms/search/exports.py
Normal file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# EXPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from code.algorithms.search.sequential import SequentialSearch;
|
||||
from code.algorithms.search.binary import BinarySearch;
|
||||
from code.algorithms.search.interpol import InterpolationSearch;
|
||||
from code.algorithms.search.jump import JumpSearchLinear;
|
||||
from code.algorithms.search.jump import JumpSearchExponentiell;
|
||||
from code.algorithms.search.ith_smallest import FindIthSmallest;
|
||||
from code.algorithms.search.ith_smallest import FindIthSmallestDC;
|
||||
from code.algorithms.search.poison import FindPoison;
|
||||
from code.algorithms.search.poison import FindPoisonFast;
|
@ -5,11 +5,11 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.maths import *;
|
||||
from src.local.typing import *;
|
||||
from local.maths import *;
|
||||
from local.typing import *;
|
||||
|
||||
from src.core.log import *;
|
||||
from src.algorithms.methods import *;
|
||||
from code.core.log import *;
|
||||
from code.algorithms.methods import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES/CONSTANTS
|
@ -5,12 +5,12 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.maths import *;
|
||||
from src.local.typing import *;
|
||||
from local.maths import *;
|
||||
from local.typing import *;
|
||||
|
||||
from src.core.log import *;
|
||||
from src.algorithms.search.sequential import SequentialSearch;
|
||||
from src.algorithms.methods import *;
|
||||
from code.core.log import *;
|
||||
from code.algorithms.search.sequential import SequentialSearch;
|
||||
from code.algorithms.methods import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES/CONSTANTS
|
@ -5,12 +5,12 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.maths import *;
|
||||
from src.local.typing import *;
|
||||
from local.maths import *;
|
||||
from local.typing import *;
|
||||
|
||||
from src.core.log import *;
|
||||
from src.algorithms.search.sequential import SequentialSearch;
|
||||
from src.algorithms.methods import *;
|
||||
from code.core.log import *;
|
||||
from code.algorithms.search.sequential import SequentialSearch;
|
||||
from code.algorithms.methods import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES/CONSTANTS
|
@ -5,11 +5,11 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.maths import *;
|
||||
from src.local.typing import *;
|
||||
from local.maths import *;
|
||||
from local.typing import *;
|
||||
|
||||
from src.core.log import *;
|
||||
from src.algorithms.methods import *;
|
||||
from code.core.log import *;
|
||||
from code.algorithms.methods import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES/CONSTANTS
|
@ -5,11 +5,11 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.maths import *;
|
||||
from src.local.typing import *;
|
||||
from local.maths import *;
|
||||
from local.typing import *;
|
||||
|
||||
from src.core.log import *;
|
||||
from src.algorithms.methods import *;
|
||||
from code.core.log import *;
|
||||
from code.algorithms.methods import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES/CONSTANTS
|
@ -5,5 +5,5 @@
|
||||
# EXPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.algorithms.sum.maxsubsum import MaxSubSum;
|
||||
from src.algorithms.sum.maxsubsum import MaxSubSumDC;
|
||||
from code.algorithms.sum.maxsubsum import MaxSubSum;
|
||||
from code.algorithms.sum.maxsubsum import MaxSubSumDC;
|
@ -5,11 +5,11 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.maths import *;
|
||||
from src.local.typing import *;
|
||||
from local.maths import *;
|
||||
from local.typing import *;
|
||||
|
||||
from src.core.log import *;
|
||||
from src.algorithms.methods import *;
|
||||
from code.core.log import *;
|
||||
from code.algorithms.methods import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES/CONSTANTS
|
@ -5,8 +5,8 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.typing import *;
|
||||
from src.local.config import *;
|
||||
from code.local.typing import *;
|
||||
from code.local.config import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES
|
@ -5,14 +5,14 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.io import *;
|
||||
from src.local.misc import *;
|
||||
from src.local.system import *;
|
||||
from src.local.typing import *;
|
||||
from code.local.io import *;
|
||||
from code.local.misc import *;
|
||||
from code.local.system import *;
|
||||
from code.local.typing import *;
|
||||
|
||||
from datetime import timedelta;
|
||||
|
||||
from src.core.metrics import *;
|
||||
from code.core.metrics import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES
|
@ -1,15 +0,0 @@
|
||||
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
|
||||
)
|
@ -1,116 +0,0 @@
|
||||
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)
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
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
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
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)
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
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(),
|
||||
"",
|
||||
)
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
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
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
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
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
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")
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
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)
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
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)
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
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)
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
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
|
@ -8,14 +8,13 @@
|
||||
import os;
|
||||
import sys;
|
||||
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.abspath(__file__), '..', '..')));
|
||||
os.chdir(os.path.abspath(os.path.join(os.path.abspath(__file__), '..', '..', '..', '..')));
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))));
|
||||
|
||||
from src.core.log import *;
|
||||
from src.core.config import *;
|
||||
from src.setup.display import *;
|
||||
from src.setup.cli import *;
|
||||
from src.algorithms.exports import *;
|
||||
from code.core.log import *;
|
||||
from code.core.config import *;
|
||||
from code.setup.display import *;
|
||||
from code.setup.cli import *;
|
||||
from code.algorithms.exports import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES/CONSTANTS
|
||||
@ -31,7 +30,7 @@ def enter(quiet: bool, debug: bool, mode: str, path: Any, **_):
|
||||
SetQuietMode(quiet);
|
||||
SetDebugMode(debug);
|
||||
configpath = path if isinstance(path, str) else PATH_TO_CONFIG;
|
||||
if mode in 'run':
|
||||
if mode == 'all':
|
||||
LoopThroughCases(path=configpath);
|
||||
else:
|
||||
DisplayHelpMessage();
|
@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# EXPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.algorithms.search.sequential import SequentialSearch;
|
||||
from src.algorithms.search.binary import BinarySearch;
|
||||
from src.algorithms.search.interpol import InterpolationSearch;
|
||||
from src.algorithms.search.jump import JumpSearchLinear;
|
||||
from src.algorithms.search.jump import JumpSearchExponentiell;
|
||||
from src.algorithms.search.ith_smallest import FindIthSmallest;
|
||||
from src.algorithms.search.ith_smallest import FindIthSmallestDC;
|
||||
from src.algorithms.search.poison import FindPoison;
|
||||
from src.algorithms.search.poison import FindPoisonFast;
|
@ -1,4 +1,3 @@
|
||||
pip>=21.3.1
|
||||
argparse>=1.4.0
|
||||
pyyaml>=5.4.1
|
||||
typing>=3.7.4.3
|
@ -5,9 +5,9 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.typing import *;
|
||||
from code.local.typing import *;
|
||||
|
||||
from src.core.log import *;
|
||||
from code.core.log import *;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# GLOBAL VARIABLES
|
||||
@ -30,7 +30,7 @@ def GetArgumentParser() -> argparse.ArgumentParser:
|
||||
'''),
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
);
|
||||
parser.add_argument('mode', nargs=1, choices=['run'], help='run = Führt alle Testfälle in der config.yml Datei durch.');
|
||||
parser.add_argument('mode', nargs=1, choices=['all'], help='all = Führt alle Testfälle in der config.yml Datei durch.');
|
||||
parser.add_argument('--path', nargs=1, type=str, help='Pfad zur alternativen Configdatei.');
|
||||
parser.add_argument('--debug', action='store_true', help='Debugging Messages stummschalten.')
|
||||
parser.add_argument('-q', '--quiet', action='store_true', help='Alle console-messages bis auf Errors stummschalten.')
|
@ -5,10 +5,10 @@
|
||||
# IMPORTS
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
from src.local.typing import *;
|
||||
from code.local.typing import *;
|
||||
|
||||
from src.core.log import *;
|
||||
from src.setup.cli import GetArgumentParser;
|
||||
from code.core.log import *;
|
||||
from code.setup.cli import GetArgumentParser;
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# METHODS display help
|
1
dist/VERSION
vendored
1
dist/VERSION
vendored
@ -1 +0,0 @@
|
||||
0.0.0
|
@ -1,51 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
##############################################################################
|
||||
# DESCRIPTION: Library for extraction of global vars from environment.
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# MAIN METHODS: .env
|
||||
##############################################################################
|
||||
|
||||
function env_value() {
|
||||
[ -f "$1" ] && source "$1" && echo "${!2}";
|
||||
}
|
||||
|
||||
function env_required() {
|
||||
! [ -f "$1" ] && echo -e "[\033[91mERROR\033[0m] Could not find environment file \033[1m$1\033[0m!" >> /dev/stderr && exit 1;
|
||||
source "$1";
|
||||
local value="${!2}";
|
||||
[ "$value" == "" ] && echo -e "[\033[91mERROR\033[0m] Argument \033[93;1m$2\033[0m not found in \033[1m$1\033[0m!" >> /dev/stderr && exit 1;
|
||||
echo "$value";
|
||||
}
|
||||
|
||||
function env_from() {
|
||||
local arguments=( "$@" );
|
||||
local path="${arguments[0]}";
|
||||
local key_from="${arguments[2]}";
|
||||
local key_to="${key_from}";
|
||||
( echo "${arguments[3]}" | grep -Eiq "^as$" ) && key_to="${arguments[4]}";
|
||||
! ( echo "$key_to" | grep -Eiq "^([[:alpha:]]|_)([[:alpha:]]|_|[[:digit:]])*$" ) && echo -e "[\033[91mERROR\033[0m] Key argument \"\033[1m$key_to\033[0m\" not a valid name for a variable!" >> /dev/stderr && exit 1;
|
||||
local value="$( env_required "$path" "$key_from" )";
|
||||
[ "$value" == "" ] && exit 1;
|
||||
export $key_to="$value";
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# GLOBAL VARIABLES:
|
||||
##############################################################################
|
||||
|
||||
# NOTE: do not use /bin/bash. Results in error under Windows. Use \/bin\/bash, bash, sh -c bash, or sh.
|
||||
export CMD_EXPLORE="bash";
|
||||
# periodic waiting time to check a process;
|
||||
export WAIT_PERIOD_IN_SECONDS=1;
|
||||
export PENDING_SYMBOL="#";
|
||||
|
||||
env_from ".env" import CONSOLE_OUT as OUT;
|
||||
env_from ".env" import CONSOLE_ERR as ERR;
|
||||
env_from ".env" import CONSOLE_VERBOSE as VERBOSE;
|
||||
env_from ".env" import CONSOLE_PATH_LOGS as PATH_LOGS;
|
||||
env_from ".env" import CONSOLE_FILENAME_LOGS_DEBUG as FILENAME_LOGS_DEBUG;
|
||||
|
||||
export LOGGINGPREFIX="";
|
291
scripts/.lib.sh
291
scripts/.lib.sh
@ -1,291 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
# DESCRIPTION: Library of methods specifically for the project.
|
||||
# Include using source .whales/.lib.sh
|
||||
##############################################################################
|
||||
|
||||
source scripts/.lib.globals.sh;
|
||||
source scripts/.lib.utils.sh;
|
||||
|
||||
##############################################################################
|
||||
# GLOBAL VARIABLES
|
||||
##############################################################################
|
||||
|
||||
env_from ".env" import REQUIREMENTS_GO as PATH_REQ_GO;
|
||||
env_from ".env" import REQUIREMENTS_PY as PATH_REQ_PY;
|
||||
env_from ".env" import NAME_OF_APP;
|
||||
env_from ".env" import TEST_TIMEOUT;
|
||||
|
||||
export CONFIGENV="data/.env";
|
||||
export PATH_PROJECT_PY="code/python";
|
||||
export PATH_PROJECT_GO="code/golang";
|
||||
export PATH_GO_ASSETS_GRAMMAR="assets/grammars";
|
||||
export PATH_GO_INTERNAL_GRAMMAR="internal/tokenisers/grammars";
|
||||
export PYTHON_APP_PREFIX=\
|
||||
'''#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-'''
|
||||
export USE_VENV=false;
|
||||
export UNITTEST_SCHEMA_PY="test_*.py";
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: Go
|
||||
##############################################################################
|
||||
|
||||
function call_go() {
|
||||
go $@;
|
||||
}
|
||||
|
||||
function install_requirements_go() {
|
||||
local path="$1";
|
||||
local cwd="$PWD";
|
||||
local has_problems=false;
|
||||
local problem_packages=();
|
||||
|
||||
pushd $PATH_PROJECT_GO >> $VERBOSE;
|
||||
# go mod tidy; # <- use to detect unused packages in project
|
||||
remove_file "go.sum";
|
||||
|
||||
_log_info "Add go requirements";
|
||||
dos_to_unix "$cwd/$path";
|
||||
local line;
|
||||
while read line; do
|
||||
line="$( _trim_trailing_comments "$line" )";
|
||||
[ "$line" == "" ] && continue;
|
||||
_log_info "Run \033[92;1mGO GET\033[0m to install \033[93;1m$line\033[0m.";
|
||||
( call_go get "$line" 2> $VERBOSE ) && continue;
|
||||
has_problems=true;
|
||||
problem_packages+=( "$line" );
|
||||
done <<< "$( cat "$cwd/$path" )";
|
||||
popd >> $VERBOSE
|
||||
|
||||
( $has_problems ) && _log_fail "Something went wrong whilst using \033[92;1mGO\033[0m to install: {\033[93;1m${problem_packages[*]}\033[0m}.";
|
||||
}
|
||||
|
||||
function compile_go() {
|
||||
local force="$1";
|
||||
local path="$2";
|
||||
local cwd="$PWD";
|
||||
_log_info "Compile \033[1mmain.go\033[0m with \033[1mgolang\033[0m";
|
||||
remove_file "dist/$NAME_OF_APP";
|
||||
pushd "$path" >> $VERBOSE;
|
||||
call_go build -o "$cwd/dist/$NAME_OF_APP" "main.go";
|
||||
popd >> $VERBOSE;
|
||||
! [ -f "dist/$NAME_OF_APP" ] && return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: Python
|
||||
##############################################################################
|
||||
|
||||
function use_python_venv_true() { USE_VENV=true; }
|
||||
function use_python_venv_false() { USE_VENV=false; }
|
||||
|
||||
function create_python_venv() {
|
||||
! ( $USE_VENV ) && return;
|
||||
_log_info "Create VENV";
|
||||
! [ -d build ] && mkdir build;
|
||||
pushd build >> $VERBOSE;
|
||||
call_python -m venv env;
|
||||
popd >> $VERBOSE;
|
||||
}
|
||||
|
||||
function activate_python_venv() {
|
||||
! ( $USE_VENV ) && return;
|
||||
if ( is_linux ); then
|
||||
source build/env/bin/activate;
|
||||
else
|
||||
source build/env/Scripts/activate;
|
||||
fi
|
||||
}
|
||||
|
||||
function deactivate_python_venv() {
|
||||
! ( $USE_VENV ) && return;
|
||||
if ( is_linux ); then
|
||||
source build/env/bin/deactivate;
|
||||
else
|
||||
source build/env/Scripts/deactivate;
|
||||
fi
|
||||
}
|
||||
|
||||
function call_python() {
|
||||
if ( is_linux ); then
|
||||
python3 $@;
|
||||
else
|
||||
py -3 $@;
|
||||
fi
|
||||
}
|
||||
|
||||
function call_v_python() { activate_python_venv && call_python $@; }
|
||||
|
||||
function call_utest() { call_python -m unittest discover $@; }
|
||||
|
||||
function call_v_utest() { activate_python_venv && call_utest $@; }
|
||||
|
||||
function call_pipinstall() {
|
||||
# Do not use --user flag with venv
|
||||
DISPLAY= && call_python -m pip install $@;
|
||||
}
|
||||
|
||||
function install_requirements_python() {
|
||||
local path="$1";
|
||||
local has_problems=false;
|
||||
local problem_packages=();
|
||||
|
||||
dos_to_unix "$path";
|
||||
local line;
|
||||
while read line; do
|
||||
line="$( _trim_trailing_comments "$line" )";
|
||||
[ "$line" == "" ] && continue;
|
||||
_log_info "Run \033[92;1mPIP\033[0m to install \033[93;1m$line\033[0m.";
|
||||
( call_pipinstall "$line" >> $VERBOSE ) && continue;
|
||||
has_problems=true;
|
||||
problem_packages+=( "$line" );
|
||||
done <<< "$( cat "$path" )";
|
||||
|
||||
( $has_problems ) && _log_fail "Something went wrong whilst using \033[92;1mPIP\033[0m to install: {\033[93;1m${problem_packages[*]}\033[0m}.";
|
||||
}
|
||||
|
||||
function install_requirements_v_python() { activate_python_venv && install_requirements_python $@; }
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: CLEANING
|
||||
##############################################################################
|
||||
|
||||
function garbage_collection_misc() {
|
||||
clean_all_folders_of_pattern ".DS_Store";
|
||||
}
|
||||
|
||||
function garbage_collection_python() {
|
||||
clean_folder_contents "$PATH_PROJECT_PY/build";
|
||||
local path;
|
||||
for path in "$PATH_PROJECT_PY"; do
|
||||
pushd "$path" >> $VERBOSE;
|
||||
# clean_all_files_of_pattern "*\.pyo";
|
||||
clean_all_folders_of_pattern "__pycache__";
|
||||
popd >> $VERBOSE;
|
||||
done
|
||||
}
|
||||
|
||||
function garbage_collection_go {
|
||||
_log_info "(There are no go files to clean.)";
|
||||
}
|
||||
|
||||
function garbage_collection_dist() {
|
||||
remove_file "dist/$NAME_OF_APP";
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# MAIN METHODS: PROCESSES
|
||||
##############################################################################
|
||||
|
||||
function run_setup() {
|
||||
_log_info "RUN SETUP";
|
||||
local current_dir="$PWD";
|
||||
pushd $PATH_PROJECT_PY >> $VERBOSE;
|
||||
create_python_venv;
|
||||
_log_info "Check and install missing requirements";
|
||||
install_requirements_v_python "$current_dir/$PATH_REQ_PY";
|
||||
popd >> $VERBOSE;
|
||||
}
|
||||
|
||||
function run_setup_go() {
|
||||
install_requirements_go "$PATH_REQ_GO";
|
||||
}
|
||||
|
||||
function run_create_artefact() {
|
||||
local current_dir="$PWD";
|
||||
local success;
|
||||
## create temp artefacts:
|
||||
local _temp="$( create_temporary_dir "dist" )";
|
||||
|
||||
mkdir "$_temp/src"
|
||||
cp -r "$PATH_PROJECT_PY/src/." "$_temp/src";
|
||||
copy_file file="VERSION" from="dist" to="${_temp}/src/setup";
|
||||
mv "${_temp}/src/__main__.py" "$_temp";
|
||||
## zip source files to single file and make executable:
|
||||
pushd "$_temp" >> $VERBOSE;
|
||||
( create_zip_archive -o "$current_dir/dist/app.zip" * -x '*__pycache__/*' -x '*.DS_Store' );
|
||||
success=$?
|
||||
popd >> $VERBOSE;
|
||||
if [ $success -eq 0 ]; then
|
||||
echo "$PYTHON_APP_PREFIX" | cat - dist/app.zip > dist/$NAME_OF_APP;
|
||||
chmod +x "dist/$NAME_OF_APP";
|
||||
fi
|
||||
## remove temp artefacts:
|
||||
remove_dir "$_temp";
|
||||
remove_file "dist/app.zip";
|
||||
! [ $success -eq 0 ] && return 1;
|
||||
_log_info "Python artefact successfully created.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
function run_create_artefact_go() {
|
||||
local current_dir="$PWD";
|
||||
local success;
|
||||
## create temp artefacts:
|
||||
local _temp="$( create_temporary_dir "dist" )";
|
||||
cp -r "$PATH_PROJECT_GO/." "$_temp";
|
||||
copy_file file="VERSION" from="dist" to="${_temp}/assets";
|
||||
( compile_go true "$_temp" );
|
||||
success=$?;
|
||||
## remove temp artefacts:
|
||||
remove_dir "$_temp";
|
||||
! [ $success -eq 0 ] && return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function run_main() {
|
||||
pushd $PATH_PROJECT_PY >> $VERBOSE;
|
||||
call_v_python src/main.py $@;
|
||||
popd >> $VERBOSE;
|
||||
}
|
||||
|
||||
function run_main_go() {
|
||||
compile_go false "$PATH_PROJECT_GO";
|
||||
./dist/$NAME_OF_APP $@;
|
||||
}
|
||||
|
||||
function run_test_unit() {
|
||||
local asverbose=$1;
|
||||
local verboseoption="-v";
|
||||
local success=0;
|
||||
! ( $asverbose ) && verboseoption="";
|
||||
_log_info "RUN UNITTESTS";
|
||||
pushd $PATH_PROJECT_PY >> $VERBOSE;
|
||||
( call_v_utest \
|
||||
$verboseoption \
|
||||
--top-level-directory "test" \
|
||||
--start-directory "test" \
|
||||
--pattern "${UNITTEST_SCHEMA_PY}" 2>&1 \
|
||||
);
|
||||
success=$?;
|
||||
popd >> $VERBOSE;
|
||||
[ $success -eq 1 ] && _log_fail "Unit tests failed!";
|
||||
_log_info "Unit tests successful!";
|
||||
return 0;
|
||||
}
|
||||
|
||||
function run_test_unit_go() {
|
||||
local asverbose="$1";
|
||||
local verboseoption="-v";
|
||||
local success;
|
||||
_log_info "RUN UNITTESTS";
|
||||
! ( $asverbose ) && verboseoption=""
|
||||
pushd $PATH_PROJECT_GO >> $VERBOSE;
|
||||
( call_go test $verboseoption -timeout $TEST_TIMEOUT -count 1 -run "^Test[A-Z].*" "$NAME_OF_APP" "./..." );
|
||||
success=$?;
|
||||
popd >> $VERBOSE
|
||||
[ $success -eq 1 ] && _log_fail "Unit tests failed!";
|
||||
_log_info "Unit tests successful!";
|
||||
return 0;
|
||||
}
|
||||
|
||||
function run_clean_artefacts() {
|
||||
_log_info "CLEAN ARTEFACTS";
|
||||
garbage_collection_misc;
|
||||
garbage_collection_python;
|
||||
garbage_collection_go;
|
||||
garbage_collection_dist;
|
||||
}
|
@ -1,504 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
##############################################################################
|
||||
# DESCRIPTION: Library of common utility functions.
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# FOR OS SENSITIVE COMMANDS
|
||||
##############################################################################
|
||||
|
||||
function is_linux() {
|
||||
[ "$OSTYPE" == "msys" ] && return 1 || return 0;
|
||||
}
|
||||
|
||||
function dos_to_unix() {
|
||||
( dos2unix --version 2> $VERBOSE >> $VERBOSE ) && dos2unix -q $1 && return;
|
||||
_log_fail "Install \033[1mdos2unix\033[0m for your system and ensure the command can be called in bash before proceeding. Cf. https://command-not-found.com/dos2unix, https://chocolatey.org/packages/dos2unix, etc.";
|
||||
}
|
||||
|
||||
function clean_scripts_dos2unix() {
|
||||
local setup_path="$1";
|
||||
local path;
|
||||
while read path; do
|
||||
[ "$path" == "" ] && continue;
|
||||
dos_to_unix "$path";
|
||||
done <<< "$( ls -a {,$setup_path/}{,.}*.sh 2> $VERBOSE )";
|
||||
}
|
||||
|
||||
function check_jq_exists() {
|
||||
( jq --version 2> $VERBOSE >> $VERBOSE ) && return 0 || return 1;
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: READING CLI ARGUMENTS
|
||||
##############################################################################
|
||||
|
||||
function has_arg() {
|
||||
echo "$1" | grep -Eq "(^.*[[:space:]]|^)$2([[:space:]].*$|$)" && return 0 || return 1;
|
||||
}
|
||||
|
||||
function get_kwarg() {
|
||||
local value="$(echo "$1" | grep -Eq "(^.*\s|^)$2=" && echo "$1" | sed -E "s/(^.*[[:space:]]|^)$2=(\"([^\"]*)\"|\'([^\']*)\'|([^[:space:]]*)).*$/\3\4\5/g" || echo "")";
|
||||
echo $value | grep -Eq "[^[:space:]]" && echo "$value" || echo "$3";
|
||||
}
|
||||
|
||||
function get_all_kwargs() {
|
||||
local arguments="$1";
|
||||
local key="$2";
|
||||
local get_one=$3;
|
||||
local default="$4"; # only used if $get_one == true
|
||||
local pattern="(^.*[[:space:]]|^)$key(\"([^\"]*)\"|\'([^\']*)\'|([^[:space:]]*)).*$";
|
||||
while ! [[ "$arguments" == "" ]]; do
|
||||
if ! ( echo "$arguments" | grep -Eq "$pattern" ); then
|
||||
arguments="";
|
||||
break;
|
||||
fi
|
||||
local value="$(echo "$arguments" | sed -E "s/$pattern/\3\4\5/g" || echo "")";
|
||||
arguments="$(echo "$arguments" | sed -E "s/$pattern/\1/g" || echo "")";
|
||||
echo "$value";
|
||||
( $get_one ) && return 0;
|
||||
done
|
||||
( $get_one ) && echo "$default";
|
||||
}
|
||||
|
||||
function get_one_kwarg() {
|
||||
get_all_kwargs "$1" "$2" true "$3";
|
||||
}
|
||||
|
||||
function get_one_kwarg_space() {
|
||||
local value="$( get_all_kwargs "$1" "$2[[:space:]]+" true "$3" )";
|
||||
( echo "$value" | grep -Eq "^-+" ) && value="$3";
|
||||
echo "$value";
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: LOGGING AND CLI-INPUTS
|
||||
##############################################################################
|
||||
|
||||
function check_answer() {
|
||||
echo "$1" | grep -q -E -i "^(y|yes|j|ja|1)$";
|
||||
}
|
||||
|
||||
function _cli_ask() {
|
||||
echo -ne "$1" >> $OUT;
|
||||
}
|
||||
|
||||
export CLI_ANSWER="";
|
||||
function _cli_ask_expected_answer() {
|
||||
local msg="$1";
|
||||
local answerpattern="$2";
|
||||
local read_break_char;
|
||||
local symb;
|
||||
CLI_ANSWER="";
|
||||
while ( true ); do
|
||||
echo -ne "$msg" >> $OUT;
|
||||
## read in CLI_ANSWER character by character:
|
||||
CLI_ANSWER="";
|
||||
read_break_char=false;
|
||||
while IFS= read -rn 1 symb; do
|
||||
case "$symb" in
|
||||
$'\04') read_break_char=true ;;
|
||||
$'\n') break ;;
|
||||
*) CLI_ANSWER="$CLI_ANSWER$symb" ;;
|
||||
esac
|
||||
done
|
||||
( $read_break_char ) && echo -e "" >> $OUT && exit 1;
|
||||
( echo "$CLI_ANSWER" | grep -Eq "$2" ) && break;
|
||||
done
|
||||
}
|
||||
|
||||
function _cli_ask_expected_answer_secure() {
|
||||
local msg="$1";
|
||||
local answerpattern="$2";
|
||||
local mask="$3";
|
||||
local read_break_char;
|
||||
local symb;
|
||||
CLI_ANSWER="";
|
||||
while ( true ); do
|
||||
echo -ne "$msg" >> $OUT;
|
||||
stty -echo;
|
||||
## read in CLI_ANSWER character by character:
|
||||
CLI_ANSWER="";
|
||||
read_break_char=false;
|
||||
while IFS= read -rN 1 symb; do
|
||||
case "$symb" in
|
||||
$'\04') read_break_char=true ;;
|
||||
$'\n') break ;;
|
||||
*) CLI_ANSWER="$CLI_ANSWER$symb" ;;
|
||||
esac
|
||||
done
|
||||
stty echo;
|
||||
( $read_break_char ) && echo -e "" >> $OUT && exit 1;
|
||||
[[ "$mask" == "true" ]] && echo -e "$( echo $CLI_ANSWER | sed -r 's/./\*/g' )" || echo -e "$mask";
|
||||
( echo "$CLI_ANSWER" | grep -Eq "$2" ) && break;
|
||||
done
|
||||
}
|
||||
|
||||
function _cli_trailing_message() {
|
||||
echo -ne "$1" >> $OUT;
|
||||
}
|
||||
|
||||
function _cli_message() {
|
||||
if [ "$2" == "true" ]; then
|
||||
_cli_trailing_message "$1";
|
||||
else
|
||||
echo -e "$1" >> $OUT;
|
||||
fi
|
||||
}
|
||||
|
||||
function _log_info() {
|
||||
_cli_message "${LOGGINGPREFIX}[\033[94;1mINFO\033[0m] $1" $2;
|
||||
}
|
||||
|
||||
function _log_debug() {
|
||||
_cli_message "${LOGGINGPREFIX}[\033[95;1mDEBUG\033[0m] $1" $2;
|
||||
if ! [ -f "$PATH_LOGS/$FILENAME_LOGS_DEBUG" ]; then
|
||||
mkdir "$PATH_LOGS" 2> $VERBOSE;
|
||||
touch "$PATH_LOGS/$FILENAME_LOGS_DEBUG";
|
||||
fi
|
||||
echo "$1" >> "$PATH_LOGS/$FILENAME_LOGS_DEBUG";
|
||||
}
|
||||
|
||||
function _log_warn() {
|
||||
_cli_message "${LOGGINGPREFIX}[\033[93;1mWARNING\033[0m] $1" $2;
|
||||
}
|
||||
|
||||
function _log_error() {
|
||||
if [ "$2" == "true" ]; then
|
||||
echo -ne "${LOGGINGPREFIX}[\033[91;1mERROR\033[0m] $1" >> $ERR;
|
||||
else
|
||||
echo -e "${LOGGINGPREFIX}[\033[91;1mERROR\033[0m] $1" >> $ERR;
|
||||
fi
|
||||
}
|
||||
|
||||
function _log_fail() {
|
||||
_log_error "$1" $2;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: HELP
|
||||
##############################################################################
|
||||
|
||||
function _help_cli_key_values() {
|
||||
local arguments=( "$@" );
|
||||
local key="${arguments[0]}";
|
||||
local indent="${arguments[1]}";
|
||||
local values="";
|
||||
for arg in "${arguments[@]:2}"; do
|
||||
if ! [ "$values" == "" ]; then values="$values|"; fi
|
||||
values="$values\033[92;1m$arg\033[0m";
|
||||
done
|
||||
local cmd="\033[93;1m$key\033[0m$indent$values";
|
||||
echo "$cmd";
|
||||
}
|
||||
|
||||
function _help_cli_key_description() {
|
||||
local arguments=( "$@" );
|
||||
local key="${arguments[0]}";
|
||||
local indent="${arguments[1]}";
|
||||
local descr="${arguments[@]:2}";
|
||||
local cmd="\033[93;1m$key\033[0m$indent\033[2;3m$descr\033[0m";
|
||||
echo "$cmd";
|
||||
}
|
||||
|
||||
function _help_cli_values() {
|
||||
local arguments=( "$@" );
|
||||
local cmd="";
|
||||
for arg in "${arguments[@]}"; do
|
||||
! [ "$cmd" == "" ] && cmd="$cmd|";
|
||||
cmd="$cmd\033[92;1m$arg\033[0m";
|
||||
done
|
||||
echo "$cmd";
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: PROGRESSBAR
|
||||
##############################################################################
|
||||
|
||||
function show_progressbar() {
|
||||
local pid=$1 # Process Id of the previous running command
|
||||
|
||||
function shutdown() {
|
||||
tput cnorm; # reset cursor
|
||||
}
|
||||
|
||||
function cursorBack() {
|
||||
echo -en "\033[$1D";
|
||||
}
|
||||
|
||||
trap shutdown EXIT;
|
||||
|
||||
local displayed=false;
|
||||
# tput civis; # cursor invisible
|
||||
while kill -0 $pid 2> $VERBOSE; do
|
||||
if [ "$displayed" == "false" ]; then
|
||||
_log_info "pending... $PENDING_SYMBOL" "true";
|
||||
displayed=true;
|
||||
else
|
||||
_cli_trailing_message "$PENDING_SYMBOL";
|
||||
fi
|
||||
sleep $WAIT_PERIOD_IN_SECONDS;
|
||||
done
|
||||
# tput cnorm; # cursor visible
|
||||
wait $pid;
|
||||
local success=$?;
|
||||
[ "$displayed" == "true" ] && _cli_trailing_message "\n";
|
||||
return $success;
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: STRINGS
|
||||
##############################################################################
|
||||
|
||||
function _trim() {
|
||||
_trim_trailing_spaces "$( _trim_leading_spaces "$1" )";
|
||||
}
|
||||
|
||||
function _trim_leading_spaces() {
|
||||
echo "$1" | sed -E "s/^[[:space:]]+(.*)$/\1/g"
|
||||
}
|
||||
|
||||
function _trim_trailing_spaces() {
|
||||
echo "$1" | sed -E "s/(^.*[^[:space:]]+|^)[[:space:]]+$/\1/g"
|
||||
}
|
||||
|
||||
function to_lower() {
|
||||
echo "$(echo "$1" |tr '[:upper:]' '[:lower:]')";
|
||||
}
|
||||
|
||||
function to_upper() {
|
||||
echo "$(echo "$1" |tr '[:lower:]' '[:upper:]')";
|
||||
}
|
||||
|
||||
function is_comment() {
|
||||
echo "$1" | grep -Eq "^\s*\#" && return 0 || return 1;
|
||||
}
|
||||
|
||||
function _trim_trailing_comments() {
|
||||
echo "$1" | sed -E "s/(^[^\#]*)\#.*$/\1/g" | sed -E "s/(^.*[^[:space:]]+|^)[[:space:]]+$/\1/g";
|
||||
}
|
||||
|
||||
## Replaces all occurrences of ~ with $HOME.
|
||||
## NOTE: use / to replace first, // to replace all.
|
||||
function expand_path() {
|
||||
echo "${1//\~/$HOME}";
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: JSON
|
||||
##############################################################################
|
||||
|
||||
function json_dictionary_kwargs_jq() {
|
||||
! ( check_jq_exists ) && _log_fail "You need to install \033[1mjq\033[0m to use this method.";
|
||||
local json="$1";
|
||||
local format=".key + \" \" + (.value|tostring)";
|
||||
echo "$json" | jq -r "to_entries | map($format) | .[]";
|
||||
}
|
||||
|
||||
# Only for json dictionaries of type Dict[str,(str|number|bool)],
|
||||
function json_dictionary_kwargs() {
|
||||
local json="$1";
|
||||
# Remove outer braces:
|
||||
json="$( echo "$json" | sed -E "s/^\{|\}$//g" )";
|
||||
# Recursively extract keys and values from right-to-left:
|
||||
local keypattern="[a-zA-Z0-9\.-_]";
|
||||
local pattern="((^.*),|(^))\"($keypattern*)\":(\"(.*)\"|(.*))$";
|
||||
function json_dictionary_kwargs_recursive() {
|
||||
local json="$1";
|
||||
[ "$json" == "" ] && return;
|
||||
! ( echo "$json" | grep -Eq "$pattern" ) && return;
|
||||
local key="$( echo "$json" | sed -E "s/$pattern/\4/g" )";
|
||||
local value="$( echo "$json" | sed -E "s/$pattern/\6\7/g" )";
|
||||
json="$( echo "$json" | sed -E "s/$pattern/\2\3/g" )";
|
||||
json_dictionary_kwargs_recursive "$json";
|
||||
echo "$key $value";
|
||||
}
|
||||
json_dictionary_kwargs_recursive "$json";
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: YAML CONFIG FILES
|
||||
##############################################################################
|
||||
|
||||
function has_config_key() {
|
||||
local config="$1";
|
||||
local key="$2";
|
||||
! [ -f $file ] && _log_fail "Config file \033[1m$config\033[0m not found!";
|
||||
echo "( cat $config )" | grep -Eq "^\s*$key:" && return 0 || return 1;
|
||||
}
|
||||
|
||||
function json_parse() {
|
||||
local args=( "$@" );
|
||||
! ( jq --version 2> $VERBOSE >> $VERBOSE ) && _log_fail "Install \033[1mjq\033[0m for your system and ensure the command can be called in bash before proceeding. Cf. https://command-not-found.com/jq, https://chocolatey.org/packages/jq, etc.";
|
||||
echo "${args[0]}" | jq ${args[@]:1};
|
||||
}
|
||||
|
||||
function yaml_parse() {
|
||||
local args=( "$@" );
|
||||
! ( yq --version 2> $VERBOSE >> $VERBOSE ) && _log_fail "Install \033[1myq\033[0m for your system and ensure the command can be called in bash before proceeding. Cf. https://command-not-found.com/yq, https://chocolatey.org/packages/yq, etc.";
|
||||
local lines="$( yq eval --tojson "${args[0]}" )";
|
||||
json_parse "$lines" ${args[@]:1};
|
||||
}
|
||||
|
||||
function get_config_key_value_simpleversion() {
|
||||
local config="$1";
|
||||
local key="$2";
|
||||
local default="$3";
|
||||
! [ -f $config ] && _log_fail "Config file \033[1m$config\033[0m not found!";
|
||||
## use sed -n .... /p to delete all non-matching lines
|
||||
## store matches in an array
|
||||
local lines=( $(echo "( cat $config )" | sed -n -E "s/^[[:space:]]*$key:(.*)$/\1/p") );
|
||||
## extract the 0th entry, if it exists, otherwise return default.
|
||||
echo "$([ ${#lines[@]} -gt 0 ] && echo "$(_trim "${lines[0]}")" || echo "$default")";
|
||||
}
|
||||
|
||||
function get_config_key_value() {
|
||||
local config="$1";
|
||||
local key="$2";
|
||||
local default="$3";
|
||||
! [ -f $config ] && _log_fail "Config file \033[1m$config\033[0m not found!";
|
||||
local value="$( yaml_parse "$config" --raw-output ".$key" 2> $VERBOSE || echo "$default" )";
|
||||
[ "$value" == "null" ] && value="$default";
|
||||
echo "$value";
|
||||
}
|
||||
|
||||
function get_config_boolean() {
|
||||
local config="$1";
|
||||
local key="$2";
|
||||
local default="$3";
|
||||
local value="$( get_config_key_value "$config" "$key" "$default" )";
|
||||
[ "$value" == "true" ] && return 0 || return 1;
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: FILES AND FOLDERS
|
||||
##############################################################################
|
||||
|
||||
function copy_file() {
|
||||
local args="$@"
|
||||
local file="$( get_kwarg "$args" "file" "" )";
|
||||
local folder_from_formatted="$( get_kwarg "$args" "from" "" )";
|
||||
local folder_to_formatted="$( get_kwarg "$args" "to" "" )";
|
||||
local rename="$( get_kwarg "$args" "rename" "" )";
|
||||
|
||||
local folder_from="$( expand_path "$folder_from_formatted" )";
|
||||
local folder_to="$( expand_path "$folder_to_formatted" )";
|
||||
|
||||
if ! [ -d "$folder_from" ]; then
|
||||
_log_error "For copy-file command: source folder \033[1m$folder_from_formatted\033[0m does not exist!";
|
||||
return;
|
||||
fi
|
||||
if ! [ -d "$folder_to" ]; then
|
||||
_log_error "For copy-file command: destination folder \033[1m$folder_to_formatted\033[0m does not exist!";
|
||||
return;
|
||||
fi
|
||||
if ! [ -f "$folder_from/$file" ]; then
|
||||
_log_error "For copy-file command: file \033[1m$folder_from_formatted/$file\033[0m could not be found!";
|
||||
return;
|
||||
fi
|
||||
|
||||
[ "$rename" == "" ] && rename="$file";
|
||||
|
||||
cp "$folder_from/$file" "$folder_to/$rename" && _log_info "Copied \033[1m$folder_from_formatted/$file\033[0m to \033[1m$folder_to_formatted/$rename\033[0m." || _log_fail "Copy-file command failed.";
|
||||
}
|
||||
|
||||
function copy_dir() {
|
||||
local args="$@"
|
||||
local dir="$( get_kwarg "$args" "dir" "" )";
|
||||
local folder_from_formatted="$( get_kwarg "$args" "from" "" )";
|
||||
local folder_to_formatted="$( get_kwarg "$args" "to" "" )";
|
||||
|
||||
local folder_from="$( expand_path "$folder_from_formatted" )";
|
||||
local folder_to="$( expand_path "$folder_to_formatted" )";
|
||||
|
||||
if ! [ -d "$folder_from" ]; then
|
||||
_log_error "For copy-dir command: source folder \033[1m$folder_from_formatted\033[0m does not exist!";
|
||||
return;
|
||||
fi
|
||||
if ! [ -d "$folder_to" ]; then
|
||||
_log_error "For copy-dir command: destination folder \033[1m$folder_to_formatted\033[0m does not exist!";
|
||||
return;
|
||||
fi
|
||||
if ! [ -d "$folder_from/$dir" ]; then
|
||||
_log_error "For copy-dir command: directory \033[1m$folder_from_formatted/$dir\033[0m could not be found!";
|
||||
return;
|
||||
fi
|
||||
|
||||
cp -r "$folder_from/$dir" "$folder_to" && _log_info "Copied \033[1m$folder_from_formatted/$dir\033[0m to \033[1m$folder_to_formatted/$rename\033[0m." || _log_fail "Copy-dir command failed.";
|
||||
}
|
||||
|
||||
function remove_file() {
|
||||
local fname="$1";
|
||||
[ -f "$fname" ] && rm -f "$fname" && _log_info "Removed file \033[1m$fname.\033[0m" || _log_info "Nothing to remove: the file \033[1m$fname\033[0m does not exist.";
|
||||
}
|
||||
|
||||
function remove_dir() {
|
||||
local path="$1";
|
||||
[ -d "$path" ] && rm -r "$path" && _log_info "Removed directory \033[1m$path.\033[0m" || _log_info "Nothing to remove: the directory \033[1m$path\033[0m does not exist.";
|
||||
}
|
||||
|
||||
function remove_dir_force() {
|
||||
local path="$1";
|
||||
[ -d "$path" ] && rm -rf "$path" && _log_info "Removed directory \033[1m$path.\033[0m" || _log_info "Nothing to remove: the directory \033[1m$path\033[0m does not exist.";
|
||||
}
|
||||
|
||||
function create_temporary_dir() {
|
||||
local current_dir="$1";
|
||||
local name="tmp";
|
||||
local path;
|
||||
local k=0;
|
||||
pushd "$current_dir" >> $VERBOSE;
|
||||
while [[ -d "${name}_${k}" ]] || [[ -f "${name}_${k}" ]]; do k=$(( $k + 1 )); done;
|
||||
path="${name}_${k}";
|
||||
mkdir "${path}";
|
||||
popd >> $VERBOSE;
|
||||
echo "${current_dir}/${path}";
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
# AUXILIARY METHODS: CLEANING
|
||||
##############################################################################
|
||||
|
||||
function clean_by_pattern() {
|
||||
local path="$1";
|
||||
local pattern="$2"
|
||||
local force=$3;
|
||||
! ( ls $path | grep -q -E "$pattern" ) && return;
|
||||
_log_info "Files to be removed:";
|
||||
ls $path | grep -E "$pattern" | awk -v PATH=$path '{print " \033[94m" PATH "/" $1 "\033[0m"}' >> $OUT;
|
||||
if ! ( $force ); then
|
||||
_cli_ask_expected_answer " Do you wish to proceed? (y/n) " "^(y|n)$";
|
||||
! [[ "$CLI_ANSWER" == "y" ]] && _log_info "skipped." && return;
|
||||
fi
|
||||
ls $path | grep -E "$pattern" | awk -v PATH=$path '{print PATH "/" $1}' | xargs rm -r;
|
||||
_log_info "deleted.";
|
||||
}
|
||||
|
||||
function clean_folder_contents() {
|
||||
local folder="$1";
|
||||
local path;
|
||||
while read path; do
|
||||
[ "$path" == "" ] && continue;
|
||||
[ -f "$path" ] && remove_file "$path" >> $VERBOSE && continue;
|
||||
[ -d "$path" ] && rm -rf "$path" && continue;
|
||||
done <<< $( find "$folder" -mindepth 1 2> $VERBOSE );
|
||||
_log_info "(\033[91mforce removed\033[0m) contents of \033[94m$folder/\033[0m";
|
||||
}
|
||||
|
||||
function clean_all_folders_of_pattern() {
|
||||
local pattern="$1";
|
||||
local objects=( $( find * -type d -name ${pattern} ) );
|
||||
local n=${#objects[@]};
|
||||
[[ $n -gt 0 ]] && find * -type d -name ${pattern} | awk '{print $1}' | xargs rm -rf;
|
||||
_log_info " (\033[91mforce removed\033[0m) $n x \033[94m${pattern}\033[0m folders";
|
||||
}
|
||||
|
||||
function clean_all_files_of_pattern() {
|
||||
local pattern="$1";
|
||||
local objects=( $( find * -type f -name ${pattern} ) );
|
||||
local n=${#objects[@]};
|
||||
[[ $n -gt 0 ]] && find * -type f -name ${pattern} | awk '{print $1}' | xargs rm -rf;
|
||||
_log_info " (\033[91mforce removed\033[0m) $n x \033[94m${pattern}\033[0m files";
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
# DESCRIPTION: Script for build-processes.
|
||||
#
|
||||
# Usage:
|
||||
# ~~~~~~
|
||||
# ./build.sh [options]
|
||||
##############################################################################
|
||||
|
||||
SCRIPTARGS="$@";
|
||||
FLAGS=( $@ );
|
||||
ME="scripts/build.sh";
|
||||
SERVICE="prod-service";
|
||||
|
||||
source scripts/.lib.sh;
|
||||
|
||||
mode="$( get_one_kwarg_space "$SCRIPTARGS" "-+mode" "" )";
|
||||
lang="$( get_one_kwarg_space "$SCRIPTARGS" "-+lang" "python" )";
|
||||
options="$( get_one_kwarg_space "$SCRIPTARGS" "-+options" "" )";
|
||||
option_venv="$( get_one_kwarg_space "$SCRIPTARGS" "-+venv" "false" )";
|
||||
( $option_venv ) && use_python_venv_true || use_python_venv_false;
|
||||
|
||||
if [ "$mode" == "setup" ]; then
|
||||
if [ "$lang" == "go" ]; then
|
||||
run_setup_go;
|
||||
else #elif [ "$lang" == "python" ]; then
|
||||
run_setup;
|
||||
fi
|
||||
elif [ "$mode" == "dist" ]; then
|
||||
if [ "$lang" == "go" ]; then
|
||||
run_create_artefact_go;
|
||||
else
|
||||
run_create_artefact;
|
||||
fi
|
||||
elif [ "$mode" == "run" ]; then
|
||||
if [ "$lang" == "go" ]; then
|
||||
run_main_go $options;
|
||||
else #elif [ "$lang" == "python" ]; then
|
||||
echo "options=$options;$SCRIPTARGS."
|
||||
run_main $options;
|
||||
fi
|
||||
else
|
||||
_log_error "Invalid cli argument.";
|
||||
_cli_message "";
|
||||
_cli_message " Call \033[1m./build.sh\033[0m with one of the commands";
|
||||
_cli_message " $( _help_cli_key_values "--mode" " " "setup" "dist" "run" )";
|
||||
_cli_message " $( _help_cli_key_values "[--lang]" " " "go" "python" )";
|
||||
_cli_message "";
|
||||
_cli_message " $( _help_cli_key_description "--lang python" " " "(default) runs option for the python source code" )";
|
||||
_cli_message " $( _help_cli_key_description "--lang go" " " "runs option for the go source code" )";
|
||||
_cli_message "";
|
||||
_cli_message " $( _help_cli_key_description "--mode setup" " " "compiles programme" )";
|
||||
_cli_message " $( _help_cli_key_description "--mode dist" " " "creates distribution artefact" )";
|
||||
_cli_message " $( _help_cli_key_description "--mode run" " " "runs the programme" )";
|
||||
_cli_message "";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
exit 0;
|
@ -1,19 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
# DESCRIPTION: Script for cleaning-processes.
|
||||
#
|
||||
# Usage:
|
||||
# ~~~~~~
|
||||
# ./clean.sh [options]
|
||||
##############################################################################
|
||||
|
||||
SCRIPTARGS="$@";
|
||||
FLAGS=( $@ );
|
||||
ME="scripts/clean.sh";
|
||||
|
||||
source scripts/.lib.sh;
|
||||
|
||||
run_clean_artefacts;
|
||||
|
||||
exit 0;
|
@ -1,54 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
# DESCRIPTION: Script for test-processes.
|
||||
#
|
||||
# Usage:
|
||||
# ~~~~~~
|
||||
# ./test.sh [options]
|
||||
##############################################################################
|
||||
|
||||
SCRIPTARGS="$@";
|
||||
FLAGS=( $@ );
|
||||
ME="scripts/test.sh";
|
||||
SERVICE="test-service";
|
||||
|
||||
source scripts/.lib.sh;
|
||||
|
||||
mode="$( get_one_kwarg_space "$SCRIPTARGS" "-+mode" "")";
|
||||
lang="$( get_one_kwarg_space "$SCRIPTARGS" "-+lang" "python" )";
|
||||
options="$( get_one_kwarg_space "$SCRIPTARGS" "-+options" "" )";
|
||||
option_venv="$( get_one_kwarg_space "$SCRIPTARGS" "-+venv" "false" )";
|
||||
( $option_venv ) && use_python_venv_true || use_python_venv_false;
|
||||
|
||||
if [ "$mode" == "setup" ]; then
|
||||
if [ "$lang" == "go" ]; then
|
||||
run_setup_go;
|
||||
else #elif [ "$lang" == "python" ]; then
|
||||
run_setup;
|
||||
fi
|
||||
elif [ "$mode" == "unit" ]; then
|
||||
if [ "$lang" == "go" ]; then
|
||||
run_test_unit_go $options;
|
||||
else #elif [ "$lang" == "python" ]; then
|
||||
run_test_unit $options;
|
||||
fi
|
||||
elif [ "$mode" == "explore" ]; then
|
||||
run_explore_console;
|
||||
else
|
||||
_log_error "Invalid cli argument.";
|
||||
_cli_message "";
|
||||
_cli_message " Call \033[1m./test.sh\033[0m with one of the commands";
|
||||
_cli_message " $( _help_cli_key_values "--mode" " " "setup" "unit" )";
|
||||
_cli_message " $( _help_cli_key_values "[--lang]" " " "go" "python" )";
|
||||
_cli_message "";
|
||||
_cli_message " $( _help_cli_key_description "--lang python" " " "(default) runs option for the python source code" )";
|
||||
_cli_message " $( _help_cli_key_description "--lang go" " " "runs option for the go source code" )";
|
||||
_cli_message "";
|
||||
_cli_message " $( _help_cli_key_description "--mode setup" " " "compiles programme with test configuration" )";
|
||||
_cli_message " $( _help_cli_key_description "--mode unit" " " "runs unit test" )";
|
||||
_cli_message "";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
exit 0;
|
Loading…
x
Reference in New Issue
Block a user