Skip to content

Commit

Permalink
feat(proton-native): package proton-native for Windows
Browse files Browse the repository at this point in the history
Close #3444, Close #3472, Close #3113
  • Loading branch information
develar committed Nov 15, 2018
1 parent a46f79a commit fd86d92
Show file tree
Hide file tree
Showing 69 changed files with 665 additions and 882 deletions.
4 changes: 4 additions & 0 deletions .idea/dictionaries/develar.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions .idea/jsLibraryMappings.xml

This file was deleted.

3 changes: 0 additions & 3 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 4 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"dependencies": {
"7zip-bin": "~4.1.0",
"@types/is-ci": "^1.1.0",
"app-builder-bin": "2.4.3",
"app-builder-bin": "2.5.1",
"archiver": "^3.0.0",
"async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.6",
Expand Down Expand Up @@ -69,9 +69,9 @@
"yargs": "^12.0.2"
},
"devDependencies": {
"@babel/core": "^7.1.5",
"@babel/core": "^7.1.6",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-decorators": "^7.1.2",
"@babel/plugin-proposal-decorators": "^7.1.6",
"@babel/plugin-proposal-do-expressions": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
Expand All @@ -86,7 +86,7 @@
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/preset-env": "^7.1.5",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
"@types/debug": "^0.0.31",
"@types/ejs": "^2.6.0",
Expand Down Expand Up @@ -121,10 +121,6 @@
"whitespace": "^2.1.0",
"worker-farm": "^1.6.0"
},
"/////": "proton-native is required only for proton tests",
"optionalDependencies": {
"proton-native": "1.1.10"
},
"jest": {
"testEnvironment": "node",
"roots": [
Expand Down
2 changes: 1 addition & 1 deletion packages/app-builder-lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"homepage": "https://github.com/electron-userland/electron-builder",
"dependencies": {
"7zip-bin": "~4.1.0",
"app-builder-bin": "2.4.3",
"app-builder-bin": "2.5.1",
"async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.6",
"chromium-pickle-js": "^0.2.0",
Expand Down
13 changes: 10 additions & 3 deletions packages/app-builder-lib/src/Framework.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FileTransformer } from "builder-util/out/fs"
import { AsarIntegrity } from "./asar/integrity"
import { Platform, PlatformPackager, ElectronPlatformName } from "./index"
import { Platform, PlatformPackager, ElectronPlatformName, AfterPackContext } from "./index"

export interface Framework {
readonly name: string
Expand All @@ -11,13 +11,20 @@ export interface Framework {

readonly isNpmRebuildRequired: boolean

readonly isDefaultAppIconProvided: boolean
getDefaultIcon?(platform: Platform): string
readonly isCopyElevateHelper: boolean

getDefaultIcon?(platform: Platform): string | null

getMainFile?(platform: Platform): string | null

getExcludedDependencies?(platform: Platform): Array<string> | null

prepareApplicationStageDirectory(options: PrepareApplicationStageDirectoryOptions): Promise<any>

beforeCopyExtraFiles?(options: BeforeCopyExtraFilesOptions): Promise<any>

afterPack?(context: AfterPackContext): Promise<any>

createTransformer?(): FileTransformer | null
}

Expand Down
151 changes: 51 additions & 100 deletions packages/app-builder-lib/src/ProtonFramework.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,39 @@
import { chmod, emptyDir, ensureDir, writeFile } from "fs-extra-p"
import { getBin } from "./binDownload"
import { FileTransformer, copyFile } from "builder-util/out/fs"
import { FileTransformer } from "builder-util/out/fs"
import { log } from "builder-util"
import { safeStringifyJson } from "builder-util-runtime"
import { Platform } from "./core"
import { NODE_MODULES_PATTERN } from "./fileTransformer"
import { Framework, AppInfo, PrepareApplicationStageDirectoryOptions } from "./index"
import * as path from "path"
import { LinuxPackager } from "./linuxPackager"
import MacPackager from "./macPackager"
import { build as buildPlist } from "plist"
import { LibUiFramework } from "./frameworks/LibUiFramework"
import { getTemplatePath } from "./util/pathManager"

export function createProtonFrameworkSupport(nodeVersion: string, appInfo: AppInfo): Framework {
return new ProtonFramework(nodeVersion === "current" ? process.versions.node : nodeVersion, `${appInfo.productFilename}.app`)
}

class ProtonFramework implements Framework {
export class ProtonFramework extends LibUiFramework {
readonly name = "proton"
readonly isDefaultAppIconProvided = false
readonly macOsDefaultTargets = ["dmg"]
readonly defaultAppIdPrefix = "com.proton-native."

// noinspection JSUnusedGlobalSymbols
readonly isNpmRebuildRequired = false
readonly defaultAppIdPrefix = "com.proton-native."

constructor(readonly version: string, readonly distMacOsAppName: string) {
constructor(version: string, distMacOsAppName: string, isUseLaunchUi: boolean) {
super(version, distMacOsAppName, isUseLaunchUi)
}

getDefaultIcon() {
return getTemplatePath("proton-native.icns")
getDefaultIcon(platform: Platform) {
if (platform === Platform.WINDOWS) {
return getTemplatePath("icons/proton-native/proton-native.ico")
}
else if (platform === Platform.LINUX) {
return getTemplatePath("icons/proton-native/linux")
}
else {
return getTemplatePath("icons/proton-native/proton-native.icns")
}
}

createTransformer(): FileTransformer | null {
let babel: any
const babelOptions: any = {ast: false, sourceMaps: "inline"}
if (process.env.TEST_SET_BABEL_PRESET === "true") {
babel = require("@babel/core")
// out test dir can be located outside of electron-builder node_modules and babel cannot resolve string names of preset
babelOptions.presets = [
[require("@babel/preset-env").default, {targets: {node: this.version}}],
require("@babel/preset-react"),
]
babelOptions.plugins = [
// stage 0
require("@babel/plugin-proposal-function-bind").default,

// stage 1
require("@babel/plugin-proposal-export-default-from").default,
require("@babel/plugin-proposal-logical-assignment-operators").default,
[require("@babel/plugin-proposal-optional-chaining").default, {loose: false}],
[require("@babel/plugin-proposal-pipeline-operator").default, {proposal: "minimal"}],
[require("@babel/plugin-proposal-nullish-coalescing-operator").default, {loose: false}],
require("@babel/plugin-proposal-do-expressions").default,

// stage 2
[require("@babel/plugin-proposal-decorators").default, {legacy: true}],
require("@babel/plugin-proposal-function-sent").default,
require("@babel/plugin-proposal-export-namespace-from").default,
require("@babel/plugin-proposal-numeric-separator").default,
require("@babel/plugin-proposal-throw-expressions").default,

// stage 3
require("@babel/plugin-syntax-dynamic-import").default,
require("@babel/plugin-syntax-import-meta").default,
[require("@babel/plugin-proposal-class-properties").default, {loose: false}],
require("@babel/plugin-proposal-json-strings").default,
]
babelOptions.babelrc = false
babel = testOnlyBabel(babel, babelOptions, this.version)
}
else {
try {
Expand Down Expand Up @@ -98,54 +64,39 @@ class ProtonFramework implements Framework {
})
}
}

private async prepareMacosApplicationStageDirectory(packager: MacPackager, options: PrepareApplicationStageDirectoryOptions) {
const appContentsDir = path.join(options.appOutDir, this.distMacOsAppName, "Contents")
await ensureDir(path.join(appContentsDir, "Resources"))
await ensureDir(path.join(appContentsDir, "MacOS"))
await copyFile(path.join(await getBin("node", `${this.version}-darwin-x64`, null), "node"), path.join(appContentsDir, "MacOS", "node"))

const appPlist: any = {
// https://github.com/albe-rosado/create-proton-app/issues/13
NSHighResolutionCapable: true,
}
await packager.applyCommonInfo(appPlist, appContentsDir)
await Promise.all([
writeFile(path.join(appContentsDir, "Info.plist"), buildPlist(appPlist)),
writeExecutableMain(path.join(appContentsDir, "MacOS", appPlist.CFBundleExecutable), `#!/bin/sh
DIR=$(dirname "$0")
"$DIR/node" "$DIR/../Resources/app/${options.packager.info.metadata.main || "index.js"}"
`),
])
}

private async prepareLinuxApplicationStageDirectory(options: PrepareApplicationStageDirectoryOptions) {
const appOutDir = options.appOutDir
await copyFile(path.join(await getBin("node", `${this.version}-linux-${options.arch === "ia32" ? "x86" : options.arch}`, null), "node"), path.join(appOutDir, "node"))
const mainPath = path.join(appOutDir, (options.packager as LinuxPackager).executableName)
await writeExecutableMain(mainPath, `#!/bin/sh
DIR=$(dirname "$0")
"$DIR/node" "$DIR/app/${options.packager.info.metadata.main || "index.js"}"
`)
}

async prepareApplicationStageDirectory(options: PrepareApplicationStageDirectoryOptions) {
await emptyDir(options.appOutDir)

const packager = options.packager
if (packager.platform === Platform.MAC) {
await this.prepareMacosApplicationStageDirectory(packager as MacPackager, options)
}
else if (packager.platform === Platform.LINUX) {
await this.prepareLinuxApplicationStageDirectory(options)
}
else {
throw new Error(`Unsupported platform: ${packager.platform}`)
}
}
}

async function writeExecutableMain(file: string, content: string) {
await writeFile(file, content, {mode: 0o755})
await chmod(file, 0o755)
}
function testOnlyBabel(babel: any, babelOptions: any, nodeVersion: string) {
// out test dir can be located outside of electron-builder node_modules and babel cannot resolve string names of preset
babelOptions.presets = [
[require("@babel/preset-env").default, {targets: {node: nodeVersion}}],
require("@babel/preset-react"),
]
babelOptions.plugins = [
// stage 0
require("@babel/plugin-proposal-function-bind").default,

// stage 1
require("@babel/plugin-proposal-export-default-from").default,
require("@babel/plugin-proposal-logical-assignment-operators").default,
[require("@babel/plugin-proposal-optional-chaining").default, {loose: false}],
[require("@babel/plugin-proposal-pipeline-operator").default, {proposal: "minimal"}],
[require("@babel/plugin-proposal-nullish-coalescing-operator").default, {loose: false}],
require("@babel/plugin-proposal-do-expressions").default,

// stage 2
[require("@babel/plugin-proposal-decorators").default, {legacy: true}],
require("@babel/plugin-proposal-function-sent").default,
require("@babel/plugin-proposal-export-namespace-from").default,
require("@babel/plugin-proposal-numeric-separator").default,
require("@babel/plugin-proposal-throw-expressions").default,

// stage 3
require("@babel/plugin-syntax-dynamic-import").default,
require("@babel/plugin-syntax-import-meta").default,
[require("@babel/plugin-proposal-class-properties").default, {loose: false}],
require("@babel/plugin-proposal-json-strings").default,
]
babelOptions.babelrc = false
return babel
}
10 changes: 6 additions & 4 deletions packages/app-builder-lib/src/binDownload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function getBinFromGithub(name: string, version: string, checksum: string
return getBin(dirName, `https://github.com/electron-userland/electron-builder-binaries/releases/download/${dirName}/${dirName}.7z`, checksum)
}

export function getBin(name: string, url: string, checksum: string | null): Promise<string> {
export function getBin(name: string, url?: string | null, checksum?: string | null): Promise<string> {
let promise = versionToPromise.get(name)
// if rejected, we will try to download again
if (promise != null) {
Expand All @@ -27,11 +27,13 @@ export function getBin(name: string, url: string, checksum: string | null): Prom
return promise
}

function doGetBin(name: string, url: string, checksum: string | null): Promise<string> {
const args = ["download-artifact", "--url", url, "--name", name]
function doGetBin(name: string, url: string | undefined | null, checksum: string | null | undefined): Promise<string> {
const args = ["download-artifact", "--name", name]
if (url != null) {
args.push("--url", url)
}
if (checksum != null) {
args.push("--sha512", checksum)
}

return executeAppBuilder(args)
}
8 changes: 4 additions & 4 deletions packages/app-builder-lib/src/codeSign/windowsCodeSign.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { executeAppBuilderAsJson, InvalidConfigurationError, asArray, log } from "builder-util/out/util"
import { getBinFromGithub } from "../binDownload"
import { InvalidConfigurationError, asArray, log } from "builder-util/out/util"
import { getBin } from "../binDownload"
import { executeAppBuilderAsJson } from "../util/appBuilder"
import { computeToolEnv, ToolInfo } from "../util/bundledTool"
import { rename } from "fs-extra-p"
import * as os from "os"
Expand All @@ -11,8 +12,7 @@ import { VmManager } from "../vm/vm"
import { WinPackager } from "../winPackager"

export function getSignVendorPath() {
//noinspection SpellCheckingInspection
return getBinFromGithub("winCodeSign", "2.3.2", "brAICKFcwBa+5eFkq+V5JJTt1XxiQNgHwW+ahUupAl2ciAAVikgpUmN7tsdQXjifCRwK2eS3zbE6lcP5y/KRIw==")
return getBin("winCodeSign")
}

export type CustomWindowsSign = (configuration: CustomWindowsSignTaskConfiguration) => Promise<any>
Expand Down
12 changes: 12 additions & 0 deletions packages/app-builder-lib/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,20 @@ export interface Configuration extends PlatformSpecificBuildOptions {
* *Proton Native only* The version of NodeJS you are packaging for.
* You can set it to `current` to set the Node.js version that you use to run electron-builder.
*/
readonly nodeVersion?: string | null

readonly launchUiVersion?: boolean | string | null

/**
* @deprecated Set framework and nodeVersion if need.
*/
readonly protonNodeVersion?: string | null

/**
* The framework name. One of `electron`, `proton-native`, `libui`. Defaults to `electron`.
*/
readonly framework?: string | null

/**
* The function (or path to file or module id) to be [run after pack](#afterpack) (but before pack into distributable format and sign).
*/
Expand Down
Loading

0 comments on commit fd86d92

Please sign in to comment.