You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
4.2 KiB
157 lines
4.2 KiB
/*! |
|
* node-sass: scripts/install.js |
|
*/ |
|
|
|
var fs = require('fs'), |
|
eol = require('os').EOL, |
|
mkdir = require('mkdirp'), |
|
path = require('path'), |
|
sass = require('../lib/extensions'), |
|
request = require('request'), |
|
log = require('npmlog'), |
|
downloadOptions = require('./util/downloadoptions'); |
|
|
|
/** |
|
* Download file, if succeeds save, if not delete |
|
* |
|
* @param {String} url |
|
* @param {String} dest |
|
* @param {Function} cb |
|
* @api private |
|
*/ |
|
|
|
function download(url, dest, cb) { |
|
var reportError = function(err) { |
|
var timeoutMessge; |
|
|
|
if (err.code === 'ETIMEDOUT') { |
|
if (err.connect === true) { |
|
// timeout is hit while your client is attempting to establish a connection to a remote machine |
|
timeoutMessge = 'Timed out attemping to establish a remote connection'; |
|
} else { |
|
timeoutMessge = 'Timed out whilst downloading the prebuilt binary'; |
|
// occurs any time the server is too slow to send back a part of the response |
|
} |
|
|
|
} |
|
cb(['Cannot download "', url, '": ', eol, eol, |
|
typeof err.message === 'string' ? err.message : err, eol, eol, |
|
timeoutMessge ? timeoutMessge + eol + eol : timeoutMessge, |
|
'Hint: If github.com is not accessible in your location', eol, |
|
' try setting a proxy via HTTP_PROXY, e.g. ', eol, eol, |
|
' export HTTP_PROXY=http://example.com:1234',eol, eol, |
|
'or configure npm proxy via', eol, eol, |
|
' npm config set proxy http://example.com:8080'].join('')); |
|
}; |
|
|
|
var successful = function(response) { |
|
return response.statusCode >= 200 && response.statusCode < 300; |
|
}; |
|
|
|
console.log('Downloading binary from', url); |
|
|
|
try { |
|
request(url, downloadOptions(), function(err, response, buffer) { |
|
if (err) { |
|
reportError(err); |
|
} else if (!successful(response)) { |
|
reportError(['HTTP error', response.statusCode, response.statusMessage].join(' ')); |
|
} else { |
|
console.log('Download complete'); |
|
|
|
if (successful(response)) { |
|
fs.createWriteStream(dest) |
|
.on('error', cb) |
|
.end(buffer, cb); |
|
} else { |
|
cb(); |
|
} |
|
} |
|
}) |
|
.on('response', function(response) { |
|
var length = parseInt(response.headers['content-length'], 10); |
|
var progress = log.newItem('', length); |
|
|
|
// The `progress` is true by default. However if it has not |
|
// been explicitly set it's `undefined` which is considered |
|
// as far as npm is concerned. |
|
if (process.env.npm_config_progress === 'true') { |
|
log.enableProgress(); |
|
|
|
response.on('data', function(chunk) { |
|
progress.completeWork(chunk.length); |
|
}) |
|
.on('end', progress.finish); |
|
} |
|
}); |
|
} catch (err) { |
|
cb(err); |
|
} |
|
} |
|
|
|
/** |
|
* Check and download binary |
|
* |
|
* @api private |
|
*/ |
|
|
|
function checkAndDownloadBinary() { |
|
if (process.env.SKIP_SASS_BINARY_DOWNLOAD_FOR_CI) { |
|
console.log('Skipping downloading binaries on CI builds'); |
|
return; |
|
} |
|
|
|
var cachedBinary = sass.getCachedBinary(), |
|
cachePath = sass.getBinaryCachePath(), |
|
binaryPath = sass.getBinaryPath(); |
|
|
|
if (sass.hasBinary(binaryPath)) { |
|
console.log('node-sass build', 'Binary found at', binaryPath); |
|
return; |
|
} |
|
|
|
try { |
|
mkdir.sync(path.dirname(binaryPath)); |
|
} catch (err) { |
|
console.error('Unable to save binary', path.dirname(binaryPath), ':', err); |
|
return; |
|
} |
|
|
|
if (cachedBinary) { |
|
console.log('Cached binary found at', cachedBinary); |
|
fs.createReadStream(cachedBinary).pipe(fs.createWriteStream(binaryPath)); |
|
return; |
|
} |
|
|
|
download(sass.getBinaryUrl(), binaryPath, function(err) { |
|
if (err) { |
|
console.error(err); |
|
return; |
|
} |
|
|
|
console.log('Binary saved to', binaryPath); |
|
|
|
cachedBinary = path.join(cachePath, sass.getBinaryName()); |
|
|
|
if (cachePath) { |
|
console.log('Caching binary to', cachedBinary); |
|
|
|
try { |
|
mkdir.sync(path.dirname(cachedBinary)); |
|
fs.createReadStream(binaryPath) |
|
.pipe(fs.createWriteStream(cachedBinary)) |
|
.on('error', function (err) { |
|
console.log('Failed to cache binary:', err); |
|
}); |
|
} catch (err) { |
|
console.log('Failed to cache binary:', err); |
|
} |
|
} |
|
}); |
|
} |
|
|
|
/** |
|
* If binary does not exist, download it |
|
*/ |
|
|
|
checkAndDownloadBinary();
|
|
|