Commit b50533ae by Michael Mifsud

Merge pull request #901 from xzyfer/feat/install/sass-binary-site

Introduce SASS_BINARY_SITE environment and refactor API tests
parents 768bf7ec 03a8d93a
......@@ -50,7 +50,7 @@ function getRuntimeInfo() {
/**
* Get binary name.
* If environment variable SASS_BINARY_NAME or
* process aurgument --binary-name is provide,
* process argument --binary-name is provided,
* return it as is, otherwise make default binary
* name: {platform}-{arch}-{v8 version}.node
*
......@@ -62,10 +62,10 @@ function getBinaryName() {
if (flags['--sass-binary-name']) {
binaryName = flags['--sass-binary-name'];
} else if (package.nodeSassConfig && package.nodeSassConfig.binaryName) {
binaryName = package.nodeSassConfig.binaryName;
} else if (process.env.SASS_BINARY_NAME) {
binaryName = process.env.SASS_BINARY_NAME;
} else if (package.nodeSassConfig && package.nodeSassConfig.binaryName) {
binaryName = package.nodeSassConfig.binaryName;
} else {
binaryName = [process.platform, '-',
process.arch, '-',
......@@ -76,21 +76,37 @@ function getBinaryName() {
}
/**
* Retrieve the URL to fetch binary.
* If environment variable SASS_BINARY_URL
* is set, return that path. Otherwise make
* path using current release version and
* binary name.
* Determine the URL to fetch binary file from.
* By default feth from the node-sass distribution
* site on GitHub.
*
* The default URL can be overriden using
* the environment variable SASS_BINARY_SITE
* or a command line option --sass-binary-site:
*
* node scripts/install.js --sass-binary-site http://example.com/
*
* The URL should to the mirror of the repository
* laid out as follows:
*
* SASS_BINARY_SITE/
*
* v3.0.0-beta.4
* v3.0.0-beta.4/freebsd-x64-14_binding.node
* ....
* v3.0.0-beta.5
* v3.0.0-beta.5/freebsd-ia32-11_binding.node
* v3.0.0-beta.5/freebsd-x64-42_binding.node
* ... etc. for all supported versions and platforms
*
* @api private
*/
function getBinaryUrl() {
return flags['--sass-binary-url'] ||
package.nodeSassConfig ? package.nodeSassConfig.binaryUrl : null ||
process.env.SASS_BINARY_URL ||
['https://github.com/sass/node-sass/releases/download/v',
package.version, '/', sass.binaryName].join('');
var site = flags['--sass-binary-site'] ||
process.env.SASS_BINARY_SITE ||
package.nodeSassConfig.binarySite;
return [site, 'v' + package.version, sass.binaryName].join('/');
}
/**
......@@ -118,7 +134,7 @@ sass.versionInfo = getVersionInfo();
/**
* Get binary path.
* If environment variable SASS_BINARY_PATH or
* process aurgument --binary-path is provide,
* process argument --sass-binary-path is provided,
* select it by appending binary name, otherwise
* make default binary path using binary name.
* Once the primary selection is made, check if
......@@ -134,10 +150,10 @@ sass.getBinaryPath = function(throwIfNotExists) {
if (flags['--sass-binary-path']) {
binaryPath = flags['--sass-binary-path'];
} else if (package.nodeSassConfig && package.nodeSassConfig.binaryPath) {
binaryPath = package.nodeSassConfig.binaryPath;
} else if (process.env.SASS_BINARY_PATH) {
binaryPath = process.env.SASS_BINARY_PATH;
} else if (package.nodeSassConfig && package.nodeSassConfig.binaryPath) {
binaryPath = package.nodeSassConfig.binaryPath;
} else {
binaryPath = path.join(__dirname, '..', 'vendor', sass.binaryName.replace(/_/, '/'));
}
......
......@@ -18,6 +18,9 @@
"node": ">=0.10.0"
},
"main": "lib/index.js",
"nodeSassConfig": {
"binarySite": "https://github.com/sass/node-sass/releases/download"
},
"bin": {
"node-sass": "bin/node-sass"
},
......
......@@ -20,22 +20,25 @@ require('../lib/extensions');
*/
function download(url, dest, cb) {
applyProxy({ rejectUnauthorized: false }, function(options) {
var returnError = function(err) {
cb(typeof err.message === 'string' ? err.message : err);
};
request.get(url, options).on('response', function(response) {
if (response.statusCode < 200 || response.statusCode >= 300) {
returnError(['Can not download file from:', url].join());
return;
}
response.pipe(fs.createWriteStream(dest));
cb();
}).on('error', returnError);
});
var returnError = function(err) {
cb(typeof err.message === 'string' ? err.message : err);
};
if (url) {
applyProxy({ rejectUnauthorized: false }, function(options) {
request.get(url, options).on('response', function(response) {
if (response.statusCode < 200 || response.statusCode >= 300) {
returnError(['Can not download file from:', url].join());
return;
}
response.pipe(fs.createWriteStream(dest));
cb();
}).on('error', returnError);
});
} else {
returnError('Download URL not defined, set SASS_BINARY_SITE in the environment to enable download.');
}
}
/**
......
......@@ -1417,83 +1417,4 @@ describe('api', function() {
done();
});
});
describe('extensions', function() {
it('should use the binary path and name set in package.json.', function(done) {
var packagePath = require.resolve('../package'),
extensionsPath = require.resolve('../lib/extensions');
delete require.cache[extensionsPath];
require.cache[packagePath].exports.nodeSassConfig = { binaryName: 'foo', binaryPath: 'bar' };
require(extensionsPath);
assert.equal(process.sass.binaryName, 'foo_binding.node');
assert.equal(process.sass.binaryPath, 'bar');
delete require.cache[packagePath];
delete require.cache[extensionsPath];
require(extensionsPath);
done();
});
it('should use the binary path and name set as environment variable.', function(done) {
var extensionsPath = require.resolve('../lib/extensions');
delete require.cache[extensionsPath];
process.env.SASS_BINARY_NAME = 'foo';
process.env.SASS_BINARY_PATH = 'bar';
require(extensionsPath);
assert.equal(process.sass.binaryName, 'foo_binding.node');
assert.equal(process.sass.binaryPath, 'bar');
delete process.env.SASS_BINARY_NAME;
delete process.env.SASS_BINARY_PATH;
delete require.cache[extensionsPath];
require(extensionsPath);
done();
});
it('should use the binary path and name set as process argument.', function(done) {
var extensionsPath = require.resolve('../lib/extensions'),
argv = process.argv;
delete require.cache[extensionsPath];
process.argv = argv.concat(['--sass-binary-name', 'foo', '--sass-binary-path', 'bar']);
require(extensionsPath);
assert.equal(process.sass.binaryName, 'foo_binding.node');
assert.equal(process.sass.binaryPath, 'bar');
process.argv = argv;
delete require.cache[extensionsPath];
require(extensionsPath);
done();
});
it('should throw error when libsass binary is missing.', function(done) {
var originalBin = process.sass.binaryPath,
renamedBin = [originalBin, '_moved'].join('');
assert.throws(function() {
fs.renameSync(originalBin, renamedBin);
process.sass.getBinaryPath(true);
}, /`libsass` bindings not found/);
fs.renameSync(renamedBin, originalBin);
done();
});
});
});
var assert = require('assert'),
fs = require('fs');
describe('runtime parameters', function() {
var packagePath = require.resolve('../package'),
extensionsPath = process.env.NODESASS_COV
? require.resolve('../lib-cov/extensions')
: require.resolve('../lib/extensions'),
// Let's use JSON to fake a deep copy
savedArgv = JSON.stringify(process.argv),
savedEnv = JSON.stringify(process.env);
beforeEach(function() {
require(packagePath);
delete require.cache[extensionsPath];
});
afterEach(function() {
delete require.cache[packagePath];
delete require.cache[extensionsPath];
process.argv = JSON.parse(savedArgv);
process.env = JSON.parse(savedEnv);
require(packagePath);
require(extensionsPath);
});
describe('in package.json', function() {
it('should use the binary path', function() {
require.cache[packagePath].exports.nodeSassConfig = { binaryPath: 'ccc' };
require(extensionsPath);
assert.equal(process.sass.binaryPath, 'ccc');
});
it('should use the binary file name', function() {
require.cache[packagePath].exports.nodeSassConfig = { binaryName: 'ddd' };
require(extensionsPath);
assert.equal(process.sass.binaryName, 'ddd_binding.node');
});
it('should use both the binary path and the file name', function() {
require.cache[packagePath].exports.nodeSassConfig = { binaryName: 'foo', binaryPath: 'bar' };
require(extensionsPath);
assert.equal(process.sass.binaryName, 'foo_binding.node');
assert.equal(process.sass.binaryPath, 'bar');
});
it('should use both the binary path and the file name', function() {
require.cache[packagePath].exports.nodeSassConfig = { binaryName: 'foo', binaryPath: 'bar' };
require(extensionsPath);
assert.equal(process.sass.binaryName, 'foo_binding.node');
assert.equal(process.sass.binaryPath, 'bar');
});
it('should use the distribution site URL', function() {
require.cache[packagePath].exports.nodeSassConfig = { binarySite: 'http://foo.example.com:9999' };
require(extensionsPath);
var URL = 'http://foo.example.com:9999/v';
assert.equal(process.sass.binaryUrl.substr(0, URL.length), URL);
});
});
describe('in the process environment variables', function() {
it('should use the binary path', function() {
process.env.SASS_BINARY_PATH = 'xxx';
require(extensionsPath);
assert.equal(process.sass.binaryPath, 'xxx');
});
it('should use the binary file name', function() {
process.env.SASS_BINARY_NAME = 'foo';
require(extensionsPath);
assert.equal(process.sass.binaryName, 'foo_binding.node');
});
it('should use both the binary path and the file name', function() {
process.env.SASS_BINARY_NAME = 'foo';
process.env.SASS_BINARY_PATH = 'bar';
require(extensionsPath);
assert.equal(process.sass.binaryName, 'foo_binding.node');
assert.equal(process.sass.binaryPath, 'bar');
});
it('should use the distribution site URL', function() {
process.env.SASS_BINARY_SITE = 'http://bar.example.com:9988';
require(extensionsPath);
var URL = 'http://bar.example.com:9988/v';
assert.equal(process.sass.binaryUrl.substr(0, URL.length), URL);
});
});
describe('using command line parameters', function() {
it('should use the binary path', function() {
process.argv.push('--sass-binary-path', 'aaa');
require(extensionsPath);
assert.equal(process.sass.binaryPath, 'aaa');
});
it('should use the binary file name', function() {
process.argv.push('--sass-binary-name', 'bbb');
require(extensionsPath);
assert.equal(process.sass.binaryName, 'bbb_binding.node');
});
it('should use both the binary path and the file name', function() {
process.argv.push('--sass-binary-name', 'foo', '--sass-binary-path', 'bar');
require(extensionsPath);
assert.equal(process.sass.binaryName, 'foo_binding.node');
assert.equal(process.sass.binaryPath, 'bar');
});
it('should use the distribution site URL', function() {
process.argv.push('--sass-binary-site', 'http://qqq.example.com:9977');
require(extensionsPath);
var URL = 'http://qqq.example.com:9977/v';
assert.equal(process.sass.binaryUrl.substr(0, URL.length), URL);
});
});
describe('checking if the command line parameter overrides environment', function() {
it('binary path', function() {
process.argv.push('--sass-binary-path', 'bbb');
process.env.SASS_BINARY_PATH = 'xxx';
require(extensionsPath);
assert.equal(process.sass.binaryPath, 'bbb');
});
it('binary name', function() {
process.argv.push('--sass-binary-name', 'ccc');
process.env.SASS_BINARY_NAME = 'yyy';
require(extensionsPath);
assert.equal(process.sass.binaryName, 'ccc_binding.node');
});
it('distribution site URL', function() {
process.argv.push('--sass-binary-site', 'http://qqq.example.com:9977');
process.env.SASS_BINARY_SITE = 'http://www.example.com:9988';
require(extensionsPath);
var URL = 'http://qqq.example.com:9977/v';
assert.equal(process.sass.binaryUrl.substr(0, URL.length), URL);
});
});
describe('checking if the command line parameter overrides package.json', function() {
it('binary path', function() {
process.argv.push('--sass-binary-path', 'ddd');
require.cache[packagePath].exports.nodeSassConfig = { binaryPath: 'yyy' };
require(extensionsPath);
assert.equal(process.sass.binaryPath, 'ddd');
});
it('binary name', function() {
process.argv.push('--sass-binary-name', 'eee');
require.cache[packagePath].exports.nodeSassConfig = { binaryName: 'zzz' };
require(extensionsPath);
assert.equal(process.sass.binaryName, 'eee_binding.node');
});
it('distribution site URL', function() {
process.argv.push('--sass-binary-site', 'http://yyy.example.com:9977');
require.cache[packagePath].exports.nodeSassConfig = { binarySite: 'http://ddd.example.com:8888' };
require(extensionsPath);
var URL = 'http://yyy.example.com:9977/v';
assert.equal(process.sass.binaryUrl.substr(0, URL.length), URL);
});
});
describe('checking if environment variable overrides package.json', function() {
it('binary path', function() {
process.env.SASS_BINARY_PATH = 'ggg';
require.cache[packagePath].exports.nodeSassConfig = { binaryPath: 'qqq' };
require(extensionsPath);
assert.equal(process.sass.binaryPath, 'ggg');
});
it('binary name', function() {
process.env.SASS_BINARY_NAME = 'hhh';
require.cache[packagePath].exports.nodeSassConfig = { binaryName: 'uuu' };
require(extensionsPath);
assert.equal(process.sass.binaryName, 'hhh_binding.node');
});
it('distribution site URL', function() {
require.cache[packagePath].exports.nodeSassConfig = { binarySite: 'http://ddd.example.com:8888' };
process.env.SASS_BINARY_SITE = 'http://iii.example.com:9988';
require(extensionsPath);
var URL = 'http://iii.example.com:9988/v';
assert.equal(process.sass.binaryUrl.substr(0, URL.length), URL);
});
});
});
describe('library detection', function() {
it('should throw error when libsass binary is missing.', function() {
var originalBin = process.sass.binaryPath,
renamedBin = [originalBin, '_moved'].join('');
assert.throws(function() {
fs.renameSync(originalBin, renamedBin);
process.sass.getBinaryPath(true);
}, /`libsass` bindings not found/);
fs.renameSync(renamedBin, originalBin);
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment