Skip to content

Commit

Permalink
Support install/run on Linux, extend arch support (#208)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
bartolomej authored Nov 13, 2023
1 parent 7c11bd6 commit bf5e100
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 66 deletions.
42 changes: 26 additions & 16 deletions apps/electron/electron-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ files:
- node_modules
- package.json
afterSign: '.erb/scripts/notarize.js'
artifactName: flowser-${version}-${os}-${arch}.${ext}

mac:
target:
Expand All @@ -19,8 +20,14 @@ mac:
entitlements: assets/entitlements.mac.plist
entitlementsInherit: assets/entitlements.mac.plist
gatekeeperAssess: false
artifactName: flowser-${version}-${os}-${arch}.${ext}
category: public.app-category.developer-tools
extraResources:
# To reference files outside the electron directory we need to use the FileSet API.
# See: https://github.com/electron-userland/electron-builder/issues/2693
- from: '../../packages/nodejs/bin/flowser-internal-amd64-darwin'
to: '.'
- from: '../../packages/nodejs/bin/flowser-internal-arm64-darwin'
to: '.'

dmg:
contents:
Expand All @@ -32,14 +39,12 @@ dmg:
y: 358
type: link
path: '/Applications'
artifactName: flowser-${version}-${os}-${arch}.${ext}
background: assets/macos-background.tiff

nsis:
oneClick: false
allowToChangeInstallationDirectory: false
deleteAppDataOnUninstall: true
artifactName: flowser-${version}-${os}-${arch}.${ext}

win:
target:
Expand All @@ -51,35 +56,40 @@ win:
arch:
- arm64
- x64
artifactName: flowser-${version}-${os}-${arch}.${ext}
icon: generated-icons/icons/win/icon.ico
extraResources:
# To reference files outside the electron directory we need to use the FileSet API.
# See: https://github.com/electron-userland/electron-builder/issues/2693
- from: '../../packages/nodejs/bin/flowser-internal-amd64-windows.exe'
to: '.'
- from: '../../packages/nodejs/bin/flowser-internal-arm64-windows.exe'
to: '.'

linux:
target:
- target: deb
arch:
- arm64
- x64
- target: zip
arch:
- arm64
- x64
category: Development
icon: generated-icons/icons/png/
artifactName: flowser-${version}-${os}-${arch}.${ext}
extraResources:
# To reference files outside the electron directory we need to use the FileSet API.
# See: https://github.com/electron-userland/electron-builder/issues/2693
- from: '../../packages/nodejs/bin/flowser-internal-amd64-linux'
to: '.'
- from: '../../packages/nodejs/bin/flowser-internal-arm64-linux'
to: '.'

directories:
app: release/app
buildResources: assets
output: release/build

extraResources:
- './assets/**'
# To reference files outside the electron directory we need to use the FileSet API.
# See: https://github.com/electron-userland/electron-builder/issues/2693
- from: '../../packages/nodejs/bin/flowser-internal-amd64-darwin'
to: '.'
- from: '../../packages/nodejs/bin/flowser-internal-amd64-linux'
to: '.'
- from: '../../packages/nodejs/bin/flowser-internal-amd64.exe'
to: '.'

publish:
provider: github
owner: onflowser
Expand Down
3 changes: 1 addition & 2 deletions apps/electron/src/services/flowser-app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import { DependencyManagerService } from './dependency-manager.service';

// Root service that ties all the pieces together and orchestrates them.
export class FlowserAppService {
static instance: FlowserAppService;
public readonly flowGatewayService: FlowGatewayService;
public readonly flowIndexerService: FlowIndexerService;
public readonly flowAccountStorageService: FlowAccountStorageService;
Expand Down Expand Up @@ -272,7 +271,6 @@ export class FlowserAppService {

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

this.processingScheduler.start();
await this.startAndReindexEmulator(workspace);
}

Expand Down Expand Up @@ -306,6 +304,7 @@ export class FlowserAppService {
});
}

this.processingScheduler.start();
await this.walletService.synchronizeIndex();
await this.flowSnapshotsService.synchronizeIndex();
}
Expand Down
21 changes: 17 additions & 4 deletions packages/nodejs/build-go-bindings.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
EXEC_PATH=bin
OUT_PATH=bin
BIN_PREFIX=flowser-internal
SOURCE_PATH=../../internal/main.go

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

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

rm -r $OUT_PATH
mkdir -p $OUT_PATH

function build() {
GOOS=$1
GOARCH=$2
POSTFIX=$3
GOOS=$GOOS GOARCH=$GOARCH go build -o "${OUT_PATH}/${BIN_PREFIX}-${GOARCH}-${GOOS}${POSTFIX}" "${SOURCE_PATH}"
}

# Windows
GOOS=windows GOARCH=amd64 go build -o "${EXEC_PATH}/${BIN_PREFIX}-amd64.exe" "${SOURCE_PATH}"
build windows amd64 .exe
build windows arm64 .exe

# MacOS
GOOS=darwin GOARCH=amd64 go build -o "${EXEC_PATH}/${BIN_PREFIX}-amd64-darwin" "${SOURCE_PATH}"
build darwin amd64
build darwin arm64

# Linux
GOOS=linux GOARCH=amd64 go build -o "${EXEC_PATH}/${BIN_PREFIX}-amd64-linux" "${SOURCE_PATH}"
build linux amd64
build linux arm64

37 changes: 28 additions & 9 deletions packages/nodejs/src/go-bindings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,34 @@ export class GoBindingsService {
}

