diff --git a/mkdocs-website/docs/en/changelog.md b/mkdocs-website/docs/en/changelog.md index 14ac2445009..cb0684f591b 100644 --- a/mkdocs-website/docs/en/changelog.md +++ b/mkdocs-website/docs/en/changelog.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- Support of linux packaging of deb,rpm, and arch linux packager builds by @atterpac in [#3909](https://github.com/wailsapp/wails/3909) - Added Support for darwin universal builds and packages by [ansxuman](https://github.com/ansxuman) in [#3902](https://github.com/wailsapp/wails/pull/3902) - Events documentation to the mkdocs webite by [atterpac](https://github.com/atterpac) in [#3867](https://github.com/wailsapp/wails/pull/3867) - Templates for sveltekit and sveltekit-ts that are set for non-SSR development by [atterpac](https://github.com/atterpac) in [#3829](https://github.com/wailsapp/wails/pull/3829) diff --git a/mkdocs-website/docs/en/getting-started/your-first-app.md b/mkdocs-website/docs/en/getting-started/your-first-app.md index 0cb65f9fa4f..2d0a9099261 100644 --- a/mkdocs-website/docs/en/getting-started/your-first-app.md +++ b/mkdocs-website/docs/en/getting-started/your-first-app.md @@ -79,6 +79,42 @@ You'll notice that the build time was faster this time. That's because the new b You should see a new executable in the `build` directory. +## Step 6: Packaging Your Application + +Once your application is ready for distribution, you can create platform-specific packages: + +=== "Mac" + + To create a `.app` bundle: + ```bash + wails3 package + ``` + This will create a production build and package it into a `.app` bundle in the `bin` directory. + +=== "Windows" + + To create an NSIS installer: + ```bash + wails3 package + ``` + This will create a production build and package it into an NSIS installer in the `bin` directory. + +=== "Linux" + + Wails supports multiple package formats for Linux distribution: + ```bash + # Create all package types (AppImage, deb, rpm, and Arch Linux) + wails3 package + + # Or create specific package types + wails3 task linux:create:appimage # AppImage format + wails3 task linux:create:deb # Debian package + wails3 task linux:create:rpm # Red Hat package + wails3 task linux:create:aur # Arch Linux package + ``` + +For more detailed information about packaging options and configuration, check out our [Packaging Guide](../learn/guides/packaging.md). + ## Conclusion -Congratulations! You've just created and built your first Wails application. This is just the beginning of what you can achieve with Wails v3 Alpha. Explore the documentation, experiment with different features, and start building amazing applications! +Congratulations! You've just created, developed and packaged your first Wails application. This is just the beginning of what you can achieve with Wails v3. Explore the documentation, experiment with different features, and start building amazing applications! diff --git a/mkdocs-website/docs/en/learn/guides/packaging.md b/mkdocs-website/docs/en/learn/guides/packaging.md new file mode 100644 index 00000000000..0ea4c4268de --- /dev/null +++ b/mkdocs-website/docs/en/learn/guides/packaging.md @@ -0,0 +1,68 @@ +# Packaging Your Application + +This guide explains how to package your Wails application for different platforms. + +## Windows + +Windows applications are packaged as `.exe` files. Wails automatically handles this during the build process, creating a standalone executable that includes all necessary resources. + +## macOS + +macOS applications are packaged as `.app` bundles. Wails creates these bundles automatically during the build process, including proper code signing and notarization if configured. + +## Linux + +Linux applications can be packaged in various formats. Wails v3 uses [nfpm](https://github.com/goreleaser/nfpm), an excellent packaging tool that makes it easy to create `.deb`, `.rpm`, and Arch Linux packages. nfpm is a powerful tool that handles the complexities of Linux packaging, making it easy to create professional-grade packages. + +### Package Types + +Wails supports creating the following types of Linux packages: +- Debian packages (`.deb`) - for Debian, Ubuntu, and related distributions +- Red Hat packages (`.rpm`) - for Red Hat, Fedora, CentOS, and related distributions +- Arch Linux packages - for Arch Linux and related distributions +- AppImage - a distribution-independent package format + +### Building Packages + +Wails provides several task commands for building Linux packages. These are defined in `Taskfile.linux.yml` and can be invoked using the `wails3 task` command: + +```bash +# Build all package types (AppImage, deb, rpm, and Arch Linux) +wails3 task linux:package + +# Build specific package types +wails3 task linux:create:appimage # Create an AppImage +wails3 task linux:create:deb # Create a Debian package +wails3 task linux:create:rpm # Create a Red Hat package +wails3 task linux:create:aur # Create an Arch Linux package +``` + +Each of these tasks will: +1. Build your application in production mode +2. Generate necessary desktop integration files +3. Create the appropriate package using nfpm + +### Configuration + +The package configuration file should follow the nfpm configuration format and is typically located at `build/nfpm/nfpm.yaml`. Here's an example: + +```yaml +name: "myapp" +arch: "amd64" +version: "v1.0.0" +maintainer: "Your Name " +description: | + A short description of your application +vendor: "Your Company" +homepage: "https://yourcompany.com" +license: "MIT" +contents: + - src: ./build/bin/myapp + dst: /usr/bin/myapp + - src: ./assets/icon.png + dst: /usr/share/icons/myapp.png + - src: ./assets/myapp.desktop + dst: /usr/share/applications/myapp.desktop +``` + +For detailed information about all available configuration options, please refer to the [nfpm configuration documentation](https://nfpm.goreleaser.com/configuration/). diff --git a/mkdocs-website/mkdocs.yml b/mkdocs-website/mkdocs.yml index 66d1745b3b9..8bdec59d739 100644 --- a/mkdocs-website/mkdocs.yml +++ b/mkdocs-website/mkdocs.yml @@ -153,6 +153,7 @@ nav: - Guides: - Customising Windows: learn/guides/customising-windows.md - File Associations: learn/guides/file-associations.md + - Packaging: learn/guides/packaging.md - Feedback: getting-started/feedback.md - Feedback: getting-started/feedback.md - What's New in v3?: whats-new.md @@ -175,4 +176,4 @@ watch: - overrides - shared copyright: - Copyright © 2024 Lea Anthony + Copyright 2024 Lea Anthony diff --git a/v3/cmd/wails3/main.go b/v3/cmd/wails3/main.go index 0d229117ab4..aa33799fb4d 100644 --- a/v3/cmd/wails3/main.go +++ b/v3/cmd/wails3/main.go @@ -72,6 +72,7 @@ func main() { tool.NewSubCommandFunction("watcher", "Watches files and runs a command when they change", commands.Watcher) tool.NewSubCommandFunction("cp", "Copy files", commands.Cp) tool.NewSubCommandFunction("buildinfo", "Show Build Info", commands.BuildInfo) + tool.NewSubCommandFunction("package", "Generate Linux packages (deb, rpm, archlinux)", commands.ToolPackage) app.NewSubCommandFunction("version", "Print the version", commands.Version) app.NewSubCommand("sponsor", "Sponsor the project").Action(openSponsor) diff --git a/v3/go.mod b/v3/go.mod index 45d678ba2a1..5e9928d3cb5 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -7,13 +7,13 @@ require ( github.com/atterpac/refresh v0.8.3 github.com/bep/debounce v1.2.1 github.com/ebitengine/purego v0.4.0-alpha.4 - github.com/go-git/go-git/v5 v5.11.0 + github.com/go-git/go-git/v5 v5.12.0 github.com/go-ole/go-ole v1.2.6 - github.com/go-task/task/v3 v3.31.0 + github.com/go-task/task/v3 v3.40.0 github.com/godbus/dbus/v5 v5.1.0 github.com/google/go-cmp v0.6.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.4.0 github.com/jackmordaunt/icns/v2 v2.2.7 github.com/jaypipes/ghw v0.12.0 github.com/leaanthony/clir v1.6.0 @@ -32,9 +32,9 @@ require ( github.com/tc-hib/winres v0.3.1 github.com/wailsapp/go-webview2 v1.0.18-0.20241130004144-dd8667af33c1 github.com/wailsapp/mimetype v1.4.1 + golang.org/x/term v0.25.0 + golang.org/x/tools v0.23.0 golang.org/x/sys v0.27.0 - golang.org/x/term v0.20.0 - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d gopkg.in/yaml.v3 v3.0.1 modernc.org/sqlite v1.21.0 ) @@ -42,53 +42,96 @@ require ( require ( atomicgo.dev/cursor v0.1.1 // indirect atomicgo.dev/keyboard v0.2.8 // indirect - dario.cat/mergo v1.0.0 // indirect + dario.cat/mergo v1.0.1 // indirect + github.com/AlekSi/pointer v1.2.0 // indirect github.com/BurntSushi/toml v1.3.2 // indirect - github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Ladicle/tabwriter v1.0.0 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect github.com/StackExchange/wmi v1.2.1 // indirect - github.com/cloudflare/circl v1.3.7 // indirect + github.com/alecthomas/chroma/v2 v2.14.0 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect + github.com/buger/jsonparser v1.1.1 // indirect + github.com/caarlos0/go-version v0.1.1 // indirect + github.com/cavaliergopher/cpio v1.0.1 // indirect + github.com/cloudflare/circl v1.3.8 // indirect github.com/containerd/console v1.0.4 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/cyphar/filepath-securejoin v0.2.5 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dlclark/regexp2 v1.11.0 // indirect + github.com/dominikbraun/graph v0.23.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/fatih/color v1.15.0 // indirect + github.com/fatih/color v1.18.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-billy/v5 v5.6.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/go-task/template v0.1.0 // indirect + github.com/gobwas/glob v0.2.3 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a // indirect github.com/gookit/color v1.5.2 // indirect + github.com/goreleaser/chglog v0.6.1 // indirect + github.com/goreleaser/fileglob v1.3.0 // indirect + github.com/goreleaser/nfpm/v2 v2.41.1 // indirect + github.com/huandu/xstrings v1.3.3 // indirect + github.com/imdario/mergo v0.3.16 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/invopop/jsonschema v0.12.0 // indirect github.com/jaypipes/pcidb v1.0.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect github.com/joho/godotenv v1.5.1 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.3 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/pgzip v1.2.6 // indirect github.com/lithammer/fuzzysearch v1.1.5 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/mattn/go-zglob v0.0.4 // indirect + github.com/mattn/go-zglob v0.0.6 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/muesli/cancelreader v0.2.2 // indirect + github.com/muesli/mango v0.1.0 // indirect + github.com/muesli/mango-cobra v1.2.0 // indirect + github.com/muesli/mango-pflag v0.1.0 // indirect + github.com/muesli/roff v0.1.0 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/radovskyb/watcher v1.0.7 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rjeczalik/notify v0.9.3 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sajari/fuzzy v1.0.0 // indirect - github.com/sergi/go-diff v1.2.0 // indirect - github.com/skeema/knownhosts v1.2.1 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/shopspring/decimal v1.2.0 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/ulikunitz/xz v0.5.12 // indirect + github.com/whilp/git-urls v1.0.0 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect + gitlab.com/digitalxero/go-conventional-commit v1.0.7 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/image v0.21.0 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/text v0.19.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect @@ -103,5 +146,5 @@ require ( modernc.org/opt v0.1.3 // indirect modernc.org/strutil v1.1.3 // indirect modernc.org/token v1.0.1 // indirect - mvdan.cc/sh/v3 v3.7.0 // indirect + mvdan.cc/sh/v3 v3.10.0 // indirect ) diff --git a/v3/go.sum b/v3/go.sum index dd369435d3d..614c68ae100 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -6,8 +6,16 @@ atomicgo.dev/keyboard v0.2.8 h1:Di09BitwZgdTV1hPyX/b9Cqxi8HVuJQwWivnZUEqlj4= atomicgo.dev/keyboard v0.2.8/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ= 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.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= +github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= +github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Ladicle/tabwriter v1.0.0 h1:DZQqPvMumBDwVNElso13afjYLNp0Z7pHqHnu0r4t9Dg= +github.com/Ladicle/tabwriter v1.0.0/go.mod h1:c4MdCjxQyTbGuQO/gvqJ+IA/89UEwrsD6hUCW98dyp4= github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= @@ -17,17 +25,32 @@ github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/ github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE= github.com/MarvinJWendt/testza v0.5.1 h1:a9Fqx6vQrHQ4CyiaLhktfTTelwGotmFWy8MNhyaohw8= github.com/MarvinJWendt/testza v0.5.1/go.mod h1:L7csM8IBqCc0HH4TRYZSPCIRg6zJeqzM1pm3FSYZBso= +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/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= 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/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +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/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/adrg/xdg v0.5.0 h1:dDaZvhMXatArP1NPHhnfaQUqWBLBsmx1h1HXQdMoFCY= github.com/adrg/xdg v0.5.0/go.mod h1:dDdY4M4DF9Rjy4kHPeNL+ilVF+p2lK8IdM9/rTSGcI4= +github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E= +github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4EbYP4i6n68SG4I= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -35,22 +58,45 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/atterpac/refresh v0.8.3 h1:Xj0rtd6Wfv/u03wZOdauASBOPxGZOJeik065S0wISNg= github.com/atterpac/refresh v0.8.3/go.mod h1:fJpWySLdpbANS8Ej5OvfZVZIVvi/9bmnhTjKS5EjQes= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= +github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= +github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/caarlos0/go-version v0.1.1 h1:1bikKHkGGVIIxqCmufhSSs3hpBScgHGacrvsi8FuIfc= +github.com/caarlos0/go-version v0.1.1/go.mod h1:Ze5Qx4TsBBi5FyrSKVg1Ibc44KGV/llAaKGp86oTwZ0= +github.com/caarlos0/testfs v0.4.4/go.mod h1:bRN55zgG4XCUVVHZCeU+/Tz1Q6AxEJOEJTliBy+1DMk= +github.com/cavaliergopher/cpio v1.0.1 h1:KQFSeKmZhv0cr+kawA3a0xTQCU4QxXF1vhU7P7av2KM= +github.com/cavaliergopher/cpio v1.0.1/go.mod h1:pBdaqQjnvXxdS/6CvNDwIANIFSP0xRKI16PX4xejRQc= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= 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.3.8 h1:j+V8jJt09PoeMFIu2uh5JUyEaIHTXVOHslFoLNAKqwI= +github.com/cloudflare/circl v1.3.8/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= +github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= +github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= +github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucVPgCo= +github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/ebitengine/purego v0.4.0-alpha.4 h1:Y7yIV06Yo5M2BAdD7EVPhfp6LZ0tEcQo5770OhYUVes= @@ -61,6 +107,10 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -71,10 +121,14 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66D github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= +github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= 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.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -82,6 +136,14 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-task/task/v3 v3.31.0 h1:o6iyj9gPJXxvxPi/u/l8e025PmM2BqKgtLNPS2i7hV4= github.com/go-task/task/v3 v3.31.0/go.mod h1:/CPDAu9nS3+soqY/e1tTrSo/zxk76lnljEV9aBTeKrg= +github.com/go-task/task/v3 v3.35.1 h1:zjQ3tLv+LIStDDTzOQx8F97NE/8FSTanjZuwgy/hwro= +github.com/go-task/task/v3 v3.35.1/go.mod h1:7F6HetCXjlBkgxNjXeTKQYpsA5Q34k4fV94fWXq8GTY= +github.com/go-task/task/v3 v3.40.0 h1:1gKx+2UDz06Jtm0MBiN+EqVN87wWEyspuEze4LRGusk= +github.com/go-task/task/v3 v3.40.0/go.mod h1:Eb9p9TYX2LpNrd8rBL+Ceht7LzSqA+WniSFeHAJlsnI= +github.com/go-task/template v0.1.0 h1:ym/r2G937RZA1bsgiWedNnY9e5kxDT+3YcoAnuIetTE= +github.com/go-task/template v0.1.0/go.mod h1:RgwRaZK+kni/hJJ7/AaOE2lPQFPbAdji/DyhC6pxo4k= +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/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -90,14 +152,34 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a h1:JJBdjSfqSy3mnDT0940ASQFghwcZ4y4cb6ttjAoXqwE= +github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a/go.mod h1:uqVAUVQLq8UY2hCDfmJ/+rtO3aw7qyhc90rCVEabEfI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI= github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg= +github.com/goreleaser/chglog v0.6.1 h1:NZKiX8l0FTQPRzBgKST7knvNZmZ04f7PEGkN2wInfhE= +github.com/goreleaser/chglog v0.6.1/go.mod h1:Bnnfo07jMZkaAb0uRNASMZyOsX6ROW6X1qbXqN3guUo= +github.com/goreleaser/fileglob v1.3.0 h1:/X6J7U8lbDpQtBvGcwwPS6OpzkNVlVEsFUVRx9+k+7I= +github.com/goreleaser/fileglob v1.3.0/go.mod h1:Jx6BoXv3mbYkEzwm9THo7xbr5egkAraxkGorbJb4RxU= +github.com/goreleaser/nfpm/v2 v2.41.1 h1:4tyZ9b817msLuyGKw53ed3suZNApkGHVZDekdGe8ZEE= +github.com/goreleaser/nfpm/v2 v2.41.1/go.mod h1:VPc5kF5OgfA+BosV/A2aB+Vg34honjWvp0Vt8ogsSi0= +github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= +github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= 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.12.0 h1:xU2/MDJfWmBhJnujHY9qwXQLs3DBsf0/Xa9vECY0Tho= @@ -111,15 +193,22 @@ github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEE github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/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/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= 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.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= +github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -145,6 +234,8 @@ github.com/lithammer/fuzzysearch v1.1.5 h1:Ag7aKU08wp0R9QCfF4GoGST9HbmAIeLP7xwMr github.com/lithammer/fuzzysearch v1.1.5/go.mod h1:1R1LRNk7yKid1BaQkmuLQaHruxcC4HmAH30Dh61Ih1Q= github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -159,14 +250,33 @@ github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwp github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-zglob v0.0.4 h1:LQi2iOm0/fGgu80AioIJ/1j9w9Oh+9DZ39J4VAGzHQM= github.com/mattn/go-zglob v0.0.4/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= +github.com/mattn/go-zglob v0.0.6 h1:mP8RnmCgho4oaUYDIDn6GNxYk+qJGUs8fJLn+twYj2A= +github.com/mattn/go-zglob v0.0.6/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/mango v0.1.0 h1:DZQK45d2gGbql1arsYA4vfg4d7I9Hfx5rX/GCmzsAvI= +github.com/muesli/mango v0.1.0/go.mod h1:5XFpbC8jY5UUv89YQciiXNlbi+iJgt29VDC5xbzrLL4= +github.com/muesli/mango-cobra v1.2.0 h1:DQvjzAM0PMZr85Iv9LIMaYISpTOliMEg+uMFtNbYvWg= +github.com/muesli/mango-cobra v1.2.0/go.mod h1:vMJL54QytZAJhCT13LPVDfkvCUJ5/4jNUKF/8NC2UjA= +github.com/muesli/mango-pflag v0.1.0 h1:UADqbYgpUyRoBja3g6LUL+3LErjpsOwaC9ywvBWe7Sg= +github.com/muesli/mango-pflag v0.1.0/go.mod h1:YEQomTxaCUp8PrbhFh10UfbhbQrM/xJ4i2PB8VTLLW0= +github.com/muesli/roff v0.1.0 h1:YD0lalCotmYuF5HhZliKWlIx7IEhiXeSfq7hNjFqGF8= +github.com/muesli/roff v0.1.0/go.mod h1:pjAHQM9hdUUwm/krAfrLGgJkXJ+YuhtsfZ42kieB2Ig= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= @@ -196,21 +306,42 @@ github.com/rjeczalik/notify v0.9.3 h1:6rJAzHTGKXGj76sbRgDiDcYj/HniypXmSJo1SWakZe github.com/rjeczalik/notify v0.9.3/go.mod h1:gF3zSOrafR9DQEWSE8TjfI9NkooDxbyT4UgRGKZA0lc= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 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.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +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/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= 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/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -219,12 +350,20 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 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= +github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= +github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/wailsapp/go-webview2 v1.0.18-0.20241130004144-dd8667af33c1 h1:El7t3J32//oQIsdvXAmbgeNKqgmKfKzU2SVp50yn0UM= github.com/wailsapp/go-webview2 v1.0.18-0.20241130004144-dd8667af33c1/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/whilp/git-urls v1.0.0 h1:95f6UMWN5FKW71ECsXRUd3FVYiXdrE7aX4NZKcPmIjU= +github.com/whilp/git-urls v1.0.0/go.mod h1:J16SAmobsqc3Qcy98brfl5f5+e0clUvg1krgwk/qCfE= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= 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/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 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -232,15 +371,24 @@ 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.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +gitlab.com/digitalxero/go-conventional-commit v1.0.7 h1:8/dO6WWG+98PMhlZowt/YjuiKhqhGlOCwlIV8SqqGh8= +gitlab.com/digitalxero/go-conventional-commit v1.0.7/go.mod h1:05Xc2BFsSyC5tKhK0y+P3bs0AwUtNuTp+mTpbCU/DZ0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb h1:c0vyKkb6yr3KR7jEfJaOSv4lG7xPkbN6r52aJz1d8a8= +golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s= golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78= @@ -248,6 +396,8 @@ 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.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -258,6 +408,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -297,6 +449,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -312,6 +466,8 @@ 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.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -322,6 +478,7 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= 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= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -360,3 +517,7 @@ modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE= modernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ= mvdan.cc/sh/v3 v3.7.0 h1:lSTjdP/1xsddtaKfGg7Myu7DnlHItd3/M2tomOcNNBg= mvdan.cc/sh/v3 v3.7.0/go.mod h1:K2gwkaesF/D7av7Kxl0HbF5kGOd2ArupNTX3X44+8l8= +mvdan.cc/sh/v3 v3.8.0 h1:ZxuJipLZwr/HLbASonmXtcvvC9HXY9d2lXZHnKGjFc8= +mvdan.cc/sh/v3 v3.8.0/go.mod h1:w04623xkgBVo7/IUK89E0g8hBykgEpN0vgOj3RJr6MY= +mvdan.cc/sh/v3 v3.10.0 h1:v9z7N1DLZ7owyLM/SXZQkBSXcwr2IGMm2LY2pmhVXj4= +mvdan.cc/sh/v3 v3.10.0/go.mod h1:z/mSSVyLFGZzqb3ZIKojjyqIx/xbmz/UHdCSv9HmqXY= diff --git a/v3/internal/commands/build_assets/Taskfile.linux.yml b/v3/internal/commands/build_assets/Taskfile.linux.yml index 814ee0ae130..eb08fbdacb0 100644 --- a/v3/internal/commands/build_assets/Taskfile.linux.yml +++ b/v3/internal/commands/build_assets/Taskfile.linux.yml @@ -28,6 +28,9 @@ tasks: PRODUCTION: "true" cmds: - task: create:appimage + - task: create:deb + - task: create:rpm + - task: create:aur create:appimage: summary: Creates an AppImage @@ -48,6 +51,51 @@ tasks: DESKTOP_FILE: '{{.APP_NAME}}.desktop' OUTPUT_DIR: '../../bin' + create:deb: + summary: Creates a deb package + deps: + - task: build + vars: + PRODUCTION: "true" + cmds: + - task: generate:dotdesktop + - task: generate:deb + + create:rpm: + summary: Creates a rpm package + deps: + - task: build + vars: + PRODUCTION: "true" + cmds: + - task: generate:dotdesktop + - task: generate:rpm + + create:aur: + summary: Creates a arch linux packager package + deps: + - task: build + vars: + PRODUCTION: "true" + cmds: + - task: generate:dotdesktop + - task: generate:aur + + generate:deb: + summary: Creates a deb package + cmds: + - wails3 tool package -name {{.APP_NAME}} -format deb -config ./build/nfpm/nfpm.yaml + + generate:rpm: + summary: Creates a rpm package + cmds: + - wails3 tool package -name {{.APP_NAME}} -format rpm -config ./build/nfpm/nfpm.yaml + + generate:aur: + summary: Creates a arch linux packager package + cmds: + - wails3 tool package -name {{.APP_NAME}} -format arch -config ./build/nfpm/nfpm.yaml + generate:dotdesktop: summary: Generates a `.desktop` file dir: build diff --git a/v3/internal/commands/task.go b/v3/internal/commands/task.go index 7d13dc559b5..f72a405ff29 100644 --- a/v3/internal/commands/task.go +++ b/v3/internal/commands/task.go @@ -3,7 +3,6 @@ package commands import ( "context" "fmt" - "github.com/go-task/task/v3/errors" "os" "path/filepath" "strings" @@ -11,10 +10,8 @@ import ( "github.com/pterm/pterm" - "github.com/go-task/task/v3/args" - "github.com/go-task/task/v3" - "github.com/go-task/task/v3/taskfile" + "github.com/go-task/task/v3/taskfile/ast" ) // BuildSettings contains the CLI build settings @@ -81,7 +78,7 @@ func RunTask(options *RunTaskOptions, otherArgs []string) error { if options.OutputGroupBegin != "" { return fmt.Errorf("task: You can't set --output-group-begin without --output=group") } - if options.OutputGroupBegin != "" { + if options.OutputGroupEnd != "" { return fmt.Errorf("task: You can't set --output-group-end without --output=group") } } @@ -103,22 +100,14 @@ func RunTask(options *RunTaskOptions, otherArgs []string) error { Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, - - OutputStyle: taskfile.Output{ - Name: options.OutputName, - Group: taskfile.OutputGroup{ - Begin: options.OutputGroupBegin, - End: options.OutputGroupEnd, - }, - }, } - var listOptions = task.NewListOptions(options.List, options.ListAll, options.ListJSON) + listOptions := task.NewListOptions(options.List, options.ListAll, options.ListJSON, false) if err := listOptions.Validate(); err != nil { fatal(err.Error()) } - if (listOptions.ShouldListTasks()) && options.Silent { + if listOptions.ShouldListTasks() && options.Silent { e.ListTaskNames(options.ListAll) return nil } @@ -134,11 +123,6 @@ func RunTask(options *RunTaskOptions, otherArgs []string) error { return nil } - var ( - calls []taskfile.Call - globals *taskfile.Vars - ) - var index int var arg string for index, arg = range os.Args[2:] { @@ -161,34 +145,8 @@ func RunTask(options *RunTaskOptions, otherArgs []string) error { } } - if e.Taskfile.Version.Compare(taskfile.V3) >= 0 { - calls, globals = args.ParseV3(tasksAndVars...) - } else { - calls, globals = args.ParseV2(tasksAndVars...) - } - - globals.Set("CLI_ARGS", taskfile.Var{Static: strings.Join(otherArgs, " ")}) - e.Taskfile.Vars.Merge(globals) - - if !options.Watch { - e.InterceptInterruptSignals() - } - - ctx := context.Background() - - if options.Status { - return e.Status(ctx, calls...) - } - - if err := e.Run(ctx, calls...); err != nil { - pterm.Error.Println(err.Error()) - - if options.ExitCode { - if err, ok := err.(*errors.TaskRunError); ok { - os.Exit(err.Code()) - } - } - os.Exit(1) + if err := e.RunTask(context.Background(), &ast.Call{Task: tasksAndVars[0]}); err != nil { + fatal(err.Error()) } return nil } diff --git a/v3/internal/commands/tool_package.go b/v3/internal/commands/tool_package.go new file mode 100644 index 00000000000..c631352a501 --- /dev/null +++ b/v3/internal/commands/tool_package.go @@ -0,0 +1,65 @@ +package commands + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/wailsapp/wails/v3/internal/flags" + "github.com/wailsapp/wails/v3/internal/packager" +) + +// ToolPackage generates a Linux package in the specified format using nfpm +func ToolPackage(options *flags.ToolPackage) error { + DisableFooter = true + + if options.ConfigPath == "" { + return fmt.Errorf("please provide a config file using the -config flag") + } + + if options.ExecutableName == "" { + return fmt.Errorf("please provide an executable name using the -name flag") + } + + // Validate format + var pkgType packager.PackageType + switch strings.ToLower(options.Format) { + case "deb": + pkgType = packager.DEB + case "rpm": + pkgType = packager.RPM + case "archlinux": + pkgType = packager.ARCH + default: + return fmt.Errorf("unsupported package format '%s'. Supported formats: deb, rpm, archlinux", options.Format) + } + + // Get absolute path of config file + configPath, err := filepath.Abs(options.ConfigPath) + if err != nil { + return fmt.Errorf("error getting absolute path of config file: %w", err) + } + + // Check if config file exists + if info, err := os.Stat(configPath); err != nil { + return fmt.Errorf("config file not found: %s", configPath) + } else if info.Mode().Perm()&0444 == 0 { + return fmt.Errorf("config file is not readable: %s", configPath) + } + + // Generate output filename based on format + if options.Format == "archlinux" { + // Arch linux packages are not .archlinux files, they are .pkg.tar.zst + options.Format = "pkg.tar.zst" + } + outputFile := filepath.Join(filepath.Dir(configPath), "bin", fmt.Sprintf("%s.%s", options.ExecutableName, options.Format)) + + // Create the package + err = packager.CreatePackageFromConfig(pkgType, configPath, outputFile) + if err != nil { + return fmt.Errorf("error creating package: %w", err) + } + + return nil +} diff --git a/v3/internal/commands/tool_package_test.go b/v3/internal/commands/tool_package_test.go new file mode 100644 index 00000000000..21d52962dab --- /dev/null +++ b/v3/internal/commands/tool_package_test.go @@ -0,0 +1,143 @@ +package commands + +import ( + "os" + "path/filepath" + "strings" + "testing" + + "github.com/wailsapp/wails/v3/internal/flags" +) + +func TestToolPackage(t *testing.T) { + tests := []struct { + name string + setup func() (*flags.ToolPackage, func()) + wantErr bool + errMsg string + }{ + { + name: "should fail with invalid format", + setup: func() (*flags.ToolPackage, func()) { + return &flags.ToolPackage{ + Format: "invalid", + ConfigPath: "config.yaml", + ExecutableName: "myapp", + }, func() {} + }, + wantErr: true, + errMsg: "unsupported package format", + }, + { + name: "should fail with missing config file", + setup: func() (*flags.ToolPackage, func()) { + return &flags.ToolPackage{ + Format: "deb", + ConfigPath: "nonexistent.yaml", + ExecutableName: "myapp", + }, func() {} + }, + wantErr: true, + errMsg: "config file not found", + }, + { + name: "should handle case-insensitive format (DEB)", + setup: func() (*flags.ToolPackage, func()) { + // Create a temporary config file + dir := t.TempDir() + configPath := filepath.Join(dir, "config.yaml") + err := os.WriteFile(configPath, []byte("name: test"), 0644) + if err != nil { + t.Fatal(err) + } + + // Create bin directory + err = os.MkdirAll(filepath.Join(dir, "bin"), 0755) + if err != nil { + t.Fatal(err) + } + + return &flags.ToolPackage{ + Format: "DEB", + ConfigPath: configPath, + ExecutableName: "myapp", + }, func() { + os.RemoveAll(filepath.Join(dir, "bin")) + } + }, + wantErr: false, + }, + { + name: "should handle case-insensitive format (RPM)", + setup: func() (*flags.ToolPackage, func()) { + // Create a temporary config file + dir := t.TempDir() + configPath := filepath.Join(dir, "config.yaml") + err := os.WriteFile(configPath, []byte("name: test"), 0644) + if err != nil { + t.Fatal(err) + } + + // Create bin directory + err = os.MkdirAll(filepath.Join(dir, "bin"), 0755) + if err != nil { + t.Fatal(err) + } + + return &flags.ToolPackage{ + Format: "RPM", + ConfigPath: configPath, + ExecutableName: "myapp", + }, func() { + os.RemoveAll(filepath.Join(dir, "bin")) + } + }, + wantErr: false, + }, + { + name: "should handle case-insensitive format (ARCHLINUX)", + setup: func() (*flags.ToolPackage, func()) { + // Create a temporary config file + dir := t.TempDir() + configPath := filepath.Join(dir, "config.yaml") + err := os.WriteFile(configPath, []byte("name: test"), 0644) + if err != nil { + t.Fatal(err) + } + + // Create bin directory + err = os.MkdirAll(filepath.Join(dir, "bin"), 0755) + if err != nil { + t.Fatal(err) + } + + return &flags.ToolPackage{ + Format: "ARCHLINUX", + ConfigPath: configPath, + ExecutableName: "myapp", + }, func() { + os.RemoveAll(filepath.Join(dir, "bin")) + } + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + options, cleanup := tt.setup() + defer cleanup() + + err := ToolPackage(options) + + if (err != nil) != tt.wantErr { + t.Errorf("ToolPackage() error = %v, wantErr %v", err, tt.wantErr) + return + } + + if tt.wantErr && !strings.Contains(err.Error(), tt.errMsg) { + t.Errorf("ToolPackage() error = %v, want error containing %v", err, tt.errMsg) + } + }) + } +} diff --git a/v3/internal/commands/updatable_build_assets/nfpm/nfpm.yaml.tmpl b/v3/internal/commands/updatable_build_assets/nfpm/nfpm.yaml.tmpl new file mode 100644 index 00000000000..6900d00a7c4 --- /dev/null +++ b/v3/internal/commands/updatable_build_assets/nfpm/nfpm.yaml.tmpl @@ -0,0 +1,50 @@ +# Feel free to remove those if you don't want/need to use them. +# Make sure to check the documentation at https://nfpm.goreleaser.com +# +# The lines below are called `modelines`. See `:help modeline` + +name: "{{.BinaryName}}" +arch: ${GOARCH} +platform: "linux" +version: "{{.ProductVersion}}" +section: "default" +priority: "extra" +maintainer: ${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}> +description: "{{.ProductDescription}}" +vendor: "{{.ProductCompany}}" +homepage: "https://wails.io" +license: "MIT" +release: "1" + +contents: + - src: "./bin/{{.BinaryName}}" + dst: "/usr/local/bin/{{.BinaryName}}" + - src: "./build/appicon.png" + dst: "/usr/share/icons/hicolor/128x128/apps/{{.BinaryName}}.png" + - src: "./build/{{.BinaryName}}.desktop" + dst: "/usr/share/applications/{{.BinaryName}}.desktop" + +depends: + - gtk3 + - libwebkit2gtk + +# replaces: +# - foobar +# provides: +# - bar +# depends: +# - gtk3 +# - libwebkit2gtk +# recommends: +# - whatever +# suggests: +# - something-else +# conflicts: +# - not-foo +# - not-bar +# changelog: "changelog.yaml" +# scripts: +# preinstall: ./build/nfpm/scripts/preinstall.sh +# postinstall: ./build/nfpm/scripts/postinstall.sh +# preremove: ./build/nfpm/scripts/preremove.sh +# postremove: ./build/nfpm/scripts/postremove.sh diff --git a/v3/internal/commands/updatable_build_assets/nfpm/scripts/postinstall.sh b/v3/internal/commands/updatable_build_assets/nfpm/scripts/postinstall.sh new file mode 100644 index 00000000000..a9bf588e2f8 --- /dev/null +++ b/v3/internal/commands/updatable_build_assets/nfpm/scripts/postinstall.sh @@ -0,0 +1 @@ +#!/bin/bash diff --git a/v3/internal/commands/updatable_build_assets/nfpm/scripts/postremove.sh b/v3/internal/commands/updatable_build_assets/nfpm/scripts/postremove.sh new file mode 100644 index 00000000000..a9bf588e2f8 --- /dev/null +++ b/v3/internal/commands/updatable_build_assets/nfpm/scripts/postremove.sh @@ -0,0 +1 @@ +#!/bin/bash diff --git a/v3/internal/commands/updatable_build_assets/nfpm/scripts/preinstall.sh b/v3/internal/commands/updatable_build_assets/nfpm/scripts/preinstall.sh new file mode 100644 index 00000000000..a9bf588e2f8 --- /dev/null +++ b/v3/internal/commands/updatable_build_assets/nfpm/scripts/preinstall.sh @@ -0,0 +1 @@ +#!/bin/bash diff --git a/v3/internal/commands/updatable_build_assets/nfpm/scripts/preremove.sh b/v3/internal/commands/updatable_build_assets/nfpm/scripts/preremove.sh new file mode 100644 index 00000000000..a9bf588e2f8 --- /dev/null +++ b/v3/internal/commands/updatable_build_assets/nfpm/scripts/preremove.sh @@ -0,0 +1 @@ +#!/bin/bash diff --git a/v3/internal/doctor/doctor.go b/v3/internal/doctor/doctor.go index c6d3c0ca773..3e1fe948df1 100644 --- a/v3/internal/doctor/doctor.go +++ b/v3/internal/doctor/doctor.go @@ -2,7 +2,6 @@ package doctor import ( "fmt" - "github.com/wailsapp/wails/v3/internal/buildinfo" "path/filepath" "runtime" "runtime/debug" @@ -10,6 +9,8 @@ import ( "strconv" "strings" + "github.com/wailsapp/wails/v3/internal/buildinfo" + "github.com/go-git/go-git/v5" "github.com/jaypipes/ghw" "github.com/pterm/pterm" diff --git a/v3/internal/doctor/packagemanager/apt.go b/v3/internal/doctor/packagemanager/apt.go index 1a85b8376be..d7d43ea3566 100644 --- a/v3/internal/doctor/packagemanager/apt.go +++ b/v3/internal/doctor/packagemanager/apt.go @@ -54,7 +54,10 @@ func (a *Apt) listPackage(name string) (string, error) { // PackageInstalled tests if the given package name is installed func (a *Apt) PackageInstalled(pkg *Package) (bool, error) { - if pkg.SystemPackage == false { + if !pkg.SystemPackage { + if pkg.InstallCheck != nil { + return pkg.InstallCheck(), nil + } return false, nil } output, err := a.listPackage(pkg.Name) @@ -64,8 +67,8 @@ func (a *Apt) PackageInstalled(pkg *Package) (bool, error) { // PackageAvailable tests if the given package is available for installation func (a *Apt) PackageAvailable(pkg *Package) (bool, error) { - if pkg.SystemPackage == false { - return false, nil + if !pkg.SystemPackage { + return true, nil } output, err := a.listPackage(pkg.Name) // We add a space to ensure we get a full match, not partial match @@ -78,8 +81,8 @@ func (a *Apt) PackageAvailable(pkg *Package) (bool, error) { // InstallCommand returns the package manager specific command to install a package func (a *Apt) InstallCommand(pkg *Package) string { - if pkg.SystemPackage == false { - return pkg.InstallCommand[a.osid] + if !pkg.SystemPackage { + return pkg.InstallCommand } return "sudo apt install " + pkg.Name } diff --git a/v3/internal/doctor/packagemanager/dnf.go b/v3/internal/doctor/packagemanager/dnf.go index a98ceac7038..7c5be417924 100644 --- a/v3/internal/doctor/packagemanager/dnf.go +++ b/v3/internal/doctor/packagemanager/dnf.go @@ -53,7 +53,10 @@ func (y *Dnf) Name() string { // PackageInstalled tests if the given package name is installed func (y *Dnf) PackageInstalled(pkg *Package) (bool, error) { - if pkg.SystemPackage == false { + if !pkg.SystemPackage { + if pkg.InstallCheck != nil { + return pkg.InstallCheck(), nil + } return false, nil } stdout, err := execCmd("dnf", "info", "installed", pkg.Name) @@ -103,7 +106,7 @@ func (y *Dnf) PackageAvailable(pkg *Package) (bool, error) { // InstallCommand returns the package manager specific command to install a package func (y *Dnf) InstallCommand(pkg *Package) string { if pkg.SystemPackage == false { - return pkg.InstallCommand[y.osid] + return pkg.InstallCommand } return "sudo dnf install " + pkg.Name } diff --git a/v3/internal/doctor/packagemanager/emerge.go b/v3/internal/doctor/packagemanager/emerge.go index 5ff21539a9a..33c78a2e6b3 100644 --- a/v3/internal/doctor/packagemanager/emerge.go +++ b/v3/internal/doctor/packagemanager/emerge.go @@ -106,7 +106,7 @@ func (e *Emerge) PackageAvailable(pkg *Package) (bool, error) { // InstallCommand returns the package manager specific command to install a package func (e *Emerge) InstallCommand(pkg *Package) string { if pkg.SystemPackage == false { - return pkg.InstallCommand[e.osid] + return pkg.InstallCommand } return "sudo emerge " + pkg.Name } diff --git a/v3/internal/doctor/packagemanager/eopkg.go b/v3/internal/doctor/packagemanager/eopkg.go index a2dc7aa8cac..060e5959537 100644 --- a/v3/internal/doctor/packagemanager/eopkg.go +++ b/v3/internal/doctor/packagemanager/eopkg.go @@ -7,7 +7,6 @@ import ( "strings" ) -// Eopkg represents the Eopkg manager type Eopkg struct { name string osid string @@ -52,7 +51,10 @@ func (e *Eopkg) Name() string { // PackageInstalled tests if the given package is installed func (e *Eopkg) PackageInstalled(pkg *Package) (bool, error) { - if pkg.SystemPackage == false { + if !pkg.SystemPackage { + if pkg.InstallCheck != nil { + return pkg.InstallCheck(), nil + } return false, nil } stdout, err := execCmd("eopkg", "info", pkg.Name) @@ -75,7 +77,7 @@ func (e *Eopkg) PackageAvailable(pkg *Package) (bool, error) { // InstallCommand returns the package manager specific command to install a package func (e *Eopkg) InstallCommand(pkg *Package) string { if pkg.SystemPackage == false { - return pkg.InstallCommand[e.osid] + return pkg.InstallCommand } return "sudo eopkg it " + pkg.Name } diff --git a/v3/internal/doctor/packagemanager/nixpkgs.go b/v3/internal/doctor/packagemanager/nixpkgs.go index 749860eba23..4141de05676 100644 --- a/v3/internal/doctor/packagemanager/nixpkgs.go +++ b/v3/internal/doctor/packagemanager/nixpkgs.go @@ -65,7 +65,10 @@ func (n *Nixpkgs) Name() string { // PackageInstalled tests if the given package name is installed func (n *Nixpkgs) PackageInstalled(pkg *Package) (bool, error) { - if pkg.SystemPackage == false { + if !pkg.SystemPackage { + if pkg.InstallCheck != nil { + return pkg.InstallCheck(), nil + } return false, nil } @@ -142,7 +145,7 @@ func (n *Nixpkgs) PackageAvailable(pkg *Package) (bool, error) { // InstallCommand returns the package manager specific command to install a package func (n *Nixpkgs) InstallCommand(pkg *Package) string { if pkg.SystemPackage == false { - return pkg.InstallCommand[n.osid] + return pkg.InstallCommand } return "nix-env -iA " + pkg.Name } diff --git a/v3/internal/doctor/packagemanager/pacman.go b/v3/internal/doctor/packagemanager/pacman.go index d585f94f770..e785901e930 100644 --- a/v3/internal/doctor/packagemanager/pacman.go +++ b/v3/internal/doctor/packagemanager/pacman.go @@ -51,7 +51,10 @@ func (p *Pacman) Name() string { // PackageInstalled tests if the given package name is installed func (p *Pacman) PackageInstalled(pkg *Package) (bool, error) { - if pkg.SystemPackage == false { + if !pkg.SystemPackage { + if pkg.InstallCheck != nil { + return pkg.InstallCheck(), nil + } return false, nil } stdout, err := execCmd("pacman", "-Q", pkg.Name) @@ -103,7 +106,7 @@ func (p *Pacman) PackageAvailable(pkg *Package) (bool, error) { // InstallCommand returns the package manager specific command to install a package func (p *Pacman) InstallCommand(pkg *Package) string { if pkg.SystemPackage == false { - return pkg.InstallCommand[p.osid] + return pkg.InstallCommand } return "sudo pacman -S " + pkg.Name } diff --git a/v3/internal/doctor/packagemanager/pm.go b/v3/internal/doctor/packagemanager/pm.go index 0602e1e03fa..6b6ced9c003 100644 --- a/v3/internal/doctor/packagemanager/pm.go +++ b/v3/internal/doctor/packagemanager/pm.go @@ -6,7 +6,8 @@ package packagemanager type Package struct { Name string Version string - InstallCommand map[string]string + InstallCommand string + InstallCheck func() bool SystemPackage bool Library bool Optional bool diff --git a/v3/internal/doctor/packagemanager/zypper.go b/v3/internal/doctor/packagemanager/zypper.go index dec28acb252..da3cb200e8b 100644 --- a/v3/internal/doctor/packagemanager/zypper.go +++ b/v3/internal/doctor/packagemanager/zypper.go @@ -54,7 +54,10 @@ func (z *Zypper) Name() string { // PackageInstalled tests if the given package name is installed func (z *Zypper) PackageInstalled(pkg *Package) (bool, error) { - if pkg.SystemPackage == false { + if !pkg.SystemPackage { + if pkg.InstallCheck != nil { + return pkg.InstallCheck(), nil + } return false, nil } stdout, err := execCmd("zypper", "info", pkg.Name) @@ -101,7 +104,7 @@ func (z *Zypper) PackageAvailable(pkg *Package) (bool, error) { // InstallCommand returns the package manager specific command to install a package func (z *Zypper) InstallCommand(pkg *Package) string { if pkg.SystemPackage == false { - return pkg.InstallCommand[z.osid] + return pkg.InstallCommand } return "sudo zypper in " + pkg.Name } diff --git a/v3/internal/flags/package.go b/v3/internal/flags/package.go new file mode 100644 index 00000000000..f4ffb99ebd8 --- /dev/null +++ b/v3/internal/flags/package.go @@ -0,0 +1,10 @@ +package flags + +// ToolPackage represents the options for the package command +type ToolPackage struct { + Common + + Format string `name:"format" description:"Package format to generate (deb, rpm, archlinux)" default:"deb"` + ExecutableName string `name:"name" description:"Name of the executable to package" default:"myapp"` + ConfigPath string `name:"config" description:"Path to the package configuration file" default:""` +} diff --git a/v3/internal/packager/packager.go b/v3/internal/packager/packager.go new file mode 100644 index 00000000000..5cf235d72ef --- /dev/null +++ b/v3/internal/packager/packager.go @@ -0,0 +1,94 @@ +// Package packager provides a simplified interface for creating Linux packages using nfpm +package packager + +import ( + "fmt" + "io" + "os" + + "github.com/goreleaser/nfpm/v2" + _ "github.com/goreleaser/nfpm/v2/apk" // Register APK packager + _ "github.com/goreleaser/nfpm/v2/arch" // Register Arch Linux packager + _ "github.com/goreleaser/nfpm/v2/deb" // Register DEB packager + _ "github.com/goreleaser/nfpm/v2/ipk" // Register IPK packager + _ "github.com/goreleaser/nfpm/v2/rpm" // Register RPM packager +) + +// PackageType represents supported package formats +type PackageType string + +const ( + // DEB is for Debian/Ubuntu packages + DEB PackageType = "deb" + // RPM is for RedHat/CentOS packages + RPM PackageType = "rpm" + // APK is for Alpine Linux packages + APK PackageType = "apk" + // IPK is for OpenWrt packages + IPK PackageType = "ipk" + // ARCH is for Arch Linux packages + ARCH PackageType = "archlinux" +) + +// CreatePackageFromConfig loads a configuration file and creates a package +func CreatePackageFromConfig(pkgType PackageType, configPath string, output string) error { + // Parse nfpm config + config, err := nfpm.ParseFile(configPath) + if err != nil { + return fmt.Errorf("error parsing config file: %w", err) + } + + // Get info for the specified packager + info, err := config.Get(string(pkgType)) + if err != nil { + return fmt.Errorf("error getting packager info: %w", err) + } + + // Get the packager + packager, err := nfpm.Get(string(pkgType)) + if err != nil { + return fmt.Errorf("error getting packager: %w", err) + } + + // Create output file + out, err := os.Create(output) + if err != nil { + return fmt.Errorf("error creating output file: %w", err) + } + defer out.Close() + + // Create the package + if err := packager.Package(info, out); err != nil { + return fmt.Errorf("error creating package: %w", err) + } + + return nil +} + +// CreatePackageFromConfigWriter loads a configuration file and writes the package to the provided writer +func CreatePackageFromConfigWriter(pkgType PackageType, configPath string, output io.Writer) error { + // Parse nfpm config + config, err := nfpm.ParseFile(configPath) + if err != nil { + return fmt.Errorf("error parsing config file: %w", err) + } + + // Get info for the specified packager + info, err := config.Get(string(pkgType)) + if err != nil { + return fmt.Errorf("error getting packager info: %w", err) + } + + // Get the packager + packager, err := nfpm.Get(string(pkgType)) + if err != nil { + return fmt.Errorf("error getting packager: %w", err) + } + + // Create the package + if err := packager.Package(info, output); err != nil { + return fmt.Errorf("error creating package: %w", err) + } + + return nil +} diff --git a/v3/internal/packager/packager_test.go b/v3/internal/packager/packager_test.go new file mode 100644 index 00000000000..3ed4a4f489d --- /dev/null +++ b/v3/internal/packager/packager_test.go @@ -0,0 +1,100 @@ +package packager + +import ( + "bytes" + "os" + "path/filepath" + "testing" +) + +func TestCreatePackageFromConfig(t *testing.T) { + // Create a temporary file for testing + content := []byte("test content") + tmpfile, err := os.CreateTemp("", "example") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmpfile.Name()) + + if _, err := tmpfile.Write(content); err != nil { + t.Fatal(err) + } + if err := tmpfile.Close(); err != nil { + t.Fatal(err) + } + + // Create a temporary config file + configContent := []byte(` +name: test-package +version: v1.0.0 +arch: amd64 +description: Test package +maintainer: Test User +license: MIT +contents: +- src: ` + tmpfile.Name() + ` + dst: /usr/local/bin/test-file +`) + + configFile, err := os.CreateTemp("", "config*.yaml") + if err != nil { + t.Fatal(err) + } + defer os.Remove(configFile.Name()) + + if _, err := configFile.Write(configContent); err != nil { + t.Fatal(err) + } + if err := configFile.Close(); err != nil { + t.Fatal(err) + } + + // Test creating packages for each format + formats := []struct { + pkgType PackageType + ext string + }{ + {DEB, "deb"}, + {RPM, "rpm"}, + {APK, "apk"}, + {IPK, "ipk"}, + {ARCH, "pkg.tar.zst"}, + } + + for _, format := range formats { + t.Run(string(format.pkgType), func(t *testing.T) { + // Test file-based package creation + outputPath := filepath.Join(os.TempDir(), "test-package."+format.ext) + err := CreatePackageFromConfig(format.pkgType, configFile.Name(), outputPath) + if err != nil { + t.Errorf("CreatePackageFromConfig failed for %s: %v", format.pkgType, err) + } + defer os.Remove(outputPath) + + // Verify the file was created + if _, err := os.Stat(outputPath); os.IsNotExist(err) { + t.Errorf("Package file was not created for %s", format.pkgType) + } + + // Test writer-based package creation + var buf bytes.Buffer + err = CreatePackageFromConfigWriter(format.pkgType, configFile.Name(), &buf) + if err != nil { + t.Errorf("CreatePackageFromConfigWriter failed for %s: %v", format.pkgType, err) + } + + // Verify some content was written + if buf.Len() == 0 { + t.Errorf("No content was written for %s", format.pkgType) + } + }) + } + + // Test with invalid config file + t.Run("InvalidConfig", func(t *testing.T) { + err := CreatePackageFromConfig(DEB, "nonexistent.yaml", "output.deb") + if err == nil { + t.Error("Expected error for invalid config, got nil") + } + }) +}