From d4b8f6b49008c46c1740b34bf3a8975beb8eada9 Mon Sep 17 00:00:00 2001 From: Kevin Martensson Date: Tue, 4 Nov 2014 13:11:48 +0100 Subject: [PATCH] Revamp build steps * Instead of providing the binaries with the package, it'll only download the needed binary for the users system. * Will only build if the tests fail. * Move `build.js` into scripts since it's not part of the actual API. * Move binaries to `vendor` folder to keep it separate from the rest of the code. Fixes #504. --- .gitignore | 3 +- lib/index.js | 2 +- package.json | 9 ++--- {lib => scripts}/build.js | 18 +++++----- scripts/install.js | 71 +++++++++++++++++++++++++++++++++++++++ scripts/prepublish | 33 ------------------ 6 files changed, 87 insertions(+), 49 deletions(-) rename {lib => scripts}/build.js (89%) create mode 100644 scripts/install.js delete mode 100644 scripts/prepublish diff --git a/.gitignore b/.gitignore index 9ee4b6601..a604ca365 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,7 @@ *.log .DS_Store .sass-cache -bin -!bin/node-sass build lib-cov node_modules +vendor diff --git a/lib/index.js b/lib/index.js index 81f2489e5..c64bd2296 100644 --- a/lib/index.js +++ b/lib/index.js @@ -13,7 +13,7 @@ function getBinding() { var candidates = [ path.join(__dirname, '..', 'build', 'Release', 'binding.node'), path.join(__dirname, '..', 'build', 'Debug', 'binding.node'), - path.join(__dirname, '..', 'bin', name, 'binding.node') + path.join(__dirname, '..', 'vendor', name, 'binding.node') ]; var candidate = candidates.filter(fs.existsSync)[0]; diff --git a/package.json b/package.json index 643ca8d43..7174d6067 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,8 @@ "gypfile": true, "scripts": { "coverage": "node scripts/coverage.js", - "install": "node lib/build.js", - "prepublish": "node scripts/prepublish", + "install": "node scripts/install.js", + "postinstall": "node scripts/build.js", "pretest": "node_modules/.bin/jshint bin lib test", "test": "node_modules/.bin/mocha test" }, @@ -44,14 +44,15 @@ "dependencies": { "chalk": "^0.5.1", "cross-spawn": "^0.2.3", + "download": "^3.1.2", + "download-status": "^2.1.0", "get-stdin": "^3.0.0", "meow": "^2.0.0", "mkdirp": "^0.5.0", "mocha": "^2.0.1", "nan": "^1.3.0", "node-watch": "^0.3.4", - "object-assign": "^1.0.0", - "shelljs": "^0.3.0" + "object-assign": "^1.0.0" }, "devDependencies": { "coveralls": "^2.11.1", diff --git a/lib/build.js b/scripts/build.js similarity index 89% rename from lib/build.js rename to scripts/build.js index 3de3feb6f..6ff81f48b 100644 --- a/lib/build.js +++ b/scripts/build.js @@ -1,7 +1,7 @@ -#!/usr/bin/env node var fs = require('fs'), path = require('path'), spawn = require('child_process').spawn, + mkdir = require('mkdirp'), Mocha = require('mocha'); /** @@ -14,24 +14,24 @@ var fs = require('fs'), function afterBuild(options) { var folder = options.debug ? 'Debug' : 'Release'; var target = path.join(__dirname, '..', 'build', folder, 'binding.node'); - var install = path.join(__dirname, '..', 'bin', options.bin, 'binding.node'); + var install = path.join(__dirname, '..', 'vendor', options.bin, 'binding.node'); - fs.mkdir(path.join(__dirname, '..', 'bin', options.bin), function (err) { + mkdir(path.join(__dirname, '..', 'vendor', options.bin), function (err) { if (err && err.code !== 'EEXIST') { console.error(err.message); - process.exit(1); + return; } fs.stat(target, function (err) { if (err) { console.error('Build succeeded but target not found'); - process.exit(1); + return; } fs.rename(target, install, function (err) { if (err) { console.error(err.message); - process.exit(1); + return; } console.log('Installed in `' + install + '`'); @@ -61,11 +61,11 @@ function build(options) { 'You need at least 1.1.5 (I think) and preferably 1.1.30.' ].join(' ')); - process.exit(code); + return; } console.error('Build failed'); - process.exit(code); + return; } afterBuild(options); @@ -120,7 +120,7 @@ function testBinary(options) { } if (!process.env.SKIP_NODE_SASS_TESTS) { - fs.stat(path.join(__dirname, '..', 'bin', options.bin, 'binding.node'), function (err) { + fs.stat(path.join(__dirname, '..', 'vendor', options.bin, 'binding.node'), function (err) { if (err) { return build(options); } diff --git a/scripts/install.js b/scripts/install.js new file mode 100644 index 000000000..0da323f68 --- /dev/null +++ b/scripts/install.js @@ -0,0 +1,71 @@ +var fs = require('fs'), + path = require('path'), + Download = require('download'), + status = require('download-status'); + +/** + * Check if binaries exists + * + * @api private + */ + +function exists() { + var v8 = 'v8-' + /[0-9]+\.[0-9]+/.exec(process.versions.v8)[0]; + var name = process.platform + '-' + process.arch + '-' + v8; + + fs.exists(path.join(__dirname, '..', 'vendor', name), function (exists) { + if (exists) { + return; + } + + fetch(name); + }); +} + +/** + * Fetch binaries + * + * @param {String} name + * @api private + */ + +function fetch(name) { + var download = new Download({ + extract: true, + mode: '777', + strip: 1 + }); + + var url = [ + 'https://github.com/sass/node-sass-binaries/raw/master/', + name + '/binding.node' + ].join(''); + + download.get(url); + download.dest(path.join(__dirname, '..', 'vendor', name)); + download.use(status()); + + download.run(function(err) { + if (err) { + console.error(err.message); + return; + } + + console.log('Binary installed in ' + download.dest()); + }); +} + +/** + * Skip if CI + */ + +if (process.env.CI || process.env.APPVEYOR) { + console.log('Skipping downloading binaries on CI builds'); + return; +} + +/** + * Run + */ + +exists(); diff --git a/scripts/prepublish b/scripts/prepublish deleted file mode 100644 index fc5dbc9b8..000000000 --- a/scripts/prepublish +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env node -/*jshint shelljs:true */ - -"use strict"; - -require('shelljs/make'); - -if (env["$CI"]) { - echo("Skipping prepublish on CI builds"); - exit(0); -} - -// Look for a local clone of -var NODE_SASS_BINARIES_DIR = "../node-sass-binaries"; - -if (!test("-e", NODE_SASS_BINARIES_DIR)) { - - if (!which("git")) { - echo("Sorry, this script requires git"); - exit(1); - } - - // Clone the binary repo to the expected location - var NODE_SASS_DIR = pwd(); - cd(".."); - exec("git clone https://github.com/sass/node-sass-binaries.git") - - cd(NODE_SASS_DIR); -} - -echo("Copying binaries to bin"); -cp("-Rf", NODE_SASS_BINARIES_DIR + "/*", "bin"); -rm(["bin/LICENSE", "bin/README.md"]);