Skip to content

Commit b0d57fc

Browse files
committed
Add AppImage
1 parent ae772f1 commit b0d57fc

File tree

7 files changed

+146
-8
lines changed

7 files changed

+146
-8
lines changed

cmd/build.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func init() {
5151
buildCmd.AddCommand(buildLinuxCmd)
5252
buildCmd.AddCommand(buildLinuxSnapCmd)
5353
buildCmd.AddCommand(buildLinuxDebCmd)
54+
buildCmd.AddCommand(buildLinuxAppImageCmd)
5455
buildCmd.AddCommand(buildDarwinCmd)
5556
buildCmd.AddCommand(buildWindowsCmd)
5657
buildCmd.AddCommand(buildWindowsMsiCmd)
@@ -104,6 +105,22 @@ var buildLinuxDebCmd = &cobra.Command{
104105
},
105106
}
106107

108+
var buildLinuxAppImageCmd = &cobra.Command{
109+
Use: "linux-appimage",
110+
Short: "Build a desktop release for linux and package it for AppImage",
111+
Run: func(cmd *cobra.Command, args []string) {
112+
assertHoverInitialized()
113+
packaging.AssertPackagingFormatInitialized("linux-appimage")
114+
115+
if !packaging.DockerInstalled() {
116+
os.Exit(1)
117+
}
118+
119+
buildNormal("linux", nil)
120+
packaging.BuildLinuxAppImage()
121+
},
122+
}
123+
107124
var buildDarwinCmd = &cobra.Command{
108125
Use: "darwin",
109126
Short: "Build a desktop release for darwin",
@@ -374,7 +391,7 @@ func buildNormal(targetOS string, vmArguments []string) {
374391
}
375392

376393
if semver.Prerelease() != "" {
377-
log.Infof("Upgrade 'go-flutter' to the latest release")
394+
log.Infof("Upgrading 'go-flutter' to the latest release")
378395
// no buildBranch provided and currentTag isn't a release,
379396
// force update. (same behaviour as previous version of hover).
380397
err = upgradeGoFlutter(targetOS, engineCachePath)
@@ -385,7 +402,7 @@ func buildNormal(targetOS string, vmArguments []string) {
385402
} else {
386403
// when the buildBranch is empty and the currentTag is a release.
387404
// Check if the 'go-flutter' needs updates.
388-
versioncheck.CheckFoGoFlutterUpdate(filepath.Join(wd, build.BuildPath), currentTag)
405+
versioncheck.CheckForGoFlutterUpdate(filepath.Join(wd, build.BuildPath), currentTag)
389406
}
390407

391408
} else {

cmd/packaging.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
func init() {
1010
initPackagingCmd.AddCommand(initLinuxSnapCmd)
1111
initPackagingCmd.AddCommand(initLinuxDebCmd)
12+
initPackagingCmd.AddCommand(initLinuxAppImageCmd)
1213
initPackagingCmd.AddCommand(initWindowsMsiCmd)
1314
rootCmd.AddCommand(initPackagingCmd)
1415
}
@@ -40,6 +41,17 @@ var initLinuxDebCmd = &cobra.Command{
4041
},
4142
}
4243

44+
var initLinuxAppImageCmd = &cobra.Command{
45+
Use: "linux-appimage",
46+
Short: "Create configuration files for AppImage packaging",
47+
Run: func(cmd *cobra.Command, args []string) {
48+
assertHoverInitialized()
49+
packaging.DockerInstalled()
50+
51+
packaging.InitLinuxAppImage()
52+
},
53+
}
54+
4355
var initWindowsMsiCmd = &cobra.Command{
4456
Use: "windows-msi",
4557
Short: "Create configuration files for msi packaging",
@@ -49,4 +61,4 @@ var initWindowsMsiCmd = &cobra.Command{
4961

5062
packaging.InitWindowsMsi()
5163
},
52-
}
64+
}

