-
Notifications
You must be signed in to change notification settings - Fork 262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
get rid of nuget #77
get rid of nuget #77
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,23 +16,23 @@ | |
"tdd": "ava --watch" | ||
}, | ||
"dependencies": { | ||
"asar": "~0.10.0", | ||
"bluebird": "^3.3.4", | ||
"archiver": "^1.0.0", | ||
"asar": "~0.11.0", | ||
"bluebird": "^3.3.5", | ||
"debug": "^2.2.0", | ||
"fs-extra": "^0.26.7", | ||
"lodash.template": "^4.2.2", | ||
"temp": "^0.8.3" | ||
"fs-extra": "^0.28.0" | ||
}, | ||
"devDependencies": { | ||
"ava": "^0.13.0", | ||
"babel-cli": "^6.6.5", | ||
"ava": "^0.14.0", | ||
"babel-cli": "^6.7.5", | ||
"babel-eslint": "^6.0.2", | ||
"babel-plugin-transform-async-to-module-method": "^6.7.0", | ||
"babel-plugin-transform-runtime": "^6.6.0", | ||
"babel-preset-es2015-node4": "^2.0.3", | ||
"babel-plugin-transform-runtime": "^6.7.5", | ||
"babel-preset-es2015-node4": "^2.1.0", | ||
"babel-preset-stage-0": "^6.5.0", | ||
"babel-register": "^6.7.2", | ||
"eslint": "^2.4.0" | ||
"eslint": "^2.8.0", | ||
"temp": "^0.8.3" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move temp in dev deps. |
||
}, | ||
"engines": { | ||
"node": ">=0.4.0" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
import template from 'lodash.template'; | ||
import spawn from './spawn-promise'; | ||
import asar from 'asar'; | ||
import path from 'path'; | ||
import * as fsUtils from './fs-utils'; | ||
import archiver from 'archiver'; | ||
import * as fs from 'fs-extra'; | ||
import { Promise } from 'bluebird'; | ||
|
||
const log = require('debug')('electron-windows-installer:main'); | ||
const log = require('debug')('electron-windows-installer'); | ||
|
||
export function convertVersion(version) { | ||
const parts = version.split('-'); | ||
|
@@ -18,29 +20,13 @@ export function convertVersion(version) { | |
} | ||
|
||
export async function createWindowsInstaller(options) { | ||
let useMono = false; | ||
|
||
const monoExe = 'mono'; | ||
const wineExe = 'wine'; | ||
|
||
if (process.platform !== 'win32') { | ||
useMono = true; | ||
if (!wineExe || !monoExe) { | ||
throw new Error('You must install both Mono and Wine on non-Windows'); | ||
} | ||
|
||
log(`Using Mono: '${monoExe}'`); | ||
log(`Using Wine: '${wineExe}'`); | ||
} | ||
|
||
let { appDirectory, outputDirectory, loadingGif } = options; | ||
outputDirectory = path.resolve(outputDirectory || 'installer'); | ||
const useMono = process.platform !== 'win32'; | ||
const { appDirectory } = options; | ||
|
||
const vendorPath = path.join(__dirname, '..', 'vendor'); | ||
const vendorUpdate = path.join(vendorPath, 'Update.exe'); | ||
const appUpdate = path.join(appDirectory, 'Update.exe'); | ||
|
||
await fsUtils.copy(vendorUpdate, appUpdate); | ||
await fsUtils.copy(path.join(vendorPath, 'Update.exe'), appUpdate); | ||
if (options.setupIcon && (options.skipUpdateIcon !== true)) { | ||
let cmd = path.join(vendorPath, 'rcedit.exe'); | ||
let args = [ | ||
|
@@ -50,17 +36,12 @@ export async function createWindowsInstaller(options) { | |
|
||
if (useMono) { | ||
args.unshift(cmd); | ||
cmd = wineExe; | ||
cmd = 'wine'; | ||
} | ||
|
||
await spawn(cmd, args); | ||
} | ||
|
||
const defaultLoadingGif = path.join(__dirname, '..', 'resources', 'install-spinner.gif'); | ||
loadingGif = loadingGif ? path.resolve(loadingGif) : defaultLoadingGif; | ||
|
||
let {certificateFile, certificatePassword, remoteReleases, signWithParams, remoteToken} = options; | ||
|
||
const metadata = { | ||
description: '', | ||
iconUrl: 'https://raw.githubusercontent.com/atom/electron/master/atom/browser/resources/win/atom.ico' | ||
|
@@ -93,69 +74,139 @@ export async function createWindowsInstaller(options) { | |
} | ||
} | ||
|
||
metadata.owners = metadata.owners || metadata.authors; | ||
metadata.version = convertVersion(metadata.version); | ||
metadata.copyright = metadata.copyright || | ||
`Copyright © ${new Date().getFullYear()} ${metadata.authors || metadata.owners}`; | ||
|
||
let templateData = await fsUtils.readFile(path.join(__dirname, '..', 'template.nuspec'), 'utf8'); | ||
if (path.sep === '/') { | ||
templateData = templateData.replace(/\\/g, '/'); | ||
} | ||
const nuspecContent = template(templateData)(metadata); | ||
|
||
log(`Created NuSpec file:\n${nuspecContent}`); | ||
const outputDirectory = path.resolve(options.outputDirectory || 'installer'); | ||
if (options.remoteReleases) { | ||
let cmd = path.join(vendorPath, 'SyncReleases.exe'); | ||
let args = ['-u', options.remoteReleases, '-r', outputDirectory]; | ||
|
||
const nugetOutput = await fsUtils.createTempDir('si-'); | ||
const targetNuspecPath = path.join(nugetOutput, metadata.name + '.nuspec'); | ||
|
||
await fsUtils.writeFile(targetNuspecPath, nuspecContent); | ||
if (useMono) { | ||
args.unshift(cmd); | ||
cmd = 'mono'; | ||
} | ||
|
||
let cmd = path.join(vendorPath, 'nuget.exe'); | ||
let args = [ | ||
'pack', targetNuspecPath, | ||
'-BasePath', appDirectory, | ||
'-OutputDirectory', nugetOutput, | ||
'-NoDefaultExcludes' | ||
]; | ||
if (options.remoteToken) { | ||
args.push('-t', options.remoteToken); | ||
} | ||
|
||
if (useMono) { | ||
args.unshift(cmd); | ||
cmd = monoExe; | ||
await spawn(cmd, args); | ||
} | ||
|
||
// Call NuGet to create our package | ||
log(await spawn(cmd, args)); | ||
const nupkgPath = path.join(nugetOutput, `${metadata.name}.${metadata.version}.nupkg`); | ||
// todo fix Squirrel.windows "Sharing violation on path" (avoid copy, use file directly) | ||
const squirrelWorkaroundDir = path.join(outputDirectory, '.tmp'); | ||
await fsUtils.mkdirs(squirrelWorkaroundDir); | ||
try { | ||
const nupkgPath = path.join(squirrelWorkaroundDir, 'in.nupkg'); | ||
await pack(metadata, appDirectory, nupkgPath); | ||
await releasify(nupkgPath, outputDirectory, options, vendorPath); | ||
} | ||
finally { | ||
await fsUtils.remove(squirrelWorkaroundDir); | ||
} | ||
|
||
if (remoteReleases) { | ||
cmd = path.join(vendorPath, 'SyncReleases.exe'); | ||
args = ['-u', remoteReleases, '-r', outputDirectory]; | ||
if (options.fixUpPaths !== false) { | ||
log('Fixing up paths'); | ||
|
||
if (useMono) { | ||
args.unshift(cmd); | ||
cmd = monoExe; | ||
if (metadata.productName || options.setupExe) { | ||
const setupPath = path.join(outputDirectory, options.setupExe || `${metadata.productName}Setup.exe`); | ||
const unfixedSetupPath = path.join(outputDirectory, 'Setup.exe'); | ||
log(`Renaming ${unfixedSetupPath} => ${setupPath}`); | ||
await fsUtils.rename(unfixedSetupPath, setupPath); | ||
} | ||
|
||
if (remoteToken) { | ||
args.push('-t', remoteToken); | ||
if (metadata.productName) { | ||
const msiPath = path.join(outputDirectory, `${metadata.productName}Setup.msi`); | ||
const unfixedMsiPath = path.join(outputDirectory, 'Setup.msi'); | ||
if (await fsUtils.fileExists(unfixedMsiPath)) { | ||
log(`Renaming ${unfixedMsiPath} => ${msiPath}`); | ||
await fsUtils.rename(unfixedMsiPath, msiPath); | ||
} | ||
} | ||
|
||
log(await spawn(cmd, args)); | ||
} | ||
} | ||
|
||
function pack(metadata, appDirectory, outFile) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No way to use 7z here because 7z doesn't support directory prefix. Anyway, we don't need to compress here, so, node implementation is ok. |
||
return new Promise(function (resolve, reject) { | ||
const archive = archiver('zip', {store: true}); | ||
const out = fs.createWriteStream(outFile); | ||
out.on('close', function () { | ||
resolve(outFile); | ||
}); | ||
archive.on('error', reject); | ||
archive.pipe(out); | ||
|
||
archive.directory(appDirectory, 'lib/net45'); | ||
|
||
archive.append(`<?xml version="1.0"?> | ||
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> | ||
<Relationship Id="Re0" Target="/${metadata.name}.nuspec" Type="http://schemas.microsoft.com/packaging/2010/07/manifest"/> | ||
<Relationship Id="Re1" Target="/package/services/metadata/core-properties/1.psmdcp" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"/> | ||
</Relationships>`, {name: '.rels', prefix: '_rels'}); | ||
|
||
const author = metadata.authors || metadata.owners; | ||
const copyright = metadata.copyright || | ||
`Copyright © ${new Date().getFullYear()} ${author}`; | ||
const version = convertVersion(metadata.version); | ||
const nuspecContent = `<?xml version="1.0"?> | ||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> | ||
<metadata> | ||
<id>${metadata.name}</id> | ||
<title>${metadata.title}</title> | ||
<version>${version}</version> | ||
<authors>${author}</authors> | ||
<owners>${metadata.owners || metadata.authors}</owners> | ||
<iconUrl>${metadata.iconUrl}</iconUrl> | ||
<requireLicenseAcceptance>false</requireLicenseAcceptance> | ||
<description>${metadata.description}</description> | ||
<copyright>${copyright}</copyright>${metadata.extraMetadataSpecs || ''} | ||
</metadata> | ||
</package>`; | ||
log(`Created NuSpec file:\n${nuspecContent}`); | ||
|
||
archive.append(nuspecContent, {name: metadata.name + '.nuspec'}); | ||
|
||
archive.append(`<?xml version="1.0"?> | ||
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> | ||
<Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/> | ||
<Default ContentType="application/octet" Extension="nuspec"/> | ||
<Default ContentType="application/octet" Extension="pak"/> | ||
<Default ContentType="application/octet" Extension="asar"/> | ||
<Default ContentType="application/octet" Extension="bin"/> | ||
<Default ContentType="application/octet" Extension="dll"/> | ||
<Default ContentType="application/octet" Extension="exe"/> | ||
<Default ContentType="application/octet" Extension="dat"/> | ||
<Default ContentType="application/vnd.openxmlformats-package.core-properties+xml" Extension="psmdcp"/> | ||
</Types>`, {name: '[Content_Types].xml'}); | ||
|
||
archive.append(`<?xml version="1.0"?> | ||
<coreProperties xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xmlns="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"> | ||
<dc:creator>${author}</dc:creator> | ||
<dc:description>${metadata.description}</dc:description> | ||
<dc:identifier>${metadata.name}</dc:identifier> | ||
<keywords/> | ||
<lastModifiedBy>NuGet, Version=3.4.0.653, Culture=neutral, PublicKeyToken=31bf3856ad364e35;Unix 15.4.0.0;.NET Framework 4.5</lastModifiedBy> | ||
<dc:title>${metadata.title}</dc:title> | ||
<version>${version}</version> | ||
</coreProperties>`, {name: '1.psmdcp', prefix: 'package/services/metadata/core-properties'}); | ||
|
||
archive.finalize(); | ||
}); | ||
} | ||
|
||
cmd = path.join(vendorPath, 'Update.com'); | ||
args = [ | ||
async function releasify(nupkgPath, outputDirectory, options, vendorPath) { | ||
let cmd = path.join(vendorPath, 'Update.com'); | ||
const args = [ | ||
'--releasify', nupkgPath, | ||
'--releaseDir', outputDirectory, | ||
'--loadingGif', loadingGif | ||
'--loadingGif', options.loadingGif ? path.resolve(options.loadingGif) : path.join(__dirname, '..', 'resources', 'install-spinner.gif') | ||
]; | ||
|
||
if (useMono) { | ||
if (process.platform !== 'win32') { | ||
args.unshift(path.join(vendorPath, 'Update-Mono.exe')); | ||
cmd = monoExe; | ||
cmd = 'mono'; | ||
} | ||
|
||
const {certificateFile, certificatePassword, signWithParams} = options; | ||
if (signWithParams) { | ||
args.push('--signWithParams'); | ||
args.push(signWithParams); | ||
|
@@ -173,25 +224,5 @@ export async function createWindowsInstaller(options) { | |
args.push('--no-msi'); | ||
} | ||
|
||
log(await spawn(cmd, args)); | ||
|
||
if (options.fixUpPaths !== false) { | ||
log('Fixing up paths'); | ||
|
||
if (metadata.productName || options.setupExe) { | ||
const setupPath = path.join(outputDirectory, options.setupExe || `${metadata.productName}Setup.exe`); | ||
const unfixedSetupPath = path.join(outputDirectory, 'Setup.exe'); | ||
log(`Renaming ${unfixedSetupPath} => ${setupPath}`); | ||
await fsUtils.rename(unfixedSetupPath, setupPath); | ||
} | ||
|
||
if (metadata.productName) { | ||
const msiPath = path.join(outputDirectory, `${metadata.productName}Setup.msi`); | ||
const unfixedMsiPath = path.join(outputDirectory, 'Setup.msi'); | ||
if (await fsUtils.fileExists(unfixedMsiPath)) { | ||
log(`Renaming ${unfixedMsiPath} => ${msiPath}`); | ||
await fsUtils.rename(unfixedMsiPath, msiPath); | ||
} | ||
} | ||
} | ||
} | ||
await spawn(cmd, args); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to debug — you need all categories in any case.
The issue — if you use different categories, you cannot get time information (debug measures time per category).