Skip to content

Commit bf5e100

Browse files
authored
Support install/run on Linux, extend arch support (#208)
* add zip linux target * implement linux support * handle case where executable is in path * fix early call to start indexing * build internal go lib for multiple architectures * update asset name generation
1 parent 7c11bd6 commit bf5e100

6 files changed

Lines changed: 122 additions & 66 deletions

File tree

apps/electron/electron-builder.yml

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ files:
77
- node_modules
88
- package.json
99
afterSign: '.erb/scripts/notarize.js'
10+
artifactName: flowser-${version}-${os}-${arch}.${ext}
1011

1112
mac:
1213
target:
@@ -19,8 +20,14 @@ mac:
1920
entitlements: assets/entitlements.mac.plist
2021
entitlementsInherit: assets/entitlements.mac.plist
2122
gatekeeperAssess: false
22-
artifactName: flowser-${version}-${os}-${arch}.${ext}
2323
category: public.app-category.developer-tools
24+
extraResources:
25+
# To reference files outside the electron directory we need to use the FileSet API.
26+
# See: https://github.com/electron-userland/electron-builder/issues/2693
27+
- from: '../../packages/nodejs/bin/flowser-internal-amd64-darwin'
28+
to: '.'
29+
- from: '../../packages/nodejs/bin/flowser-internal-arm64-darwin'
30+
to: '.'
2431

2532
dmg:
2633
contents:
@@ -32,14 +39,12 @@ dmg:
3239
y: 358
3340
type: link
3441
path: '/Applications'
35-
artifactName: flowser-${version}-${os}-${arch}.${ext}
3642
background: assets/macos-background.tiff
3743

3844
nsis:
3945
oneClick: false
4046
allowToChangeInstallationDirectory: false
4147
deleteAppDataOnUninstall: true
42-
artifactName: flowser-${version}-${os}-${arch}.${ext}
4348

4449
win:
4550
target:
@@ -51,35 +56,40 @@ win:
5156
arch:
5257
- arm64
5358
- x64
54-
artifactName: flowser-${version}-${os}-${arch}.${ext}
5559
icon: generated-icons/icons/win/icon.ico
60+
extraResources:
61+
# To reference files outside the electron directory we need to use the FileSet API.
62+
# See: https://github.com/electron-userland/electron-builder/issues/2693
63+
- from: '../../packages/nodejs/bin/flowser-internal-amd64-windows.exe'
64+
to: '.'
65+
- from: '../../packages/nodejs/bin/flowser-internal-arm64-windows.exe'
66+
to: '.'
5667

5768
linux:
5869
target:
5970
- target: deb
6071
arch:
6172
- arm64
6273
- x64
74+
- target: zip
75+
arch:
76+
- arm64
77+
- x64
6378
category: Development
6479
icon: generated-icons/icons/png/
65-
artifactName: flowser-${version}-${os}-${arch}.${ext}
80+
extraResources:
81+
# To reference files outside the electron directory we need to use the FileSet API.
82+
# See: https://github.com/electron-userland/electron-builder/issues/2693
83+
- from: '../../packages/nodejs/bin/flowser-internal-amd64-linux'
84+
to: '.'
85+
- from: '../../packages/nodejs/bin/flowser-internal-arm64-linux'
86+
to: '.'
6687

6788
directories:
6889
app: release/app
6990
buildResources: assets
7091
output: release/build
7192

72-
extraResources:
73-
- './assets/**'
74-
# To reference files outside the electron directory we need to use the FileSet API.
75-
# See: https://github.com/electron-userland/electron-builder/issues/2693
76-
- from: '../../packages/nodejs/bin/flowser-internal-amd64-darwin'
77-
to: '.'
78-
- from: '../../packages/nodejs/bin/flowser-internal-amd64-linux'
79-
to: '.'
80-
- from: '../../packages/nodejs/bin/flowser-internal-amd64.exe'
81-
to: '.'
82-
8393
publish:
8494
provider: github
8595
owner: onflowser

apps/electron/src/services/flowser-app.service.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import { DependencyManagerService } from './dependency-manager.service';
3131

3232
// Root service that ties all the pieces together and orchestrates them.
3333
export class FlowserAppService {
34-
static instance: FlowserAppService;
3534
public readonly flowGatewayService: FlowGatewayService;
3635
public readonly flowIndexerService: FlowIndexerService;
3736
public readonly flowAccountStorageService: FlowAccountStorageService;
@@ -272,7 +271,6 @@ export class FlowserAppService {
272271

273272
this.walletStorageService.setFileName(`flowser-wallet-${workspaceId}.json`);
274273

275-
this.processingScheduler.start();
276274
await this.startAndReindexEmulator(workspace);
277275
}
278276

@@ -306,6 +304,7 @@ export class FlowserAppService {
306304
});
307305
}
308306

