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.
 
 

194 lines
6.0 KiB

'use strict';
var _templateObject = _taggedTemplateLiteral(['\n URL: ', '\n ', '\n '], ['\n URL: ', '\n ', '\n ']),
_templateObject2 = _taggedTemplateLiteral(['\n Failed downloading the Cypress binary.\n Response code: ', '\n Response message: ', '\n '], ['\n Failed downloading the Cypress binary.\n Response code: ', '\n Response message: ', '\n ']);
function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
var _ = require('lodash');
var os = require('os');
var path = require('path');
var progress = require('request-progress');
var Promise = require('bluebird');
var request = require('request');
var url = require('url');
var debug = require('debug')('cypress:cli');
var _require = require('common-tags'),
stripIndent = _require.stripIndent;
var is = require('check-more-types');
var _require2 = require('../errors'),
throwFormErrorText = _require2.throwFormErrorText,
errors = _require2.errors;
var fs = require('../fs');
var util = require('../util');
var info = require('./info');
var baseUrl = 'https://download.cypress.io/';
var prepend = function prepend(urlPath) {
var endpoint = url.resolve(baseUrl, urlPath);
var platform = os.platform();
var arch = os.arch();
return endpoint + '?platform=' + platform + '&arch=' + arch;
};
var getUrl = function getUrl(version) {
if (is.url(version)) {
debug('version is already an url', version);
return version;
}
return version ? prepend('desktop/' + version) : prepend('desktop');
};
var statusMessage = function statusMessage(err) {
return err.statusCode ? [err.statusCode, err.statusMessage].join(' - ') : err.toString();
};
var prettyDownloadErr = function prettyDownloadErr(err, version) {
var msg = stripIndent(_templateObject, getUrl(version), statusMessage(err));
debug(msg);
return throwFormErrorText(errors.failedDownload)(msg);
};
// attention:
// when passing relative path to NPM post install hook, the current working
// directory is set to the `node_modules/cypress` folder
// the user is probably passing relative path with respect to root package folder
function formAbsolutePath(filename) {
if (path.isAbsolute(filename)) {
return filename;
}
return path.join(process.cwd(), '..', '..', filename);
}
// downloads from given url
// return an object with
// {filename: ..., downloaded: true}
var downloadFromUrl = function downloadFromUrl(options) {
return new Promise(function (resolve, reject) {
var url = getUrl(options.version);
debug('Downloading from', url);
debug('Saving file to', options.downloadDestination);
var req = request({
url: url,
followRedirect: function followRedirect(response) {
var version = response.headers['x-version'];
if (version) {
// set the version in options if we have one.
// this insulates us from potential redirect
// problems where version would be set to undefined.
options.version = version;
}
// yes redirect
return true;
}
});
// closure
var started = null;
progress(req, {
throttle: options.throttle
}).on('response', function (response) {
// start counting now once we've gotten
// response headers
started = new Date();
// if our status code does not start with 200
if (!/^2/.test(response.statusCode)) {
debug('response code %d', response.statusCode);
var err = new Error(stripIndent(_templateObject2, response.statusCode, response.statusMessage));
reject(err);
}
}).on('error', reject).on('progress', function (state) {
// total time we've elapsed
// starting on our first progress notification
var elapsed = new Date() - started;
var eta = util.calculateEta(state.percent, elapsed);
// send up our percent and seconds remaining
options.onProgress(state.percent, util.secsRemaining(eta));
})
// save this download here
.pipe(fs.createWriteStream(options.downloadDestination)).on('finish', function () {
debug('downloading finished');
resolve({
filename: options.downloadDestination,
downloaded: true
});
});
});
};
// returns an object with zip filename
// and a flag if the file was really downloaded
// or not. Maybe it was already there!
// {filename: ..., downloaded: true|false}
var download = function download() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (!options.version) {
debug('empty Cypress version to download, will try latest');
return downloadFromUrl(options);
}
debug('need to download Cypress version %s', options.version);
// first check the original filename
return fs.pathExists(options.version).then(function (exists) {
if (exists) {
debug('found file right away', options.version);
return {
filename: options.version,
downloaded: false
};
}
var possibleFile = formAbsolutePath(options.version);
debug('checking local file', possibleFile, 'cwd', process.cwd());
return fs.pathExists(possibleFile).then(function (exists) {
if (exists) {
debug('found local file', possibleFile);
debug('skipping download');
return {
filename: possibleFile,
downloaded: false
};
} else {
return downloadFromUrl(options);
}
});
});
};
var start = function start(options) {
_.defaults(options, {
version: null,
throttle: 100,
onProgress: function onProgress() {},
downloadDestination: path.join(info.getInstallationDir(), 'cypress.zip')
});
// make sure our 'dist' installation dir exists
return info.ensureInstallationDir().then(function () {
return download(options);
}).catch(function (err) {
return prettyDownloadErr(err, options.version);
});
};
module.exports = {
start: start,
getUrl: getUrl
};