mirror of
https://github.com/Mikescher/kpsync.git
synced 2025-08-25 00:38:03 +02:00
download kind works
This commit is contained in:
parent
e7293464c1
commit
0f9b423d2f
4
.gitignore
vendored
4
.gitignore
vendored
@ -35,4 +35,6 @@ atlassian-ide-plugin.xml
|
||||
########## Custom ##########
|
||||
|
||||
|
||||
_out/*
|
||||
_out/*
|
||||
|
||||
script_old.sh
|
@ -3,18 +3,29 @@ package app
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"fyne.io/systray"
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/syncext"
|
||||
"mikescher.com/kpsync"
|
||||
"mikescher.com/kpsync/assets"
|
||||
"mikescher.com/kpsync/log"
|
||||
)
|
||||
|
||||
type Application struct {
|
||||
masterLock sync.Mutex
|
||||
|
||||
config kpsync.Config
|
||||
|
||||
trayReady bool
|
||||
sigStopChan chan bool
|
||||
sigErrChan chan error
|
||||
trayReady bool
|
||||
uploadRunning *syncext.AtomicBool
|
||||
|
||||
sigStopChan chan bool // keepass exited
|
||||
sigErrChan chan error // fatal error
|
||||
|
||||
sigSyncLoopStopChan chan bool // stop sync loop
|
||||
sigTermKeepassChan chan bool // stop keepass
|
||||
|
||||
dbFile string
|
||||
stateFile string
|
||||
@ -25,10 +36,14 @@ func NewApplication() *Application {
|
||||
cfg := kpsync.LoadConfig()
|
||||
|
||||
return &Application{
|
||||
config: cfg,
|
||||
trayReady: false,
|
||||
sigStopChan: make(chan bool, 128),
|
||||
sigErrChan: make(chan error, 128),
|
||||
masterLock: sync.Mutex{},
|
||||
config: cfg,
|
||||
uploadRunning: syncext.NewAtomicBool(false),
|
||||
trayReady: false,
|
||||
sigStopChan: make(chan bool, 128),
|
||||
sigErrChan: make(chan error, 128),
|
||||
sigSyncLoopStopChan: make(chan bool, 128),
|
||||
sigTermKeepassChan: make(chan bool, 128),
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +57,9 @@ func (app *Application) Run() {
|
||||
app.sigErrChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
app.setTrayStateDirect("Sleeping...", assets.IconDefault)
|
||||
|
||||
err = app.runSyncLoop()
|
||||
if err != nil {
|
||||
app.sigErrChan <- err
|
||||
@ -55,14 +73,27 @@ func (app *Application) Run() {
|
||||
select {
|
||||
case <-sigTerm:
|
||||
|
||||
app.sigSyncLoopStopChan <- true
|
||||
app.sigTermKeepassChan <- true
|
||||
log.LogInfo("Stopping application (received SIGTERM signal)")
|
||||
|
||||
// TODO term
|
||||
|
||||
case _ = <-app.sigErrChan:
|
||||
case err := <-app.sigErrChan:
|
||||
|
||||
app.sigSyncLoopStopChan <- true
|
||||
app.sigTermKeepassChan <- true
|
||||
log.LogInfo("Stopping application (received ERROR)")
|
||||
log.LogError(err.Error(), err)
|
||||
|
||||
// TODO stop
|
||||
|
||||
case _ = <-app.sigStopChan:
|
||||
|
||||
app.sigSyncLoopStopChan <- true
|
||||
app.sigTermKeepassChan <- true
|
||||
log.LogInfo("Stopping application (received STOP)")
|
||||
|
||||
// TODO stop
|
||||
}
|
||||
|
||||
|
166
app/sync.go
166
app/sync.go
@ -1,11 +1,18 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/timeext"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"mikescher.com/kpsync/assets"
|
||||
"mikescher.com/kpsync/log"
|
||||
)
|
||||
@ -20,6 +27,11 @@ func (app *Application) initSync() error {
|
||||
app.dbFile = path.Join(app.config.WorkDir, path.Base(app.config.LocalFallback))
|
||||
app.stateFile = path.Join(app.config.WorkDir, "kpsync.state")
|
||||
|
||||
if isKeepassRunning() {
|
||||
log.LogError("keepassxc is already running!", nil)
|
||||
return exerr.New(exerr.TypeInternal, "keepassxc is already running").Build()
|
||||
}
|
||||
|
||||
state := app.readState()
|
||||
|
||||
needsDownload := true
|
||||
@ -29,16 +41,18 @@ func (app *Application) initSync() error {
|
||||
if err != nil {
|
||||
log.LogError("Failed to calculate local database checksum", err)
|
||||
} else if localCS == state.Checksum {
|
||||
remoteETag, err := app.getRemoteETag()
|
||||
remoteETag, remoteLM, err := app.getRemoteETag()
|
||||
if err != nil {
|
||||
log.LogError("Failed to get remote ETag", err)
|
||||
} else if remoteETag == state.ETag {
|
||||
|
||||
log.LogInfo(fmt.Sprintf("Found local database matching remote database - skip initial download"))
|
||||
log.LogInfo(fmt.Sprintf("Checksum (cached) := %s", state.Checksum))
|
||||
log.LogInfo(fmt.Sprintf("Checksum (local) := %s", localCS))
|
||||
log.LogInfo(fmt.Sprintf("ETag (cached) := %s", state.ETag))
|
||||
log.LogInfo(fmt.Sprintf("ETag (remote) := %s", remoteETag))
|
||||
log.LogInfo(fmt.Sprintf("Checksum (cached) := %s", state.Checksum))
|
||||
log.LogInfo(fmt.Sprintf("Checksum (local) := %s", localCS))
|
||||
log.LogInfo(fmt.Sprintf("ETag (cached) := %s", state.ETag))
|
||||
log.LogInfo(fmt.Sprintf("ETag (remote) := %s", remoteETag))
|
||||
log.LogInfo(fmt.Sprintf("LastModified (cached) := %s", state.LastModified.Format(time.RFC3339)))
|
||||
log.LogInfo(fmt.Sprintf("LastModified (remote) := %s", remoteLM.Format(time.RFC3339)))
|
||||
needsDownload = false
|
||||
|
||||
}
|
||||
@ -46,22 +60,152 @@ func (app *Application) initSync() error {
|
||||
}
|
||||
|
||||
if needsDownload {
|
||||
func() {
|
||||
fin := app.setTrayState("Downloading database", assets.IconDefault)
|
||||
err = func() error {
|
||||
fin := app.setTrayState("Downloading database", assets.IconDownload)
|
||||
defer fin()
|
||||
|
||||
log.LogInfo(fmt.Sprintf("Downloading remote database to %s", app.dbFile))
|
||||
|
||||
etag, err := app.downloadDatabase()
|
||||
etag, lm, sha, sz, err := app.downloadDatabase()
|
||||
if err != nil {
|
||||
log.LogError("Failed to download remote database", err)
|
||||
app.sigErrChan <- exerr.Wrap(err, "Failed to download remote database").Build()
|
||||
return
|
||||
return exerr.Wrap(err, "Failed to download remote database").Build()
|
||||
}
|
||||
|
||||
log.LogInfo(fmt.Sprintf("Downloaded remote database to %s", app.dbFile))
|
||||
log.LogInfo(fmt.Sprintf("Checksum := %s", sha))
|
||||
log.LogInfo(fmt.Sprintf("ETag := %s", etag))
|
||||
log.LogInfo(fmt.Sprintf("Size := %s", langext.FormatBytes(sz)))
|
||||
log.LogInfo(fmt.Sprintf("LastModified := %s", lm.Format(time.RFC3339)))
|
||||
|
||||
err = app.saveState(etag, lm, sha, sz)
|
||||
if err != nil {
|
||||
log.LogError("Failed to save state", err)
|
||||
return exerr.Wrap(err, "Failed to save state").Build()
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
return exerr.Wrap(err, "").Build()
|
||||
}
|
||||
} else {
|
||||
log.LogInfo(fmt.Sprintf("Skip download - use existing local database %s", app.dbFile))
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
||||
log.LogInfo("Starting keepassxc...")
|
||||
|
||||
cmd := exec.Command("keepassxc", app.dbFile)
|
||||
|
||||
go func() {
|
||||
select {
|
||||
case <-app.sigTermKeepassChan:
|
||||
log.LogInfo("Received signal to terminate keepassxc")
|
||||
if cmd != nil && cmd.Process != nil {
|
||||
log.LogInfo(fmt.Sprintf("Terminating keepassxc %d", cmd.Process.Pid))
|
||||
err := cmd.Process.Signal(syscall.SIGTERM)
|
||||
if err != nil {
|
||||
log.LogError("Failed to terminate keepassxc", err)
|
||||
} else {
|
||||
log.LogInfo("keepassxc terminated successfully")
|
||||
}
|
||||
} else {
|
||||
log.LogInfo("No keepassxc process to terminate")
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
log.LogError("Failed to start keepassxc", err)
|
||||
app.sigErrChan <- exerr.Wrap(err, "Failed to start keepassxc").Build()
|
||||
return
|
||||
}
|
||||
|
||||
log.LogInfo(fmt.Sprintf("keepassxc started with PID %d", cmd.Process.Pid))
|
||||
|
||||
err = cmd.Wait()
|
||||
|
||||
exitErr := &exec.ExitError{}
|
||||
if errors.As(err, &exitErr) {
|
||||
|
||||
log.LogInfo(fmt.Sprintf("keepass exited with code %d", exitErr.ExitCode()))
|
||||
app.sigStopChan <- true
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.LogError("Failed to run keepassxc", err)
|
||||
app.sigErrChan <- exerr.Wrap(err, "Failed to run keepassxc").Build()
|
||||
return
|
||||
}
|
||||
|
||||
log.LogInfo("keepassxc exited successfully")
|
||||
app.sigStopChan <- true
|
||||
return
|
||||
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *Application) runSyncLoop() error {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return exerr.Wrap(err, "failed to init file-watcher").Build()
|
||||
}
|
||||
defer func() { _ = watcher.Close() }()
|
||||
|
||||
err = watcher.Add(app.config.WorkDir)
|
||||
if err != nil {
|
||||
return exerr.Wrap(err, "").Build()
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-app.sigSyncLoopStopChan:
|
||||
log.LogInfo("Stopping sync loop (received signal)")
|
||||
return nil
|
||||
|
||||
case event := <-watcher.Events:
|
||||
log.LogInfo(fmt.Sprintf("inotify event: [%s] %s", event.Op.String(), event.Name))
|
||||
|
||||
if event.Has(fsnotify.Write) && event.Name == app.dbFile {
|
||||
func() {
|
||||
app.masterLock.Lock()
|
||||
app.uploadRunning.Wait(false)
|
||||
app.uploadRunning.Set(true)
|
||||
app.masterLock.Unlock()
|
||||
|
||||
defer app.uploadRunning.Set(false)
|
||||
|
||||
log.LogInfo("Database file was modified")
|
||||
log.LogInfo(fmt.Sprintf("Sleeping for %d seconds", app.config.Debounce))
|
||||
|
||||
time.Sleep(timeext.FromSeconds(app.config.Debounce))
|
||||
|
||||
state := app.readState()
|
||||
localCS, err := app.calcLocalChecksum()
|
||||
if err != nil {
|
||||
log.LogError("Failed to calculate local database checksum", err)
|
||||
return
|
||||
}
|
||||
|
||||
if localCS == state.Checksum {
|
||||
log.LogInfo("Local database still matches remote (via checksum) - no need to upload")
|
||||
log.LogInfo(fmt.Sprintf("Checksum (remote/cached) := %s", state.Checksum))
|
||||
log.LogInfo(fmt.Sprintf("Checksum (local) := %s", localCS))
|
||||
return
|
||||
}
|
||||
|
||||
//TODO upload with IfMatch
|
||||
}()
|
||||
}
|
||||
case err := <-watcher.Errors:
|
||||
log.LogError("Filewatcher reported an error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
38
app/tray.go
38
app/tray.go
@ -18,3 +18,41 @@ func (app *Application) initTray() {
|
||||
|
||||
systray.Run(trayOnReady, nil)
|
||||
}
|
||||
|
||||
func (app *Application) setTrayState(txt string, icon []byte) func() {
|
||||
if !app.trayReady {
|
||||
return func() {}
|
||||
}
|
||||
|
||||
app.masterLock.Lock()
|
||||
defer app.masterLock.Unlock()
|
||||
|
||||
systray.SetIcon(icon)
|
||||
systray.SetTooltip(txt)
|
||||
|
||||
fin := func() {
|
||||
app.masterLock.Lock()
|
||||
defer app.masterLock.Unlock()
|
||||
|
||||
if !app.trayReady {
|
||||
return
|
||||
}
|
||||
|
||||
systray.SetIcon(assets.IconDefault)
|
||||
systray.SetTooltip("Sleeping...")
|
||||
}
|
||||
|
||||
return fin
|
||||
}
|
||||
|
||||
func (app *Application) setTrayStateDirect(txt string, icon []byte) {
|
||||
if !app.trayReady {
|
||||
return
|
||||
}
|
||||
|
||||
app.masterLock.Lock()
|
||||
defer app.masterLock.Unlock()
|
||||
|
||||
systray.SetIcon(icon)
|
||||
systray.SetTooltip(txt)
|
||||
}
|
||||
|
59
app/utils.go
59
app/utils.go
@ -3,9 +3,13 @@ package app
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/cryptext"
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
|
||||
"github.com/shirou/gopsutil/v3/process"
|
||||
"mikescher.com/kpsync/log"
|
||||
)
|
||||
|
||||
func fileExists(p string) bool {
|
||||
@ -17,12 +21,16 @@ func fileExists(p string) bool {
|
||||
}
|
||||
|
||||
type State struct {
|
||||
ETag string `json:"etag"`
|
||||
Size int64 `json:"size"`
|
||||
Checksum string `json:"checksum"`
|
||||
ETag string `json:"etag"`
|
||||
Size int64 `json:"size"`
|
||||
Checksum string `json:"checksum"`
|
||||
LastModified time.Time `json:"lastModified"`
|
||||
}
|
||||
|
||||
func (app *Application) readState() *State {
|
||||
app.masterLock.Lock()
|
||||
defer app.masterLock.Unlock()
|
||||
|
||||
bin, err := os.ReadFile(app.stateFile)
|
||||
if err != nil {
|
||||
return nil
|
||||
@ -37,6 +45,30 @@ func (app *Application) readState() *State {
|
||||
return &state
|
||||
}
|
||||
|
||||
func (app *Application) saveState(eTag string, lastModified time.Time, checksum string, size int64) error {
|
||||
app.masterLock.Lock()
|
||||
defer app.masterLock.Unlock()
|
||||
|
||||
obj := State{
|
||||
ETag: eTag,
|
||||
Size: size,
|
||||
Checksum: checksum,
|
||||
LastModified: lastModified,
|
||||
}
|
||||
|
||||
bin, err := json.MarshalIndent(obj, "", " ")
|
||||
if err != nil {
|
||||
return exerr.Wrap(err, "Failed to marshal state").Build()
|
||||
}
|
||||
|
||||
err = os.WriteFile(app.stateFile, bin, 0644)
|
||||
if err != nil {
|
||||
return exerr.Wrap(err, "Failed to write state file").Build()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *Application) calcLocalChecksum() (string, error) {
|
||||
bin, err := os.ReadFile(app.dbFile)
|
||||
if err != nil {
|
||||
@ -45,3 +77,24 @@ func (app *Application) calcLocalChecksum() (string, error) {
|
||||
|
||||
return cryptext.BytesSha256(bin), nil
|
||||
}
|
||||
|
||||
func isKeepassRunning() bool {
|
||||
proc, err := process.Processes()
|
||||
if err != nil {
|
||||
log.LogError("failed to query existing keepass process", err)
|
||||
return false
|
||||
}
|
||||
|
||||
for _, p := range proc {
|
||||
name, err := p.Name()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.ToLower(name) == "keepass" || strings.ToLower(name) == "keepassxc" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
@ -1,5 +1,99 @@
|
||||
package app
|
||||
|
||||
func (app *Application) initSync() {
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/cryptext"
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/timeext"
|
||||
)
|
||||
|
||||
func (app *Application) downloadDatabase() (string, time.Time, string, int64, error) {
|
||||
|
||||
client := http.Client{Timeout: 90 * time.Second}
|
||||
|
||||
req, err := http.NewRequest("GET", app.config.WebDAVURL, nil)
|
||||
if err != nil {
|
||||
return "", time.Time{}, "", 0, exerr.Wrap(err, "").Build()
|
||||
}
|
||||
|
||||
req.SetBasicAuth(app.config.WebDAVUser, app.config.WebDAVPass)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", time.Time{}, "", 0, exerr.Wrap(err, "Failed to download remote database").Build()
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", time.Time{}, "", 0, exerr.New(exerr.TypeInternal, "Failed to download remote database").Int("sc", resp.StatusCode).Build()
|
||||
}
|
||||
|
||||
bin, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", time.Time{}, "", 0, exerr.Wrap(err, "Failed to read response body").Build()
|
||||
}
|
||||
|
||||
etag := resp.Header.Get("ETag")
|
||||
if etag == "" {
|
||||
return "", time.Time{}, "", 0, exerr.New(exerr.TypeInternal, "ETag header is missing").Build()
|
||||
}
|
||||
|
||||
lmStr := resp.Header.Get("Last-Modified")
|
||||
|
||||
lm, err := time.Parse("Mon, 02 Jan 2006 15:04:05 MST", lmStr)
|
||||
if err != nil {
|
||||
return "", time.Time{}, "", 0, exerr.Wrap(err, "Failed to parse Last-Modified header").Build()
|
||||
}
|
||||
|
||||
lm = lm.In(timeext.TimezoneBerlin)
|
||||
|
||||
sha := cryptext.BytesSha256(bin)
|
||||
|
||||
sz := int64(len(bin))
|
||||
|
||||
err = os.WriteFile(app.dbFile, bin, 0644)
|
||||
if err != nil {
|
||||
return "", time.Time{}, "", 0, exerr.Wrap(err, "Failed to write database file").Build()
|
||||
}
|
||||
|
||||
return etag, lm, sha, sz, nil
|
||||
}
|
||||
|
||||
func (app *Application) getRemoteETag() (string, time.Time, error) {
|
||||
client := http.Client{Timeout: 90 * time.Second}
|
||||
|
||||
req, err := http.NewRequest("HEAD", app.config.WebDAVURL, nil)
|
||||
if err != nil {
|
||||
return "", time.Time{}, exerr.Wrap(err, "").Build()
|
||||
}
|
||||
|
||||
req.SetBasicAuth(app.config.WebDAVUser, app.config.WebDAVPass)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", time.Time{}, exerr.Wrap(err, "Failed to download remote database").Build()
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", time.Time{}, exerr.New(exerr.TypeInternal, "Failed to download remote database").Int("sc", resp.StatusCode).Build()
|
||||
}
|
||||
|
||||
etag := resp.Header.Get("ETag")
|
||||
if etag == "" {
|
||||
return "", time.Time{}, exerr.New(exerr.TypeInternal, "ETag header is missing").Build()
|
||||
}
|
||||
|
||||
lmStr := resp.Header.Get("Last-Modified")
|
||||
|
||||
lm, err := time.Parse("Mon, 02 Jan 2006 15:04:05 MST", lmStr)
|
||||
if err != nil {
|
||||
return "", time.Time{}, exerr.Wrap(err, "Failed to parse Last-Modified header").Build()
|
||||
}
|
||||
|
||||
lm = lm.In(timeext.TimezoneBerlin)
|
||||
|
||||
return etag, lm, nil
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed IconInit.png
|
||||
//go:embed iconInit.png
|
||||
var IconInit []byte
|
||||
|
||||
//go:embed iconDefault.png
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 323 B |
BIN
assets/iconDownload.png
Normal file
BIN
assets/iconDownload.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 307 B |
BIN
assets/iconInit.png
Normal file
BIN
assets/iconInit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 316 B |
@ -48,26 +48,26 @@ func LoadConfig() Config {
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if strings.HasSuffix(configPath, "~") {
|
||||
if strings.HasPrefix(configPath, "~") {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
log.FatalErr("Failed to query users home directory", err)
|
||||
}
|
||||
fmt.Println(usr.HomeDir)
|
||||
|
||||
configPath = strings.TrimSuffix(configPath, "~")
|
||||
configPath = strings.TrimPrefix(configPath, "~")
|
||||
configPath = fmt.Sprintf("%s/%s", usr.HomeDir, configPath)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(configPath); os.IsNotExist(err) && configPath != "" {
|
||||
_ = os.WriteFile(configPath, langext.Must(json.Marshal(Config{
|
||||
_ = os.WriteFile(configPath, langext.Must(json.MarshalIndent(Config{
|
||||
WebDAVURL: "https://your-nextcloud-domain.example/remote.php/dav/files/keepass.kdbx",
|
||||
WebDAVUser: "",
|
||||
WebDAVPass: "",
|
||||
LocalFallback: "",
|
||||
WorkDir: "/tmp/kpsync",
|
||||
Debounce: 3500,
|
||||
})), 0644)
|
||||
}, "", " ")), 0644)
|
||||
}
|
||||
|
||||
cfgBin, err := os.ReadFile(configPath)
|
||||
|
50
go.mod
50
go.mod
@ -3,8 +3,50 @@ module mikescher.com/kpsync
|
||||
go 1.24.6
|
||||
|
||||
require (
|
||||
fyne.io/systray v1.11.0 // indirect
|
||||
git.blackforestbytes.com/BlackForestBytes/goext v0.0.594 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
fyne.io/systray v1.11.0
|
||||
git.blackforestbytes.com/BlackForestBytes/goext v0.0.594
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/shirou/gopsutil/v3 v3.24.5
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.13.3 // indirect
|
||||
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/gin-gonic/gin v1.10.1 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
github.com/rs/zerolog v1.34.0 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.4 // indirect
|
||||
golang.org/x/arch v0.19.0 // indirect
|
||||
golang.org/x/crypto v0.40.0 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
138
go.sum
138
go.sum
@ -2,7 +2,145 @@ fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg=
|
||||
fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs=
|
||||
git.blackforestbytes.com/BlackForestBytes/goext v0.0.594 h1:tFbvEAe7FMvLuW9/RuXXlxsi8/Ve7xVrFxZnk8e/0yU=
|
||||
git.blackforestbytes.com/BlackForestBytes/goext v0.0.594/go.mod h1:vczjjViG013HjA5Ka3VTE7axDgqMChn1EsvEVg9LZnU=
|
||||
github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0=
|
||||
github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
|
||||
github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
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/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
||||
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
|
||||
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
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.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
|
||||
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
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/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
||||
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
||||
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
|
||||
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
||||
github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw=
|
||||
go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
|
||||
golang.org/x/arch v0.19.0 h1:LmbDQUodHThXE+htjrnmVD73M//D9GTH6wFZjyDkjyU=
|
||||
golang.org/x/arch v0.19.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
|
@ -1,5 +1,9 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/exerr"
|
||||
)
|
||||
|
||||
//TODO
|
||||
|
||||
func Fatal(msg string) {
|
||||
@ -8,15 +12,20 @@ func Fatal(msg string) {
|
||||
|
||||
func FatalErr(msg string, err error) {
|
||||
if err != nil {
|
||||
panic("ERROR: " + msg + "\n" + err.Error())
|
||||
println("FATAL: " + msg)
|
||||
println(" " + err.Error())
|
||||
println(exerr.FromError(err).FormatLog(exerr.LogPrintOverview))
|
||||
panic(0)
|
||||
} else {
|
||||
panic("ERROR: " + msg)
|
||||
panic("FATAL: " + msg)
|
||||
}
|
||||
}
|
||||
|
||||
func LogError(msg string, err error) {
|
||||
if err != nil {
|
||||
println("ERROR: " + msg + "\n" + err.Error())
|
||||
println("ERROR: " + msg)
|
||||
println(" " + err.Error())
|
||||
println(exerr.FromError(err).FormatLog(exerr.LogPrintOverview))
|
||||
} else {
|
||||
println("ERROR: " + msg)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user