From 13b0529d80ba8b481c7a1c2cb52d6f0e3e9dc383 Mon Sep 17 00:00:00 2001 From: evshiron Date: Wed, 12 Apr 2017 12:29:17 +0800 Subject: [PATCH] feat(nsis-gen): support nsis7z compression --- assets/project/package.json | 2 +- src/lib/Builder.ts | 77 +++++++++++++++++++++++++++++--- src/lib/nsis-gen/Nsis7Zipper.ts | 23 ++++++++++ src/lib/nsis-gen/NsisComposer.ts | 57 ++++++++++++++++------- src/lib/nsis-gen/index.ts | 1 + 5 files changed, 137 insertions(+), 23 deletions(-) create mode 100644 src/lib/nsis-gen/Nsis7Zipper.ts diff --git a/assets/project/package.json b/assets/project/package.json index d0d04fc..888ab59 100644 --- a/assets/project/package.json +++ b/assets/project/package.json @@ -13,7 +13,7 @@ "nwVersion": "lts", "targets": [ "zip", - "nsis" + "nsis7z" ], "win": { "versionStrings": { diff --git a/src/lib/Builder.ts b/src/lib/Builder.ts index ac72de6..fb62f45 100644 --- a/src/lib/Builder.ts +++ b/src/lib/Builder.ts @@ -14,7 +14,7 @@ import { Downloader } from './Downloader'; import { FFmpegDownloader } from './FFmpegDownloader'; import { BuildConfig } from './config'; import { NsisVersionInfo } from './common'; -import { NsisComposer, NsisDiffer, nsisBuild } from './nsis-gen'; +import { NsisComposer, NsisDiffer, Nsis7Zipper, nsisBuild } from './nsis-gen'; import { mergeOptions, findExecutable, findFFmpeg, findRuntimeRoot, findExcludableDependencies, tmpName, tmpFile, tmpDir, fixWindowsVersion, copyFileAsync, extractGeneric, compress } from './util'; interface IBuilderOptions { @@ -482,17 +482,17 @@ export class Builder { protected async buildArchiveTarget(type: string, targetDir: string) { - const targetZip = join(dirname(targetDir), `${ basename(targetDir) }.${ type }`); + const targetArchive = join(dirname(targetDir), `${ basename(targetDir) }.${ type }`); - await removeAsync(targetZip); + await removeAsync(targetArchive); const files = await globby([ '**/*' ], { cwd: targetDir, }); - await compress(targetDir, files, type, targetZip); + await compress(targetDir, files, type, targetArchive); - return targetZip; + return targetArchive; } @@ -555,6 +555,67 @@ export class Builder { } + protected async buildNsis7zTarget(platform: string, arch: string, targetDir: string, pkg: any, config: BuildConfig) { + + if(platform != 'win') { + if(!this.options.mute) { + console.info(`Skip building nsis7z target for ${ platform }.`); + } + return; + } + + const sourceArchive = await this.buildArchiveTarget('7z', targetDir); + + const versionInfo = new NsisVersionInfo(resolve(this.dir, config.output, 'versions.nsis.json')); + + const targetNsis = resolve(dirname(targetDir), `${ basename(targetDir) }-Setup.exe`); + + const data = await (new Nsis7Zipper(sourceArchive, { + + // Basic. + appName: config.win.versionStrings.ProductName, + companyName: config.win.versionStrings.CompanyName, + description: config.win.versionStrings.FileDescription, + version: fixWindowsVersion(config.win.productVersion), + copyright: config.win.versionStrings.LegalCopyright, + + // Compression. + compression: 'lzma', + solid: true, + + languages: config.nsis.languages, + + // Output. + output: targetNsis, + + })).make(); + + const script = await tmpName(); + await writeFileAsync(script, data); + + await nsisBuild(targetDir, script, { + mute: this.options.mute, + }); + + await removeAsync(script); + + await versionInfo.addVersion(pkg.version, '', targetDir); + await versionInfo.addInstaller(pkg.version, arch, targetNsis); + + if(config.nsis.diffUpdaters) { + + for(const version of await versionInfo.getVersions()) { + if(semver.gt(pkg.version, version)) { + await this.buildNsisDiffUpdater(platform, arch, versionInfo, version, pkg.version, pkg, config); + } + } + + } + + await versionInfo.save(); + + } + protected async buildTask(platform: string, arch: string, pkg: any, config: BuildConfig) { const downloader = new Downloader({ @@ -608,6 +669,12 @@ export class Builder { console.info(`Building nsis target ends within ${ this.getTimeDiff(started) }ms.`); } break; + case 'nsis7z': + await this.buildNsis7zTarget(platform, arch, targetDir, pkg, config); + if(!this.options.mute) { + console.info(`Building nsis7z target ends within ${ this.getTimeDiff(started) }ms.`); + } + break; default: throw new Error('ERROR_UNKNOWN_TARGET'); } diff --git a/src/lib/nsis-gen/Nsis7Zipper.ts b/src/lib/nsis-gen/Nsis7Zipper.ts new file mode 100644 index 0000000..2c33bc1 --- /dev/null +++ b/src/lib/nsis-gen/Nsis7Zipper.ts @@ -0,0 +1,23 @@ + +import { dirname, basename, join, relative, resolve, win32 } from 'path'; + +import { NsisComposer, INsisComposerOptions } from './NsisComposer'; + +export class Nsis7Zipper extends NsisComposer { + + constructor(protected path: string, options: INsisComposerOptions) { + super(options); + + } + + protected async makeInstallerFiles(): Promise { + return `SetOutPath "$INSTDIR" +SetCompress off +DetailPrint "Extracting archive..." +File "${ win32.normalize(resolve(this.path)) }" +DetailPrint "Installing archive..." +Nsis7z::ExtractWithDetails "$OUTDIR\\${ basename(this.path) }" "Installing %s..." +Delete "$OUTDIR\\${ basename(this.path) }"`; + } + +} diff --git a/src/lib/nsis-gen/NsisComposer.ts b/src/lib/nsis-gen/NsisComposer.ts index 580248e..271a5c8 100644 --- a/src/lib/nsis-gen/NsisComposer.ts +++ b/src/lib/nsis-gen/NsisComposer.ts @@ -70,7 +70,23 @@ ${ NsisComposer.DIVIDER } # ${ NsisComposer.DIVIDER } -${ NsisComposer.DIVIDER } +${ await this.makeGeneralSection() } + +${ await this.makeModernUISection() } + +${ await this.makeVersionSection() } + +${ await this.makeHookSection() } + +${ await this.makeInstallSection() } + +${ await this.makeUninstallSection() } +`; + + } + + protected async makeGeneralSection(): Promise { + return `${ NsisComposer.DIVIDER } # # General # @@ -86,9 +102,11 @@ InstallDir "$LOCALAPPDATA\\${ this.options.appName }" InstallDirRegKey HKCU "Software\\${ this.options.appName }" "InstallDir" RequestExecutionLevel user -XPStyle on +XPStyle on`; + } -${ NsisComposer.DIVIDER } + protected async makeModernUISection(): Promise { + return `${ NsisComposer.DIVIDER } # # Modern UI # @@ -125,11 +143,13 @@ ${ this.options.languages.length > 1 ? `!insertmacro MUI_RESERVEFILE_LANGDLL` : '' -} +}`; + } -${ NsisComposer.DIVIDER } + protected async makeVersionSection(): Promise { + return `${ NsisComposer.DIVIDER } # -# Resources +# Versions # ${ NsisComposer.DIVIDER } @@ -138,9 +158,11 @@ VIAddVersionKey "ProductName" "${ this.options.appName }" VIAddVersionKey "CompanyName" "${ this.options.companyName }" VIAddVersionKey "FileDescription" "${ this.options.description }" VIAddVersionKey "FileVersion" "${ this.fixedVersion }" -VIAddVersionKey "LegalCopyright" "${ this.options.copyright }" +VIAddVersionKey "LegalCopyright" "${ this.options.copyright }"`; + } -${ NsisComposer.DIVIDER } + protected async makeHookSection(): Promise { + return `${ NsisComposer.DIVIDER } # # Hooks # @@ -154,9 +176,11 @@ Function .onInit : '' } -FunctionEnd +FunctionEnd`; + } -${ NsisComposer.DIVIDER } + protected async makeInstallSection(): Promise { + return `${ NsisComposer.DIVIDER } # # Install # @@ -181,9 +205,11 @@ ${ await this.makeInstallerFiles() } WriteUninstaller "$INSTDIR\\Uninstall.exe" -SectionEnd +SectionEnd`; + } -${ NsisComposer.DIVIDER } + protected async makeUninstallSection(): Promise { + return `${ NsisComposer.DIVIDER } # # Uninstall # @@ -191,6 +217,7 @@ ${ NsisComposer.DIVIDER } Section Uninstall +# FIXME: Remove only files installed. RMDir /r "$INSTDIR" !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder @@ -201,16 +228,12 @@ RMDir "$SMPROGRAMS\\$StartMenuFolder" DeleteRegKey HKCU "Software\\${ this.options.appName }" -SectionEnd -`; - +SectionEnd`; } protected async makeInstallerFiles(): Promise { - return `SetOutPath "$INSTDIR" FILE /r .\\*.*`; - } } diff --git a/src/lib/nsis-gen/index.ts b/src/lib/nsis-gen/index.ts index 3a5726e..934d651 100644 --- a/src/lib/nsis-gen/index.ts +++ b/src/lib/nsis-gen/index.ts @@ -4,6 +4,7 @@ import { spawn } from 'child_process'; export * from './NsisComposer'; export * from './NsisDiffer'; +export * from './Nsis7Zipper'; const DIR_ASSETS = resolve(dirname(module.filename), '../../../assets/'); const DIR_NSIS = resolve(DIR_ASSETS, 'nsis');