307+
this.processingScheduler.start();
309308
await this.walletService.synchronizeIndex();
310309
await this.flowSnapshotsService.synchronizeIndex();
311310
}
Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
EXEC_PATH=bin
1+
OUT_PATH=bin
22
BIN_PREFIX=flowser-internal
33
SOURCE_PATH=../../internal/main.go
44

@@ -10,12 +10,25 @@ SOURCE_PATH=../../internal/main.go
1010

1111
# https://freshman.tech/snippets/go/cross-compile-go-programs
1212

13+
rm -r $OUT_PATH
14+
mkdir -p $OUT_PATH
15+
16+
function build() {
17+
GOOS=$1
18+
GOARCH=$2
19+
POSTFIX=$3
20+
GOOS=$GOOS GOARCH=$GOARCH go build -o "${OUT_PATH}/${BIN_PREFIX}-${GOARCH}-${GOOS}${POSTFIX}" "${SOURCE_PATH}"
21+
}
22+
1323
# Windows
14-
GOOS=windows GOARCH=amd64 go build -o "${EXEC_PATH}/${BIN_PREFIX}-amd64.exe" "${SOURCE_PATH}"
24+
build windows amd64 .exe
25+
build windows arm64 .exe
1526

1627
# MacOS
17-
GOOS=darwin GOARCH=amd64 go build -o "${EXEC_PATH}/${BIN_PREFIX}-amd64-darwin" "${SOURCE_PATH}"
28+
build darwin amd64
29+
build darwin arm64
1830

1931
# Linux
20-
GOOS=linux GOARCH=amd64 go build -o "${EXEC_PATH}/${BIN_PREFIX}-amd64-linux" "${SOURCE_PATH}"
32+
build linux amd64
33+
build linux arm64
2134

packages/nodejs/src/go-bindings.service.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,34 @@ export class GoBindingsService {
101101
}
102102

103103
private getExecutableName(): string {
104-
switch (os.platform()) {
105-
case "darwin":
106-
return "flowser-internal-amd64-darwin";
107-
case "linux":
108-
return "flowser-internal-amd64-linux";
109-
case "win32":
110-
return "flowser-internal-amd64.exe";
111-
default:
112-
throw new Error(`Unsupported platform: ${os.platform()}`);
104+
const archRemap = new Map([
105+
["x64", "amd64"]
106+
]);
107+
const platformRemap = new Map([
108+
["win32", "windows"]
109+
]);
110+
111+
const arch = archRemap.get(os.arch()) ?? os.arch();
112+
const platform = platformRemap.get(os.platform()) ?? os.platform();
113+
const extension = platform === "windows" ? ".exe" : "";
114+
115+
const supportedArches = new Set([
116+
"amd64",
117+
"arm64"
118+
]);
119+
if (!supportedArches.has(arch)) {
120+
throw new Error(`Unsupported architecture: ${arch}`)
113121
}
122+
123+
const supportedPlatforms = new Set([
124+
"darwin",
125+
"linux",
126+
"win32"
127+
]);
128+
if (!supportedPlatforms.has(platform)) {
129+
throw new Error(`Unsupported platform: ${platform}`)
130+
}
131+
132+
return `flowser-internal-${arch}-${platform}${extension}`
114133
}
115134
}

pkg/flowser/app.go

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
const (
2121
darwin = "darwin"
2222
windows = "windows"
23+
linux = "linux"
2324
)
2425

