diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 34b4ad8..1c1d925 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -66,12 +66,14 @@ jobs: run: | set -eu apt-get update -qq - # libwebkit2gtk-4.1-dev and libasound2-dev are not optional: + # libwebkitgtk-6.0-dev and libasound2-dev are not optional: # the app is cgo, and without alsa.pc oto/v3 fails at # `pkg-config --cflags -- alsa` before anything is compiled. + # ubuntu:24.04 ships webkitgtk-6.0, which is what wails v3 + # builds against by default. apt-get install -y -qq --no-install-recommends \ ca-certificates curl git jq build-essential pkg-config \ - libwebkit2gtk-4.1-dev libgtk-3-dev libasound2-dev ffmpeg + libwebkitgtk-6.0-dev libgtk-4-dev libasound2-dev ffmpeg # Cloned by hand rather than with actions/checkout: that is a JS # action and needs node inside the job container before any step @@ -217,7 +219,7 @@ jobs: apt-get update -qq apt-get install -y -qq --no-install-recommends \ ca-certificates curl git jq build-essential pkg-config \ - libwebkit2gtk-4.1-dev libgtk-3-dev libasound2-dev \ + libwebkitgtk-6.0-dev libgtk-4-dev libasound2-dev \ xvfb dbus dbus-x11 ffmpeg libasound2t64 \ alsa-utils libasound2-plugins pulseaudio pulseaudio-utils diff --git a/.planning/plans/active/009-wails-v3-migration.md b/.planning/plans/active/009-wails-v3-migration.md index cae8831..bfdcf24 100644 --- a/.planning/plans/active/009-wails-v3-migration.md +++ b/.planning/plans/active/009-wails-v3-migration.md @@ -1,8 +1,11 @@ # 009 — Wails v3 migration -**Status:** Phase 0 complete — **go**. Phase 1 **partly done** (toolchain -and build assets landed; Makefile rewrite and the tag swap not started). -Phases 2–7 not started. +**Status:** Phases 0–3 complete. The Go side is entirely on v3: nothing +in the tree imports `wails/v2`, all three lint and test configurations +are green, and `go build .` produces a running binary. **Phase 4 +(bindings) is next, and until it lands the app builds but the frontend +cannot talk to it** — `frontend/wailsjs/` is v2's tree and nothing +regenerates it. **Branch:** `wails-v3`, off `main` at `edb13a6`. **Created:** 2026-08-13 **Phase 0 run:** 2026-08-13 against **v3.0.0-beta.8** @@ -292,20 +295,21 @@ passes; `grep -r webkit2_41` returns nothing. **Est.** Half a session. Low risk, high churn. -### Phase 1 — what actually landed (`e7873bd`) +### Phase 1 — what actually landed -Steps 2, 3 (partly), 4 and 7 are done; 1, 5 and 6 are not. +Split across two commits, because steps 5 and 6 could not land before +the app was on the v3 API: swapping the build tag before `main.go` was +ported would have broken the only build that then worked. -- **Done.** `wails/v3 v3.0.0-beta.8` pinned and `wails3` added to the - `tool` block beside the v2 CLI. `build/` holds the scaffold's asset - tree with `config.yml`'s `info` block filled from `wails.json`. - `Taskfile.yml` defaults `PACKAGE_MANAGER` to pnpm. -- **Not done.** The Makefile still calls `go tool wails` (v2) - throughout, `webkit2_41` is still on all ~30 sites, and `wails.json` - is still present — deliberately, because the v2 CLI reads it and the - app has not moved to the v3 API yet. Steps 5 and 6 are entangled - with Phase 2 and should land with it: swapping the tag before - `main.go` is ported breaks the only build that currently works. +- **`e7873bd`** — `wails/v3 v3.0.0-beta.8` pinned, `wails3` added to + the `tool` block, `build/` asset tree copied from a scaffold with + `config.yml` filled from `wails.json`, `Taskfile.yml` on pnpm. +- **With Phase 2/3** — the Makefile's six `go tool wails` invocations, + every `webkit2_41` site (50 of them, not the ~30 the inventory + estimated), `lefthook.yml`, both packaging recipes, and `ci.yml`'s + apt lists. `backend/logging` is **deleted**, not ported, answering + one of the open questions: v3 takes a `*slog.Logger` directly, so + v2's `logger.Logger` adapter had no remaining caller. **Two things the plan did not anticipate.** @@ -317,18 +321,20 @@ trees (`build/android`, `build/ios`, ~40 files) are not carried — this is a desktop player and cannot target them — and their `includes:` entries are dropped from `Taskfile.yml`. -**GTK4 is unavailable on the dev machine, so the gtk3 fallback is in -use.** `webkitgtk-6.0` is not installed and installing it needs sudo. -The consequence is sharper than the plan's "fallback if GTK4 -misbehaves": **`go tool wails3` does not work at all**, because the -CLI itself links `internal/operatingsystem`, which `pkg-config`s -`gtk4 webkitgtk-6.0` under default tags. `go run -tags gtk3 -github.com/wailsapp/wails/v3/cmd/wails3` builds and runs fine -(`doctor` reports `-tags gtk3` and Webkit2Gtk v2.52.5), so that — not -`go tool wails3` — is the invocation the Makefile must use until -`sudo pacman -S webkitgtk-6.0` happens. Phase 0's claim that -"`wails3 doctor` reports both toolchains" was not true on this -machine. +**The v3 CLI needs the GTK4 toolchain to compile at all — not just the +app.** Before `webkitgtk-6.0` was installed, `go tool wails3` failed +outright, because the CLI links `internal/operatingsystem`, which +`pkg-config`s `gtk4 webkitgtk-6.0` under default tags. That is sharper +than the plan's "fallback if GTK4 misbehaves": the gtk3 fallback +covers the *app*, and reaching it meant building the CLI by hand with +`go run -tags gtk3 …/cmd/wails3`. + +Resolved — `webkitgtk-6.0` 2.52.5 and `gtk4` 4.22.4 are installed, and +`go tool wails3 doctor` now reports both toolchains with gtk3 and +webkit2gtk marked legacy, which is the state Phase 0 described. The +default (GTK4) path is what the migration targets; the gtk3 escape +hatch is recorded here only so the next person recognises the failure +if they meet it on a fresh machine. --- @@ -401,6 +407,57 @@ services callable, quit-during-writes still vetoes. **Est.** One session. This is the "1–4 hours" the official guide prices. +### Phase 2 — what actually landed + +The shape held, but four things differed from the plan. + +**`WebviewGpuPolicy` did not survive where the plan said it would.** +It is not on v3's `LinuxOptions` at all — it moved to `LinuxWindow`, +inside `WebviewWindowOptions`, so it is a per-window setting now. The +NVIDIA/Wayland `WEBKIT_DISABLE_DMABUF_RENDERER` workaround in +`main.go` is **kept**: v3's `operatingsystem` package detects the +driver, but nothing in it sets that variable, so removing ours would +have removed the fix. + +**There is no `OnStartup` or `OnDomReady` option.** Both are gone from +`application.Options`. The app-level wiring is driven from +`app.Event.OnApplicationEvent(events.Common.ApplicationStarted, …)`, +which fires after every service's `ServiceStartup`. That ordering is +what makes the split work: the services take their context from the +runtime, and `OnStartup` is left holding only the cross-service wiring +that belongs to no single service. + +**Ten services convert, not twelve.** `jobs.Registry` and +`explore.SearchIndex` have a `SetContext` too, but neither is bound — +the registry is wrapped by `jobs.NewService` and the index is internal +to `explore.Service` — so both keep it. Converting them would have +been churn for no binding removed. The ten that are bound now +implement `ServiceStartup`, and each therefore imports +`wails/v3/pkg/application`, which is a real cost: five files imported +wails before, fifteen do now. + +**`application.NewService` is generic over a concrete pointer type**, +so `FEBindings []any` could not survive as a slice of values — the +binding generator is a static analyser that reads those call sites, so +a `[]any` would have generated nothing at all. It is +`[]application.Service` built from explicit `NewService` calls. + +**The quit veto changed shape, and this is the part to test +deliberately.** v2's `MessageDialog` blocked and returned the button; +v3's `Show()` returns immediately and the answer arrives on a +`Button.OnClick` callback — on GTK4 `gtkDispatch` runs the dialog in a +goroutine. So `ShouldQuit` cannot ask and answer in one call. It +vetoes the quit, shows the dialog, and calls `app.Quit()` from the +callback if the user says quit; `quitConfirmed` is what stops that +second `Quit()` coming straight back and asking again, and +`quitAsking` stops a second close attempt stacking dialogs. + +**Window state moved off the quit path entirely.** It was `OnBeforeClose`'s +other job; it is now a `Common.WindowClosing` hook, because the size +has to be read while the window still exists and v3's `OnShutdown` +takes no context and no window. The sub-minimum guard is kept for the +reason it was written. + --- ## Phase 3 — Events @@ -451,6 +508,28 @@ push-driven views. **Est.** Half a session. +### Phase 3 — what actually landed + +Exactly as designed, and it is the migration's whole point: the +`ctx.Value("events")` probe of a **v2-private context key** is gone, +replaced by `application.Get() == nil`. D1 held — `events.Emit` keeps +its `ctx`, all 45 call sites and all 7 test files are untouched, and +one production file changed. + +Two adjustments. `Deliver` no longer rejects a nil context outright: +a nil context cannot carry a sink, but it is no longer a reason not to +deliver, because delivery does not go through the context any more. +And `TestNoDirectRuntimeEmits`'s needle moved from `.EventsEmit(` to +`.Event.Emit(` — the test is kept, but its justification is now the +weaker one written into its doc comment: not "a direct call can kill +the process" (v3's emit cannot), but "one emit path is what lets +`emitStatus` drop an unchanged payload for every caller at once". + +The six test files that called `SetContext` on a converted service now +call `ServiceStartup(ctx, application.ServiceOptions{})`. That is the +one place the plan's "zero test edits" ambition does not apply — it is +Phase 2's rename reaching the tests, not Phase 5's fake. + --- ## Phase 4 — Bindings diff --git a/Makefile b/Makefile index 55e45b2..bd0063e 100644 --- a/Makefile +++ b/Makefile @@ -8,10 +8,10 @@ LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' DEV_YJ_HOME ?= $(HOME)/.local/share/yellowjacket-dev dev: setup generate clean - if [ -f .env ]; then set -a; . ./.env; set +a; fi; : "$${YJ_HOME:=$(DEV_YJ_HOME)}"; export YJ_HOME; go tool wails dev -tags webkit2_41 -loglevel Debug -v 2 + if [ -f .env ]; then set -a; . ./.env; set +a; fi; : "$${YJ_HOME:=$(DEV_YJ_HOME)}"; export YJ_HOME; go tool wails3 dev -config ./build/config.yml dev-debug: setup generate clean - if [ -f .env ]; then set -a; . ./.env; set +a; fi; : "$${YJ_HOME:=$(DEV_YJ_HOME)}"; export YJ_HOME; YJ_LOG_LEVEL=debug go tool wails dev -tags webkit2_41 -loglevel Debug -v 2 + if [ -f .env ]; then set -a; . ./.env; set +a; fi; : "$${YJ_HOME:=$(DEV_YJ_HOME)}"; export YJ_HOME; YJ_LOG_LEVEL=debug go tool wails3 dev -config ./build/config.yml # ── Headless harness (plan 005) ────────────────────────────────────── # The same dev server `make dev` runs, minus the blocking GTK window: @@ -100,11 +100,15 @@ ui-visual-update: ## Re-record the screenshot baselines ui-setup: ## Install the Vitest browser provider's own Chromium (once) @cd frontend && pnpm install && npx playwright install chromium -# frontend/wailsjs is generated by `wails`, NOT by `go generate`, so the -# pre-commit codegen check does not cover it: a renamed Go struct field -# currently surfaces at runtime, in a window. File modes are ignored -# because `wails generate module` rewrites the runtime files as 755. -bindings-check: ## Fail if frontend/wailsjs is stale against the Go bindings +# Bindings are generated by `wails`, NOT by `go generate`, so the +# pre-commit codegen check does not cover them: a renamed Go struct +# field currently surfaces at runtime, in a window. +# +# NOTE (plan 009 phase 4): this still checks v2's frontend/wailsjs, +# which nothing regenerates now that the v2 CLI is gone. It is +# excluded from the pre-commit hook until the frontend moves to +# frontend/bindings. +bindings-check: ## Fail if the generated bindings are stale @./scripts/bindings-check.sh # A backtick inside a comment in a css`` literal ends the literal, and @@ -125,11 +129,17 @@ skill-check: ## Fail if .pi/ documents a make target that does not exist commit-check: ## Fail if a commit subject is not a Conventional Commit @./scripts/commit-check.sh $(if $(RANGE),--range $(RANGE)) -bindings: ## Regenerate frontend/wailsjs from the bound Go structs - go tool wails generate module -tags webkit2_41 - @chmod 644 frontend/wailsjs/runtime/runtime.js \ - frontend/wailsjs/runtime/runtime.d.ts \ - frontend/wailsjs/runtime/package.json +# v3 generates TypeScript into frontend/bindings/, nested by Go import +# path, rather than v2's frontend/wailsjs/. The 93 frontend import +# sites still point at the old tree, so this writes the new one beside +# it until plan 009 phase 4 moves them; the chmod dance that used to +# follow is gone with v2's generator, which wrote its runtime files 755. +# +# The tag set is pinned deliberately: the generator is a static +# analyser, so it only sees the configuration it is told about, and the +# one that matters is the one users run. +bindings: ## Regenerate frontend/bindings from the bound Go services + go tool wails3 generate bindings -clean=true -ts -i .PHONY: dev-headless dev-headless-fresh dev-stop dev-logs \ sandbox-seed sandbox-seed-bulk sandbox-seeds e2e e2e-setup e2e-report \ @@ -158,7 +168,7 @@ fresh-install: setup generate clean case "$$(findmnt -no FSTYPE -T "$$YJ_HOME" 2>/dev/null)" in \ tmpfs|ramfs) echo "==> WARNING: $$YJ_HOME is RAM-backed; the search index import needs ~6GB of real disk. Set FRESH_HOME_BASE to a disk-backed path." ;; \ esac; \ - go tool wails dev -tags webkit2_41 -loglevel Debug -v 2 + go tool wails3 dev -config ./build/config.yml # Named, persistent sandboxes: `make sandbox foo` runs dev against # $(FRESH_HOME_BASE)/yellowjacket-sandbox-foo, creating it on first use @@ -218,7 +228,7 @@ sandbox-%: setup generate clean case "$$(findmnt -no FSTYPE -T "$$YJ_HOME" 2>/dev/null)" in \ tmpfs|ramfs) echo "==> WARNING: $$YJ_HOME is RAM-backed; the search index import needs ~6GB of real disk. Set FRESH_HOME_BASE to a disk-backed path." ;; \ esac; \ - go tool wails dev -tags webkit2_41 -loglevel Debug -v 2 + go tool wails3 dev -config ./build/config.yml sandboxes: ## List existing named sandboxes @ls -d "$(SANDBOX_DIR)"-* 2>/dev/null \ @@ -228,10 +238,10 @@ sandboxes: ## List existing named sandboxes .PHONY: sandbox sandbox-rm sandboxes build-dev: generate - go tool wails build -tags webkit2_41 -debug -clean -ldflags "$(LDFLAGS)" + go tool wails3 task build DEV=true build-prod: generate - go tool wails build -tags webkit2_41 -clean -upx -ldflags "-s -w $(LDFLAGS)" + go tool wails3 task build build-frontend: cd frontend && pnpm install && pnpm build @@ -272,14 +282,16 @@ bulkdata-clean: ## Delete the bulk measurement library .PHONY: testdata testdata-force testdata-clean bulkdata bulkdata-clean # The tag sets must match `make test` exactly, or lint is checking three -# configurations that nothing builds. webkit2_41 is not optional: without -# it wails resolves webkit2gtk-4.0, which Ubuntu 24.04 no longer ships, so -# the `dev` pass (wails' own app_dev.go is dev-tagged and pulls in the 4.0 -# assetserver) fails to typecheck anywhere but Arch. +# configurations that nothing builds. The webkit2_41 tag these all used +# to carry is gone with v2: v3 builds against GTK4 + WebKitGTK 6.0 by +# default, which both Arch and ubuntu:24.04 ship, so the default tag set +# is the one that ships. (`-tags gtk3` still exists as an escape hatch +# for a machine without webkitgtk-6.0; it is not what CI or releases +# build.) lint: - go tool golangci-lint run --build-tags webkit2_41 - go tool golangci-lint run --build-tags "webkit2_41 indexbuild" - go tool golangci-lint run --build-tags "webkit2_41 dev" + go tool golangci-lint run + go tool golangci-lint run --build-tags indexbuild + go tool golangci-lint run --build-tags dev # Three passes: the app build, the `indexbuild` build that adds the # CI-only dump importer, and the `dev` build that adds profiling and @@ -287,12 +299,12 @@ lint: # exercise backend/explore/dump*.go, cmd/indexbuild or the harness # control surface at all. test: testdata - go test -tags webkit2_41 -race -count=1 -timeout 120s ./... - go test -tags "webkit2_41 indexbuild" -race -count=1 -timeout 300s \ + go test -race -count=1 -timeout 120s ./... + go test -tags indexbuild -race -count=1 -timeout 300s \ ./backend/explore/... ./cmd/... # backend/testctl only exists under the `dev` tag, so the pass above # does not compile it, let alone run it. - go test -tags "webkit2_41 dev" -race -count=1 -timeout 120s \ + go test -tags dev -race -count=1 -timeout 120s \ ./backend/testctl/... vulncheck: diff --git a/backend/app.go b/backend/app.go index 2ea2010..48ad648 100644 --- a/backend/app.go +++ b/backend/app.go @@ -10,9 +10,10 @@ import ( "log/slog" "net/http" "path/filepath" + "sync/atomic" "time" - wailsruntime "github.com/wailsapp/wails/v2/pkg/runtime" + "github.com/wailsapp/wails/v3/pkg/application" "yellowjacket/backend/assets" "yellowjacket/backend/autotagservice" @@ -39,7 +40,9 @@ import ( // YellowJacketApp is the main application struct for Wails. type YellowJacketApp struct { - FEBindings []any + // Services is what v3 binds to the frontend. Each entry's + // ServiceStartup runs before the app-level wiring in OnStartup. + Services []application.Service FrontendUtil *frontendutil.FrontendUtil logger *slog.Logger @@ -61,6 +64,12 @@ type YellowJacketApp struct { appContext context.Context appConfig *config.Config startupErr error + + // quitAsking guards the one quit-confirmation dialog; quitConfirmed + // records that the user already answered "quit anyway", so the + // Quit() issued from that callback is not questioned again. + quitAsking atomic.Bool + quitConfirmed atomic.Bool } // NewYellowJacketApp creates and initializes the application. @@ -211,26 +220,31 @@ func NewYellowJacketApp( ) } - yjApp.FEBindings = []any{ - yjApp.FrontendUtil, - yjApp.appConfig, - yjApp.library, - yjApp.playlist, - yjApp.queue, - yjApp.player, - yjApp.tagWriter, - yjApp.explore, - yjApp.autotag, - jobs.NewService(yjApp.jobs), - home.NewService( + // application.NewService is generic over a concrete pointer type — + // the static analyser that generates bindings reads these calls, so + // a []any of the same values would generate nothing. + yjApp.Services = []application.Service{ + application.NewService(yjApp.FrontendUtil), + application.NewService(yjApp.appConfig), + application.NewService(yjApp.library), + application.NewService(yjApp.playlist), + application.NewService(yjApp.queue), + application.NewService(yjApp.player), + application.NewService(yjApp.tagWriter), + application.NewService(yjApp.explore), + application.NewService(yjApp.autotag), + application.NewService(jobs.NewService(yjApp.jobs)), + application.NewService(home.NewService( yjApp.logger.WithGroup("home"), yjApp.database, yjApp.library, - ), + )), } if yjApp.downloadSvc != nil { - yjApp.FEBindings = append(yjApp.FEBindings, yjApp.downloadSvc) + yjApp.Services = append( + yjApp.Services, application.NewService(yjApp.downloadSvc), + ) } return yjApp, nil @@ -329,19 +343,18 @@ func (yj *YellowJacketApp) WindowConfig() *config.WindowConfig { return yj.appConfig.Window } -// OnStartup initializes components that require the Wails runtime context. +// OnStartup wires the services to each other once the runtime exists. +// +// It is no longer where each service *gets* the context: every bound +// service implements v3's ServiceStartup, which the runtime calls +// before this runs. What is left here is the cross-service wiring — +// hooks, adapters and the callbacks that make one package drive +// another — which has no home inside any single service. func (yj *YellowJacketApp) OnStartup(ctx context.Context) { defer profiling.TimeOp(yj.logger, "app.OnStartup")() - // initialize anything that needs to use the wails runtime AFTER its been initialized - // you CANNOT use the wails runtime during this function yj.appContext = ctx - // Set context for components that need Wails runtime for events - yj.appConfig.SetContext(ctx) - yj.FrontendUtil.SetContext(ctx) - yj.library.SetContext(ctx) - yj.playlist.SetContext(ctx) yj.playlist.EnsureDefaultPlaylist() // Recover playlists that lost tracks from a pre-fix FullRescan. go yj.playlist.RepopulateFromM3U() @@ -358,14 +371,11 @@ func (yj *YellowJacketApp) OnStartup(ctx context.Context) { ) } - yj.player.SetContext(ctx) - yj.tagWriter.SetContext(ctx) - yj.explore.SetContext(ctx) - yj.autotag.SetContext(ctx) + // The job registry is not a bound service — it is wrapped by + // jobs.NewService for that — so it still takes the context by hand. yj.jobs.SetContext(ctx) if yj.downloadSvc != nil { - yj.downloadSvc.SetContext(ctx) yj.initDownloadRuntime(ctx) } @@ -375,8 +385,6 @@ func (yj *YellowJacketApp) OnStartup(ctx context.Context) { yj.library.RestorePausedScans() yj.explore.AdoptPausedIndexBuild() - // Wire queue (created in NewYellowJacketApp for Wails binding) - yj.queue.SetContext(ctx) yj.queue.SetPlayer(yj.player) yj.queue.SetFallbackSource(&queueFallbackAdapter{ config: yj.appConfig, @@ -515,37 +523,32 @@ func (yj *YellowJacketApp) OnStartup(ctx context.Context) { yj.player.SetMediaControls(yj.mediaControls) } -// OnBeforeClose captures window state while the window is still alive, -// and asks first when quitting would abandon a job that is writing to -// the user's files. -// -// Returning true keeps the window open. Quitting mid-apply cancels the -// service context and leaves a folder half-retagged with nothing -// recording where it stopped (errors.p4), which is the one case worth -// interrupting a quit for. -func (yj *YellowJacketApp) OnBeforeClose(ctx context.Context) bool { - if yj.confirmQuitDuringWrites(ctx) { - return true +// SaveWindowState captures the window's size while the window is still +// alive. It is registered on the WindowClosing event, because at +// shutdown there is no window left to measure. +func (yj *YellowJacketApp) SaveWindowState(window application.Window) { + if window == nil { + return } - w, h := wailsruntime.WindowGetSize(ctx) + w, h := window.Size() // Guard against a bogus size clobbering a good saved one. During // teardown / hot-reload the runtime can report a zero or below- // minimum size; persisting that would shrink the window to the // minimum on next launch. Keep the previously-saved size instead. if w < config.MinWidth || h < config.MinHeight { - yj.logger.Warn("OnBeforeClose: ignoring bogus window size", + yj.logger.Warn("window close: ignoring bogus window size", "width", w, "height", h, "kept_width", yj.appConfig.Window.Width, "kept_height", yj.appConfig.Window.Height, ) - return false + return } - yj.logger.Info("OnBeforeClose: saving window state", + yj.logger.Info("window close: saving window state", "width", w, "height", h, "accentColor", yj.appConfig.Theme.AccentColor, @@ -561,39 +564,69 @@ func (yj *YellowJacketApp) OnBeforeClose(ctx context.Context) bool { "err", err, ) } +} + +// ShouldQuit answers v3's quit veto: false keeps the app running. +// +// Quitting mid-apply cancels the service context and leaves a folder +// half-retagged with nothing recording where it stopped (errors.p4), +// which is the one case worth interrupting a quit for. +// +// The shape differs from v2's OnBeforeClose because v3's dialog is +// asynchronous — Show() returns immediately and the answer arrives on +// a button callback — so this cannot ask and answer in one call. It +// vetoes the quit, asks, and quits again from the callback if the user +// says so. quitConfirmed is what stops that second Quit() coming +// straight back here and asking a second time. +func (yj *YellowJacketApp) ShouldQuit() bool { + if yj.quitConfirmed.Load() { + return true + } + + if yj.autotag == nil || !yj.autotag.WritesInFlight() { + return true + } + + // A dialog already up must not spawn another on every close attempt. + if !yj.quitAsking.CompareAndSwap(false, true) { + return false + } + + app := application.Get() + if app == nil { + // No runtime to ask through: never trap the user in the app. + return true + } + + dialog := app.Dialog.Question() + dialog.SetTitle("Tags are still being written") + dialog.SetMessage( + "YellowJacket is rewriting tags on your files. " + + "Quitting now leaves that folder holding a mix of old and " + + "new tags.\n\nQuit anyway?", + ) + + quit := dialog.AddButton("Quit anyway") + quit.OnClick(func() { + yj.quitConfirmed.Store(true) + yj.quitAsking.Store(false) + app.Quit() + }) + + stay := dialog.AddButton("Keep writing") + stay.OnClick(func() { yj.quitAsking.Store(false) }) + stay.SetAsDefault() + stay.SetAsCancel() + + dialog.Show() return false } -// confirmQuitDuringWrites returns true when the user chose to stay. -// A dialog that cannot be shown is not allowed to trap anyone in the -// app, so any error here quits. -func (yj *YellowJacketApp) confirmQuitDuringWrites(ctx context.Context) bool { - if yj.autotag == nil || !yj.autotag.WritesInFlight() { - return false - } - - answer, err := wailsruntime.MessageDialog(ctx, wailsruntime.MessageDialogOptions{ - Type: wailsruntime.QuestionDialog, - Title: "Tags are still being written", - Message: "YellowJacket is rewriting tags on your files. " + - "Quitting now leaves that folder holding a mix of old and " + - "new tags.\n\nQuit anyway?", - Buttons: []string{"Quit anyway", "Keep writing"}, - DefaultButton: "Keep writing", - CancelButton: "Keep writing", - }) - if err != nil { - yj.logger.Warn("could not ask about quitting mid-write", "err", err) - - return false - } - - return answer == "Keep writing" || answer == "No" -} - -// OnShutdown saves player state and cleans up resources before the application exits. -func (yj *YellowJacketApp) OnShutdown(_ context.Context) { +// OnShutdown saves player state and cleans up resources before the +// application exits. v3 passes no context — the app is going away, so +// there is nothing left to scope work to. +func (yj *YellowJacketApp) OnShutdown() { if yj.player != nil { yj.player.SaveState() } @@ -612,10 +645,17 @@ func (yj *YellowJacketApp) OnShutdown(_ context.Context) { // driven by the frontend: once its stores have registered their event // listeners, index.ts calls Player.EmitCurrentState() and // Queue.EmitCurrentState() via Wails bindings. -func (yj *YellowJacketApp) OnDomReady(ctx context.Context) { +func (yj *YellowJacketApp) OnDomReady(_ context.Context) { if yj.startupErr != nil { yj.logger.Error("startup error", "err", yj.startupErr.Error()) - wailsruntime.Quit(ctx) + + // A startup failure is not a mid-write quit, so go straight out + // rather than through the ShouldQuit question. + yj.quitConfirmed.Store(true) + + if app := application.Get(); app != nil { + app.Quit() + } return } diff --git a/backend/assets/handler.go b/backend/assets/handler.go index abd5cf9..383b4e3 100644 --- a/backend/assets/handler.go +++ b/backend/assets/handler.go @@ -3,15 +3,22 @@ package assets import ( "embed" + "fmt" + "io/fs" "log/slog" "net/http" - "github.com/wailsapp/wails/v2/pkg/options/assetserver" + "github.com/wailsapp/wails/v3/pkg/application" ) +// distRoot is where the frontend build lands inside the embedded FS. +// v2 knew this prefix itself; v3 takes an fs.FS rooted at the assets, +// so the sub-FS is taken here. +const distRoot = "frontend/dist" + // Handler serves frontend assets with custom route support. type Handler struct { - Options *assetserver.Options + Options application.AssetOptions logger *slog.Logger frontendDistAssets embed.FS serveMux *http.ServeMux @@ -25,8 +32,16 @@ func NewAssetHandler(logger *slog.Logger, frontendDistAssets embed.FS) (*Handler frontendDistAssets: frontendDistAssets, serveMux: http.NewServeMux(), } - handler.Options = &assetserver.Options{ - Assets: handler.frontendDistAssets, + + dist, err := fs.Sub(frontendDistAssets, distRoot) + if err != nil { + return nil, fmt.Errorf( + "could not open %s in the embedded assets: %w", distRoot, err, + ) + } + + handler.Options = application.AssetOptions{ + Handler: application.AssetFileServerFS(dist), Middleware: handler.Middleware, } diff --git a/backend/autotagservice/service.go b/backend/autotagservice/service.go index 13f7e6a..aa6b1be 100644 --- a/backend/autotagservice/service.go +++ b/backend/autotagservice/service.go @@ -19,6 +19,8 @@ import ( "sync" "time" + "github.com/wailsapp/wails/v3/pkg/application" + "yellowjacket/backend/autotag" "yellowjacket/backend/database" "yellowjacket/backend/database/sql/sqlcgen" @@ -199,13 +201,20 @@ func NewService( } } -// SetContext stores the Wails runtime context (called from -// OnStartup). -func (s *Service) SetContext(ctx context.Context) { +// ServiceStartup is v3's service lifecycle hook: it runs once the +// runtime exists, and ctx is cancelled when the app shuts down. It +// replaces v2's SetContext, which had to be called by hand from +// OnStartup and was exported, so it was also bound to the frontend. +func (s *Service) ServiceStartup( + ctx context.Context, + _ application.ServiceOptions, +) error { s.mu.Lock() defer s.mu.Unlock() s.ctx = ctx + + return nil } // emitEvent emits a Wails runtime event under the service lock, which diff --git a/backend/config/config.go b/backend/config/config.go index dbba7a0..c178ccb 100644 --- a/backend/config/config.go +++ b/backend/config/config.go @@ -10,6 +10,7 @@ import ( "path" "github.com/BurntSushi/toml" + "github.com/wailsapp/wails/v3/pkg/application" "yellowjacket/backend/download" "yellowjacket/backend/events" @@ -280,9 +281,17 @@ func (c *Config) applyDefaults() { c.Downloads.ApplyDefaults() } -// SetContext sets the Wails runtime context for event emission. -func (c *Config) SetContext(ctx context.Context) { +// ServiceStartup is v3's service lifecycle hook: it runs once the +// runtime exists, and ctx is cancelled when the app shuts down. It +// replaces v2's SetContext, which had to be called by hand from +// OnStartup and was exported, so it was also bound to the frontend. +func (c *Config) ServiceStartup( + ctx context.Context, + _ application.ServiceOptions, +) error { c.ctx = ctx + + return nil } // GetLibraryDirectory returns the currently configured library directory path. diff --git a/backend/config/emit_test.go b/backend/config/emit_test.go index c2099f1..8aeb5e0 100644 --- a/backend/config/emit_test.go +++ b/backend/config/emit_test.go @@ -6,6 +6,8 @@ import ( "path/filepath" "testing" + "github.com/wailsapp/wails/v3/pkg/application" + "yellowjacket/backend/events" ) @@ -28,7 +30,10 @@ func setupRecordedConfig(t *testing.T) (*Config, *events.Recorder) { } rec := events.NewRecorder() - conf.SetContext(events.WithSink(context.Background(), rec)) + _ = conf.ServiceStartup( + events.WithSink(context.Background(), rec), + application.ServiceOptions{}, + ) return conf, rec } diff --git a/backend/download/service.go b/backend/download/service.go index a350be8..18752aa 100644 --- a/backend/download/service.go +++ b/backend/download/service.go @@ -7,6 +7,8 @@ import ( "log/slog" "strconv" + "github.com/wailsapp/wails/v3/pkg/application" + "yellowjacket/backend/events" ) @@ -47,9 +49,17 @@ func NewService( } } -// SetContext injects the Wails runtime context for event emission. -func (s *Service) SetContext(ctx context.Context) { +// ServiceStartup is v3's service lifecycle hook: it runs once the +// runtime exists, and ctx is cancelled when the app shuts down. It +// replaces v2's SetContext, which had to be called by hand from +// OnStartup and was exported, so it was also bound to the frontend. +func (s *Service) ServiceStartup( + ctx context.Context, + _ application.ServiceOptions, +) error { s.ctx = ctx + + return nil } // emit publishes an event, tolerating a service that has no runtime diff --git a/backend/events/emit.go b/backend/events/emit.go index 25ee01a..6c0d5be 100644 --- a/backend/events/emit.go +++ b/backend/events/emit.go @@ -5,11 +5,11 @@ import ( "errors" "log/slog" - "github.com/wailsapp/wails/v2/pkg/runtime" + "github.com/wailsapp/wails/v3/pkg/application" ) -// ErrNoRuntime is returned by Deliver when the context carries neither -// a test Sink nor a live Wails runtime, so the event went nowhere. +// ErrNoRuntime is returned by Deliver when there is neither a test Sink +// in the context nor a running application, so the event went nowhere. var ErrNoRuntime = errors.New( "no Wails runtime or event sink in context", ) @@ -46,14 +46,16 @@ func sinkFrom(ctx context.Context) Sink { // Emit publishes a Wails event, tolerating any context. // // This is the only supported way to emit an event: nothing outside this -// package may call runtime.EventsEmit, which TestNoDirectEventsEmit -// enforces. +// package may call app.Event.Emit, which TestNoDirectRuntimeEmits +// enforces. That rule outlived its original reason — v2's +// runtime.EventsEmit called log.Fatalf on a context that did not carry +// the runtime, taking the process down from any background worker — +// and is kept because one emit path is what keeps emitStatus-style +// deduplication honest. // -// runtime.EventsEmit calls log.Fatalf when the context is nil or lacks -// the runtime's "events" value, terminating the process rather than -// returning an error. Background workers that outlive a context, and -// any test that constructs a service directly, both hit that path — so -// an event with nowhere to go is dropped and logged here instead. +// The context is no longer a delivery mechanism: v3's emit takes none. +// It stays because WithSink travels in it, which is what makes a +// service that emits events testable in-process. func Emit(ctx context.Context, name string, data ...any) { if err := Deliver(ctx, name, data...); err != nil { slog.Default().Debug( @@ -70,21 +72,26 @@ func Emit(ctx context.Context, name string, data ...any) { // // Ordinary emitters want Emit. func Deliver(ctx context.Context, name string, data ...any) error { - if ctx == nil { + // A nil context cannot carry a sink, but it is no longer a reason + // not to deliver: v3 emits through the application, not the context. + if ctx != nil { + if sink := sinkFrom(ctx); sink != nil { + sink.Emit(name, data...) + + return nil + } + } + + // application.Get() returns nil when no app is running — under test, + // before Run, and after shutdown. It does not terminate the + // process, which is what the v2 probe of the private "events" + // context key existed to avoid. + app := application.Get() + if app == nil { return ErrNoRuntime } - if sink := sinkFrom(ctx); sink != nil { - sink.Emit(name, data...) - - return nil - } - - if ctx.Value("events") == nil { - return ErrNoRuntime - } - - runtime.EventsEmit(ctx, name, data...) + app.Event.Emit(name, data...) return nil } diff --git a/backend/events/noemit_test.go b/backend/events/noemit_test.go index d3ce57c..2498765 100644 --- a/backend/events/noemit_test.go +++ b/backend/events/noemit_test.go @@ -16,6 +16,13 @@ var allowedEmitters = map[string]bool{ // TestNoDirectRuntimeEmits fails if anything outside backend/events // calls the Wails runtime's event emitter directly. // +// The original reason was survival: v2's runtime.EventsEmit called +// log.Fatalf on a context that did not carry the runtime, so a direct +// call from a background worker could take the process down. v3's +// emit takes no context and cannot do that, and the rule is kept for +// the weaker but still real reason — one emit path is what lets +// emitStatus drop an unchanged payload for every caller at once. +// // This is a text walk rather than a golangci-lint rule because // golangci-lint runs once per build configuration, so a call in an // indexbuild- or dev-tagged file is only seen by the pass that compiles @@ -23,10 +30,11 @@ var allowedEmitters = map[string]bool{ // entirely. func TestNoDirectRuntimeEmits(t *testing.T) { // A selector, not a bare name: built at runtime so this file does - // not match itself, and qualified so it catches every import alias - // the tree uses (plain runtime., and wailsruntime.) without also - // matching an identifier that merely ends in the same letters. - needle := ".Events" + "Emit(" + // not match itself, and qualified so it catches the call however + // the application value is named (app.Event.Emit, a.Event.Emit, + // application.Get().Event.Emit) without matching an identifier + // that merely ends in the same letters. + needle := ".Event" + ".Emit(" root := filepath.Join("..", "..") diff --git a/backend/explore/explore.go b/backend/explore/explore.go index 526a0cf..56b229f 100644 --- a/backend/explore/explore.go +++ b/backend/explore/explore.go @@ -9,6 +9,7 @@ import ( "sync" "time" + "github.com/wailsapp/wails/v3/pkg/application" "golang.org/x/sync/singleflight" "yellowjacket/backend/database" @@ -139,11 +140,18 @@ func (e *Service) CAALimiter() *RateLimiter { return e.caaLimiter } -// SetContext injects the Wails runtime context. Called from -// OnStartup after the Wails runtime is initialised. -func (e *Service) SetContext(ctx context.Context) { +// ServiceStartup is v3's service lifecycle hook: it runs once the +// runtime exists, and ctx is cancelled when the app shuts down. It +// replaces v2's SetContext, which had to be called by hand from +// OnStartup and was exported, so it was also bound to the frontend. +func (e *Service) ServiceStartup( + ctx context.Context, + _ application.ServiceOptions, +) error { e.ctx = ctx e.index.SetContext(ctx) + + return nil } // StartIndexBuild kicks off the background search index build. diff --git a/backend/frontendutil/frontendutil.go b/backend/frontendutil/frontendutil.go index 4ec6752..f00ed56 100644 --- a/backend/frontendutil/frontendutil.go +++ b/backend/frontendutil/frontendutil.go @@ -3,12 +3,18 @@ package frontendutil import ( "context" + "errors" "fmt" + "log/slog" "os" - "github.com/wailsapp/wails/v2/pkg/runtime" + "github.com/wailsapp/wails/v3/pkg/application" ) +// ErrNoRuntime is returned when a dialog is asked for with no running +// application to parent it to — under test, or after shutdown. +var ErrNoRuntime = errors.New("no Wails runtime to show a dialog") + // FrontendUtil provides frontend-bound Go functions. type FrontendUtil struct { ctx context.Context @@ -19,18 +25,35 @@ func NewFrontendUtil() (*FrontendUtil, error) { return &FrontendUtil{}, nil } -// SetContext sets the Wails runtime context. -func (fe *FrontendUtil) SetContext(ctx context.Context) { +// ServiceStartup is v3's service lifecycle hook: it runs once the +// runtime exists, and ctx is cancelled when the app shuts down. It +// replaces v2's SetContext, which had to be called by hand from +// OnStartup and was exported, so it was also bound to the frontend. +func (fe *FrontendUtil) ServiceStartup( + ctx context.Context, + _ application.ServiceOptions, +) error { fe.ctx = ctx + + return nil } // DirectoryPicker opens a directory selection dialog. +// +// v3 has no separate directory dialog: it is the file dialog told to +// choose directories and not files. func (fe *FrontendUtil) DirectoryPicker() (string, error) { - runtime.LogInfo(fe.ctx, "selecting a directory") + app := application.Get() + if app == nil { + return "", ErrNoRuntime + } - dir, err := runtime.OpenDirectoryDialog( - fe.ctx, - runtime.OpenDialogOptions{}) + slog.Default().Info("selecting a directory") + + dir, err := app.Dialog.OpenFile(). + CanChooseDirectories(true). + CanChooseFiles(false). + PromptForSingleSelection() if err != nil { return "", fmt.Errorf( "could not open directory dialog\n%w", err, @@ -46,20 +69,17 @@ func (fe *FrontendUtil) PlaylistFilePicker() ( []string, error, ) { - runtime.LogInfo(fe.ctx, "selecting playlist files") + app := application.Get() + if app == nil { + return nil, ErrNoRuntime + } - files, err := runtime.OpenMultipleFilesDialog( - fe.ctx, - runtime.OpenDialogOptions{ - Title: "Import Playlist", - Filters: []runtime.FileFilter{ - { - DisplayName: "Playlist Files (*.m3u, *.m3u8)", - Pattern: "*.m3u;*.m3u8", - }, - }, - }, - ) + slog.Default().Info("selecting playlist files") + + files, err := app.Dialog.OpenFile(). + SetTitle("Import Playlist"). + AddFilter("Playlist Files (*.m3u, *.m3u8)", "*.m3u;*.m3u8"). + PromptForMultipleSelection() if err != nil { return nil, fmt.Errorf( "could not open file dialog: %w", err, @@ -73,18 +93,15 @@ func (fe *FrontendUtil) PlaylistFilePicker() ( // files (JPEG, PNG). Returns the selected file path, or empty // string if the user cancelled. func (fe *FrontendUtil) ImageFilePicker() (string, error) { - file, err := runtime.OpenFileDialog( - fe.ctx, - runtime.OpenDialogOptions{ - Title: "Select Cover Art", - Filters: []runtime.FileFilter{ - { - DisplayName: "Image Files (*.jpg, *.jpeg, *.png)", - Pattern: "*.jpg;*.jpeg;*.png", - }, - }, - }, - ) + app := application.Get() + if app == nil { + return "", ErrNoRuntime + } + + file, err := app.Dialog.OpenFile(). + SetTitle("Select Cover Art"). + AddFilter("Image Files (*.jpg, *.jpeg, *.png)", "*.jpg;*.jpeg;*.png"). + PromptForSingleSelection() if err != nil { return "", fmt.Errorf("could not open file dialog: %w", err) } diff --git a/backend/library/library.go b/backend/library/library.go index 333535c..5b7cd98 100644 --- a/backend/library/library.go +++ b/backend/library/library.go @@ -16,6 +16,7 @@ import ( "sync/atomic" "time" + "github.com/wailsapp/wails/v3/pkg/application" "golang.org/x/sync/errgroup" "yellowjacket/backend/autotag" @@ -183,13 +184,21 @@ func (l *Library) AcquirePipelineLock() { l.pipelineMu.Lock() } // ReleasePipelineLock releases the pipeline mutex after a tag write. func (l *Library) ReleasePipelineLock() { l.pipelineMu.Unlock() } -// SetContext sets the Wails runtime context and registers event handlers. -func (l *Library) SetContext(ctx context.Context) { +// ServiceStartup is v3's service lifecycle hook: it runs once the +// runtime exists, and ctx is cancelled when the app shuts down. It +// replaces v2's SetContext, which had to be called by hand from +// OnStartup and was exported, so it was also bound to the frontend. +func (l *Library) ServiceStartup( + ctx context.Context, + _ application.ServiceOptions, +) error { l.mu.Lock() l.ctx = ctx l.mu.Unlock() l.registerEventHandlers() + + return nil } // emit publishes a Wails event under the library lock, which the diff --git a/backend/logging/logging.go b/backend/logging/logging.go deleted file mode 100644 index 46bedaa..0000000 --- a/backend/logging/logging.go +++ /dev/null @@ -1,94 +0,0 @@ -// Package logging provides a slog-based logger adapter for Wails. -package logging - -import ( - "fmt" - "log/slog" - "strings" -) - -// Logger wraps slog to implement the Wails logger interface. -type Logger struct { - slogger *slog.Logger - moduleFilters []string -} - -// NewLogger creates a logger with optional message filters. -func NewLogger(slogger *slog.Logger, filters []string) *Logger { - return &Logger{ - slogger: slogger, - moduleFilters: filters, - } -} - -// Print outputs a message if not filtered. -func (l *Logger) Print(message string) { - if l.isFilteredOut(message) { - return - } - - fmt.Printf("[Print] %s\n", message) -} - -// Trace logs a trace-level message if not filtered. -func (l *Logger) Trace(message string) { - if l.isFilteredOut(message) { - return - } - - l.slogger.Debug("[Trace] " + message) -} - -// Debug logs a debug-level message if not filtered. -func (l *Logger) Debug(message string) { - if l.isFilteredOut(message) { - return - } - - l.slogger.Debug(message) -} - -// Info logs an info-level message if not filtered. -func (l *Logger) Info(message string) { - if l.isFilteredOut(message) { - return - } - - l.slogger.Info(message) -} - -// Warning logs a warning-level message if not filtered. -func (l *Logger) Warning(message string) { - if l.isFilteredOut(message) { - return - } - - l.slogger.Warn(message) -} - -func (l *Logger) Error(message string) { - if l.isFilteredOut(message) { - return - } - - l.slogger.Error(message) -} - -// Fatal logs a fatal-level message if not filtered. -func (l *Logger) Fatal(message string) { - if l.isFilteredOut(message) { - return - } - - l.slogger.Error("[Trace] " + message) -} - -func (l *Logger) isFilteredOut(message string) bool { - for _, f := range l.moduleFilters { - if strings.HasPrefix(message, fmt.Sprintf("[%s]", f)) { - return true - } - } - - return false -} diff --git a/backend/player/emit_test.go b/backend/player/emit_test.go index d677afb..a30717a 100644 --- a/backend/player/emit_test.go +++ b/backend/player/emit_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/wailsapp/wails/v3/pkg/application" + "yellowjacket/backend/events" ) @@ -17,7 +19,7 @@ func recordedPlayer(t *testing.T) (*Player, *events.Recorder) { p := NewPlayer(slog.Default(), nil) rec := events.NewRecorder() - p.SetContext(events.WithSink(t.Context(), rec)) + _ = p.ServiceStartup(events.WithSink(t.Context(), rec), application.ServiceOptions{}) return p, rec } diff --git a/backend/player/player.go b/backend/player/player.go index 3c29718..400135c 100644 --- a/backend/player/player.go +++ b/backend/player/player.go @@ -16,6 +16,7 @@ import ( "github.com/gopxl/beep/v2/effects" "github.com/gopxl/beep/v2/generators" "github.com/gopxl/beep/v2/speaker" + "github.com/wailsapp/wails/v3/pkg/application" "yellowjacket/backend/coverart" "yellowjacket/backend/database" @@ -191,15 +192,22 @@ func (p *Player) SetMediaControls(h mediacontrols.Handler) { p.mediaControls = h } -// SetContext sets the Wails runtime context and restores persisted -// state. -func (p *Player) SetContext(ctx context.Context) { +// ServiceStartup is v3's service lifecycle hook: it runs once the +// runtime exists, and ctx is cancelled when the app shuts down. It +// replaces v2's SetContext, which had to be called by hand from +// OnStartup and was exported, so it was also bound to the frontend. +func (p *Player) ServiceStartup( + ctx context.Context, + _ application.ServiceOptions, +) error { p.mu.Lock() defer p.mu.Unlock() p.ctx = ctx p.restoreStateLocked() p.startPositionTicker() + + return nil } // positionTickInterval is how often the backend reports its own diff --git a/backend/player/player_test.go b/backend/player/player_test.go index 078ca57..0f6a149 100644 --- a/backend/player/player_test.go +++ b/backend/player/player_test.go @@ -5,6 +5,8 @@ import ( "os" "testing" + "github.com/wailsapp/wails/v3/pkg/application" + "yellowjacket/internal/testfixtures" ) @@ -40,7 +42,7 @@ func TestPlayer(t *testing.T) { } // SetContext restores persisted state; only works with a real Wails context. - p.SetContext(t.Context()) + _ = p.ServiceStartup(t.Context(), application.ServiceOptions{}) t.Logf("initializing player") for _, track := range testQueue { diff --git a/backend/playlist/emit_test.go b/backend/playlist/emit_test.go index f1b49d0..1cf6399 100644 --- a/backend/playlist/emit_test.go +++ b/backend/playlist/emit_test.go @@ -6,6 +6,8 @@ import ( "log/slog" "testing" + "github.com/wailsapp/wails/v3/pkg/application" + "yellowjacket/backend/database" "yellowjacket/backend/events" ) @@ -30,7 +32,7 @@ func setupRecordedService( svc.dataDirOverride = t.TempDir() rec := events.NewRecorder() - svc.SetContext(events.WithSink(context.Background(), rec)) + _ = svc.ServiceStartup(events.WithSink(context.Background(), rec), application.ServiceOptions{}) return svc, db, rec } diff --git a/backend/playlist/playlist.go b/backend/playlist/playlist.go index e522f8d..526381f 100644 --- a/backend/playlist/playlist.go +++ b/backend/playlist/playlist.go @@ -15,6 +15,8 @@ import ( "sync" "time" + "github.com/wailsapp/wails/v3/pkg/application" + "yellowjacket/backend/coverart" "yellowjacket/backend/database" "yellowjacket/backend/database/sql/sqlcgen" @@ -161,15 +163,21 @@ func (s *Service) SetFavoritesConfig( s.favoritesConf = provider } -// SetContext sets the Wails runtime context and runs the -// one-time startup migration to bootstrap M3U8 files for -// existing playlists. -func (s *Service) SetContext(ctx context.Context) { +// ServiceStartup is v3's service lifecycle hook: it runs once the +// runtime exists, and ctx is cancelled when the app shuts down. It +// replaces v2's SetContext, which had to be called by hand from +// OnStartup and was exported, so it was also bound to the frontend. +func (s *Service) ServiceStartup( + ctx context.Context, + _ application.ServiceOptions, +) error { s.mu.Lock() s.ctx = ctx s.mu.Unlock() s.migrateExistingPlaylists() + + return nil } // GetAllPlaylists returns all playlists ordered by most recently diff --git a/backend/queue/emit_test.go b/backend/queue/emit_test.go index a3db95a..4e7a978 100644 --- a/backend/queue/emit_test.go +++ b/backend/queue/emit_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/wailsapp/wails/v3/pkg/application" + "yellowjacket/backend/database" "yellowjacket/backend/events" ) @@ -29,7 +31,7 @@ func setupRecordedQueue(t *testing.T) (*Queue, *database.DB, *events.Recorder) { q.SetPlayer(&mockTrackLoader{}) rec := events.NewRecorder() - q.SetContext(events.WithSink(context.Background(), rec)) + _ = q.ServiceStartup(events.WithSink(context.Background(), rec), application.ServiceOptions{}) return q, db, rec } diff --git a/backend/queue/playbackfailed_test.go b/backend/queue/playbackfailed_test.go index b6ac48c..3ad8179 100644 --- a/backend/queue/playbackfailed_test.go +++ b/backend/queue/playbackfailed_test.go @@ -6,6 +6,8 @@ import ( "log/slog" "testing" + "github.com/wailsapp/wails/v3/pkg/application" + "yellowjacket/backend/database" "yellowjacket/backend/events" ) @@ -44,7 +46,7 @@ func setupFailingQueue( q.SetPlayer(loader) rec := events.NewRecorder() - q.SetContext(events.WithSink(context.Background(), rec)) + _ = q.ServiceStartup(events.WithSink(context.Background(), rec), application.ServiceOptions{}) return q, db, rec, loader } diff --git a/backend/queue/queue.go b/backend/queue/queue.go index f141550..29af07d 100644 --- a/backend/queue/queue.go +++ b/backend/queue/queue.go @@ -8,6 +8,8 @@ import ( "sync" "sync/atomic" + "github.com/wailsapp/wails/v3/pkg/application" + "yellowjacket/backend/coverart" "yellowjacket/backend/database" "yellowjacket/backend/profiling" @@ -198,12 +200,20 @@ func NewQueue(logger *slog.Logger, db *database.DB) *Queue { } } -// SetContext sets the Wails runtime context for event emission. -func (q *Queue) SetContext(ctx context.Context) { +// ServiceStartup is v3's service lifecycle hook: it runs once the +// runtime exists, and ctx is cancelled when the app shuts down. It +// replaces v2's SetContext, which had to be called by hand from +// OnStartup and was exported, so it was also bound to the frontend. +func (q *Queue) ServiceStartup( + ctx context.Context, + _ application.ServiceOptions, +) error { q.mu.Lock() defer q.mu.Unlock() q.ctx = ctx + + return nil } // SetPlayer provides the queue with a reference to the player for auto-advance. diff --git a/backend/tagwriter/pipeline.go b/backend/tagwriter/pipeline.go index 5d6e4f2..658f116 100644 --- a/backend/tagwriter/pipeline.go +++ b/backend/tagwriter/pipeline.go @@ -7,6 +7,8 @@ import ( "log/slog" "time" + "github.com/wailsapp/wails/v3/pkg/application" + "yellowjacket/backend/database" "yellowjacket/backend/events" ) @@ -76,10 +78,17 @@ func NewTagWriter( } } -// SetContext stores the Wails runtime context for event emission. -// Called during the two-phase init pattern in OnStartup. -func (tw *TagWriter) SetContext(ctx context.Context) { +// ServiceStartup is v3's service lifecycle hook: it runs once the +// runtime exists, and ctx is cancelled when the app shuts down. It +// replaces v2's SetContext, which had to be called by hand from +// OnStartup and was exported, so it was also bound to the frontend. +func (tw *TagWriter) ServiceStartup( + ctx context.Context, + _ application.ServiceOptions, +) error { tw.ctx = ctx + + return nil } // WriteTrackTags is the single entry point for writing metadata to diff --git a/go.mod b/go.mod index c7db38e..17bcf03 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gopxl/beep/v2 v2.1.1 github.com/klauspost/compress v1.18.3 github.com/parquet-go/parquet-go v0.30.1 - github.com/wailsapp/wails/v2 v2.10.2 + github.com/wailsapp/wails/v3 v3.0.0-beta.8 go.uploadedlobster.com/mbtypes v0.4.0 go.uploadedlobster.com/musicbrainzws2 v0.18.0 golang.org/x/image v0.41.0 @@ -53,16 +53,14 @@ require ( github.com/Ladicle/tabwriter v1.0.0 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/MirrexOne/unqueryvet v1.5.3 // indirect github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect github.com/ProtonMail/go-crypto v1.3.0 // indirect - github.com/StackExchange/wmi v1.2.1 // indirect github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect - github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect + github.com/adrg/xdg v0.5.3 // indirect github.com/alecthomas/chroma/v2 v2.23.1 // indirect github.com/alecthomas/go-check-sumtype v0.3.1 // indirect github.com/alessio/shellescape v1.4.1 // indirect @@ -80,7 +78,6 @@ require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bep/debounce v1.2.1 // indirect github.com/bkielbasa/cyclop v1.2.3 // indirect github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect @@ -116,6 +113,7 @@ require ( github.com/clipperhouse/stringish v0.1.1 // indirect github.com/clipperhouse/uax29/v2 v2.4.0 // indirect github.com/cloudflare/circl v1.6.3 // indirect + github.com/coder/websocket v1.8.14 // indirect github.com/containerd/console v1.0.5 // indirect github.com/creack/pty v1.1.24 // indirect github.com/cubicdaiya/gonp v1.0.4 // indirect @@ -138,7 +136,6 @@ require ( github.com/fatih/color v1.18.0 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/firefart/nonamedreturns v1.0.6 // indirect - github.com/flytam/filenamify v1.2.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.12 // indirect @@ -182,14 +179,12 @@ require ( github.com/google/cel-go v0.26.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/rpmpack v0.7.1 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/gookit/color v1.6.0 // indirect github.com/gordonklaus/ineffassign v0.2.0 // indirect github.com/goreleaser/chglog v0.7.4 // indirect github.com/goreleaser/fileglob v1.4.0 // indirect github.com/goreleaser/nfpm/v2 v2.44.1 // indirect github.com/gorilla/css v1.0.1 // indirect - github.com/gorilla/websocket v1.5.3 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.5.0 // indirect github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect @@ -198,7 +193,6 @@ require ( github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect github.com/hashicorp/go-version v1.8.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect github.com/huandu/xstrings v1.5.0 // indirect github.com/icza/bitio v1.1.0 // indirect @@ -207,7 +201,6 @@ require ( github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgx/v5 v5.7.5 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/jackmordaunt/icns v1.0.0 // indirect github.com/jackmordaunt/icns/v2 v2.2.7 // indirect github.com/jaypipes/ghw v0.21.3 // indirect github.com/jaypipes/pcidb v1.1.1 // indirect @@ -241,8 +234,6 @@ require ( github.com/konoui/lipo v0.10.0 // indirect github.com/kulti/thelper v0.7.1 // indirect github.com/kunwardeep/paralleltest v1.0.15 // indirect - github.com/labstack/echo/v4 v4.13.4 // indirect - github.com/labstack/gommon v0.4.2 // indirect github.com/lasiar/canonicalheader v1.1.2 // indirect github.com/ldez/exptostd v0.4.5 // indirect github.com/ldez/gomoddirectives v0.8.0 // indirect @@ -251,19 +242,13 @@ require ( github.com/ldez/tagliatelle v0.7.2 // indirect github.com/ldez/usetesting v0.5.0 // indirect github.com/leaanthony/clir v1.7.0 // indirect - github.com/leaanthony/debme v1.2.1 // indirect github.com/leaanthony/dmg v0.0.0-20260731074841-5c28840cf819 // indirect - github.com/leaanthony/go-ansi-parser v1.6.1 // indirect - github.com/leaanthony/gosod v1.0.4 // indirect - github.com/leaanthony/slicer v1.6.0 // indirect - github.com/leaanthony/u v1.1.1 // indirect github.com/leaanthony/winicon v1.0.0 // indirect github.com/leonklingele/grouper v1.1.2 // indirect github.com/lithammer/fuzzysearch v1.1.8 // indirect github.com/lmittmann/tint v1.1.3 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/macabu/inamedparam v0.2.0 // indirect - github.com/magiconair/properties v1.8.6 // indirect github.com/manuelarte/embeddedstructfieldcheck v0.4.0 // indirect github.com/manuelarte/funcorder v0.5.0 // indirect github.com/maratori/testableexamples v1.0.1 // indirect @@ -300,7 +285,6 @@ require ( github.com/nunnatsa/ginkgolinter v0.23.0 // indirect github.com/parquet-go/bitpack v1.0.0 // indirect github.com/parquet-go/jsonlite v1.0.0 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pganalyze/pg_query_go/v6 v6.1.0 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect @@ -309,7 +293,6 @@ require ( github.com/pingcap/log v1.1.0 // indirect github.com/pingcap/tidb/pkg/parser v0.0.0-20250324122243-d51e00e5bbf0 // indirect github.com/pjbgf/sha1cd v0.6.0 // indirect - github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.12.1 // indirect @@ -331,9 +314,8 @@ require ( github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/ryancurrah/gomodguard v1.4.1 // indirect github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect - github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect + github.com/sagikazarmark/locafero v0.11.0 // indirect github.com/sajari/fuzzy v1.0.0 // indirect - github.com/samber/lo v1.50.0 // indirect github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect @@ -346,11 +328,11 @@ require ( github.com/sivchari/containedctx v1.0.3 // indirect github.com/skeema/knownhosts v1.3.2 // indirect github.com/sonatard/noctx v0.4.0 // indirect + github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/sourcegraph/go-diff v0.7.0 // indirect github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.10.0 // indirect github.com/spf13/cobra v1.10.2 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/spf13/viper v1.21.0 // indirect github.com/sqlc-dev/sqlc v1.30.0 // indirect @@ -363,13 +345,8 @@ require ( github.com/tc-hib/winres v0.3.1 // indirect github.com/tetafro/godot v1.5.4 // indirect github.com/tetratelabs/wazero v1.9.0 // indirect - github.com/tidwall/gjson v1.18.0 // indirect - github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.1 // indirect - github.com/tidwall/sjson v1.2.5 // indirect github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 // indirect github.com/timonwong/loggercheck v0.11.0 // indirect - github.com/tkrajina/go-reflector v0.5.8 // indirect github.com/tomarrell/wrapcheck/v2 v2.12.0 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/twpayne/go-geom v1.6.1 // indirect @@ -378,16 +355,9 @@ require ( github.com/ultraware/whitespace v0.2.0 // indirect github.com/uudashr/gocognit v1.2.0 // indirect github.com/uudashr/iface v1.4.1 // indirect - github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/wailsapp/go-webview2 v1.0.21 // indirect - github.com/wailsapp/mimetype v1.4.1 // indirect github.com/wailsapp/task/v3 v3.40.1-patched3 // indirect - github.com/wailsapp/wails/v3 v3.0.0-beta.8 // indirect github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07 // indirect github.com/wasilibs/wazero-helpers v0.0.0-20240620070341-3dff1577cd52 // indirect - github.com/wzshiming/ctc v1.2.3 // indirect - github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xen0n/gosmopolitan v1.3.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect @@ -422,7 +392,6 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect google.golang.org/grpc v1.75.0 // indirect google.golang.org/protobuf v1.36.8 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect @@ -437,14 +406,12 @@ require ( mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 // indirect ) -// replace github.com/wailsapp/wails/v2 v2.10.1 => /home/logan/go/pkg/mod tool ( github.com/a-h/templ/cmd/templ github.com/evilmartians/lefthook github.com/golangci/golangci-lint/v2/cmd/golangci-lint github.com/sqlc-dev/sqlc/cmd/sqlc - github.com/wailsapp/wails/v2/cmd/wails github.com/wailsapp/wails/v3/cmd/wails3 golang.org/x/vuln/cmd/govulncheck yellowjacket diff --git a/go.sum b/go.sum index ebe2c0c..1858f35 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,6 @@ codeberg.org/chavacava/garif v0.2.0 h1:F0tVjhYbuOCnvNcU3YSpO6b3Waw6Bimy4K0mM8y6M codeberg.org/chavacava/garif v0.2.0/go.mod h1:P2BPbVbT4QcvLZrORc2T29szK3xEOlnl0GiPTJmEqBQ= codeberg.org/polyfloyd/go-errorlint v1.9.0 h1:VkdEEmA1VBpH6ecQoMR4LdphVI3fA4RrCh2an7YmodI= codeberg.org/polyfloyd/go-errorlint v1.9.0/go.mod h1:GPRRu2LzVijNn4YkrZYJfatQIdS+TrcK8rL5Xs24qw8= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= dev.gaijin.team/go/exhaustruct/v4 v4.0.0 h1:873r7aNneqoBB3IaFIzhvt2RFYTuHgmMjoKfwODoI1Y= @@ -83,6 +81,8 @@ github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= +github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= +github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Djarvur/go-err113 v0.1.1 h1:eHfopDqXRwAi+YmCUas75ZE0+hoBHJ2GQNLYRSxao4g= github.com/Djarvur/go-err113 v0.1.1/go.mod h1:IaWJdYFLg76t2ihfflPZnM1LIQszWOsFDh2hhhAVF6k= github.com/Ladicle/tabwriter v1.0.0 h1:DZQqPvMumBDwVNElso13afjYLNp0Z7pHqHnu0r4t9Dg= @@ -100,33 +100,29 @@ github.com/MarvinJWendt/testza v0.5.2 h1:53KDo64C1z/h/d/stCYCPY69bt/OSwjq5KpFNwi github.com/MarvinJWendt/testza v0.5.2/go.mod h1:xu53QFE5sCdjtMCKk8YMQ2MnymimEctc4n3EjyIYvEY= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/MirrexOne/unqueryvet v1.5.3 h1:LpT3rsH+IY3cQddWF9bg4C7jsbASdGnrOSofY8IPEiw= github.com/MirrexOne/unqueryvet v1.5.3/go.mod h1:fs9Zq6eh1LRIhsDIsxf9PONVUjYdFHdtkHIgZdJnyPU= github.com/OpenPeeDeeP/depguard/v2 v2.2.1 h1:vckeWVESWp6Qog7UZSARNqfu/cZqvki8zsuj3piCMx4= github.com/OpenPeeDeeP/depguard/v2 v2.2.1/go.mod h1:q4DKzC4UcVaAvcfd41CZh0PWpGgzrVxUYBlgKNGquUo= -github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= -github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= -github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= -github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k= +github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw= +github.com/ProtonMail/gopenpgp/v2 v2.7.1 h1:Awsg7MPc2gD3I7IFac2qE3Gdls0lZW8SzrFZ3k1oz0s= +github.com/ProtonMail/gopenpgp/v2 v2.7.1/go.mod h1:/BU5gfAVwqyd8EfC3Eu7zmuhwYQpKs+cGD8M//iiaxs= github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ69NYAb5jbGNfHanvm1+iYlo= github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ= github.com/a-h/templ v0.3.977 h1:kiKAPXTZE2Iaf8JbtM21r54A8bCNsncrfnokZZSrSDg= github.com/a-h/templ v0.3.977/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= +github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= +github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/chroma/v2 v2.23.1 h1:nv2AVZdTyClGbVQkIzlDm/rnhk1E9bU9nXwmZ/Vk/iY= @@ -171,8 +167,8 @@ github.com/atterpac/refresh v1.0.0 h1:IK/rh3w5cD7nb6GuqzfScIdNuAz/E0sZz10k1pioIF github.com/atterpac/refresh v1.0.0/go.mod h1:+vQ8OHgGmZ7wwoZfxxkT6Nr/gKA8j78Rbt+qcLLDEoc= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= -github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= +github.com/aymanbagabas/go-udiff v0.3.1 h1:LV+qyBQ2pqe0u42ZsUEtPiCaUoqgA9gYRDs3vj1nolY= +github.com/aymanbagabas/go-udiff v0.3.1/go.mod h1:G0fsKmG+P6ylD0r6N/KgQD/nWzgfnl8ZBcNLgcbrw8E= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -180,8 +176,6 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= -github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= github.com/bkielbasa/cyclop v1.2.3 h1:faIVMIGDIANuGPWH031CZJTi2ymOQBULs9H21HSMa5w= github.com/bkielbasa/cyclop v1.2.3/go.mod h1:kHTwA9Q0uZqOADdupvcFJQtp/ksSnytRMe8ztxG8Fuo= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= @@ -204,6 +198,8 @@ github.com/butuzov/ireturn v0.4.0 h1:+s76bF/PfeKEdbG8b54aCocxXmi0wvYdOVsWxVO7n8E github.com/butuzov/ireturn v0.4.0/go.mod h1:ghI0FrCmap8pDWZwfPisFD1vEc56VKH4NpQUxDHta70= github.com/butuzov/mirror v1.3.0 h1:HdWCXzmwlQHdVhwvsfBb2Au0r3HyINry3bDWLYXiKoc= github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI= +github.com/caarlos0/testfs v0.4.4 h1:3PHvzHi5Lt+g332CiShwS8ogTgS3HjrmzZxCm6JCDr8= +github.com/caarlos0/testfs v0.4.4/go.mod h1:bRN55zgG4XCUVVHZCeU+/Tz1Q6AxEJOEJTliBy+1DMk= github.com/catenacyber/perfsprint v0.10.1 h1:u7Riei30bk46XsG8nknMhKLXG9BcXz3+3tl/WpKm0PQ= github.com/catenacyber/perfsprint v0.10.1/go.mod h1:DJTGsi/Zufpuus6XPGJyKOTMELe347o6akPvWG9Zcsc= github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY= @@ -227,38 +223,34 @@ github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 h1:JFgG/x github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7/go.mod h1:ISC1gtLcVilLOf23wvTfoQuYbW2q0JevFxPfUzZ9Ybw= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk= -github.com/charmbracelet/glamour v0.8.0 h1:tPrjL3aRcQbn++7t18wOpgLyl8wrOHUEDS7IZ68QtZs= -github.com/charmbracelet/glamour v0.8.0/go.mod h1:ViRgmKkf3u5S7uakt2czJ272WSg2ZenlYEZXT2x7Bjw= github.com/charmbracelet/glamour v0.10.0 h1:MtZvfwsYCx8jEPFJm3rIBFIMZUfUJ765oX8V6kXldcY= github.com/charmbracelet/glamour v0.10.0/go.mod h1:f+uf+I/ChNmqo087elLnVdCiVgjSKWuXa/l6NU2ndYk= github.com/charmbracelet/huh v0.8.0 h1:Xz/Pm2h64cXQZn/Jvele4J3r7DDiqFCNIVteYukxDvY= github.com/charmbracelet/huh v0.8.0/go.mod h1:5YVc+SlZ1IhQALxRPpkGwwEKftN/+OlJlnJYlDRFqN4= -github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= -github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE= github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA= -github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= -github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= github.com/charmbracelet/x/ansi v0.11.4 h1:6G65PLu6HjmE858CnTUQY1LXT3ZUWwfvqEROLF8vqHI= github.com/charmbracelet/x/ansi v0.11.4/go.mod h1:/5AZ+UfWExW3int5H5ugnsG/PWjNcSQcwYsHBlPFQN4= -github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= -github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= github.com/charmbracelet/x/cellbuf v0.0.14 h1:iUEMryGyFTelKW3THW4+FfPgi4fkmKnnaLOXuc+/Kj4= github.com/charmbracelet/x/cellbuf v0.0.14/go.mod h1:P447lJl49ywBbil/KjCk2HexGh4tEY9LH0/1QrZZ9rA= -github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30= -github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= +github.com/charmbracelet/x/conpty v0.1.0 h1:4zc8KaIcbiL4mghEON8D72agYtSeIgq8FSThSPQIb+U= +github.com/charmbracelet/x/conpty v0.1.0/go.mod h1:rMFsDJoDwVmiYM10aD4bH2XiRgwI7NYJtQgl5yskjEQ= +github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86 h1:JSt3B+U9iqk37QUU2Rvb6DSBYRLtWqFqfxf8l5hOZUA= +github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0= +github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ= +github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= github.com/charmbracelet/x/exp/slice v0.0.0-20260122224438-b01af16209d9 h1:BBTx26Fy+CW9U3kLiWBuWn9pI9C1NybaS+p/AZeAOkA= github.com/charmbracelet/x/exp/slice v0.0.0-20260122224438-b01af16209d9/go.mod h1:vqEfX6xzqW1pKKZUUiFOKg0OQ7bCh54Q2vR/tserrRA= github.com/charmbracelet/x/exp/strings v0.0.0-20260122224438-b01af16209d9 h1:JevRYfkTT0sN9OIXAOncYNC0cTP1Gml/0mCSnsmRkRk= github.com/charmbracelet/x/exp/strings v0.0.0-20260122224438-b01af16209d9/go.mod h1:/ehtMPNh9K4odGFkqYJKpIYyePhdp1hLBRvyY4bWkH8= -github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= -github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= +github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= +github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= +github.com/charmbracelet/x/xpty v0.1.2 h1:Pqmu4TEJ8KeA9uSkISKMU3f+C1F6OGBn8ABuGlqCbtI= +github.com/charmbracelet/x/xpty v0.1.2/go.mod h1:XK2Z0id5rtLWcpeNiMYBccNNBrP2IJnzHI0Lq13Xzq4= github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM= github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -273,16 +265,13 @@ github.com/clipperhouse/displaywidth v0.7.0 h1:QNv1GYsnLX9QBrcWUtMlogpTXuM5FVnBw github.com/clipperhouse/displaywidth v0.7.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o= github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= -github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY= -github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/clipperhouse/uax29/v2 v2.4.0 h1:RXqE/l5EiAbA4u97giimKNlmpvkmz+GrBVTelsoXy9g= github.com/clipperhouse/uax29/v2 v2.4.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= +github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= +github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/console v1.0.5 h1:R0ymNeydRqH2DmakFNdmjR2k0t7UPuiOV/N/27/qqsc= github.com/containerd/console v1.0.5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= @@ -293,8 +282,6 @@ github.com/cubicdaiya/gonp v1.0.4 h1:ky2uIAJh81WiLcGKBVD5R7KsM/36W6IqqTy6Bo6rGws github.com/cubicdaiya/gonp v1.0.4/go.mod h1:iWGuP/7+JVTn02OWhRemVbMmG1DOUnmrGTYYACpOI0I= github.com/curioswitch/go-reassign v0.3.0 h1:dh3kpQHuADL3cobV/sSGETA8DOv457dwl+fbBAhrQPs= github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88= -github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= -github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= github.com/d4l3k/messagediff v1.2.2-0.20190829033028-7e0a312ae40b/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= @@ -324,9 +311,8 @@ github.com/ebitengine/oto/v3 v3.3.3 h1:m6RV69OqoXYSWCDsHXN9rc07aDuDstGHtait7HXSM github.com/ebitengine/oto/v3 v3.3.3/go.mod h1:MZeb/lwoC4DCOdiTIxYezrURTw7EvK/yF863+tmBI+U= github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A= github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= -github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM= -github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ= github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= +github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -345,11 +331,8 @@ github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4 github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/firefart/nonamedreturns v1.0.6 h1:vmiBcKV/3EqKY3ZiPxCINmpS431OcE1S47AQUwhrg8E= github.com/firefart/nonamedreturns v1.0.6/go.mod h1:R8NisJnSIpvPWheCq0mNRXJok6D8h7fagJTF8EMEwCo= -github.com/flytam/filenamify v1.2.0 h1:7RiSqXYR4cJftDQ5NuvljKMfd/ubKnW/j9C6iekChgI= -github.com/flytam/filenamify v1.2.0/go.mod h1:Dzf9kVycwcsBlr2ATg6uxjqiFgKGH+5SKFuhdeP5zu8= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= -github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= 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/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= @@ -370,14 +353,10 @@ github.com/go-flac/go-flac/v2 v2.0.4 h1:atf/kFa8U9idtkA//NO22XGr+MzQLeXZecnmP9sY github.com/go-flac/go-flac/v2 v2.0.4/go.mod h1:sYOlTKxutMW0RDYF+KlD6Zn+VOCZlIFQG/r/usPveCs= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= -github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-billy/v5 v5.9.0 h1:jItGXszUDRtR/AlferWPTMN4j38BQ88XnXKbilmmBPA= github.com/go-git/go-billy/v5 v5.9.0/go.mod h1:jCnQMLj9eUgGU7+ludSTYoZL/GGmii14RxKFj7ROgHw= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= -github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= github.com/go-git/go-git/v5 v5.19.2 h1:wkfn7vOlUBu8ivAWKBWisTiwJK4jYHzTF8Ndv1LyGqY= github.com/go-git/go-git/v5 v5.19.2/go.mod h1:QqCBE1EFN5ddFmrliLQ3/ntRCUjZU3EJuwuB/jWEHjk= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -395,7 +374,6 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= @@ -437,8 +415,6 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -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/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ= github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= github.com/godoc-lint/godoc-lint v0.11.2 h1:Bp0FkJWoSdNsBikdNgIcgtaoo+xz6I/Y9s5WSBQUeeM= @@ -452,8 +428,6 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -550,6 +524,8 @@ github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQ github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= github.com/gookit/color v1.6.0 h1:JjJXBTk1ETNyqyilJhkTXJYYigHG24TM9Xa2M1xAhRA= github.com/gookit/color v1.6.0/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs= +github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= +github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= github.com/gopxl/beep/v2 v2.1.1 h1:6FYIYMm2qPAdWkjX+7xwKrViS1x0Po5kDMdRkq8NVbU= github.com/gopxl/beep/v2 v2.1.1/go.mod h1:ZAm9TGQ9lvpoiFLd4zf5B1IuyxZhgRACMId1XJbaW0E= github.com/gordonklaus/ineffassign v0.2.0 h1:Uths4KnmwxNJNzq87fwQQDDnbNb7De00VOk9Nu0TySs= @@ -562,8 +538,6 @@ github.com/goreleaser/nfpm/v2 v2.44.1 h1:g+QNjkEx+C2Zu8dB48t9da/VfV0CWS5TMjxT8HG github.com/goreleaser/nfpm/v2 v2.44.1/go.mod h1:drIYLqkla9SaOLbSnaFOmSIv5LXGfhHcbK54st97b4s= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= -github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= -github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= @@ -590,8 +564,6 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= @@ -611,16 +583,10 @@ github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs= github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/jackmordaunt/icns v1.0.0 h1:RYSxplerf/l/DUd09AHtITwckkv/mqjVv4DjYdPmAMQ= -github.com/jackmordaunt/icns v1.0.0/go.mod h1:7TTQVEuGzVVfOPPlLNHJIkzA6CoV7aH1Dv9dW351oOo= github.com/jackmordaunt/icns/v2 v2.2.7 h1:K/RbfvuzjmjVY5y4g+XENRs8ZZatwz4YnLHypa2KwQg= github.com/jackmordaunt/icns/v2 v2.2.7/go.mod h1:ovoTxGguSuoUGKMk5Nn3R7L7BgMQkylsO+bblBuI22A= -github.com/jaypipes/ghw v0.13.0 h1:log8MXuB8hzTNnSktqpXMHc0c/2k/WgjOMSUtnI1RV4= -github.com/jaypipes/ghw v0.13.0/go.mod h1:In8SsaDqlb1oTyrbmTC14uy+fbBMvp+xdqX51MidlD8= github.com/jaypipes/ghw v0.21.3 h1:v5mUHM+RN854Vqmk49Uh213jyUA4+8uqaRajlYESsh8= github.com/jaypipes/ghw v0.21.3/go.mod h1:GPrvwbtPoxYUenr74+nAnWbardIZq600vJDD5HnPsPE= -github.com/jaypipes/pcidb v1.0.1 h1:WB2zh27T3nwg8AE8ei81sNRb9yWBii3JGNJtT7K9Oic= -github.com/jaypipes/pcidb v1.0.1/go.mod h1:6xYUz/yYEyOkIkUt2t2J2folIuZ4Yg6uByCGFXMCeE4= github.com/jaypipes/pcidb v1.1.1 h1:QmPhpsbmmnCwZmHeYAATxEaoRuiMAJusKYkUncMC0ro= github.com/jaypipes/pcidb v1.1.1/go.mod h1:x27LT2krrUgjf875KxQXKB0Ha/YXLdZRVmw6hH0G7g8= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -650,6 +616,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jszwec/csvutil v1.5.1/go.mod h1:Rpu7Uu9giO9subDyMCIQfHVDuLrcaC36UA4YcJjGBkg= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julz/importas v0.2.0 h1:y+MJN/UdL63QbFJHws9BVC5RpA2iq0kpjrFajTGivjQ= @@ -664,8 +632,6 @@ github.com/kaptinlin/messageformat-go v0.4.7 h1:HQ/OvFUSU7+fAHWkZnP2ug9y+A/ZyTE8 github.com/kaptinlin/messageformat-go v0.4.7/go.mod h1:DusKpv8CIybczGvwIVn3j13hbR3psr5mOwhFudkiq1c= github.com/karamaru-alpha/copyloopvar v1.2.2 h1:yfNQvP9YaGQR7VaWLYcfZUlRP2eo2vhExWKxD/fP6q0= github.com/karamaru-alpha/copyloopvar v1.2.2/go.mod h1:oY4rGZqZ879JkJMtX3RRkcXRkmUvH0x35ykgaKgsgJY= -github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v1.4.0 h1:6xxtP5bZ2E4NF5tuQulISpTO2z8XbtH8cg1PWkxoFkQ= github.com/kevinburke/ssh_config v1.4.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= github.com/kisielk/errcheck v1.9.0 h1:9xt1zI9EBfcYBvdU1nVrzMzzUPUtPKs9bVSIM3TAb3M= @@ -673,15 +639,11 @@ github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkHAIKE/contextcheck v1.1.6 h1:7HIyRcnyzxL9Lz06NGhiKvenXq7Zw6Q0UQu/ttjfJCE= github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw= github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= -github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= 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/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= @@ -716,10 +678,6 @@ github.com/kulti/thelper v0.7.1 h1:fI8QITAoFVLx+y+vSyuLBP+rcVIB8jKooNSCT2EiI98= github.com/kulti/thelper v0.7.1/go.mod h1:NsMjfQEy6sd+9Kfw8kCP61W1I0nerGSYSFnGaxQkcbs= github.com/kunwardeep/paralleltest v1.0.15 h1:ZMk4Qt306tHIgKISHWFJAO1IDQJLc6uDyJMLyncOb6w= github.com/kunwardeep/paralleltest v1.0.15/go.mod h1:di4moFqtfz3ToSKxhNjhOZL+696QtJGCFe132CbBLGk= -github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA= -github.com/labstack/echo/v4 v4.13.4/go.mod h1:g63b33BZ5vZzcIUF8AtRH40DrTlXnx4UMC8rBdndmjQ= -github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= -github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/lasiar/canonicalheader v1.1.2 h1:vZ5uqwvDbyJCnMhmFYimgMZnJMjwljN5VGY0VKbMXb4= github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI= github.com/ldez/exptostd v0.4.5 h1:kv2ZGUVI6VwRfp/+bcQ6Nbx0ghFWcGIKInkG/oFn1aQ= @@ -735,23 +693,10 @@ github.com/ldez/tagliatelle v0.7.2/go.mod h1:PtGgm163ZplJfZMZ2sf5nhUT170rSuPgBim github.com/ldez/usetesting v0.5.0 h1:3/QtzZObBKLy1F4F8jLuKJiKBjjVFi1IavpoWbmqLwc= github.com/ldez/usetesting v0.5.0/go.mod h1:Spnb4Qppf8JTuRgblLrEWb7IE6rDmUpGvxY3iRrzvDQ= github.com/leaanthony/clir v1.0.4/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0= -github.com/leaanthony/clir v1.3.0 h1:L9nPDWrmc/qU9UWZZvRaFajWYuO0np9V5p+5gxyYno0= -github.com/leaanthony/clir v1.3.0/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0= github.com/leaanthony/clir v1.7.0 h1:xiAnhl7ryPwuH3ERwPWZp/pCHk8wTeiwuAOt6MiNyAw= github.com/leaanthony/clir v1.7.0/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0= -github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc= -github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA= github.com/leaanthony/dmg v0.0.0-20260731074841-5c28840cf819 h1:XuDsI+4yv48FxBG5TetpcqLkIsvJP4G94BNbfQB8G0s= github.com/leaanthony/dmg v0.0.0-20260731074841-5c28840cf819/go.mod h1:gL114o+2XWHHI50xydocqXc4sBntbpiyaLyarUH0VA4= -github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A= -github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU= -github.com/leaanthony/gosod v1.0.4 h1:YLAbVyd591MRffDgxUOU1NwLhT9T1/YiwjKZpkNFeaI= -github.com/leaanthony/gosod v1.0.4/go.mod h1:GKuIL0zzPj3O1SdWQOdgURSuhkF+Urizzxh26t9f1cw= -github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY= -github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js= -github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8= -github.com/leaanthony/u v1.1.1 h1:TUFjwDGlNX+WuwVEzDqQwC2lOv0P4uhTQw7CMFdiK7M= -github.com/leaanthony/u v1.1.1/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI= github.com/leaanthony/winicon v1.0.0 h1:ZNt5U5dY71oEoKZ97UVwJRT4e+5xo5o/ieKuHuk8NqQ= github.com/leaanthony/winicon v1.0.0/go.mod h1:en5xhijl92aphrJdmRPlh4NI1L6wq3gEm0LpXAPghjU= github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY= @@ -760,14 +705,10 @@ github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8 github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= github.com/lmittmann/tint v1.1.3 h1:Hv4EaHWXQr+GTFnOU4VKf8UvAtZgn0VuKT+G0wFlO3I= github.com/lmittmann/tint v1.1.3/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddBCpE= github.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U= -github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/manuelarte/embeddedstructfieldcheck v0.4.0 h1:3mAIyaGRtjK6EO9E73JlXLtiy7ha80b2ZVGyacxgfww= github.com/manuelarte/embeddedstructfieldcheck v0.4.0/go.mod h1:z8dFSyXqp+fC6NLDSljRJeNQJJDWnY7RoWFzV3PC6UM= github.com/manuelarte/funcorder v0.5.0 h1:llMuHXXbg7tD0i/LNw8vGnkDTHFpTnWqKPI85Rknc+8= @@ -867,8 +808,6 @@ github.com/parquet-go/jsonlite v1.0.0 h1:87QNdi56wOfsE5bdgas0vRzHPxfJgzrXGml1zZd github.com/parquet-go/jsonlite v1.0.0/go.mod h1:nDjpkpL4EOtqs6NQugUsi0Rleq9sW/OtC1NnZEnxzF0= github.com/parquet-go/parquet-go v0.30.1 h1:Oy6ganNrAdFiVwy7wNmWagfPTWA2X9Z3tVHBc7JtuX8= github.com/parquet-go/parquet-go v0.30.1/go.mod h1:navtkAYr2LGoJVp141oXPlO/sxLvaOe3la2JEoD8+rg= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= 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/pganalyze/pg_query_go/v6 v6.1.0 h1:jG5ZLhcVgL1FAw4C/0VNQaVmX1SUJx71wBGdtTtBvls= @@ -884,12 +823,8 @@ github.com/pingcap/log v1.1.0 h1:ELiPxACz7vdo1qAvvaWJg1NrYFoY6gqAh/+Uo6aXdD8= github.com/pingcap/log v1.1.0/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= github.com/pingcap/tidb/pkg/parser v0.0.0-20250324122243-d51e00e5bbf0 h1:W3rpAI3bubR6VWOcwxDIG0Gz9G5rl5b3SL116T0vBt0= github.com/pingcap/tidb/pkg/parser v0.0.0-20250324122243-d51e00e5bbf0/go.mod h1:+8feuexTKcXHZF/dkDfvCwEyBAmgb4paFc3/WeYV2eE= -github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= -github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= github.com/pjbgf/sha1cd v0.6.0 h1:3WJ8Wz8gvDz29quX1OcEmkAlUg9diU4GxJHqs0/XiwU= github.com/pjbgf/sha1cd v0.6.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -926,8 +861,6 @@ github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEej github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= -github.com/pterm/pterm v0.12.80 h1:mM55B+GnKUnLMUSqhdINe4s6tOuVQIetQ3my8JGyAIg= -github.com/pterm/pterm v0.12.80/go.mod h1:c6DeF9bSnOSeFPZlfs4ZRAFcf5SCoTwvwQ5xaKGQlHo= github.com/pterm/pterm v0.12.82 h1:+D9wYhCaeaK0FIQoZtqbNQuNpe2lB2tajKKsTd5paVQ= github.com/pterm/pterm v0.12.82/go.mod h1:TyuyrPjnxfwP+ccJdBTeWHtd/e0ybQHkOS/TakajZCw= github.com/quasilyte/go-ruleguard v0.4.5 h1:AGY0tiOT5hJX9BTdx/xBdoCubQUAE2grkqY2lSwvZcA= @@ -962,12 +895,10 @@ github.com/ryancurrah/gomodguard v1.4.1 h1:eWC8eUMNZ/wM/PWuZBv7JxxqT5fiIKSIyTvjb github.com/ryancurrah/gomodguard v1.4.1/go.mod h1:qnMJwV1hX9m+YJseXEBhd2s90+1Xn6x9dLz11ualI1I= github.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU= github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ= -github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI= -github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs= +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/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY= github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo= -github.com/samber/lo v1.50.0 h1:XrG0xOeHs+4FQ8gJR97zDz5uOFMW7OwFWiFVzqopKgY= -github.com/samber/lo v1.50.0/go.mod h1:RjZyNk6WSnUFRKK6EyOhsRJMqft3G+pg7dCWHQCWvsc= github.com/sanposhiho/wastedassign/v2 v2.1.0 h1:crurBF7fJKIORrV85u9UUpePDYGWnwvv3+A96WvwXT0= github.com/sanposhiho/wastedassign/v2 v2.1.0/go.mod h1:+oSmSC+9bQ+VUAxA66nBb0Z7N8CK7mscKTDYC6aIek4= github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ= @@ -976,13 +907,13 @@ github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tM github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= github.com/sashamelentyev/usestdlibvars v1.29.0 h1:8J0MoRrw4/NAXtjQqTHrbW9NN+3iMf7Knkq057v4XOQ= github.com/sashamelentyev/usestdlibvars v1.29.0/go.mod h1:8PpnjHMk5VdeWlVb4wCdrB8PNbLqZ3wBZTZWkrpZZL8= +github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg= +github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI= github.com/schollz/progressbar/v3 v3.19.0 h1:Ea18xuIRQXLAUidVDox3AbwfUhD0/1IvohyTutOIFoc= github.com/schollz/progressbar/v3 v3.19.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec= github.com/securego/gosec/v2 v2.23.0 h1:h4TtF64qFzvnkqvsHC/knT7YC5fqyOCItlVR8+ptEBo= github.com/securego/gosec/v2 v2.23.0/go.mod h1:qRHEgXLFuYUDkI2T7W7NJAmOkxVhkR0x9xyHOIcMNZ0= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= @@ -997,30 +928,29 @@ github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE= github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= -github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= -github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/skeema/knownhosts v1.3.2 h1:EDL9mgf4NzwMXCTfaxSD/o/a5fxDw/xL9nkU28JjdBg= github.com/skeema/knownhosts v1.3.2/go.mod h1:bEg3iQAuw+jyiw+484wwFJoKSLwcfd7fqRy+N0QTiow= +github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= +github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= +github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= +github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/sonatard/noctx v0.4.0 h1:7MC/5Gg4SQ4lhLYR6mvOP6mQVSxCrdyiExo7atBs27o= github.com/sonatard/noctx v0.4.0/go.mod h1:64XdbzFb18XL4LporKXp8poqZtPKbCrqQ402CV+kJas= +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/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= 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.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= -github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= 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/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 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.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= -github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +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/sqlc-dev/sqlc v1.30.0 h1:H4HrNwPc0hntxGWzAbhlfplPRN4bQpXFx+CaEMcKz6c= github.com/sqlc-dev/sqlc v1.30.0/go.mod h1:QnEN+npugyhUg1A+1kkYM3jc2OMOFsNlZ1eh8mdhad0= @@ -1042,8 +972,7 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/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.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= -github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tc-hib/winres v0.3.1 h1:CwRjEGrKdbi5CvZ4ID+iyVhgyfatxFoizjPhzez9Io4= github.com/tc-hib/winres v0.3.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= @@ -1055,22 +984,10 @@ github.com/tetafro/godot v1.5.4 h1:u1ww+gqpRLiIA16yF2PV1CV1n/X3zhyezbNXC3E14Sg= github.com/tetafro/godot v1.5.4/go.mod h1:eOkMrVQurDui411nBY2FA05EYH01r14LuWY/NrVDVcU= github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= -github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= -github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -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/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= -github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= -github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 h1:9LPGD+jzxMlnk5r6+hJnar67cgpDIz/iyD+rfl5r2Vk= github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460= github.com/timonwong/loggercheck v0.11.0 h1:jdaMpYBl+Uq9mWPXv1r8jc5fC3gyXx4/WGwTnnNKn4M= github.com/timonwong/loggercheck v0.11.0/go.mod h1:HEAWU8djynujaAVX7QI65Myb8qgfcZ1uKbdpg3ZzKl8= -github.com/tkrajina/go-reflector v0.5.8 h1:yPADHrwmUbMq4RGEyaOUpz2H90sRsETNVpjzo3DLVQQ= -github.com/tkrajina/go-reflector v0.5.8/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4= github.com/tomarrell/wrapcheck/v2 v2.12.0 h1:H/qQ1aNWz/eeIhxKAFvkfIA+N7YDvq6TWVFL27Of9is= github.com/tomarrell/wrapcheck/v2 v2.12.0/go.mod h1:AQhQuZd0p7b6rfW+vUwHm5OMCGgp63moQ9Qr/0BpIWo= github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= @@ -1087,32 +1004,20 @@ github.com/uudashr/gocognit v1.2.0 h1:3BU9aMr1xbhPlvJLSydKwdLN3tEUUrzPSSM8S4hDYR github.com/uudashr/gocognit v1.2.0/go.mod h1:k/DdKPI6XBZO1q7HgoV2juESI2/Ofj9AcHPZhBBdrTU= github.com/uudashr/iface v1.4.1 h1:J16Xl1wyNX9ofhpHmQ9h9gk5rnv2A6lX/2+APLTo0zU= github.com/uudashr/iface v1.4.1/go.mod h1:pbeBPlbuU2qkNDn0mmfrxP2X+wjPMIQAy+r1MBXSXtg= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/wailsapp/go-webview2 v1.0.21 h1:k3dtoZU4KCoN/AEIbWiPln3P2661GtA2oEgA2Pb+maA= -github.com/wailsapp/go-webview2 v1.0.21/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc= -github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= -github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= github.com/wailsapp/task/v3 v3.40.1-patched3 h1:i6O1WNdSur9CGaiMDIYGjsmj/qS4465zqv+WEs6sPRs= github.com/wailsapp/task/v3 v3.40.1-patched3/go.mod h1:jIP48r8ftoSQNlxFP4+aEnkvGQqQXqCnRi/B7ROaecE= -github.com/wailsapp/wails/v2 v2.10.2 h1:29U+c5PI4K4hbx8yFbFvwpCuvqK9VgNv8WGobIlKlXk= -github.com/wailsapp/wails/v2 v2.10.2/go.mod h1:XuN4IUOPpzBrHUkEd7sCU5ln4T/p1wQedfxP7fKik+4= github.com/wailsapp/wails/v3 v3.0.0-beta.8 h1:r5d+5ERZ6TYI/OPJnqq91Ugux+TkfplCURUi/+6vA/Q= github.com/wailsapp/wails/v3 v3.0.0-beta.8/go.mod h1:A/OaL1mXOnwWynTJv4rZU89Wbk5q3rtq3C3qkx4rRN0= github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07 h1:mJdDDPblDfPe7z7go8Dvv1AJQDI3eQ/5xith3q2mFlo= github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07/go.mod h1:Ak17IJ037caFp4jpCw/iQQ7/W74Sqpb1YuKJU6HTKfM= github.com/wasilibs/wazero-helpers v0.0.0-20240620070341-3dff1577cd52 h1:OvLBa8SqJnZ6P+mjlzc2K7PM22rRUPE1x32G9DTPrC4= github.com/wasilibs/wazero-helpers v0.0.0-20240620070341-3dff1577cd52/go.mod h1:jMeV4Vpbi8osrE/pKUxRZkVaA0EX7NZN0A9/oRzgpgY= -github.com/wzshiming/ctc v1.2.3 h1:q+hW3IQNsjIlOFBTGZZZeIXTElFM4grF4spW/errh/c= -github.com/wzshiming/ctc v1.2.3/go.mod h1:2tVAtIY7SUyraSk0JxvwmONNPFL4ARavPuEsg5+KA28= -github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae h1:tpXvBXC3hpQBDCc9OojJZCQMVRAbT3TTdUMP8WguXkY= -github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae/go.mod h1:VTAq37rkGeV+WOybvZwjXiJOicICdpLCN8ifpISjK20= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xen0n/gosmopolitan v1.3.0 h1:zAZI1zefvo7gcpbCOrPSHJZJYA9ZgLfJqtKzZ5pHqQM= github.com/xen0n/gosmopolitan v1.3.0/go.mod h1:rckfr5T6o4lBtM1ga7mLGKZmLxswUoH1zxHgNXOsEt4= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= @@ -1131,19 +1036,16 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= -github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE= github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -github.com/yuin/goldmark-emoji v1.0.3 h1:aLRkLHOuBR2czCY4R8olwMjID+tENfhyFDMCRhbIQY4= -github.com/yuin/goldmark-emoji v1.0.3/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U= github.com/yuin/goldmark-emoji v1.0.6 h1:QWfF2FYaXwL74tfGOW5izeiZepUDroDJfWubQI9HTHs= github.com/yuin/goldmark-emoji v1.0.6/go.mod h1:ukxJDKFpdFb5x0a5HqbdlcKtebh086iJpI31LTKmWuA= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo= @@ -1208,8 +1110,6 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1222,8 +1122,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY= -golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -1234,8 +1132,6 @@ golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMx golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= -golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ= -golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk= golang.org/x/image v0.41.0 h1:8wS72eGJMJaBxK6okTzd4WaXumUlTVlb753MlsSvTCo= golang.org/x/image v0.41.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1263,8 +1159,6 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1298,7 +1192,6 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1308,8 +1201,6 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= -golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1333,8 +1224,6 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1356,7 +1245,6 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1397,12 +1285,8 @@ 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.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 h1:bTLqdHv7xrGlFbvf5/TXNxy/iUwwdkjhqQTJDjW7aj0= -golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4/go.mod h1:g5NllXBEermZrmR51cJDQxmJUHUOfRAaNyWBM+R+548= golang.org/x/telemetry v0.0.0-20260625142307-59b4966ccb57 h1:nwGZBCt+FnXUrGsj5vjzAsEmkcaFvd82BbOjECiFYZc= golang.org/x/telemetry v0.0.0-20260625142307-59b4966ccb57/go.mod h1:3AWMyWHS+caVoiEXpiq6+tzKA40J4vQT3MYr80ZtQpc= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1413,8 +1297,6 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1428,8 +1310,6 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1489,8 +1369,6 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= @@ -1596,14 +1474,11 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1625,8 +1500,6 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.7.0 h1:w6WUp1VbkqPEgLz4rkBzH/CSU6HkoqNLp6GstyTx3lU= honnef.co/go/tools v0.7.0/go.mod h1:pm29oPxeP3P82ISxZDgIYeOaf9ta6Pi0EWvCFoLG2vc= -howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= -howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= howett.net/plist v1.0.2-0.20250314012144-ee69052608d9 h1:eeH1AIcPvSc0Z25ThsYF+Xoqbn0CI/YnXVYoTLFdGQw= howett.net/plist v1.0.2-0.20250314012144-ee69052608d9/go.mod h1:fyFX5Hj5tP1Mpk8obqA9MZgXT416Q5711SDT7dQLTLk= modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis= diff --git a/lefthook.yml b/lefthook.yml index 7acb02a..4afa86d 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -14,11 +14,11 @@ pre-commit: commands: go-vet: glob: "*.go" - run: go vet -tags webkit2_41 ./... + run: go vet ./... golangci-lint: glob: "*.go" - run: go tool golangci-lint run --timeout 5m --build-tags webkit2_41 ./... + run: go tool golangci-lint run --timeout 5m ./... codegen-check: glob: "*.{go,sql,templ}" @@ -61,7 +61,7 @@ pre-push: commands: go-test: glob: "*.go" - run: go test -tags webkit2_41 -race -count=1 -timeout 120s ./... + run: go test -race -count=1 -timeout 120s ./... go-mod-verify: run: go mod verify diff --git a/main.go b/main.go index 271d2e3..2e47297 100644 --- a/main.go +++ b/main.go @@ -8,14 +8,12 @@ import ( "strings" "github.com/golang-cz/devslog" - "github.com/wailsapp/wails/v2" - "github.com/wailsapp/wails/v2/pkg/options" - "github.com/wailsapp/wails/v2/pkg/options/linux" + "github.com/wailsapp/wails/v3/pkg/application" + "github.com/wailsapp/wails/v3/pkg/events" "yellowjacket/backend" "yellowjacket/backend/assets" "yellowjacket/backend/config" - "yellowjacket/backend/logging" "yellowjacket/backend/profiling" "yellowjacket/internal/dev" ) @@ -69,33 +67,52 @@ func main() { os.Exit(1) } - // Create application with options winCfg := yjApp.WindowConfig() - err = wails.Run(&options.App{ - Title: "yellowjacket", - Width: winCfg.Width, - Height: winCfg.Height, - Logger: logging.NewLogger( - sLogger, - []string{}, - ), - AssetServer: assetHandler.Options, - BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1}, - OnStartup: yjApp.OnStartup, - OnDomReady: yjApp.OnDomReady, - OnBeforeClose: yjApp.OnBeforeClose, - OnShutdown: yjApp.OnShutdown, - Bind: yjApp.FEBindings, + app := application.New(application.Options{ + Name: "yellowjacket", + Description: "A cross-platform desktop music player", + Services: yjApp.Services, + Assets: assetHandler.Options, + // v3 logs through slog directly, so v2's logger.Logger adapter + // (backend/logging) is gone rather than ported. + Logger: sLogger, + ShouldQuit: yjApp.ShouldQuit, + OnShutdown: yjApp.OnShutdown, + }) + + // The services' own ServiceStartup hooks have run by the time this + // fires; what is left is the wiring between them. + app.Event.OnApplicationEvent( + events.Common.ApplicationStarted, + func(*application.ApplicationEvent) { + yjApp.OnStartup(app.Context()) + yjApp.OnDomReady(app.Context()) + }, + ) + + window := app.Window.NewWithOptions(application.WebviewWindowOptions{ + Title: "yellowjacket", + Width: winCfg.Width, + Height: winCfg.Height, MinWidth: config.MinWidth, MinHeight: config.MinHeight, - MaxWidth: 0, - MaxHeight: 0, - Linux: &linux.Options{ - WebviewGpuPolicy: linux.WebviewGpuPolicyAlways, + BackgroundColour: application.NewRGB(27, 38, 54), + URL: "/", + Linux: application.LinuxWindow{ + WebviewGpuPolicy: application.WebviewGpuPolicyAlways, }, }) + // The window's size has to be read while the window still exists, + // which OnShutdown is too late for. + window.OnWindowEvent( + events.Common.WindowClosing, + func(*application.WindowEvent) { yjApp.SaveWindowState(window) }, + ) + + err = app.Run() + stopProfiler() if err != nil { diff --git a/packaging/arch/PKGBUILD b/packaging/arch/PKGBUILD index 38e0247..f2d9dc8 100644 --- a/packaging/arch/PKGBUILD +++ b/packaging/arch/PKGBUILD @@ -6,7 +6,7 @@ pkgdesc="Cross-platform desktop music player — local library, MusicBrainz expl arch=('x86_64') url="https://git.ljones.me/yonlu/yellowjacket" license=('custom') -depends=('webkit2gtk-4.1' 'gtk3' 'alsa-lib' 'hicolor-icon-theme') +depends=('webkitgtk-6.0' 'gtk4' 'alsa-lib' 'hicolor-icon-theme') makedepends=('go>=1.25' 'nodejs>=22' 'pnpm' 'git') options=('!lto') @@ -49,7 +49,7 @@ build() { # `go tool wails/sqlc/templ` resolve from the tool directives in go.mod, so no # extra CLIs are needed. Wails runs the frontend install+build itself. go generate ./... - go tool wails build -tags webkit2_41 -clean -trimpath \ + go tool wails3 build -clean -trimpath \ -ldflags "-s -w -X 'main.version=v$pkgver' -X 'main.commit=$commit'" } diff --git a/packaging/homebrew/Formula/yellowjacket.rb b/packaging/homebrew/Formula/yellowjacket.rb index aa0e6f5..3e950b7 100644 --- a/packaging/homebrew/Formula/yellowjacket.rb +++ b/packaging/homebrew/Formula/yellowjacket.rb @@ -40,8 +40,7 @@ class Yellowjacket < Formula ldflags = "-s -w -X 'main.version=v#{version}' -X 'main.commit=#{commit}'" system "go", "generate", "./..." - system "go", "tool", "wails", "build", - "-tags", "webkit2_41", + system "go", "tool", "wails3", "build", "-clean", "-trimpath", "-ldflags", ldflags diff --git a/scripts/bindings-check.sh b/scripts/bindings-check.sh index a2ac8ff..7623b8d 100755 --- a/scripts/bindings-check.sh +++ b/scripts/bindings-check.sh @@ -23,7 +23,7 @@ if [ -n "$(git status --porcelain -- "$TARGET")" ]; then exit 1 fi -go tool wails generate module -tags webkit2_41 >/dev/null 2>&1 +go tool wails generate module >/dev/null 2>&1 # `wails generate module` rewrites the three runtime files as 755 every # time. That is not drift, so compare content only. diff --git a/scripts/dev-headless.sh b/scripts/dev-headless.sh index 6bdce4b..bb2b73a 100755 --- a/scripts/dev-headless.sh +++ b/scripts/dev-headless.sh @@ -12,7 +12,7 @@ # # * We run the dev *binary*, not `wails dev`. app_dev.go parses # -devserver / -assetdir / -loglevel straight from os.Args, so a -# `go build -tags "dev webkit2_41"` binary serves the identical +# `go build -tags "dev"` binary serves the identical # devserver with no file watcher, no rebuild supervisor and no # reload broadcast: one process, one PID, deterministic startup. # @@ -131,7 +131,7 @@ echo "$YJ_HOME" >"$HOME_FILE" if [ "$BUILD" = 1 ]; then echo "dev-headless: building frontend + dev binary..." (cd frontend && pnpm install --silent && pnpm build >/dev/null) - go build -tags "dev webkit2_41" -o "$BIN" . + go build -tags "dev" -o "$BIN" . fi if [ ! -x "$BIN" ]; then