initial commit [141.14.140.180,mike]
This commit is contained in:
+19
@@ -0,0 +1,19 @@
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
._*
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
*.swp
|
||||
*.lock
|
||||
._*
|
||||
*.o
|
||||
*.a
|
||||
*/bin/*
|
||||
*/tmp/*
|
||||
bin/*
|
||||
tmp/*
|
||||
gbld
|
||||
@@ -0,0 +1,453 @@
|
||||
// ============================================================================ simple golang builder (mwx'2026)
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
)
|
||||
|
||||
var version = "1.18.4"
|
||||
|
||||
var VERSIONURL = "http://gozilla.fhi.mpg.de/gbld/version.txt"
|
||||
var UPDATEBASEURL = "http://gozilla.fhi.mpg.de/gbld"
|
||||
|
||||
var oses = []string{"darwin", "linux", "windows"}
|
||||
var arches = []string{"arm64", "amd64"}
|
||||
|
||||
var GO string
|
||||
var GOIMPORTS string
|
||||
|
||||
var done chan bool
|
||||
|
||||
|
||||
func main() { // ========================================================================================== main
|
||||
|
||||
checkforupdate()
|
||||
|
||||
if len(os.Args) == 1 { // read predefined builds
|
||||
c, err := os.ReadFile("gbld.menu.json")
|
||||
if err == nil {
|
||||
var sel []string
|
||||
var buildjson map[string][]string
|
||||
|
||||
err := json.Unmarshal([]byte(c), &buildjson)
|
||||
if err == nil {
|
||||
for k := range buildjson {
|
||||
sel = append(sel, k)
|
||||
}
|
||||
tmp := ""
|
||||
err = survey.AskOne(&survey.Select{Message: "Select build", Options: sel}, &tmp)
|
||||
os.Args = []string{"gbld"}
|
||||
os.Args = append(os.Args, buildjson[tmp]...)
|
||||
} else {
|
||||
PE(err.Error())
|
||||
os.Exit(0);
|
||||
}
|
||||
} else {
|
||||
os.Args = []string{"gbld","-b","-i","-1",dirName()}
|
||||
}
|
||||
}
|
||||
|
||||
opt_b := flag.Bool("b", false, "")
|
||||
opt_1 := flag.Bool("1", false, "")
|
||||
opt_i := flag.Bool("i", false, "")
|
||||
opt_x := flag.Bool("x", false, "")
|
||||
opt_c := flag.String("c", "", "")
|
||||
opt_o := flag.String("o", "", "")
|
||||
opt_a := flag.Bool("a", false, "")
|
||||
opt_v := flag.Bool("v", false, "")
|
||||
opt_h := flag.Bool("h", false, "")
|
||||
opt_u := flag.Bool("u", false, "")
|
||||
|
||||
flag.Usage = func() {
|
||||
P()
|
||||
info()
|
||||
P()
|
||||
P(Cw("Usage:"))
|
||||
P(Cy(" gbld [-b] [-1] [-i] [-a] [-c <CMD>] [-o <OPTIONS>] [build name]"))
|
||||
P(Cy(" gbld -u"))
|
||||
P(Cw(" -b build only"))
|
||||
P(Cw(" -1 run only once"))
|
||||
P(Cw(" -i run gpimports before build"))
|
||||
P(Cw(" -a build for all platforms"))
|
||||
P(Cw(" -o <OPTIONS> exec options"))
|
||||
P(Cw(" -c <CMD> run command after build"))
|
||||
P(Cw(" -v show version"))
|
||||
P(Cw(" -h show help"))
|
||||
P(Cw(" -u upload builds to gozilla"))
|
||||
P()
|
||||
P(Cw(" · if build is supplied the current directory name will be used"))
|
||||
P()
|
||||
P(Cw(" · if no option supplied try to read '") + Cy("gbld.menu.json") + Cw("'"))
|
||||
P(Cm(` {`))
|
||||
P(Cm(` "build": ["-b","gbld"],`))
|
||||
P(Cm(` "help": ["-h"]`))
|
||||
P(Cm(` }`))
|
||||
P()
|
||||
P(Cw(" · if no option is supplied and no '") + Cy("gbld.menu.json") + Cw("' is available"))
|
||||
P(Cw(" the current directory name with ") + Cy("-b -i -1") + Cw(" as options will be used"))
|
||||
P()
|
||||
}
|
||||
|
||||
flag.Parse()
|
||||
|
||||
path, err := exec.LookPath("go") // ··························································· check for 'go'
|
||||
if err != nil {
|
||||
fmt.Println(Crb("Error: ") + Cwb("go") + " not found")
|
||||
os.Exit(0)
|
||||
|
||||
}
|
||||
GO = path
|
||||
|
||||
|
||||
path, err = exec.LookPath("goimports") // ·············································· check for 'goimports'
|
||||
if err != nil {
|
||||
fmt.Println(Crb("Error: ") + Cwb("goimports") + " not found")
|
||||
os.Exit(0)
|
||||
}
|
||||
GOIMPORTS = path
|
||||
|
||||
|
||||
if *opt_v { // ·················································································· show version
|
||||
info()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if *opt_h { // ····················································································· show help
|
||||
flag.Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
name := flag.Arg(0) // ································································ command line arguments
|
||||
if len(name) == 0 {
|
||||
name=dirName()
|
||||
if len(name) == 0 {
|
||||
flag.Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
file := name + ".go"
|
||||
if !fileExists(file) {
|
||||
P(Crb("file not found: " + file))
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
var ot int64 = 0
|
||||
var st int = 1
|
||||
var xmd *exec.Cmd = nil
|
||||
|
||||
if (!*opt_1) {
|
||||
PN("\033[2J\033[1;1H")
|
||||
info()
|
||||
}
|
||||
|
||||
|
||||
if *opt_u { // ······································································ upload builds to gozilla
|
||||
targetversion:=targetversion(file)
|
||||
|
||||
for _, osys := range oses {
|
||||
for _, arch := range arches {
|
||||
ofile:="bin/"+name+"_"+targetversion+"_"+osys+"_"+arch
|
||||
_, err := os.Stat(ofile)
|
||||
if err == nil {
|
||||
|
||||
cmd := exec.Command("ssh","root@gozilla","rm", "/db/www/"+prgname()+"/*_"+osys+"_"+arch )
|
||||
P(Cy(cmd))
|
||||
cmd.Run()
|
||||
|
||||
|
||||
cmd = exec.Command("scp",ofile, "root@gozilla:/db/www/"+prgname())
|
||||
P(Cy(cmd))
|
||||
cmd.Run()
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err := os.Stat("bin/version.txt")
|
||||
if err == nil {
|
||||
cmd := exec.Command("scp","bin/version.txt", "root@gozilla:/db/www/"+prgname())
|
||||
P(Cy(cmd))
|
||||
cmd.Run()
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
|
||||
for { // ------------------------------------------------------------------------------------------- main loop
|
||||
lmf := lmf("./")
|
||||
|
||||
var dt int64 = 0
|
||||
|
||||
if fileExists(name) {
|
||||
dt = lmf - filemodtime(name)
|
||||
} else {
|
||||
dt = 1
|
||||
}
|
||||
|
||||
if (dt > 0 && ot != lmf) || st == 1 { // ·············································· new version detected
|
||||
|
||||
if st == 0 && !*opt_1{
|
||||
PN("\033[2J\033[1;1H")
|
||||
}
|
||||
P(Cc("--- start compiling " + file + " ---"))
|
||||
|
||||
stopRunning(xmd)
|
||||
|
||||
o := "" // ········································································· increase build number
|
||||
|
||||
readFile, err := os.Open("build.go")
|
||||
if err == nil {
|
||||
backup("build.go")
|
||||
fileScanner := bufio.NewScanner(readFile)
|
||||
fileScanner.Split(bufio.ScanLines)
|
||||
r := regexp.MustCompile("var\\s+build\\s*=\\s*\"(.*)\"$")
|
||||
for fileScanner.Scan() {
|
||||
line := fileScanner.Text()
|
||||
s := r.FindStringSubmatch(line)
|
||||
if len(s) > 0 {
|
||||
b := Atoi(s[1]) + 1
|
||||
o = o + "var build = \"" + Itoa(b) + "\"\n"
|
||||
P("build:", s[1], "->", b)
|
||||
} else {
|
||||
o = o + line + "\n"
|
||||
}
|
||||
}
|
||||
readFile.Close()
|
||||
os.WriteFile("build.go", []byte(o), 0644)
|
||||
}
|
||||
|
||||
targetversion:=""
|
||||
readFile, err = os.Open(file)
|
||||
if err == nil {
|
||||
fileScanner := bufio.NewScanner(readFile)
|
||||
fileScanner.Split(bufio.ScanLines)
|
||||
r := regexp.MustCompile("var\\s+version\\s*=\\s*\"(.*)\"$")
|
||||
for fileScanner.Scan() {
|
||||
line := fileScanner.Text()
|
||||
s := r.FindStringSubmatch(line)
|
||||
if len(s) > 0 {
|
||||
targetversion=s[1]
|
||||
}
|
||||
}
|
||||
readFile.Close()
|
||||
}
|
||||
|
||||
if (targetversion=="") {
|
||||
PE("target version not found")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if *opt_i { // ············································································· run goimports
|
||||
re := regexp.MustCompile(`(?s)import\s*\((.*?)\)`)
|
||||
files, err := os.ReadDir(".")
|
||||
if err != nil { fmt.Printf("Error: %v\n", err); return }
|
||||
|
||||
for _, f := range files {
|
||||
if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") {
|
||||
fileName := f.Name()
|
||||
cmd := exec.Command("goimports", fileName)
|
||||
output, err := cmd.Output()
|
||||
if err != nil { continue }
|
||||
origContent, _ := os.ReadFile(fileName)
|
||||
tempMatch := re.FindStringSubmatch(string(output))
|
||||
if len(tempMatch) < 2 { continue }
|
||||
newImportBlock := tempMatch[1]
|
||||
updatedContent := ReplaceFirst(re,string(origContent),fmt.Sprintf("import (%s)", newImportBlock))
|
||||
if (string(origContent) != updatedContent) {
|
||||
backup(fileName)
|
||||
PF("%s %s\n",Cw("imports updated:"),Cmb(fileName))
|
||||
os.WriteFile(fileName, []byte(updatedContent), 0644)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cmd := exec.Command("go", "build", "-o", "bin/"+name, name)
|
||||
|
||||
PF("%s %s\n", Cw("running:"), Cyb("go build "+name))
|
||||
|
||||
out, err := cmd.CombinedOutput()
|
||||
|
||||
if err != nil { // ·········································································· build failed
|
||||
|
||||
PN(Cy(string(out)))
|
||||
P(Cr("--- build failed: " + name + " ---"))
|
||||
|
||||
} else { // ·············································································· build succeeded
|
||||
|
||||
if *opt_a { // ······························································· build for other platforms
|
||||
for _, osys := range oses {
|
||||
for _, arch := range arches {
|
||||
|
||||
ofile:="bin/"+name+"_"+targetversion+"_"+osys+"_"+arch
|
||||
P(Cy(ofile))
|
||||
|
||||
cmd := exec.Command(GO, "build", "-o", ofile, name)
|
||||
cmd.Env = append(os.Environ(), "GOOS="+osys, "GOARCH="+arch)
|
||||
cmd.Run()
|
||||
}
|
||||
}
|
||||
|
||||
os.WriteFile("bin/version.txt", []byte(targetversion), 0644)
|
||||
|
||||
}
|
||||
|
||||
P(Cb("--- compiling done: " + name + " ---"))
|
||||
|
||||
if len(*opt_c) > 0 { // ··························································· execute post command
|
||||
params := strings.Fields(*opt_c)
|
||||
app := params[0]
|
||||
args := params[1:]
|
||||
|
||||
P(Cw(*opt_c))
|
||||
xmd = exec.Command(app, args...)
|
||||
xmd.Stdout = os.Stdout
|
||||
xmd.Stdin = os.Stdin
|
||||
xmd.Stderr = os.Stderr
|
||||
xmd.Run()
|
||||
}
|
||||
|
||||
if !*opt_b && !*opt_a {
|
||||
stopRunning(xmd)
|
||||
|
||||
args := []string{}
|
||||
if len(*opt_o) > 0 {
|
||||
args = strings.Fields(*opt_o)
|
||||
}
|
||||
|
||||
xmd = exec.Command("./bin/"+name, args...) // ······································· start new build
|
||||
var stdoutBuf, stderrBuf bytes.Buffer
|
||||
xmd.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
|
||||
xmd.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
|
||||
xmd.Start()
|
||||
|
||||
PF("%s %d\n", Cw("process started:"), xmd.Process.Pid)
|
||||
}
|
||||
|
||||
P(Cg("--- end building: " + name + " ---"))
|
||||
if *opt_x {
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
ot = lmf
|
||||
}
|
||||
|
||||
if *opt_1 {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
st = 0
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func backup(src string) { // ---------------------------------------------------------------------- backup files
|
||||
sourceFile,_ := os.Open(src)
|
||||
defer sourceFile.Close()
|
||||
dst:=SF("./tmp/%s.%s",src,time.Now().Format("20060102150405"))
|
||||
destFile,_ := os.Create(dst)
|
||||
defer destFile.Close()
|
||||
io.Copy(destFile, sourceFile)
|
||||
destFile.Sync()
|
||||
destFile.Close()
|
||||
}
|
||||
|
||||
// ===================================================================================================== SUPPORT
|
||||
|
||||
func targetversion(file string) string { // ---------------------------------------------- detect target version
|
||||
targetversion:=""
|
||||
readFile, err := os.Open(file)
|
||||
if err == nil {
|
||||
fileScanner := bufio.NewScanner(readFile)
|
||||
fileScanner.Split(bufio.ScanLines)
|
||||
r := regexp.MustCompile("var\\s+version\\s*=\\s*\"(.*)\"$")
|
||||
for fileScanner.Scan() {
|
||||
line := fileScanner.Text()
|
||||
s := r.FindStringSubmatch(line)
|
||||
if len(s) > 0 {
|
||||
targetversion=s[1]
|
||||
}
|
||||
}
|
||||
readFile.Close()
|
||||
}
|
||||
|
||||
if (targetversion=="") {
|
||||
PE("target version not found")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
return targetversion
|
||||
}
|
||||
|
||||
|
||||
func lmf(dir string) int64 { // -------------------------------------- get last modification date from .go files
|
||||
var tmax int64 = 0
|
||||
files, err := ioutil.ReadDir("./")
|
||||
if err == nil {
|
||||
r1, _ := regexp.Compile("^\\.")
|
||||
r2, _ := regexp.Compile("build\\.go")
|
||||
r3, _ := regexp.Compile("\\.go$")
|
||||
for _, file := range files {
|
||||
if r3.MatchString(file.Name()) {
|
||||
if !r1.MatchString(file.Name()) && !r2.MatchString(file.Name()) {
|
||||
tf := filemodtime(file.Name())
|
||||
if tf > tmax {
|
||||
tmax = tf
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tmax
|
||||
}
|
||||
|
||||
func stopRunning(cmd *exec.Cmd) { // -------------------------------------------------- stop running old process
|
||||
if cmd == nil || cmd.ProcessState != nil && cmd.ProcessState.Exited() || cmd.Process == nil {
|
||||
return
|
||||
}
|
||||
|
||||
err := cmd.Process.Kill()
|
||||
if err == nil {
|
||||
cmd.Wait()
|
||||
P("process stopped:", cmd.Process.Pid)
|
||||
}
|
||||
}
|
||||
|
||||
func fileExists(filename string) bool { // ------------------------------------------------ check if file exists
|
||||
info, err := os.Stat(filename)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
func dirName() string { // ------------------------------------------------------- get name of current directory
|
||||
pwd,err := os.Getwd()
|
||||
if err == nil {
|
||||
return filepath.Base(pwd)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func info() { // ------------------------------------------------------------------------------------- show info
|
||||
PF("%s (%s (%s), toolbox %s, %s)\n", Cwb("gbld - simple golang builder"),
|
||||
Cgb("v"+version), Cgb(build), Cgb("v"+tbversion), Ccb("mwx'2026"))
|
||||
}
|
||||
|
||||
// ========================================================================================================= END
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"build (-b -i -1 gbld)": ["-b","-i","-1","gbld"]
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
module gbld
|
||||
|
||||
go 1.26.1
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||
github.com/eknkc/basex v1.0.1
|
||||
github.com/fatih/color v1.19.0
|
||||
github.com/minio/selfupdate v0.6.0
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/tidwall/gjson v1.19.0
|
||||
)
|
||||
|
||||
require (
|
||||
aead.dev/minisign v0.2.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.5.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b // indirect
|
||||
golang.org/x/sys v0.42.0 // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
)
|
||||
@@ -0,0 +1,122 @@
|
||||
aead.dev/minisign v0.2.0 h1:kAWrq/hBRu4AARY6AlciO83xhNnW9UaC8YipS2uhLPk=
|
||||
aead.dev/minisign v0.2.0/go.mod h1:zdq6LdSd9TbuSxchxwhpA9zEb9YXcVGoE8JakuiGaIQ=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
||||
github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
|
||||
github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
|
||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
|
||||
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
|
||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/eknkc/basex v1.0.1 h1:TcyAkqh4oJXgV3WYyL4KEfCMk9W8oJCpmx1bo+jVgKY=
|
||||
github.com/eknkc/basex v1.0.1/go.mod h1:k/F/exNEHFdbs3ZHuasoP2E7zeWwZblG84Y7Z59vQRo=
|
||||
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
|
||||
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
|
||||
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/minio/selfupdate v0.6.0 h1:i76PgT0K5xO9+hjzKcacQtO7+MjJ4JKA8Ak8XQ9DDwU=
|
||||
github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/tidwall/gjson v1.19.0 h1:xwxm7n691Uf3u5OFjzngavjGTh55KX5q/9w9xHW88JU=
|
||||
github.com/tidwall/gjson v1.19.0/go.mod h1:V37/opeE/JbLUOfH0QTXiNez2l0RUjYUhpT4szFQAfc=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b h1:QAqMVf3pSa6eeTsuklijukjXBlj7Es2QQplab+/RbQ4=
|
||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -0,0 +1,14 @@
|
||||
//go:build linux
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func filemodtime(build string) int64 {
|
||||
fibuild, _ := os.Stat(build)
|
||||
tb := fibuild.Sys().(*syscall.Stat_t).Mtim
|
||||
return tb.Sec
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//go:build darwin
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func filemodtime(build string) int64 {
|
||||
fibuild, _ := os.Stat(build)
|
||||
tb := fibuild.Sys().(*syscall.Stat_t).Mtimespec
|
||||
return tb.Sec
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
// ======================================================================================= go toolbox (mwx'2026)
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/rand"
|
||||
"database/sql"
|
||||
"encoding/base64"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/AlecAivazis/survey/v2/terminal"
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/eknkc/basex"
|
||||
"github.com/fatih/color"
|
||||
"github.com/minio/selfupdate"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
var tbversion = "0.4.1"
|
||||
|
||||
var CHRS = "VW9IdGJ6eXh1T25DRHdrc2M5MlhOQVNQcEJFWnJhWVY2ZEowaFJLdmoxNUdxVDRJZkZpTTdRZW0zTFc4Z2w="
|
||||
var LR = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
|
||||
|
||||
|
||||
func checkforupdate() { // --------------------------------------------------------------- check for new version
|
||||
prg := prgname()
|
||||
resp, err := http.Get(VERSIONURL)
|
||||
if err == nil {
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
if scanner.Scan() {
|
||||
lversion := strings.TrimSpace(scanner.Text())
|
||||
sv_version, err := semver.NewVersion(version)
|
||||
if err == nil {
|
||||
sv_lversion, err := semver.NewVersion(lversion)
|
||||
if err == nil {
|
||||
if (sv_lversion.GreaterThan(sv_version)) {
|
||||
ans:=Yesno(SF("new '%s' version found (%s -> %s), update now?",prg,sv_version,sv_lversion),true);
|
||||
if (ans) {
|
||||
updateurl:=SF("%s/%s_%s_%s_%s",UPDATEBASEURL,prg,lversion,runtime.GOOS,runtime.GOARCH)
|
||||
|
||||
if err := doupdate(updateurl); err != nil {
|
||||
PO(SF("Update failed: %v\n", err))
|
||||
os.Exit(1)
|
||||
}
|
||||
PO("Update successful!","please run your last command again")
|
||||
os.Exit(0)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resp.Body.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func doupdate(url string) error { // ----------------------------------------------------------------- do update
|
||||
resp, err := http.Get(url)
|
||||
if err != nil { return err }
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK { return fmt.Errorf("server returned status: %v", resp.Status) }
|
||||
err = selfupdate.Apply(resp.Body, selfupdate.Options{})
|
||||
if err != nil { return err }
|
||||
return nil
|
||||
}
|
||||
|
||||
func Enc(str string) string { // ----------------------------------------------------------------- encode string
|
||||
enc, _ := basex.NewEncoding(Db64(CHRS))
|
||||
return enc.Encode([]byte(Rndstr(2) + str))
|
||||
}
|
||||
|
||||
func Dec(str string) string { // ----------------------------------------------------------------- decode string
|
||||
enc, _ := basex.NewEncoding(Db64(CHRS))
|
||||
b, _ := enc.Decode(str)
|
||||
return string(b[2:])
|
||||
}
|
||||
|
||||
func Db64(txt string) string { // ------------------------------------------------------------- string to base64
|
||||
d, _ := base64.StdEncoding.DecodeString(txt)
|
||||
return string(d)
|
||||
}
|
||||
|
||||
func Rndstr(n int) string { // ------------------------------------------------------- random string with length
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
n, _ := rand.Int(rand.Reader, big.NewInt(int64(len(LR))))
|
||||
b[i] = LR[n.Int64()]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func Input(msg string, def string) string { // -------------------------------- AlecAivazis/survey: input string
|
||||
tmp := ""
|
||||
err := survey.AskOne(&survey.Input{Message: msg, Default: def}, &tmp)
|
||||
if err != nil {
|
||||
if err == terminal.InterruptErr {
|
||||
P(Crb("Interrupted."))
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
return tmp
|
||||
}
|
||||
|
||||
func Inputpw(msg string) string { // ---------------------------------------- AlecAivazis/survey: input password
|
||||
tmp := ""
|
||||
err := survey.AskOne(&survey.Password{Message: msg}, &tmp)
|
||||
if err != nil {
|
||||
if err == terminal.InterruptErr {
|
||||
P(Crb("Interrupted."))
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
return tmp
|
||||
}
|
||||
|
||||
func Yesno(msg string, def bool) bool { // ------------------------------------------ AlecAivazis/survey: yes/no
|
||||
var err error
|
||||
tmp := ""
|
||||
if def {
|
||||
err = survey.AskOne(&survey.Select{Message: msg, Options: []string{"Yes", "No"}}, &tmp)
|
||||
} else {
|
||||
err = survey.AskOne(&survey.Select{Message: msg, Options: []string{"No", "Yes"}}, &tmp)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if err == terminal.InterruptErr {
|
||||
P(Crb("Interrupted."))
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
if tmp == "Yes" {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func Getid(n int) string { // --------------------------------------------------------- get base62 random string
|
||||
const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
ret := make([]byte, n)
|
||||
for i := 0; i < n; i++ {
|
||||
num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
|
||||
ret[i] = letters[num.Int64()]
|
||||
}
|
||||
return string(ret)
|
||||
}
|
||||
|
||||
func GETid(n int) string { // --------------------------------------------------------- get base36 random string
|
||||
const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
ret := make([]byte, n)
|
||||
for i := 0; i < n; i++ {
|
||||
num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters))))
|
||||
ret[i] = letters[num.Int64()]
|
||||
}
|
||||
return string(ret)
|
||||
}
|
||||
|
||||
func Mytable(rows *sql.Rows) []map[string]interface{} { // ----------------------------- load mysql result table
|
||||
defer rows.Close()
|
||||
columns, _ := rows.Columns()
|
||||
count := len(columns)
|
||||
tableData := make([]map[string]interface{}, 0)
|
||||
values := make([]interface{}, count)
|
||||
valuePtrs := make([]interface{}, count)
|
||||
for rows.Next() {
|
||||
for i := 0; i < count; i++ {
|
||||
valuePtrs[i] = &values[i]
|
||||
}
|
||||
rows.Scan(valuePtrs...)
|
||||
entry := make(map[string]interface{})
|
||||
for i, col := range columns {
|
||||
var v interface{}
|
||||
val := values[i]
|
||||
b, ok := val.([]byte)
|
||||
if ok {
|
||||
v = string(b)
|
||||
} else {
|
||||
v = val
|
||||
}
|
||||
entry[col] = v
|
||||
}
|
||||
tableData = append(tableData, entry)
|
||||
}
|
||||
return (tableData)
|
||||
}
|
||||
|
||||
func Checkip(network string, ip string) bool { // ---------- check if ip is in range (cidr address or single ip)
|
||||
if net.ParseIP(ip) == nil {
|
||||
return false
|
||||
}
|
||||
_, subnet, err := net.ParseCIDR(network)
|
||||
if err == nil {
|
||||
if subnet.Contains(net.ParseIP(ip)) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if network == ip {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func Isflagpassed(name string) bool { // -------------------------------------------------- check if flag is set
|
||||
found := false
|
||||
flag.Visit(func(f *flag.Flag) {
|
||||
if f.Name == name {
|
||||
found = true
|
||||
}
|
||||
})
|
||||
return found
|
||||
}
|
||||
|
||||
func Body(r *http.Response) string { // ------------------------------------------------------------ http body
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err == nil {
|
||||
return string(body)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func Atoi(s string) int { // ------------------------------------------------------------------------------ atoi
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
func Itoa(i int) string { // ------------------------------------------------------------------------------ itoa
|
||||
return strconv.Itoa(i)
|
||||
}
|
||||
|
||||
func GJA(j string, k string) []string { // -------------------------------------------------- convert gjson array
|
||||
var ret []string
|
||||
for _, c := range gjson.Get(j, k).Array() {
|
||||
ret = append(ret, c.String())
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------ print simple
|
||||
|
||||
func P(a ...any) (n int, err error) { return fmt.Fprintln(os.Stdout, a...) }
|
||||
func PN(a ...any) (n int, err error) { return fmt.Fprint(os.Stdout, a...) }
|
||||
func PF(format string, a ...any) (n int, err error) { return fmt.Fprintf(os.Stdout, format, a...) }
|
||||
func SF(format string, a ...any) string { return fmt.Sprintf(format, a...) }
|
||||
|
||||
func PE(msg ...string) (n int, err error) {
|
||||
if (len(msg)==2) { return fmt.Fprintf(os.Stdout, "%s: %s (%s)\n", Crb("ERROR"), Cwb(msg[0]),msg[1]) }
|
||||
return fmt.Fprintf(os.Stdout, "%s: %s\n", Crb("ERROR"), Cwb(msg))
|
||||
}
|
||||
func PO(msg ...string) (n int, err error) {
|
||||
if (len(msg)==2) { return fmt.Fprintf(os.Stdout, "%s: %s (%s)\n", Cgb("OK"), Cwb(msg[0]),msg[1]) }
|
||||
return fmt.Fprintf(os.Stdout, "%s: %s\n", Cgb("OK"), Cwb(msg))
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------ regular expression
|
||||
|
||||
func ReplaceFirst(re *regexp.Regexp, str, replace string) string {
|
||||
loc := re.FindStringIndex(str)
|
||||
if loc == nil { return str }
|
||||
return str[:loc[0]] + replace + str[loc[1]:]
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------- string functions
|
||||
|
||||
func Shortstr(s string, length int) string {
|
||||
runes := []rune(s)
|
||||
if len(runes) <= length {
|
||||
return s
|
||||
}
|
||||
return string(runes[:length-2]) + ".."
|
||||
}
|
||||
|
||||
func SR(str string, n int) string { return strings.Repeat(str, n) }
|
||||
|
||||
func RemoveAllMatches(slice []string, target string) []string { // remove matching string from array
|
||||
result := slice[:0]
|
||||
for _, v := range slice {
|
||||
if v != target {
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------- system functions
|
||||
|
||||
func prgname() string { // program name
|
||||
exepath, err := os.Executable()
|
||||
if err != nil {
|
||||
PE(SF("Error getting executable path: %s", err))
|
||||
return ""
|
||||
}
|
||||
exename := filepath.Base(exepath)
|
||||
return exename
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------ viper abbrevations
|
||||
|
||||
func VX(key string) bool { return viper.IsSet(key) }
|
||||
func VS(key string) string { return viper.GetString(key) }
|
||||
func VSS(key string) []string { return viper.GetStringSlice(key) }
|
||||
func VB(key string) bool { return viper.GetBool(key) }
|
||||
func VI(key string) int { return viper.GetInt(key) }
|
||||
|
||||
// ------------------------------------------------------------------------------------------------- text colors
|
||||
|
||||
var Cr func(...interface{}) string = color.New(color.FgRed).SprintFunc()
|
||||
var Cg func(...interface{}) string = color.New(color.FgGreen).SprintFunc()
|
||||
var Cy func(...interface{}) string = color.New(color.FgYellow).SprintFunc()
|
||||
var Cb func(...interface{}) string = color.New(color.FgBlue).SprintFunc()
|
||||
var Cm func(...interface{}) string = color.New(color.FgMagenta).SprintFunc()
|
||||
var Cc func(...interface{}) string = color.New(color.FgCyan).SprintFunc()
|
||||
var Cw func(...interface{}) string = color.New(color.FgWhite).SprintFunc()
|
||||
|
||||
var Crb func(...interface{}) string = color.New(color.Bold, color.FgRed).SprintFunc()
|
||||
var Cgb func(...interface{}) string = color.New(color.Bold, color.FgGreen).SprintFunc()
|
||||
var Cyb func(...interface{}) string = color.New(color.Bold, color.FgYellow).SprintFunc()
|
||||
var Cbb func(...interface{}) string = color.New(color.Bold, color.FgBlue).SprintFunc()
|
||||
var Cmb func(...interface{}) string = color.New(color.Bold, color.FgMagenta).SprintFunc()
|
||||
var Ccb func(...interface{}) string = color.New(color.Bold, color.FgCyan).SprintFunc()
|
||||
var Cwb func(...interface{}) string = color.New(color.Bold, color.FgWhite).SprintFunc()
|
||||
|
||||
// ========================================================================================================= END
|
||||
Reference in New Issue
Block a user