2526
// New create new Flowser application.
@@ -29,7 +30,7 @@ func New() *App {
2930

3031
type App struct{}
3132

32-
var errorPlatformNotSupported = errors.New("OS not supported, only supporting Windows and Mac OS")
33+
var errorPlatformNotSupported = errors.New("platform not supported, please submit an issue: https://github.com/onflowser/flowser/issues")
3334

3435
// Run starts the Flowser application with provided path to the flow project.
3536
//
@@ -94,23 +95,26 @@ func (a *App) Remove(installDir string) error {
9495
// unzip content from source compressed file to a target directory.
9596
func (a *App) unzip(source string, target string) error {
9697
var cmd *exec.Cmd
98+
99+
appDir, err := a.appDir(target)
100+
if err != nil {
101+
return err
102+
}
103+
97104
switch runtime.GOOS {
98105
case darwin:
99106
// Use native unzip tool as it handles the creation of required symbolic links
100107
cmd = exec.Command("unzip", source, "-d", target)
101108
case windows:
102-
appDir, err := a.appDir(target)
103-
if err != nil {
104-
return err
105-
}
106-
107109
if err := os.MkdirAll(appDir, os.ModePerm); err != nil {
108110
return err
109111
}
110112

111113
// tar utility is available from Windows build 17063 consider using other command or a custom implementation
112114
// https://learn.microsoft.com/en-us/virtualization/community/team-blog/2017/20171219-tar-and-curl-come-to-windows
113115
cmd = exec.Command("tar", "-xf", source, "-C", appDir)
116+
case linux:
117+
cmd = exec.Command("unzip", source, "-d", appDir)
114118
default:
115119
return errorPlatformNotSupported
116120
}
@@ -123,6 +127,7 @@ func (a *App) appDir(installDir string) (string, error) {
123127
files := map[string]string{
124128
darwin: "Flowser.app",
125129
windows: "@flowserapp",
130+
linux: "Flowser",
126131
}
127132
executable, ok := files[runtime.GOOS]
128133
if !ok {
@@ -137,18 +142,25 @@ func (a *App) executable(installDir string) (string, error) {
137142
files := map[string]string{
138143
darwin: "Contents/MacOS/Flowser",
139144
windows: "Flowser.exe",
145+
linux: "flowser",
140146
}
141-
file, ok := files[runtime.GOOS]
147+
execFileSubPath, ok := files[runtime.GOOS]
142148
if !ok {
143149
return "", errorPlatformNotSupported
144150
}
145151

152+
// some linux installers may install app in folder present in PATH.
153+
execFilePath, err := exec.LookPath("flowser")
154+
if err == nil {
155+
return execFilePath, nil
156+
}
157+
146158
appDir, err := a.appDir(installDir)
147159
if err != nil {
148160
return "", err
149161
}
150162

151-
return path.Join(appDir, file), nil
163+
return path.Join(appDir, execFileSubPath), nil
152164
}
153165

154166
func downloadLatestReleaseAsset() (string, error) {
@@ -189,10 +201,7 @@ func getLatestRelease() (*flowserRelease, error) {
189201
return nil, err
190202
}
191203
latestVersion := strings.Replace(*release.TagName, "v", "", 1)
192-
targetAssetName, err := getAssetName(latestVersion)
193-
if err != nil {
194-
return nil, err
195-
}
204+
targetAssetName := getAssetName(latestVersion)
196205
for _, asset := range release.Assets {
197206
if *asset.Name == targetAssetName {
198207
return &flowserRelease{
@@ -201,20 +210,9 @@ func getLatestRelease() (*flowserRelease, error) {
201210
}, nil
202211
}
203212
}
204-
return nil, errors.New("no asset found")
213+
return nil, fmt.Errorf("asset not found: %s", targetAssetName)
205214
}
206215

207-
func getAssetName(version string) (string, error) {
208-
isArm := strings.HasPrefix(runtime.GOARCH, "arm")
209-
switch runtime.GOOS {
210-
case darwin:
211-
if isArm {
212-
return fmt.Sprintf("Flowser-%s-arm64-mac.zip", version), nil
213-
}
214-
return fmt.Sprintf("Flowser-%s-mac.zip", version), nil
215-
case windows:
216-
return fmt.Sprintf("Flowser-%s-win.zip", version), nil
217-
default:
218-
return "", errorPlatformNotSupported
219-
}
216+
func getAssetName(version string) string {
217+
return fmt.Sprintf("Flowser-%s-%s-%s.zip", version, runtime.GOOS, runtime.GOARCH)
220218
}

pkg/main/main.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,42 @@ package main
22

33
import (
44
"fmt"
5-
"github.com/onflowser/flowser/pkg/flowser"
65
"os"
7-
"path"
6+
7+
"github.com/onflowser/flowser/v2/pkg/flowser"
88
)
99

1010
func main() {
11+
if len(os.Args) < 3 {
12+
panic("Missing args. Usage: <command_name> <install_dir>")
13+
}
14+
15+
commandName := os.Args[1]
16+
installDir := os.Args[2]
17+
1118
app := flowser.New()
12-
installDir := path.Join("..", "test-install")
1319

14-
if !app.Installed(installDir) {
20+
switch commandName {
21+
case "install":
22+
if app.Installed(installDir) {
23+
fmt.Println("Already installed")
24+
os.Exit(0)
25+
}
1526
err := app.Install(installDir)
16-
fmt.Println("Installing Flowser...")
1727
if err != nil {
1828
panic(err)
1929
}
2030

21-
}
31+
case "run":
32+
if len(os.Args) != 4 {
33+
fmt.Println("Missing project dir arg")
34+
os.Exit(1)
35+
}
36+
projectDir := os.Args[3]
37+
err := app.Run(installDir, projectDir)
2238

23-
projectDir := os.Args[1]
24-
fmt.Println("Running Flowser")
25-
app.Run(installDir, projectDir)
39+
if err != nil {
40+
panic(err)
41+
}
42+
}
2643
}

0 commit comments

Comments
 (0)