diff --git a/nsis-auto-updater/README.md b/nsis-auto-updater/README.md new file mode 100644 index 00000000000..d7f9fcf93a0 --- /dev/null +++ b/nsis-auto-updater/README.md @@ -0,0 +1 @@ +See wiki soon. \ No newline at end of file diff --git a/nsis-auto-updater/package.json b/nsis-auto-updater/package.json index 9c79cbf2fc5..b2907c476be 100644 --- a/nsis-auto-updater/package.json +++ b/nsis-auto-updater/package.json @@ -3,10 +3,11 @@ "version": "0.0.1", "description": "NSIS Auto Updater", "main": "out/nsis-auto-updater/src/nsis-updater.js", - "scripts": { - }, "author": "Vladimir Krivosheev", "license": "MIT", + "repository": "electron-userland/electron-builder", + "bugs": "https://github.com/electron-userland/electron-builder/issues", + "homepage": "https://github.com/electron-userland/electron-builder", "files": [ "out" ], @@ -17,9 +18,5 @@ "bundledDependencies": [ "fs-extra-p", "bluebird" - ], - "devDependencies": { - "@types/electron": "^0.37.14", - "@types/node": "^4.0.30" - } + ] } diff --git a/nsis-auto-updater/src/nsis-updater.ts b/nsis-auto-updater/src/nsis-updater.ts index 50eac0db2b4..6cf1275aa25 100644 --- a/nsis-auto-updater/src/nsis-updater.ts +++ b/nsis-auto-updater/src/nsis-updater.ts @@ -1,8 +1,55 @@ import { EventEmitter } from "events" -import { app } from "electron" import { spawn } from "child_process" import * as path from "path" import { tmpdir } from "os" +import { Promise as BluebirdPromise } from "bluebird" +import { BintrayClient } from "../../src/publish/bintray" +import { HttpError } from "../../src/publish/restApiRequest" + +//noinspection JSUnusedLocalSymbols +const __awaiter = require("../../src/util/awaiter") + +interface VersionInfo { + version: string +} + +interface Provider { + checkForUpdates(): Promise +} + +//noinspection ReservedWordAsName +interface BintraySourceMetadata { + // e.g. develar + readonly user: string + // e.g. onshape-desktop-shell + readonly package: string + + // e.g. generic or bin, defaults to generic + readonly repository?: string | null +} + +class BintrayProvider { + private client: BintrayClient + + constructor(configuration: BintraySourceMetadata) { + this.client = new BintrayClient(configuration.user, configuration.package, configuration.repository || "generic") + } + + async checkForUpdates(): Promise { + try { + const data = await this.client.getVersion("_latest") + return { + version: data.name, + } + } + catch (e) { + if (e instanceof HttpError && e.response.statusCode === 404) { + throw new Error(`No latest version, please ensure that user, repository and package correctly configured. Or at least one version is published.${e.stack || e.message}`) + } + throw e + } + } +} class NsisUpdater extends EventEmitter { private setupPath = path.join(tmpdir(), 'innobox-upgrade.exe') @@ -10,6 +57,8 @@ class NsisUpdater extends EventEmitter { private updateAvailable = false private quitAndInstallCalled = false + private client: Provider + constructor(public updateUrl?: string) { super() } @@ -18,17 +67,21 @@ class NsisUpdater extends EventEmitter { return this.updateUrl } - setFeedURL(value: string) { - this.updateUrl = value + setFeedURL(value: string | BintraySourceMetadata) { + this.updateUrl = value.toString() + + this.client = new BintrayProvider(value) } - checkForUpdates(): void { + checkForUpdates(): Promise { if (this.updateUrl == null) { - this.emitError("Update URL is not set") - return + const message = "Update URL is not set" + this.emitError(message) + return BluebirdPromise.reject(new Error(message)) } this.emit("checking-for-update") + return this.client.checkForUpdates() } quitAndInstall(): void { @@ -49,7 +102,7 @@ class NsisUpdater extends EventEmitter { stdio: "ignore", }).unref() - app.quit() + require("electron").app.quit() } // emit both error object and message, this is to keep compatibility with old APIs diff --git a/nsis-auto-updater/tsconfig.json b/nsis-auto-updater/tsconfig.json index a69352c204b..6597298bdbb 100755 --- a/nsis-auto-updater/tsconfig.json +++ b/nsis-auto-updater/tsconfig.json @@ -16,13 +16,16 @@ "skipLibCheck": true }, "files": [ + "../node_modules/@types/node/index.d.ts", "../node_modules/fs-extra-p/index.d.ts", "../node_modules/fs-extra-p/bluebird.d.ts", - "../src/util/httpRequest.ts" + "../src/util/httpRequest.ts", + "../src/publish/restApiRequest.ts", + "../src/publish/bintray.ts", + "../src/util/awaiter.ts" ], "include": [ - "src/**/*.ts", - "node_modules/@types/**/*.d.ts" + "src/**/*.ts" ], "exclude": [ ] diff --git a/package.json b/package.json index 1e4f29797fd..36f61b14602 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "files": [ "out", "templates", - "certs/root_certs.keychain" + "certs/root_certs.keychain", + "nsis-auto-updater/out", + "nsis-auto-updater/package.json" ], "bin": { "build": "./out/build-cli.js", @@ -14,23 +16,20 @@ "install-app-deps": "./out/install-app-deps.js" }, "scripts": { - "compile": "npm run compile-production && npm run compile-test", + "compile": "npm run compile-production && npm run compile-test && npm run compile-updater", "compile-production": "ts-babel", "compile-test": "ts-babel test", "compile-updater": "tsc -p nsis-auto-updater", "lint": "tslint 'src/**/*.ts' 'test/src/**/*.ts'", "pretest": "npm run compile && npm run lint", "test": "node ./test/out/helpers/runTests.js", - "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "semantic-release": "semantic-release pre && cd nsis-auto-updater && npm install --production && cd .. && 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 -f wiki wiki:master", "whitespace": "whitespace 'src/**/*.ts'", "docker-images": "docker/build.sh" }, - "repository": { - "type": "git", - "url": "https://github.com/electron-userland/electron-builder.git" - }, + "repository": "electron-userland/electron-builder", "engines": { "node": ">=0.4.0" }, @@ -75,10 +74,10 @@ "fs-extra-p": "^1.0.6", "hosted-git-info": "^2.1.5", "image-size": "^0.5.0", - "isbinaryfile": "^3.0.0", + "isbinaryfile": "^3.0.1", "lodash.template": "^4.3.0", "mime": "^1.3.4", - "minimatch": "^3.0.2", + "minimatch": "^3.0.3", "normalize-package-data": "^2.3.5", "path-sort": "^0.1.0", "plist": "^1.2.0", @@ -89,7 +88,6 @@ "sanitize-filename": "^1.6.0", "semver": "^5.3.0", "source-map-support": "^0.4.2", - "tslint": "^3.14.0-dev.1", "update-notifier": "^1.0.2", "uuid-1345": "^0.99.6", "yargs": "^4.8.1" @@ -110,7 +108,7 @@ "@types/debug": "0.0.28", "@types/mime": "0.0.28", "@types/progress": "^1.1.27", - "@types/semver": "^4.3.27", + "@types/semver": "^5.3.28", "@types/source-map-support": "^0.2.27", "ava-tf": "^0.15.4", "babel-plugin-array-includes": "^2.0.3", @@ -122,7 +120,7 @@ "json8": "^0.9.2", "pre-git": "^3.10.0", "ts-babel": "^1.0.4", - "tslint": "3.14.0", + "tslint": "^3.14.0-dev.1", "typescript": "^2.1.0-dev.20160802", "whitespace": "^2.1.0" }, diff --git a/src/packager/dirPackager.ts b/src/packager/dirPackager.ts index dd6d094e749..d46b051e725 100644 --- a/src/packager/dirPackager.ts +++ b/src/packager/dirPackager.ts @@ -1,7 +1,8 @@ import { Promise as BluebirdPromise } from "bluebird" -import { emptyDir } from "fs-extra-p" +import { emptyDir, rename } from "fs-extra-p" import { warn } from "../util/log" import { AppInfo } from "../appInfo" +import * as path from "path" const downloadElectron: (options: any) => Promise = BluebirdPromise.promisify(require("electron-download")) const extract: any = BluebirdPromise.promisify(require("extract-zip")) @@ -27,7 +28,6 @@ export interface ElectronPackagerOptions { const supportedPlatforms: any = { // Maps to module ID for each platform (lazy-required if used) darwin: "./mac", - linux: "./linux", mas: "./mac", // map to darwin win32: "./win32" } @@ -57,5 +57,14 @@ export async function pack(opts: ElectronPackagerOptions, out: string, platform: emptyDir(out) ]))[0] await extract(zipPath, {dir: out}) - await require(supportedPlatforms[platform]).createApp(opts, out, initializeApp) + + if (platform === "linux") { + await BluebirdPromise.all([ + initializeApp(), + rename(path.join(out, "electron"), path.join(out, opts.appInfo.productFilename)) + ]) + } + else { + await (require(supportedPlatforms[platform])).createApp(opts, out, initializeApp) + } } \ No newline at end of file diff --git a/src/packager/linux.ts b/src/packager/linux.ts deleted file mode 100644 index 0566370185a..00000000000 --- a/src/packager/linux.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { rename } from "fs-extra-p" -import * as path from "path" -import { ElectronPackagerOptions } from "./dirPackager" -import { Promise as BluebirdPromise } from "bluebird" - -export function createApp(opts: ElectronPackagerOptions, appOutDir: string, initializeApp: () => Promise) { - return BluebirdPromise.all([ - initializeApp(), - rename(path.join(appOutDir, "electron"), path.join(appOutDir, opts.appInfo.productFilename)) - ]) -} \ No newline at end of file diff --git a/src/publish/BintrayPublisher.ts b/src/publish/BintrayPublisher.ts index b4fbbd5b2b7..80512cbb118 100644 --- a/src/publish/BintrayPublisher.ts +++ b/src/publish/BintrayPublisher.ts @@ -1,41 +1,35 @@ import { Publisher, PublishOptions } from "./publisher" import { Promise as BluebirdPromise } from "bluebird" -import { bintrayRequest, HttpError, doApiRequest, uploadFile } from "./gitHubRequest" +import { HttpError, doApiRequest } from "./restApiRequest" +import { uploadFile } from "./uploader" import { log } from "../util/log" import { debug } from "../util/util" import { basename } from "path" import { stat } from "fs-extra-p" +import { BintrayClient, Version } from "./bintray" //noinspection JSUnusedLocalSymbols const __awaiter = require("../util/awaiter") -//noinspection ReservedWordAsName -interface Version { - readonly name: string - readonly package: string -} - export class BintrayPublisher implements Publisher { private _versionPromise: BluebirdPromise - private readonly auth: string - private basePath: string + private readonly client: BintrayClient constructor(private user: string, apiKey: string, private version: string, private packageName: string, private repo: string = "generic", private options: PublishOptions = {}) { - this.auth = `Basic ${new Buffer(`${user}:${apiKey}`).toString("base64")}` - this.basePath = `/packages/${this.user}/${this.repo}/${this.packageName}` + this.client = new BintrayClient(user, packageName, repo, apiKey) this._versionPromise = >this.init() } private async init(): Promise { try { - return await bintrayRequest(`${this.basePath}/versions/${this.version}`, this.auth) + return await this.client.getVersion(this.version) } catch (e) { if (e instanceof HttpError && e.response.statusCode === 404) { if (this.options.publish !== "onTagOrDraft") { log(`Version ${this.version} doesn't exist, creating one`) - return this.createVersion() + return this.client.createVersion(this.version) } else { log(`Version ${this.version} doesn't exist, artifacts will be not published`) @@ -46,12 +40,6 @@ export class BintrayPublisher implements Publisher { } } - private createVersion() { - return bintrayRequest(`${this.basePath}/versions`, this.auth, { - name: this.version, - }) - } - async upload(file: string, artifactName?: string): Promise { const fileName = artifactName || basename(file) const version = await this._versionPromise @@ -74,7 +62,7 @@ export class BintrayPublisher implements Publisher { "X-Bintray-Override": "1", "X-Bintray-Publish": "1", } - }, this.auth, uploadFile.bind(this, file, fileStat, fileName)) + }, this.client.auth, uploadFile.bind(this, file, fileStat, fileName)) } catch (e) { if (e instanceof HttpError && e.response.statusCode === 502 && badGatewayCount++ < 3) { @@ -93,10 +81,6 @@ export class BintrayPublisher implements Publisher { } const version = this._versionPromise.value() - if (version == null) { - return BluebirdPromise.resolve() - } - - return bintrayRequest(`/packages/${this.user}/${this.repo}/${this.packageName}/versions/${version.name}`, this.auth, null, "DELETE") + return version == null ? BluebirdPromise.resolve() : this.client.deleteVersion(version.name) } } \ No newline at end of file diff --git a/src/publish/bintray.ts b/src/publish/bintray.ts new file mode 100644 index 00000000000..8517d44af17 --- /dev/null +++ b/src/publish/bintray.ts @@ -0,0 +1,31 @@ +import { bintrayRequest } from "./restApiRequest" + +//noinspection ReservedWordAsName +export interface Version { + readonly name: string + readonly package: string +} + +export class BintrayClient { + private readonly basePath: string + readonly auth: string | null + + constructor(private user: string, private packageName: string, private repo: string = "generic", apiKey?: string | null) { + this.auth = apiKey == null ? null : `Basic ${new Buffer(`${user}:${apiKey}`).toString("base64")}` + this.basePath = `/packages/${this.user}/${this.repo}/${this.packageName}` + } + + getVersion(version: string): Promise { + return bintrayRequest(`${this.basePath}/versions/${version}`, this.auth) + } + + createVersion(version: string): Promise { + return bintrayRequest(`${this.basePath}/versions`, this.auth, { + name: version, + }) + } + + deleteVersion(version: string): Promise { + return bintrayRequest(`/packages/${this.user}/${this.repo}/${this.packageName}/versions/${version}`, this.auth, null, "DELETE") + } +} \ No newline at end of file diff --git a/src/publish/gitHubPublisher.ts b/src/publish/gitHubPublisher.ts index 630bc97f0dc..e8f76b07166 100644 --- a/src/publish/gitHubPublisher.ts +++ b/src/publish/gitHubPublisher.ts @@ -5,9 +5,10 @@ import { basename } from "path" import { parse as parseUrl } from "url" import * as mime from "mime" import { stat } from "fs-extra-p" -import { gitHubRequest, HttpError, doApiRequest, uploadFile } from "./gitHubRequest" +import { githubRequest, HttpError, doApiRequest } from "./restApiRequest" import { Promise as BluebirdPromise } from "bluebird" import { PublishPolicy, PublishOptions, Publisher } from "./publisher" +import { uploadFile } from "./uploader" //noinspection JSUnusedLocalSymbols const __awaiter = require("../util/awaiter") @@ -56,7 +57,7 @@ export class GitHubPublisher implements Publisher { private async init(): Promise { const createReleaseIfNotExists = this.policy !== "onTagOrDraft" // we don't use "Get a release by tag name" because "tag name" means existing git tag, but we draft release and don't create git tag - const releases = await gitHubRequest>(`/repos/${this.owner}/${this.repo}/releases`, this.token) + const releases = await githubRequest>(`/repos/${this.owner}/${this.repo}/releases`, this.token) for (let release of releases) { if (release.tag_name === this.tag) { if (release.draft) { @@ -121,10 +122,10 @@ export class GitHubPublisher implements Publisher { if (e.response.statusCode === 422 && e.description != null && e.description.errors != null && e.description.errors[0].code === "already_exists") { // delete old artifact and re-upload log(`Artifact ${fileName} already exists, overwrite one`) - const assets = await gitHubRequest>(`/repos/${this.owner}/${this.repo}/releases/${release.id}/assets`, this.token) + const assets = await githubRequest>(`/repos/${this.owner}/${this.repo}/releases/${release.id}/assets`, this.token) for (let asset of assets) { if (asset!.name === fileName) { - await gitHubRequest(`/repos/${this.owner}/${this.repo}/releases/assets/${asset!.id}`, this.token, null, "DELETE") + await githubRequest(`/repos/${this.owner}/${this.repo}/releases/assets/${asset!.id}`, this.token, null, "DELETE") continue uploadAttempt } } @@ -143,7 +144,7 @@ export class GitHubPublisher implements Publisher { } private createRelease() { - return gitHubRequest(`/repos/${this.owner}/${this.repo}/releases`, this.token, { + return githubRequest(`/repos/${this.owner}/${this.repo}/releases`, this.token, { tag_name: this.tag, name: this.version, draft: this.options.draft == null || this.options.draft, @@ -154,7 +155,7 @@ export class GitHubPublisher implements Publisher { // test only //noinspection JSUnusedGlobalSymbols async getRelease(): Promise { - return gitHubRequest(`/repos/${this.owner}/${this.repo}/releases/${this._releasePromise.value().id}`, this.token) + return githubRequest(`/repos/${this.owner}/${this.repo}/releases/${this._releasePromise.value().id}`, this.token) } //noinspection JSUnusedGlobalSymbols @@ -170,7 +171,7 @@ export class GitHubPublisher implements Publisher { for (let i = 0; i < 3; i++) { try { - return await gitHubRequest(`/repos/${this.owner}/${this.repo}/releases/${release.id}`, this.token, null, "DELETE") + return await githubRequest(`/repos/${this.owner}/${this.repo}/releases/${release.id}`, this.token, null, "DELETE") } catch (e) { if (e instanceof HttpError && (e.response.statusCode === 405 || e.response.statusCode === 502)) { diff --git a/src/publish/gitHubRequest.ts b/src/publish/restApiRequest.ts similarity index 75% rename from src/publish/gitHubRequest.ts rename to src/publish/restApiRequest.ts index d8837eeee42..690ed9618eb 100644 --- a/src/publish/gitHubRequest.ts +++ b/src/publish/restApiRequest.ts @@ -3,20 +3,16 @@ import { RequestOptions } from "https" import { IncomingMessage, ClientRequest } from "http" import { addTimeOutHandler } from "../util/httpRequest" import { Promise as BluebirdPromise } from "bluebird" -import { createReadStream, Stats } from "fs-extra-p" -import progressStream = require("progress-stream") -import ProgressBar = require("progress") -import { ReadStream } from "tty" //noinspection JSUnusedLocalSymbols const __awaiter = require("../util/awaiter") -export function gitHubRequest(path: string, token: string | null, data: { [name: string]: any; } | null = null, method: string = "GET"): BluebirdPromise { +export function githubRequest(path: string, token: string | null, data: { [name: string]: any; } | null = null, method: string = "GET"): BluebirdPromise { return request("api.github.com", path, token, data, method) } -export function bintrayRequest(path: string, token: string | null, data: { [name: string]: any; } | null = null, method: string = "GET"): BluebirdPromise { - return request("api.bintray.com", path, token, data, method) +export function bintrayRequest(path: string, auth: string | null, data: { [name: string]: any; } | null = null, method: string = "GET"): BluebirdPromise { + return request("api.bintray.com", path, auth, data, method) } function request(hostname: string, path: string, token: string | null, data: { [name: string]: any; } | null = null, method: string = "GET"): BluebirdPromise { @@ -104,26 +100,4 @@ export class HttpError extends Error { constructor(public response: IncomingMessage, public description: any = null) { super(response.statusCode + " " + response.statusMessage + (description == null ? "" : ("\n" + JSON.stringify(description, null, " "))) + "\nHeaders: " + JSON.stringify(response.headers, null, " ")) } -} - -export function uploadFile(file: string, fileStat: Stats, fileName: string, request: ClientRequest, reject: (error: Error) => void) { - const progressBar = (process.stdin).isTTY ? new ProgressBar(`Uploading ${fileName} [:bar] :percent :etas`, { - total: fileStat.size, - incomplete: " ", - stream: process.stdout, - width: 20, - }) : null - - const fileInputStream = createReadStream(file) - fileInputStream.on("error", reject) - fileInputStream - .pipe(progressStream({ - length: fileStat.size, - time: 1000 - }, progress => { - if (progressBar != null) { - progressBar.tick(progress.delta) - } - })) - .pipe(request) } \ No newline at end of file diff --git a/src/publish/uploader.ts b/src/publish/uploader.ts new file mode 100644 index 00000000000..13a14751654 --- /dev/null +++ b/src/publish/uploader.ts @@ -0,0 +1,27 @@ +import progressStream = require("progress-stream") +import ProgressBar = require("progress") +import { createReadStream, Stats } from "fs-extra-p" +import { ReadStream } from "tty" +import { ClientRequest } from "http" + +export function uploadFile(file: string, fileStat: Stats, fileName: string, request: ClientRequest, reject: (error: Error) => void) { + const progressBar = (process.stdin).isTTY ? new ProgressBar(`Uploading ${fileName} [:bar] :percent :etas`, { + total: fileStat.size, + incomplete: " ", + stream: process.stdout, + width: 20, + }) : null + + const fileInputStream = createReadStream(file) + fileInputStream.on("error", reject) + fileInputStream + .pipe(progressStream({ + length: fileStat.size, + time: 1000 + }, progress => { + if (progressBar != null) { + progressBar.tick(progress.delta) + } + })) + .pipe(request) +} \ No newline at end of file diff --git a/templates/nsis/boringInstaller.nsh b/templates/nsis/boringInstaller.nsh index 41a655fb12f..a221621ff42 100644 --- a/templates/nsis/boringInstaller.nsh +++ b/templates/nsis/boringInstaller.nsh @@ -18,6 +18,69 @@ FunctionEnd !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_LANGUAGE "English" +!insertmacro MUI_LANGUAGE "German" +!insertmacro MUI_LANGUAGE "French" +!insertmacro MUI_LANGUAGE "Spanish" +!insertmacro MUI_LANGUAGE "SpanishInternational" +!insertmacro MUI_LANGUAGE "SimpChinese" +!insertmacro MUI_LANGUAGE "TradChinese" +!insertmacro MUI_LANGUAGE "Japanese" +#!insertmacro MUI_LANGUAGE "Korean" +!insertmacro MUI_LANGUAGE "Italian" +!insertmacro MUI_LANGUAGE "Dutch" +#!insertmacro MUI_LANGUAGE "Danish" +#!insertmacro MUI_LANGUAGE "Swedish" +#!insertmacro MUI_LANGUAGE "Norwegian" +#!insertmacro MUI_LANGUAGE "NorwegianNynorsk" +#!insertmacro MUI_LANGUAGE "Finnish" +#!insertmacro MUI_LANGUAGE "Greek" +!insertmacro MUI_LANGUAGE "Russian" +#!insertmacro MUI_LANGUAGE "Portuguese" +#!insertmacro MUI_LANGUAGE "PortugueseBR" +#!insertmacro MUI_LANGUAGE "Polish" +#!insertmacro MUI_LANGUAGE "Ukrainian" +!insertmacro MUI_LANGUAGE "Czech" +#!insertmacro MUI_LANGUAGE "Slovak" +#!insertmacro MUI_LANGUAGE "Croatian" +#!insertmacro MUI_LANGUAGE "Bulgarian" +#!insertmacro MUI_LANGUAGE "Hungarian" +#!insertmacro MUI_LANGUAGE "Thai" +#!insertmacro MUI_LANGUAGE "Romanian" +#!insertmacro MUI_LANGUAGE "Latvian" +#!insertmacro MUI_LANGUAGE "Macedonian" +#!insertmacro MUI_LANGUAGE "Estonian" +#!insertmacro MUI_LANGUAGE "Turkish" +#!insertmacro MUI_LANGUAGE "Lithuanian" +#!insertmacro MUI_LANGUAGE "Slovenian" +#!insertmacro MUI_LANGUAGE "Serbian" +#!insertmacro MUI_LANGUAGE "SerbianLatin" +#!insertmacro MUI_LANGUAGE "Arabic" +#!insertmacro MUI_LANGUAGE "Farsi" +#!insertmacro MUI_LANGUAGE "Hebrew" +#!insertmacro MUI_LANGUAGE "Indonesian" +#!insertmacro MUI_LANGUAGE "Mongolian" +#!insertmacro MUI_LANGUAGE "Luxembourgish" +#!insertmacro MUI_LANGUAGE "Albanian" +#!insertmacro MUI_LANGUAGE "Breton" +#!insertmacro MUI_LANGUAGE "Belarusian" +#!insertmacro MUI_LANGUAGE "Icelandic" +#!insertmacro MUI_LANGUAGE "Malay" +#!insertmacro MUI_LANGUAGE "Bosnian" +#!insertmacro MUI_LANGUAGE "Kurdish" +#!insertmacro MUI_LANGUAGE "Irish" +#!insertmacro MUI_LANGUAGE "Uzbek" +#!insertmacro MUI_LANGUAGE "Galician" +#!insertmacro MUI_LANGUAGE "Afrikaans" +#!insertmacro MUI_LANGUAGE "Catalan" +#!insertmacro MUI_LANGUAGE "Esperanto" +#!insertmacro MUI_LANGUAGE "Asturian" +#!insertmacro MUI_LANGUAGE "Basque" +#!insertmacro MUI_LANGUAGE "Pashto" +#!insertmacro MUI_LANGUAGE "ScotsGaelic" +#!insertmacro MUI_LANGUAGE "Georgian" +#!insertmacro MUI_LANGUAGE "Vietnamese" +#!insertmacro MUI_LANGUAGE "Welsh" +#!insertmacro MUI_LANGUAGE "Armenian" Function GuiInit !insertmacro UAC_PageElevation_OnGuiInit diff --git a/templates/nsis/installer.nsi b/templates/nsis/installer.nsi index c4313b7fa25..8ba9571aa28 100644 --- a/templates/nsis/installer.nsi +++ b/templates/nsis/installer.nsi @@ -152,7 +152,11 @@ Section "un.install" # delete the installed files RMDir /r $INSTDIR - RMDir /r "$APPDATA\${PRODUCT_FILENAME}" + ${GetParameters} $R0 + ${GetOptions} $R0 "/KEEP_APP_DATA" $R1 + ${If} ${Errors} + RMDir /r "$APPDATA\${PRODUCT_FILENAME}" + ${EndIf} !insertmacro MULTIUSER_RegistryRemoveInstallInfo diff --git a/templates/nsis/multiUserUi.nsh b/templates/nsis/multiUserUi.nsh index 8516ce2d9b9..76d4138a028 100755 --- a/templates/nsis/multiUserUi.nsh +++ b/templates/nsis/multiUserUi.nsh @@ -52,18 +52,16 @@ Var RadioButtonLabel1 ${GetParameters} $R0 ${GetOptions} $R0 "/allusers" $R1 - IfErrors notallusers - Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers - Abort - - notallusers: + ${IfNot} ${Errors} + Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.AllUsers + Abort + ${EndIf} ${GetOptions} $R0 "/currentuser" $R1 - IfErrors notcurrentuser - Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser - Abort - - notcurrentuser: + ${IfNot} ${Errors} + Call ${UNINSTALLER_FUNCPREFIX}MultiUser.InstallMode.CurrentUser + Abort + ${EndIf} # If uninstalling, will check if there is both a per-user and per-machine installation. If there is only one, will skip the form. # If uninstallation was invoked from the "add/remove programs" Windows will automatically requests elevation (depending if uninstall keys are in HKLM or HKCU) @@ -81,9 +79,9 @@ Var RadioButtonLabel1 !endif !if "${UNINSTALLER_PREFIX}" == UN - !insertmacro MUI_HEADER_TEXT "Choose Installation Options" "Who should this application be installed for?" + !insertmacro MUI_HEADER_TEXT "Choose Uninstallation Options" "Which installation should be removed?" !else - !insertmacro MUI_HEADER_TEXT "Choose Uninstallation Options" "Which installation should be removed?" + !insertmacro MUI_HEADER_TEXT "Choose Installation Options" "Who should this application be installed for?" !endif nsDialogs::Create 1018 diff --git a/test/src/ArtifactPublisherTest.ts b/test/src/ArtifactPublisherTest.ts index ea358278039..7bc28591851 100644 --- a/test/src/ArtifactPublisherTest.ts +++ b/test/src/ArtifactPublisherTest.ts @@ -1,6 +1,6 @@ import test from "./helpers/avaEx" import { GitHubPublisher } from "out/publish/gitHubPublisher" -import { HttpError } from "out/publish/gitHubRequest" +import { HttpError } from "out/publish/restApiRequest" import { join } from "path" import { assertThat } from "./helpers/fileAssert" import { BintrayPublisher } from "out/publish/BintrayPublisher" diff --git a/test/src/nsisTest.ts b/test/src/nsisTest.ts index b8cbab67edb..64fc15f9f39 100644 --- a/test/src/nsisTest.ts +++ b/test/src/nsisTest.ts @@ -9,7 +9,7 @@ import { assertThat } from "./helpers/fileAssert" //noinspection JSUnusedLocalSymbols const __awaiter = require("out/util/awaiter") -test("nsis", () => assertPack("test-app-one", signed({ +test("one-click", () => assertPack("test-app-one", signed({ targets: Platform.WINDOWS.createTarget(["nsis"]), }), { useTempDir: true, @@ -44,6 +44,7 @@ test.ifNotCiOsx("boring", () => assertPack("test-app-one", signed({ } } }))) + test.ifNotCiOsx("installerHeaderIcon", () => { let headerIconPath: string | null = null return assertPack("test-app-one", { diff --git a/test/src/nsisUpdaterTest.ts b/test/src/nsisUpdaterTest.ts new file mode 100644 index 00000000000..af09f1e795e --- /dev/null +++ b/test/src/nsisUpdaterTest.ts @@ -0,0 +1,16 @@ +import test from "./helpers/avaEx" + +//noinspection JSUnusedLocalSymbols +const __awaiter = require("out/util/awaiter") + +const updater = require("../../nsis-auto-updater/out/nsis-auto-updater/src/nsis-updater") + +test("Check updates - no latest version", async (t) => { + //noinspection ReservedWordAsName + updater.setFeedURL({ + user: "actperepo", + package: "no-versions", + }) + + t.throws(updater.checkForUpdates(), /No latest version, please ensure that/) +}) \ No newline at end of file