cmd/packaging/linux-appimage.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package packaging
2+
3+
import (
4+
"github.com/go-flutter-desktop/hover/internal/build"
5+
"github.com/go-flutter-desktop/hover/internal/log"
6+
"github.com/go-flutter-desktop/hover/internal/pubspec"
7+
"github.com/otiai10/copy"
8+
"os"
9+
"path/filepath"
10+
)
11+
12+
func InitLinuxAppImage() {
13+
projectName := pubspec.GetPubSpec().Name
14+
packagingFormat := "linux-appimage"
15+
createPackagingFormatDirectory(packagingFormat)
16+
appImageDirectoryPath := packagingFormatPath(packagingFormat)
17+
appRunFilePath, err := filepath.Abs(filepath.Join(appImageDirectoryPath, "AppRun"))
18+
if err != nil {
19+
log.Errorf("Failed to resolve absolute path for AppRun file %s: %v", appRunFilePath, err)
20+
os.Exit(1)
21+
}
22+
23+
appRunFile, err := os.Create(appRunFilePath)
24+
if err != nil {
25+
log.Errorf("Failed to create AppRun file %s: %v", appRunFilePath, err)
26+
os.Exit(1)
27+
}
28+
appRunFileContent := []string{
29+
`#!/bin/sh`,
30+
`cd "$(dirname "$0")"`,
31+
`exec ./build/` + projectName,
32+
}
33+
for _, line := range appRunFileContent {
34+
if _, err := appRunFile.WriteString(line + "\n"); err != nil {
35+
log.Errorf("Could not write AppRun file: %v", err)
36+
os.Exit(1)
37+
}
38+
}
39+
err = appRunFile.Close()
40+
if err != nil {
41+
log.Errorf("Could not close AppRun file: %v", err)
42+
os.Exit(1)
43+
}
44+
err = os.Chmod(appRunFilePath, 0777)
45+
if err != nil {
46+
log.Errorf("Failed to change file permissions for AppRun file: %v", err)
47+
os.Exit(1)
48+
}
49+
50+
desktopFilePath, err := filepath.Abs(filepath.Join(appImageDirectoryPath, projectName+".desktop"))
51+
if err != nil {
52+
log.Errorf("Failed to resolve absolute path for desktop file %s: %v", desktopFilePath, err)
53+
os.Exit(1)
54+
}
55+
createLinuxDesktopFile(desktopFilePath, packagingFormat, "", "/build/assets/icon")
56+
createDockerfile(packagingFormat)
57+
58+
printInitFinished(packagingFormat)
59+
}
60+
61+
func BuildLinuxAppImage() {
62+
projectName := pubspec.GetPubSpec().Name
63+
packagingFormat := "linux-appimage"
64+
tmpPath := getTemporaryBuildDirectory(projectName, packagingFormat)
65+
log.Infof("Packaging AppImage in %s", tmpPath)
66+
67+
err := copy.Copy(build.OutputDirectoryPath("linux"), filepath.Join(tmpPath, "build"))
68+
if err != nil {
69+
log.Errorf("Could not copy build folder: %v", err)
70+
os.Exit(1)
71+
}
72+
err = copy.Copy(packagingFormatPath(packagingFormat), filepath.Join(tmpPath))
73+
if err != nil {
74+
log.Errorf("Could not copy packaging configuration folder: %v", err)
75+
os.Exit(1)
76+
}
77+
78+
outputFileName := projectName + "-x86_64.AppImage"
79+
outputFilePath := filepath.Join(build.OutputDirectoryPath("linux-appimage"), outputFileName)
80+
runDockerPackaging(tmpPath, packagingFormat, []string{"appimagetool", ".",})
81+
82+
err = os.Rename(filepath.Join(tmpPath, outputFileName), outputFilePath)
83+
if err != nil {
84+
log.Errorf("Could not move AppImage file: %v", err)
85+
os.Exit(1)
86+
}
87+
err = os.RemoveAll(tmpPath)
88+
if err != nil {
89+
log.Errorf("Could not remove temporary build directory: %v", err)
90+
os.Exit(1)
91+
}
92+
printPackagingFinished(packagingFormat)
93+
}

cmd/packaging/linux.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ func createLinuxDesktopFile(desktopFilePath string, packagingFormat string, exec
1616
}
1717
desktopFileContent := []string{
1818
"[Desktop Entry]",
19-
"Encoding=UTF-8",
20-
"Version=" + pubspec.GetPubSpec().Version,
19+
"Version=1.0",
2120
"Type=Application",
2221
"Terminal=false",
23-
"Exec=" + exec,
2422
"Name=" + pubspec.GetPubSpec().Name,
2523
"Icon=" + icon,
24+
"Categories=",
25+
}
26+
if exec != "" {
27+
desktopFileContent = append(desktopFileContent, "Exec="+exec)
2628
}
2729

2830
for _, line := range desktopFileContent {

cmd/packaging/packaging.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,19 @@ func createDockerfile(packagingFormat string) {
109109
dockerFileContent = []string{
110110
"FROM ubuntu:bionic",
111111
}
112+
} else if packagingFormat == "linux-appimage" {
113+
dockerFileContent = []string{
114+
"FROM ubuntu:bionic",
115+
"WORKDIR /opt",
116+
"RUN apt-get update && \\",
117+
"apt-get install libglib2.0-0 curl file -y",
118+
"RUN curl -LO https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage && \\",
119+
"chmod a+x appimagetool-x86_64.AppImage && \\",
120+
"./appimagetool-x86_64.AppImage --appimage-extract && \\",
121+
"mv squashfs-root appimagetool && \\",
122+
"rm appimagetool-x86_64.AppImage",
123+
"ENV PATH=/opt/appimagetool/usr/bin:/opt/linuxdeploy/usr/bin:$PATH",
124+
}
112125
} else if packagingFormat == "windows-msi" {
113126
dockerFileContent = []string{
114127
"FROM ubuntu:bionic",

cmd/upgrade.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func upgradeGoFlutter(targetOS string, engineCachePath string) (err error) {
6868
cmdGoGetU := exec.Command(build.GoBin, "get", "-u", "github.com/go-flutter-desktop/go-flutter"+buildBranch)
6969
cmdGoGetU.Dir = filepath.Join(wd, build.BuildPath)
7070
cmdGoGetU.Env = append(os.Environ(),
71+
"GOPROXY=direct", // github.com/golang/go/issues/32955 (allows '/' in branch name)
7172
"GO111MODULE=on",
7273
"CGO_LDFLAGS="+cgoLdflags,
7374
)

internal/versioncheck/version.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ import (
1414
"github.com/tcnksm/go-latest"
1515
)
1616

17-
// CheckFoGoFlutterUpdate check the last 'go-flutter' timestamp we have cached
17+
// CheckForGoFlutterUpdate check the last 'go-flutter' timestamp we have cached
1818
// for the current project. If the last update comes back to more than X days,
1919
// fetch the last Github release semver. If the Github semver is more recent
2020
// than the current one, display the update notice.
21-
func CheckFoGoFlutterUpdate(goDirectoryPath string, currentTag string) {
21+
func CheckForGoFlutterUpdate(goDirectoryPath string, currentTag string) {
2222
cachedGoFlutterCheckPath := filepath.Join(goDirectoryPath, ".last_goflutter_check")
2323
cachedGoFlutterCheckBytes, err := ioutil.ReadFile(cachedGoFlutterCheckPath)
2424
if err != nil && !os.IsNotExist(err) {

0 commit comments

Comments
 (0)