private getExecutableName(): string {
switch (os.platform()) {
case "darwin":
return "flowser-internal-amd64-darwin";
case "linux":
return "flowser-internal-amd64-linux";
case "win32":
return "flowser-internal-amd64.exe";
default:
throw new Error(`Unsupported platform: ${os.platform()}`);
const archRemap = new Map([
["x64", "amd64"]
]);
const platformRemap = new Map([
["win32", "windows"]
]);

const arch = archRemap.get(os.arch()) ?? os.arch();
const platform = platformRemap.get(os.platform()) ?? os.platform();
const extension = platform === "windows" ? ".exe" : "";

const supportedArches = new Set([
"amd64",
"arm64"
]);
if (!supportedArches.has(arch)) {
throw new Error(`Unsupported architecture: ${arch}`)
}

const supportedPlatforms = new Set([
"darwin",
"linux",
"win32"
]);
if (!supportedPlatforms.has(platform)) {
throw new Error(`Unsupported platform: ${platform}`)
}

return `flowser-internal-${arch}-${platform}${extension}`
}
}
50 changes: 24 additions & 26 deletions pkg/flowser/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
const (
darwin = "darwin"
windows = "windows"
linux = "linux"
)

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

type App struct{}

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

// Run starts the Flowser application with provided path to the flow project.
//
Expand Down Expand Up @@ -94,23 +95,26 @@ func (a *App) Remove(installDir string) error {
// unzip content from source compressed file to a target directory.
func (a *App) unzip(source string, target string) error {
var cmd *exec.Cmd

appDir, err := a.appDir(target)
if err != nil {
return err
}

switch runtime.GOOS {
case darwin:
// Use native unzip tool as it handles the creation of required symbolic links
cmd = exec.Command("unzip", source, "-d", target)
case windows:
appDir, err := a.appDir(target)
if err != nil {
return err
}

if err := os.MkdirAll(appDir, os.ModePerm); err != nil {
return err
}

// tar utility is available from Windows build 17063 consider using other command or a custom implementation
// https://learn.microsoft.com/en-us/virtualization/community/team-blog/2017/20171219-tar-and-curl-come-to-windows
cmd = exec.Command("tar", "-xf", source, "-C", appDir)
case linux:
cmd = exec.Command("unzip", source, "-d", appDir)
default:
return errorPlatformNotSupported
}
Expand All @@ -123,6 +127,7 @@ func (a *App) appDir(installDir string) (string, error) {
files := map[string]string{
darwin: "Flowser.app",
windows: "@flowserapp",
linux: "Flowser",
}
executable, ok := files[runtime.GOOS]
if !ok {
Expand All @@ -137,18 +142,25 @@ func (a *App) executable(installDir string) (string, error) {
files := map[string]string{
darwin: "Contents/MacOS/Flowser",
windows: "Flowser.exe",
linux: "flowser",
}
file, ok := files[runtime.GOOS]
execFileSubPath, ok := files[runtime.GOOS]
if !ok {
return "", errorPlatformNotSupported
}

// some linux installers may install app in folder present in PATH.
execFilePath, err := exec.LookPath("flowser")
if err == nil {
return execFilePath, nil
}

appDir, err := a.appDir(installDir)
if err != nil {
return "", err
}

return path.Join(appDir, file), nil
return path.Join(appDir, execFileSubPath), nil
}

func downloadLatestReleaseAsset() (string, error) {
Expand Down Expand Up @@ -189,10 +201,7 @@ func getLatestRelease() (*flowserRelease, error) {
return nil, err
}
latestVersion := strings.Replace(*release.TagName, "v", "", 1)
targetAssetName, err := getAssetName(latestVersion)
if err != nil {
return nil, err
}
targetAssetName := getAssetName(latestVersion)
for _, asset := range release.Assets {
if *asset.Name == targetAssetName {
return &flowserRelease{
Expand All @@ -201,20 +210,9 @@ func getLatestRelease() (*flowserRelease, error) {
}, nil
}
}
return nil, errors.New("no asset found")
return nil, fmt.Errorf("asset not found: %s", targetAssetName)
}

func getAssetName(version string) (string, error) {
isArm := strings.HasPrefix(runtime.GOARCH, "arm")
switch runtime.GOOS {
case darwin:
if isArm {
return fmt.Sprintf("Flowser-%s-arm64-mac.zip", version), nil
}
return fmt.Sprintf("Flowser-%s-mac.zip", version), nil
case windows:
return fmt.Sprintf("Flowser-%s-win.zip", version), nil
default:
return "", errorPlatformNotSupported
}
func getAssetName(version string) string {
return fmt.Sprintf("Flowser-%s-%s-%s.zip", version, runtime.GOOS, runtime.GOARCH)
}
35 changes: 26 additions & 9 deletions pkg/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,42 @@ package main

import (
"fmt"
"github.com/onflowser/flowser/pkg/flowser"
"os"
"path"

"github.com/onflowser/flowser/v2/pkg/flowser"
)

func main() {
if len(os.Args) < 3 {
panic("Missing args. Usage: <command_name> <install_dir>")
}

commandName := os.Args[1]
installDir := os.Args[2]

app := flowser.New()
installDir := path.Join("..", "test-install")

if !app.Installed(installDir) {
switch commandName {
case "install":
if app.Installed(installDir) {
fmt.Println("Already installed")
os.Exit(0)
}
err := app.Install(installDir)
fmt.Println("Installing Flowser...")
if err != nil {
panic(err)
}

}
case "run":
if len(os.Args) != 4 {
fmt.Println("Missing project dir arg")
os.Exit(1)
}
projectDir := os.Args[3]
err := app.Run(installDir, projectDir)

projectDir := os.Args[1]
fmt.Println("Running Flowser")
app.Run(installDir, projectDir)
if err != nil {
panic(err)
}
}
}

0 comments on commit bf5e100

Please sign in to comment.