Skip to content

Commit

Permalink
Update default taskfile. WIP linux packaging
Browse files Browse the repository at this point in the history
  • Loading branch information
leaanthony committed Nov 20, 2023
1 parent b9558cc commit 12efb8b
Show file tree
Hide file tree
Showing 14 changed files with 1,525 additions and 44 deletions.
2 changes: 1 addition & 1 deletion mkdocs-website/shared/alpha2.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
`wails init`,:material-check-bold:,:material-check-bold:,:material-check-bold:
`wails build`,:material-check-bold:,:material-check-bold:,:material-check-bold:
`wails dev`," "," "," "
`wails package`," ",:material-check-bold:," "
`wails package`," ",:material-check-bold:,:material-check-bold:
2 changes: 2 additions & 0 deletions v3/cmd/wails3/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ func main() {
generate.NewSubCommandFunction("bindings", "Generate bindings + models", commands.GenerateBindings)
generate.NewSubCommandFunction("constants", "Generate JS constants from Go", commands.GenerateConstants)
generate.NewSubCommandFunction(".desktop", "Generate .desktop file", commands.GenerateDotDesktop)
generate.NewSubCommandFunction("appimage", "Generate Linux AppImage", commands.GenerateAppImage)

plugin := app.NewSubCommand("plugin", "Plugin tools")
//plugin.NewSubCommandFunction("list", "List plugins", commands.PluginList)
plugin.NewSubCommandFunction("init", "Initialise a new plugin", commands.PluginInit)
Expand Down
1 change: 1 addition & 0 deletions v3/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/go-task/task/v3 v3.31.0
github.com/godbus/dbus/v5 v5.1.0
github.com/google/go-cmp v0.5.9
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/google/uuid v1.3.0
github.com/gorilla/pat v1.0.1
github.com/gorilla/sessions v1.2.1
Expand Down
2 changes: 2 additions & 0 deletions v3/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hf
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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
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.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
Expand Down
173 changes: 173 additions & 0 deletions v3/internal/commands/appimage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package commands

import (
_ "embed"
"fmt"
"github.com/pterm/pterm"
"github.com/wailsapp/wails/v3/internal/s"
"os"
"path/filepath"
"sync"
)

//go:embed linuxdeploy-plugin-gtk.sh
var gtkPlugin []byte

func log(p *pterm.ProgressbarPrinter, message string) {
p.UpdateTitle(message)
pterm.Info.Println(message)
p.Increment()
}

type GenerateAppImageOptions struct {
Binary string `description:"The binary to package including path"`
Icon string `description:"Path to the icon"`
DesktopFile string `description:"Path to the desktop file"`
OutputDir string `description:"Path to the output directory" default:"."`
BuildDir string `description:"Path to the build directory"`
}

func GenerateAppImage(options *GenerateAppImageOptions) error {

defer func() {
pterm.DefaultSpinner.Stop()
}()

if options.Binary == "" {
return fmt.Errorf("binary not provided")
}
if options.Icon == "" {
return fmt.Errorf("icon path not provided")
}
if options.DesktopFile == "" {
return fmt.Errorf("desktop file path not provided")
}
if options.BuildDir == "" {
// Create temp directory
var err error
options.BuildDir, err = os.MkdirTemp("", "wails-appimage-*")
if err != nil {
return err
}
}
var err error
options.OutputDir, err = filepath.Abs(options.OutputDir)
if err != nil {
return err
}

return generateAppImage(options)
}

func generateAppImage(options *GenerateAppImageOptions) error {
numberOfSteps := 5
p, _ := pterm.DefaultProgressbar.WithTotal(numberOfSteps).WithTitle("Generating AppImage").Start()

// Get the last path of the binary and normalise the name
name := normaliseName(filepath.Base(options.Binary))

appDir := filepath.Join(options.BuildDir, name+"-x86_64.AppDir")
s.RMDIR(appDir)

log(p, "Preparing AppImage Directory: "+appDir)

usrBin := filepath.Join(appDir, "usr", "bin")
s.MKDIR(options.BuildDir)
s.MKDIR(usrBin)
s.COPY(options.Binary, usrBin)
s.CHMOD(filepath.Join(usrBin, filepath.Base(options.Binary)), 0755)
dotDirIcon := filepath.Join(appDir, ".DirIcon")
s.COPY(options.Icon, dotDirIcon)
iconLink := filepath.Join(appDir, filepath.Base(options.Icon))
s.DELETE(iconLink)
s.SYMLINK(".DirIcon", iconLink)
s.COPY(options.DesktopFile, appDir)

// Download linuxdeploy and make it executable
s.CD(options.BuildDir)

// Download necessary files
log(p, "Downloading AppImage tooling")
var wg sync.WaitGroup
wg.Add(2)
go func() {
if !s.EXISTS(filepath.Join(options.BuildDir, "linuxdeploy-x86_64.AppImage")) {
s.DOWNLOAD("https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage", filepath.Join(options.BuildDir, "linuxdeploy-x86_64.AppImage"))
}
s.CHMOD(filepath.Join(options.BuildDir, "linuxdeploy-x86_64.AppImage"), 0755)
wg.Done()
}()
go func() {
target := filepath.Join(appDir, "AppRun")
if !s.EXISTS(target) {
s.DOWNLOAD("https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-x86_64", target)
}
s.CHMOD(target, 0755)
wg.Done()
}()
wg.Wait()

log(p, "Processing GTK files.")
files := s.FINDFILES("/usr/lib", "WebKitNetworkProcess", "WebKitWebProcess", "libwebkit2gtkinjectedbundle.so")
if len(files) != 3 {
return fmt.Errorf("unable to locate all WebKit libraries")
}
s.CD(appDir)
for _, file := range files {
targetDir := filepath.Dir(file)
// Strip leading forward slash
if targetDir[0] == '/' {
targetDir = targetDir[1:]
}
var err error
targetDir, err = filepath.Abs(targetDir)
if err != nil {
return err
}
s.MKDIR(targetDir)
s.COPY(file, targetDir)
}
// Copy GTK Plugin
err := os.WriteFile(filepath.Join(options.BuildDir, "linuxdeploy-plugin-gtk.sh"), gtkPlugin, 0755)
if err != nil {
return err
}

// Determine GTK Version
// Run ldd on the binary and capture the output
targetBinary := filepath.Join(appDir, "usr", "bin", options.Binary)
lddOutput, err := s.EXEC(fmt.Sprintf("ldd %s", targetBinary))
if err != nil {
println(string(lddOutput))
return err
}
lddString := string(lddOutput)
// Check if GTK3 is present
var DeployGtkVersion string
if s.CONTAINS(lddString, "libgtk-x11-2.0.so") {
DeployGtkVersion = "2"
} else if s.CONTAINS(lddString, "libgtk-3.so") {
DeployGtkVersion = "3"
} else if s.CONTAINS(lddString, "libgtk-4.so") {
DeployGtkVersion = "4"
} else {
return fmt.Errorf("unable to determine GTK version")
}
// Run linuxdeploy to bundle the application
s.CD(options.BuildDir)
log(p, "Generating AppImage (This may take a while...)")
cmd := fmt.Sprintf("./linuxdeploy-x86_64.AppImage --appimage-extract-and-run --appdir %s --output appimage --plugin gtk", appDir)
s.SETENV("DEPLOY_GTK_VERSION", DeployGtkVersion)
output, err := s.EXEC(cmd)
if err != nil {
println(output)
return err
}

// Move file to output directory
targetFile := filepath.Join(options.BuildDir, name+"-x86_64.AppImage")
s.MOVE(targetFile, options.OutputDir)

log(p, "AppImage created: "+targetFile)
return nil
}
80 changes: 80 additions & 0 deletions v3/internal/commands/appimage_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//go:build full_test

package commands_test

import (
"github.com/wailsapp/wails/v3/internal/commands"
"github.com/wailsapp/wails/v3/internal/s"
"testing"
)

func Test_generateAppImage(t *testing.T) {

tests := []struct {
name string
options *commands.GenerateAppImageOptions
wantErr bool
setup func()
teardown func()
}{
{
name: "Should fail if binary path is not provided",
options: &commands.GenerateAppImageOptions{},
wantErr: true,
},
{
name: "Should fail if Icon is not provided",
options: &commands.GenerateAppImageOptions{
Binary: "testapp",
},
wantErr: true,
},

{
name: "Should fail if desktop file is not provided",
options: &commands.GenerateAppImageOptions{
Binary: "testapp",
Icon: "testicon",
},
wantErr: true,
},
{
name: "Should work if inputs are valid",
options: &commands.GenerateAppImageOptions{
Binary: "testapp",
Icon: "appicon.png",
DesktopFile: "testapp.desktop",
},
setup: func() {
// Compile the test application
s.CD("appimage_testfiles")
testDir := s.CWD()
_, err := s.EXEC(`go build -ldflags="-s -w" -o testapp`)
if err != nil {
t.Fatal(err)
}
s.DEFER(func() {
s.CD(testDir)
s.RM("testapp")
s.RM("testapp-x86_64.AppImage")
})
},
teardown: func() {
s.CALLDEFER()
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.setup != nil {
tt.setup()
}
if err := commands.GenerateAppImage(tt.options); (err != nil) != tt.wantErr {
t.Errorf("generateAppImage() error = %v, wantErr %v", err, tt.wantErr)
}
if tt.teardown != nil {
tt.teardown()
}
})
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 12efb8b

Please sign in to comment.