From 8080c872f80f311d949e6fe5c58f44e9d2f81f38 Mon Sep 17 00:00:00 2001 From: Alan Stoll Date: Thu, 3 Jul 2014 09:23:40 -0400 Subject: [PATCH 1/3] close gracefully on osx until we can make new window from the tray --- shell/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/index.js b/shell/index.js index 4f9f5abf8..71e4543c9 100644 --- a/shell/index.js +++ b/shell/index.js @@ -12,7 +12,7 @@ module.exports = function(copay) { // quit when all windows are closed app.on('window-all-closed', function() { - if (process.platform !== 'darwin') app.quit(); + app.quit(); }); // initilization when ready From c05895f8797f884ae68295d2903d6d2e933a3b14 Mon Sep 17 00:00:00 2001 From: Alan Stoll Date: Thu, 3 Jul 2014 09:23:40 -0400 Subject: [PATCH 2/3] build scripts for copay shell binaries --- package.json | 3 +- shell/scripts/dist.js | 168 ++++++++++++++++++++++++++++++++++ shell/scripts/lib/download.js | 102 +++++++++++++++++++++ 3 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 shell/scripts/dist.js create mode 100644 shell/scripts/lib/download.js diff --git a/package.json b/package.json index 3bbbc4c45..1e943a55b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "shell": "node shell/scripts/launch.js", "setup-shell": "node shell/scripts/download-atom-shell.js", "chrome": "source browser-extensions/chrome/build.sh", - "firefox": "source browser-extensions/firefox/build.sh" + "firefox": "source browser-extensions/firefox/build.sh", + "dist": "node shell/scripts/dist.js" }, "homepage": "https://github.com/bitpay/copay", "devDependencies": { diff --git a/shell/scripts/dist.js b/shell/scripts/dist.js new file mode 100644 index 000000000..09cd68c30 --- /dev/null +++ b/shell/scripts/dist.js @@ -0,0 +1,168 @@ +require('shelljs/global'); +var color = require('cli-color'); + +var download = require('./lib/download')(); +var async = require('async'); + +var atom_version = 'v0.13.0'; + +var app_root = './'; + +var build_dir = 'shell/scripts/build'; +var dist_dir = 'dist'; + +var darwin_app_dir = '/Copay.app/Contents/Resources/app'; +var linux_app_dir = '/resources/app'; +var windows_app_dir = '/resources/app'; + +rm('-rf', build_dir); +rm('-rf', dist_dir); + +async.series([ + function(callback) { + download.atom(atom_version, 'darwin', 'x64', callback); + }, + function(callback){ + download.atom(atom_version, 'linux', 'x64', callback); + }, + function(callback) { + download.atom(atom_version, 'win32', 'ia32', callback); + }, + function() { + runBuild(); + }]); + +function runBuild() { + + mkdir(build_dir); + + /* DARWIN BUILD */ + + console.log(color.blue('{copay}'), ''); + console.log(color.blue('{copay}'), 'Starting DARWIN build'); + console.log(color.blue('{copay}'), ''); + + // Copy the core atom shell + cp('-r', app_root + '/shell/scripts/bin/darwin/*', build_dir); + mv(build_dir + '/Atom.app', build_dir + '/Copay.app'); + mv(build_dir + '/Copay.app/Contents/MacOS/Atom', build_dir + '/Copay.app/Contents/MacOS/Copay'); + + // Replace Atom darwin assets with Copay assets + cp(app_root + '/shell/assets/darwin/copay.icns', build_dir + '/Copay.app/Contents/Resources/copay.icns'); + cp('-f', app_root + '/shell/assets/darwin/Info.plist', build_dir + '/Copay.app/Contents/Info.plist'); + rm(build_dir + '/Copay.app/Contents/Resources/atom.icns'); + + // Copy Copay sources + cp('-r', app_root + '/css', build_dir + darwin_app_dir); + cp('-r', app_root + '/js', build_dir + darwin_app_dir); + cp('-r', app_root + '/font', build_dir + darwin_app_dir); + cp('-r', app_root + '/img', build_dir + darwin_app_dir); + cp('-r', app_root + '/lib', build_dir + darwin_app_dir); + cp('-r', app_root + '/sound', build_dir + darwin_app_dir); + cp('-r', app_root + '/shell/*.js*', build_dir + darwin_app_dir + '/shell'); + cp('-r', app_root + '/shell/lib/*', build_dir + darwin_app_dir + '/shell/lib'); + cp(app_root + '*.js', build_dir + darwin_app_dir); + cp(app_root + '*.json', build_dir + darwin_app_dir); + cp(app_root + '*.html', build_dir + darwin_app_dir); + + cp('-r', app_root + '/node_modules/express', build_dir + darwin_app_dir + "/node_modules"); + + // Clean up extra Atom sources + rm('-r', build_dir + darwin_app_dir + '/../*.lproj'); + rm('-r', build_dir + darwin_app_dir + '/../default_app'); + + mkdir('-p', app_root + '/dist/darwin'); + cp('-r', app_root + build_dir + '/*', app_root + '/dist/darwin/'); + rm('-rf', app_root + build_dir + '/*'); + + console.log(color.blue('{copay}'), 'Copied files to ' + 'dist/darwin'); + + if (which('hdiutil') != null) { + cd(app_root + '/dist/darwin'); + exec('ln -s /Applications Applications'); + exec('hdiutil create ../Copay-darwin-x64.dmg -volname "Copay Installer - Drag Copay to Applications Folder" -fs HFS+ -srcfolder "."'); + exec("rm Applications"); + cd('../..'); + } + + /* Linux Build */ + + console.log(color.blue('{copay}'), ''); + console.log(color.blue('{copay}'), 'Starting LINUX build'); + console.log(color.blue('{copay}'), ''); + + // Copy the core atom shell + cp('-r', app_root + '/shell/scripts/bin/linux/*', build_dir); + mv(build_dir + '/atom', build_dir + '/Copay'); + + // Copy Copay sources + cp('-r', app_root + '/css', build_dir + linux_app_dir); + cp('-r', app_root + '/js', build_dir + linux_app_dir); + cp('-r', app_root + '/font', build_dir + linux_app_dir); + cp('-r', app_root + '/img', build_dir + linux_app_dir); + cp('-r', app_root + '/lib', build_dir + linux_app_dir); + cp('-r', app_root + '/sound', build_dir + linux_app_dir); + cp('-r', app_root + '/shell/*.js*', build_dir + linux_app_dir + '/shell'); + cp('-r', app_root + '/shell/lib/*', build_dir + linux_app_dir + '/shell/lib'); + cp(app_root + '*.js', build_dir + linux_app_dir); + cp(app_root + '*.json', build_dir + linux_app_dir); + cp(app_root + '*.html', build_dir + linux_app_dir); + + cp('-r', app_root + '/node_modules/express', build_dir + linux_app_dir + "/node_modules"); + + // Clean up extra Atom sources + rm('-r', build_dir + linux_app_dir + '/../default_app'); + cp('-r', app_root + build_dir + '/*', app_root + '/dist/linux'); + rm('-rf', app_root + build_dir + '/*'); + + exec('tar czf ./dist/Copay-linux-x64.tar.gz -C ./dist/linux .'); + + console.log(color.blue('{copay}'), 'Copied files to ' + 'dist/linux'); + + /* Windows Build */ + + console.log(color.blue('{copay}'), ''); + console.log(color.blue('{copay}'), 'Starting WIN32 build'); + console.log(color.blue('{copay}'), ''); + + // Copy the core atom shell + cp('-r', app_root + '/shell/scripts/bin/win32/*', build_dir); + mv(build_dir + '/atom.exe', build_dir + '/Copay.exe'); + + // Copy Copay sources + cp('-r', app_root + '/css', build_dir + windows_app_dir); + cp('-r', app_root + '/js', build_dir + windows_app_dir); + cp('-r', app_root + '/font', build_dir + windows_app_dir); + cp('-r', app_root + '/img', build_dir + windows_app_dir); + cp('-r', app_root + '/lib', build_dir + windows_app_dir); + cp('-r', app_root + '/sound', build_dir + windows_app_dir); + cp('-r', app_root + '/shell/*.js*', build_dir + windows_app_dir + '/shell'); + cp('-r', app_root + '/shell/lib/*', build_dir + windows_app_dir + '/shell/lib'); + cp(app_root + '*.js', build_dir + windows_app_dir); + cp(app_root + '*.json', build_dir + windows_app_dir); + cp(app_root + '*.html', build_dir + windows_app_dir); + + cp('-r', app_root + '/node_modules/express', build_dir + windows_app_dir + "/node_modules"); + + cp(app_root + "/shell/assets/win32/*", build_dir); + + mkdir('-p', app_root + '/dist/windows'); + cp('-r', app_root + build_dir + '/*', app_root + '/dist/windows/'); + + console.log(color.blue('{copay}'), 'Copied files to ' + 'dist/windows'); + + + // generating windows installer requires makensis + // install on OSX with "brew install makensis" + if (which('makensis') != null) { + console.log(color.blue('{copay}'), 'Running NSIS to generate win32 installer'); + cd(build_dir); + exec('makensis -V2 build-installer.nsi'); + cd("../../.."); + cp(build_dir + '/copay-setup.exe', app_root + '/dist/Copay-setup-win32.exe') + } + + console.log(color.blue('{copay}')); + console.log(color.blue('{copay}'), 'BUILD COMPLETE'); + console.log(color.blue('{copay}'), 'Files can be found in the dist directory'); +} diff --git a/shell/scripts/lib/download.js b/shell/scripts/lib/download.js new file mode 100644 index 000000000..1bb4f0c9a --- /dev/null +++ b/shell/scripts/lib/download.js @@ -0,0 +1,102 @@ +var path = require('path'); +var fs = require('fs'); +var GitHub = require('github-releases'); +var async = require('async'); +var readl = require('readline'); +var color = require('cli-color'); +var github = new GitHub({ repo: 'atom/atom-shell' }); +var exec = require('child_process').exec; +var os = require('os'); + +var Static = function() { + + return { + atom: function(version, platform, arch, callback) { + var targetRoot = path.normalize(__dirname + '/../bin/'), + target = path.normalize(__dirname + '/../bin/' + platform); + + console.log(color.blue('{copay}'), 'Downloading atom-shell ' + version + ' ' + platform + '-' + arch); + + if(!fs.existsSync(targetRoot)) { + fs.mkdirSync(targetRoot); + } + + if (!fs.existsSync(target)) { + fs.mkdirSync(target); + } else { + console.log(color.blue('{copay}'), platform + '-' + arch + ' ' + ' already downloaded'); + callback.call(this, null); + } + + + + console.log(color.blue('{copay}'), 'getting atom-shell release ' + version); + + github.getReleases({ tag_name: version }, function(err, releases) { + var filename = 'atom-shell-' + version + '-' + platform + '-' + arch + '.zip'; + + if (err || !releases.length) { + return console.log(color.blue('{copay}'), 'Release not found'); + } + + console.log(color.blue('{copay}'), 'looking for prebuilt binary ' + filename); + + for (var a = 0; a < releases[0].assets.length; a++) { + var asset = releases[0].assets[a]; + + if (asset.name === filename) { + + console.log(color.blue('{copay}'), 'downloading ' + asset.name); + + var rl = readl.createInterface({ + input: process.stdin, + output: process.stdout + }); + + rl.write(' bytes received: 0'); + + return github.downloadAsset(asset, function(err, inStream) { + if (err) { + console.log(err); + process.exit(); + } + + var bytes = 0; + + inStream.on('data', function(chunk) { + rl.write(null, { ctrl: true, name: 'u' }); + rl.write(' bytes received: ' + (bytes + chunk.length)); + bytes += chunk.length; + }); + + inStream.on('end', function() { + rl.close(); + console.log(''); + console.log(color.blue('{copay}'), 'downloaded!'); + }); + + var out = target; + var tmp = os.tmpDir() + '/atom-shell.zip'; + var outStream = fs.createWriteStream(tmp); + + outStream.on('finish', function() { + console.log(color.blue('{copay}'), 'unzipping archive'); + exec('unzip -o ' + tmp + ' -d ' + out, function(err, stdout, stderr) { + console.log(err || stderr || (color.blue('{copay}') + ' done!')) + callback.call(this, null); + }); + }); + + inStream.pipe(outStream); + + }); + } + } + + }); + + } + } +} + +module.exports = Static; From ad681c7344511150fd005947233924d028e69982 Mon Sep 17 00:00:00 2001 From: Alan Stoll Date: Thu, 3 Jul 2014 09:23:40 -0400 Subject: [PATCH 3/3] docs and some cleanup for copay native binaries builds --- .gitignore | 10 ++++++++++ README.md | 13 +++++++++++++ dist/README.md | 1 + shell/README.md | 3 ++- shell/scripts/dist.js | 23 ++++++++++++++++++----- shell/scripts/lib/download.js | 2 ++ 6 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 dist/README.md diff --git a/.gitignore b/.gitignore index 16ecd65e1..0a7848506 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,13 @@ coverage/ shell/bin/linux shell/bin/darwin shell/bin/win32 + +shell/scripts/bin +shell/scripts/build + +dist/darwin +dist/linux +dist/windows +dist/*.dmg +dist/*.tar.gz +dist/*.exe diff --git a/README.md b/README.md index 1ec1f5809..b7ddb314a 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,19 @@ Once this script has completed, you can launch the shell-based Copay by running: npm run shell ``` +## Building Native Shell Binaries/Installers (OSX) + +``` +npm run dist +``` + +This script will download atom shell binaries and combine them with Copay sources +to build a DMG for osx-x64, an installer EXE for win32, and a .tar.gz for linux-x64. +It was developed to be run on OSX. The outputs are copied to the dist directory. + +DMG is created with hdiutil +EXE is created with makensis (brew install makensis) + ## Tests Open test/index.html in your browser to test the models. Install and run karma diff --git a/dist/README.md b/dist/README.md new file mode 100644 index 000000000..1d883f95d --- /dev/null +++ b/dist/README.md @@ -0,0 +1 @@ +This is the destination directory for the built atom-shell binaries and the files used to create them \ No newline at end of file diff --git a/shell/README.md b/shell/README.md index 970f9882d..36c1408e4 100644 --- a/shell/README.md +++ b/shell/README.md @@ -8,4 +8,5 @@ using [Atom Shell](https://github.com/atom/atom-shell). ## Building -Automated build scripts are currently being developed. +Run from the top level (copay) directory: +npm run dist diff --git a/shell/scripts/dist.js b/shell/scripts/dist.js index 09cd68c30..1555dbe70 100644 --- a/shell/scripts/dist.js +++ b/shell/scripts/dist.js @@ -15,9 +15,17 @@ var darwin_app_dir = '/Copay.app/Contents/Resources/app'; var linux_app_dir = '/resources/app'; var windows_app_dir = '/resources/app'; -rm('-rf', build_dir); -rm('-rf', dist_dir); +console.log(color.blue('{copay}'), ''); +console.log(color.blue('{copay}'), 'Preparing to build Copay binaries'); +console.log(color.blue('{copay}'), ''); +/* Clean up before the build */ +rm('-rf', build_dir); +rm(dist_dir + '/Copay*'); +rm('-rf', dist_dir + '/darwin', dist_dir + '/linux', dist_dir + '/windows'); + +// Download the atom shell binaries. If you exceed your download quota, +// just download the zips manually and unpack them into shell/scripts/bin/ async.series([ function(callback) { download.atom(atom_version, 'darwin', 'x64', callback); @@ -65,6 +73,7 @@ function runBuild() { cp(app_root + '*.json', build_dir + darwin_app_dir); cp(app_root + '*.html', build_dir + darwin_app_dir); + // Copay needs express, put other node deps here if you need any cp('-r', app_root + '/node_modules/express', build_dir + darwin_app_dir + "/node_modules"); // Clean up extra Atom sources @@ -146,9 +155,13 @@ function runBuild() { cp(app_root + "/shell/assets/win32/*", build_dir); + rm('-r', build_dir + windows_app_dir + '/../default_app'); + mkdir('-p', app_root + '/dist/windows'); cp('-r', app_root + build_dir + '/*', app_root + '/dist/windows/'); + rm('-rf', app_root + build_dir + '/*'); + console.log(color.blue('{copay}'), 'Copied files to ' + 'dist/windows'); @@ -156,10 +169,10 @@ function runBuild() { // install on OSX with "brew install makensis" if (which('makensis') != null) { console.log(color.blue('{copay}'), 'Running NSIS to generate win32 installer'); - cd(build_dir); + cd('dist/windows'); exec('makensis -V2 build-installer.nsi'); - cd("../../.."); - cp(build_dir + '/copay-setup.exe', app_root + '/dist/Copay-setup-win32.exe') + cd("../../"); + cp('dist/windows/copay-setup.exe', app_root + '/dist/Copay-setup-win32.exe') } console.log(color.blue('{copay}')); diff --git a/shell/scripts/lib/download.js b/shell/scripts/lib/download.js index 1bb4f0c9a..d13f692a6 100644 --- a/shell/scripts/lib/download.js +++ b/shell/scripts/lib/download.js @@ -26,6 +26,7 @@ var Static = function() { } else { console.log(color.blue('{copay}'), platform + '-' + arch + ' ' + ' already downloaded'); callback.call(this, null); + return; } @@ -36,6 +37,7 @@ var Static = function() { var filename = 'atom-shell-' + version + '-' + platform + '-' + arch + '.zip'; if (err || !releases.length) { + console.log(err); return console.log(color.blue('{copay}'), 'Release not found'); }