From e7cee5eab8760ea0cc5d134baea7c887e80949cb Mon Sep 17 00:00:00 2001 From: develar Date: Wed, 4 May 2016 08:31:50 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20use=20self-containe=20fpm=20on=20OS=20X?= =?UTF-8?q?=20=E2=80=94=20don't=20need=20to=20install=20ruby=20anymore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../libraries/electron_builder_for_tests.xml | 1 - .idea/runConfigurations/linuxPackagerTest.xml | 2 +- .travis.yml | 8 +-- docs/Multi Platform Build.md | 3 +- package.json | 20 +++++-- src/build-cli.ts | 2 +- src/errorMessages.ts | 6 +- src/fpmDownload.ts | 59 +++++++++++++++++++ src/gitHubRequest.ts | 2 +- src/httpRequest.ts | 2 +- src/linuxPackager.ts | 12 +++- test/install-linux-dependencies.sh | 2 + test/src/helpers/avaEx.ts | 6 ++ test/src/linuxPackagerTest.ts | 4 +- test/src/winPackagerTest.ts | 6 +- tsconfig.json | 1 + 16 files changed, 109 insertions(+), 27 deletions(-) create mode 100644 src/fpmDownload.ts diff --git a/.idea/libraries/electron_builder_for_tests.xml b/.idea/libraries/electron_builder_for_tests.xml index ccbf7c28a4b..2cd2ca154b5 100644 --- a/.idea/libraries/electron_builder_for_tests.xml +++ b/.idea/libraries/electron_builder_for_tests.xml @@ -8,7 +8,6 @@ - \ No newline at end of file diff --git a/.idea/runConfigurations/linuxPackagerTest.xml b/.idea/runConfigurations/linuxPackagerTest.xml index 830fab3a21a..00b845a62cd 100644 --- a/.idea/runConfigurations/linuxPackagerTest.xml +++ b/.idea/runConfigurations/linuxPackagerTest.xml @@ -1,5 +1,5 @@ - + diff --git a/.travis.yml b/.travis.yml index 2c189a6f5ef..e49fdca873a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -11,14 +11,15 @@ env: - NODE_VERSION=4 - NODE_VERSION=6 -language: ruby +language: c cache: + apt: true + bundler: true directories: - node_modules - test/testApp/node_modules - $HOME/.electron - - $HOME/.npm addons: apt: @@ -33,7 +34,6 @@ before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install gnu-tar dpkg libicns graphicsmagick git-lfs; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then git lfs pull; fi - - gem install --no-rdoc --no-ri fpm - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then test/install-linux-dependencies.sh; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then curl -L https://github.com/github/git-lfs/releases/download/v1.2.0/git-lfs-linux-amd64-1.2.0.tar.gz | tar -xz; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then git-lfs-1.2.0/git-lfs pull; fi @@ -41,8 +41,8 @@ before_install: install: - nvm install $NODE_VERSION - npm install npm -g -- npm prune - npm install +- npm prune script: - npm run test diff --git a/docs/Multi Platform Build.md b/docs/Multi Platform Build.md index 7d6a4613f89..89a6abd259c 100755 --- a/docs/Multi Platform Build.md +++ b/docs/Multi Platform Build.md @@ -22,8 +22,7 @@ brew install Caskroom/cask/xquartz wine mono To build app in distributable format for Linux on OS X: ``` -brew install ruby gnu-tar libicns graphicsmagick -gem install fpm +brew install gnu-tar libicns graphicsmagick ``` ## Linux diff --git a/package.json b/package.json index a58be89fff7..207a8c31e85 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "test": "node ./test/out/helpers/runTests.js", "semantic-release": "semantic-release pre && npm publish && semantic-release post", "//": "Update wiki if docs changed. Update only if functionalily are generally available (latest release, not next)", - "update-wiki": "git subtree split -b wiki --prefix docs/ && git push wiki wiki:master" + "update-wiki": "git subtree split -b wiki --prefix docs/ && git push wiki wiki:master", + "whitespace": "whitespace src/*.ts" }, "repository": { "type": "git", @@ -64,7 +65,7 @@ "electron-osx-sign-tf": "~0.5.0-beta.0", "electron-packager-tf": "^7.0.2-beta.0", "electron-winstaller-fixed": "~2.4.0-beta.1", - "fs-extra-p": "^1.0.0", + "fs-extra-p": "^1.0.1", "globby": "^4.0.0", "hosted-git-info": "^2.1.4", "image-size": "^0.5.0", @@ -76,7 +77,7 @@ "signcode-tf": "^0.5.0", "source-map-support": "^0.4.0", "tmp": "0.0.28", - "typescript": "^1.9.0-dev.20160502" + "typescript": "^1.9.0-dev.20160503" }, "optionalDependencies": { "appdmg-tf": "^0.3.11" @@ -84,7 +85,10 @@ "config": { "pre-git": { "commit-msg": "conventional" - } + }, + "pre-commit": [ + "npm run whitespace" + ] }, "devDependencies": { "ava-tf": "^0.12.4-beta.6", @@ -102,7 +106,8 @@ "ts-babel": "^0.8.6", "tsconfig-glob": "^0.4.3", "tslint": "next", - "typescript": "^1.9.0-dev.20160414" + "typescript": "^1.9.0-dev.20160414", + "whitespace": "^2.0.0" }, "babel": { "plugins": [ @@ -118,5 +123,8 @@ "test/out/*" ] }, - "typings": "./out/electron-builder.d.ts" + "typings": "./out/electron-builder.d.ts", + "publishConfig": { + "tag": "next" + } } diff --git a/src/build-cli.ts b/src/build-cli.ts index ff9603ff86e..11818948fa4 100644 --- a/src/build-cli.ts +++ b/src/build-cli.ts @@ -38,7 +38,7 @@ if (args.help) { } else { if (args.appDir) { - warn(`-appDir CLI parameter is deprecated, please configure build.directories.app instead + warn(`-appDir CLI parameter is deprecated, please configure build.directories.app instead See https://github.com/electron-userland/electron-builder/wiki/Options#MetadataDirectories-app`) } diff --git a/src/errorMessages.ts b/src/errorMessages.ts index 62b3e8bc201..4b0cc7720c6 100644 --- a/src/errorMessages.ts +++ b/src/errorMessages.ts @@ -1,5 +1,5 @@ export const buildIsMissed = `Please specify 'build' configuration in the development package.json ('%s'), at least - + build: { "app-bundle-id": "your.id", "app-category-type": "your.app.category.type", @@ -14,11 +14,11 @@ export const authorEmailIsMissed = `Please specify author 'email' in the applica See https://docs.npmjs.com/files/package.json#people-fields-author-contributors -It is required to set Linux .deb package maintainer. Or you can set maintainer in the custom linux options. +It is required to set Linux .deb package maintainer. Or you can set maintainer in the custom linux options. (see https://github.com/electron-userland/electron-builder#distributable-format-configuration). ` -export const buildInAppSpecified = `'build' in the application package.json ('%s') is not supported since 3.0 anymore +export const buildInAppSpecified = `'build' in the application package.json ('%s') is not supported since 3.0 anymore Please move 'build' into the development package.json ('%s') ` \ No newline at end of file diff --git a/src/fpmDownload.ts b/src/fpmDownload.ts new file mode 100644 index 00000000000..8a91028ab4e --- /dev/null +++ b/src/fpmDownload.ts @@ -0,0 +1,59 @@ +import { statOrNull, spawn, debug } from "./util" +import { emptyDir, move, remove } from "fs-extra-p" +import { download } from "./httpRequest" +import { path7za } from "7zip-bin" +import * as path from "path" +import { tmpdir } from "os" +import { Promise as BluebirdPromise } from "bluebird" + +//noinspection JSUnusedLocalSymbols +const __awaiter = require("./awaiter") + +let tmpDirCounter = 0 + +function getTempName(prefix?: string | n): string { + return `${prefix == null ? "" : prefix + "-"}${process.pid}-${tmpDirCounter++}-${Date.now()}` +} + +const versionToPromise = new Map>() + +// can be called in parallel, all calls for the same version will get the same promise - will be downloaded only once +export function downloadFpm(version: string): Promise { + let promise = versionToPromise.get(version) + // if rejected, we will try to download again + if (promise != null && !promise!.isRejected()) { + return promise! + } + + promise = >doDownloadFpm(version) + versionToPromise.set(version, promise) + return promise +} + +async function doDownloadFpm(version: string): Promise { + const dirName = `fpm-${version}-osx` + const url = `https://github.com/develar/fpm-self-contained/releases/download/v${version}/${dirName}.7z` + const cache = path.join(__dirname, "..", "node_modules", ".fpm") + const fpmDir = path.join(cache, dirName) + + const stat = await statOrNull(fpmDir) + if (stat != null && stat.isDirectory()) { + return path.join(fpmDir, "fpm") + } + + // the only version currently supported (i.e. all clients are consumed the same version + await emptyDir(cache) + + const archiveName = path.join(tmpdir(), getTempName("fpm-download") + ".7z") + await download(url, archiveName) + const tempUnpackDir = path.join(cache, getTempName()) + await spawn(path7za, ["x", archiveName, "-o" + tempUnpackDir, "-bb" + (debug.enabled ? "3" : "0"), "-bd"], { + cwd: cache, + stdio: ["ignore", "inherit", "inherit"], + }) + + await move(path.join(tempUnpackDir, dirName), fpmDir, {clobber: true}) + await BluebirdPromise.all([remove(tempUnpackDir), remove(archiveName)]) + + return path.join(fpmDir, "fpm") +} \ No newline at end of file diff --git a/src/gitHubRequest.ts b/src/gitHubRequest.ts index 99cc04c7644..9e5defca366 100644 --- a/src/gitHubRequest.ts +++ b/src/gitHubRequest.ts @@ -38,7 +38,7 @@ export function doGitHubRequest(options: RequestOptions, token: string | null if (response.statusCode === 404) { // error is clear, we don't need to read detailed error description reject(new HttpError(response, `method: ${options.method} url: https://${options.hostname}${options.path} - + Please double check that your GitHub Token is correct. Due to security reasons GitHub doesn't report actual status, but 404. `)) } diff --git a/src/httpRequest.ts b/src/httpRequest.ts index 40f66cc798b..19fb6e83c1e 100644 --- a/src/httpRequest.ts +++ b/src/httpRequest.ts @@ -29,7 +29,7 @@ function doDownload(url: string, destination: string, redirectCount: number, cal hostname: parsedUrl.hostname, path: parsedUrl.path, headers: { - "User-Agent": "electron-complete-builder" + "User-Agent": "electron-builder" } }, (response: IncomingMessage) => { if (response.statusCode >= 400) { diff --git a/src/linuxPackager.ts b/src/linuxPackager.ts index bdaa8b69c4d..87894d4029c 100755 --- a/src/linuxPackager.ts +++ b/src/linuxPackager.ts @@ -5,6 +5,7 @@ import { Platform, LinuxBuildOptions } from "./metadata" import { dir as _tpmDir, TmpOptions } from "tmp" import { exec, log, use } from "./util" import { outputFile, readFile, readdir } from "fs-extra-p" +import { downloadFpm } from "./fpmDownload" const template = require("lodash.template") //noinspection JSUnusedLocalSymbols @@ -18,6 +19,8 @@ export class LinuxPackager extends PlatformPackager { private readonly packageFiles: Promise> private readonly scriptFiles: Promise> + private readonly fpmPath: Promise + constructor(info: BuildInfo) { super(info) @@ -33,6 +36,13 @@ export class LinuxPackager extends PlatformPackager { }) this.packageFiles = this.computePackageFiles(tempDir) this.scriptFiles = this.createScripts(tempDir) + + if (process.platform === "darwin" && process.env.USE_SYSTEM_FPM !== "true") { + this.fpmPath = downloadFpm("1.5.0-1") + } + else { + this.fpmPath = BluebirdPromise.resolve("fpm") + } } } @@ -201,7 +211,7 @@ Icon=${this.metadata.name} args.push(`${appOutDir}/=/opt/${this.appName}`) args.push(...(await this.packageFiles)!) - await exec("fpm", args) + await exec(await this.fpmPath, args) return destination } } diff --git a/test/install-linux-dependencies.sh b/test/install-linux-dependencies.sh index 5f92b4355c4..0cfa411fb04 100755 --- a/test/install-linux-dependencies.sh +++ b/test/install-linux-dependencies.sh @@ -1,3 +1,5 @@ +gem install --no-rdoc --no-ri fpm + wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add - sudo dpkg --add-architecture i386 diff --git a/test/src/helpers/avaEx.ts b/test/src/helpers/avaEx.ts index b3623d54e62..41ed600fa07 100644 --- a/test/src/helpers/avaEx.ts +++ b/test/src/helpers/avaEx.ts @@ -5,6 +5,7 @@ declare module "ava-tf" { export const ifNotWindows: typeof test; export const ifOsx: typeof test; export const ifNotCi: typeof test; + export const ifNotCiOsx: typeof test; export const ifNotTravis: typeof test; } @@ -24,6 +25,11 @@ Object.defineProperties(test, { return process.env.CI ? this.skip : this } }, + "ifNotCiOsx": { + get: function () { + return process.env.CI && process.platform === "darwin" ? this.skip : this + } + }, "ifNotTravis": { get: function () { return process.env.TRAVIS ? this.skip : this diff --git a/test/src/linuxPackagerTest.ts b/test/src/linuxPackagerTest.ts index 25ccbfbc0cc..b17221f0e60 100755 --- a/test/src/linuxPackagerTest.ts +++ b/test/src/linuxPackagerTest.ts @@ -7,9 +7,7 @@ import { Platform } from "out" //noinspection JSUnusedLocalSymbols const __awaiter = require("out/awaiter") -test.ifNotWindows("linux", async () => { - await assertPack("test-app-one", platform(Platform.LINUX)) -}) +test.ifNotWindows("linux", () => assertPack("test-app-one", platform(Platform.LINUX))) test.ifNotWindows("linux - icons from ICNS", async () => { await assertPack("test-app-one", { diff --git a/test/src/winPackagerTest.ts b/test/src/winPackagerTest.ts index e7c36c8a864..804f5d58c06 100755 --- a/test/src/winPackagerTest.ts +++ b/test/src/winPackagerTest.ts @@ -11,7 +11,7 @@ import * as assertThat from "should/as-function" //noinspection JSUnusedLocalSymbols const __awaiter = require("out/awaiter") -test.ifNotTravis("win", () => assertPack("test-app-one", platform(Platform.WINDOWS), +test.ifNotCiOsx("win", () => assertPack("test-app-one", platform(Platform.WINDOWS), { tempDirCreated: process.env.TEST_DELTA ? it => modifyPackageJson(it, data => { data.build.win = { @@ -21,7 +21,7 @@ test.ifNotTravis("win", () => assertPack("test-app-one", platform(Platform.WINDO } )) -test.ifNotTravis("noMsi as string", t => t.throws(assertPack("test-app-one", platform(Platform.WINDOWS), +test.ifNotCiOsx("noMsi as string", t => t.throws(assertPack("test-app-one", platform(Platform.WINDOWS), { tempDirCreated: it => modifyPackageJson(it, data => { data.build.win = { @@ -67,7 +67,7 @@ test("detect install-spinner", () => { }) }) -test.ifNotTravis("icon < 256", (t: any) => t.throws(assertPack("test-app-one", platform(Platform.WINDOWS), { +test.ifNotCiOsx("icon < 256", (t: any) => t.throws(assertPack("test-app-one", platform(Platform.WINDOWS), { tempDirCreated: projectDir => move(path.join(projectDir, "build", "incorrect.ico"), path.join(projectDir, "build", "icon.ico"), {clobber: true}) }), /Windows icon image size must be at least 256x256/)) diff --git a/tsconfig.json b/tsconfig.json index 99b6504084a..34ebe126f19 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -61,6 +61,7 @@ "src/builder.ts", "src/codeSign.ts", "src/errorMessages.ts", + "src/fpmDownload.ts", "src/gitHubPublisher.ts", "src/gitHubRequest.ts", "src/httpRequest.ts",