From d2b408a2f34e73b29ef030ac1e067df33d83e481 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 1 Oct 2015 20:16:12 +0200 Subject: [PATCH 01/38] peer dependencies support --- github.js | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/github.js b/github.js index 88b5a68..0cf78b5 100644 --- a/github.js +++ b/github.js @@ -468,19 +468,21 @@ GithubLocation.prototype = { }); }, - processPackageConfig: function(pjson, packageName) { - if (!pjson.jspm || !pjson.jspm.files) - delete pjson.files; + processPackageConfig: function(packageConfig, packageName) { + if (!packageConfig.jspm || !packageConfig.jspm.files) + delete packageConfig.files; var self = this; - if (pjson.dependencies && !pjson.registry && (!pjson.jspm || !pjson.jspm.dependencies)) { + if ((packageConfig.dependencies || packageConfig.peerDependencies) && !packageConfig.registry && (!packageConfig.jspm || !(packageConfig.jspm.dependencies || packageConfig.jspm.peerDependencies))) { var hasDependencies = false; - for (var p in pjson.dependencies) + for (var p in packageConfig.dependencies) + hasDependencies = true; + for (var p in packageConfig.peerDependencies) hasDependencies = true; if (packageName && hasDependencies) { - var looksLikeNpm = pjson.name && pjson.version && (pjson.description || pjson.repository || pjson.author || pjson.license || pjson.scripts); + var looksLikeNpm = packageConfig.name && packageConfig.version && (packageConfig.description || packageConfig.repository || packageConfig.author || packageConfig.license || packageConfig.scripts); var isSemver = semver.valid(packageName.split('@').pop()); var noDepsMsg; @@ -489,31 +491,37 @@ GithubLocation.prototype = { if (!isSemver) noDepsMsg = 'To install this package as it would work on npm, install with a registry override via %jspm install ' + packageName + ' -o "{registry:\'npm\'}"%.' else - noDepsMsg = 'If the dependencies aren\'t needed ignore this message. Alternatively set a `registry` or `dependencies` override or use the npm registry version at %jspm install npm:' + pjson.name + '@^' + pjson.version + '% instead.'; + noDepsMsg = 'If the dependencies aren\'t needed ignore this message. Alternatively set a `registry` or `dependencies` override or use the npm registry version at %jspm install npm:' + packageConfig.name + '@^' + packageConfig.version + '% instead.'; } else { noDepsMsg = 'If this is your own package, add `"registry": "jspm"` to the package.json to ensure the dependencies are installed.' } if (noDepsMsg) { - delete pjson.dependencies; + delete packageConfig.dependencies; + delete packageConfig.peerDependencies; this.ui.log('warn', '`' + packageName + '` dependency installs skipped as it\'s a GitHub package with no registry property set.\n' + noDepsMsg + '\n'); } } else { - delete pjson.dependencies; + delete packageConfig.dependencies; + delete packageConfig.peerDependencies; } } // on GitHub, single package names ('jquery') are from jspm registry // double package names ('components/jquery') are from github registry - if (!pjson.registry) { - for (var d in pjson.dependencies) { - var depName = pjson.dependencies[d]; + if (!packageConfig.registry || packageConfig.registry == 'github') { + for (var d in packageConfig.dependencies) + packageConfig.dependencies[d] = convertDependency(d, packageConfig.dependencies[d]); + for (var d in packageConfig.peerDependencies) + packageConfig.peerDependencies[d] = convertDependency(d, packageConfig.peerDependencies[d]); + + function convertDependency(d, depName) { var depVersion; if (depName.indexOf(':') != -1) - continue; + return depName; if (depName.indexOf('@') != -1) { depName = depName.substr(0, depName.indexOf('@')); @@ -525,10 +533,12 @@ GithubLocation.prototype = { } if (depName.split('/').length == 1) - pjson.dependencies[d] = 'jspm:' + depName + (depVersion && depVersion !== true ? '@' + depVersion : ''); + return 'jspm:' + depName + (depVersion && depVersion !== true ? '@' + depVersion : ''); + + return depName; } } - return pjson; + return packageConfig; }, download: function(repo, version, hash, meta, outDir) { From f5c017451d8b5796305da46a2ffbc8080c89156a Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 5 Oct 2015 15:07:11 +0200 Subject: [PATCH 02/38] only set any main if found --- github.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/github.js b/github.js index 0cf78b5..be730ec 100644 --- a/github.js +++ b/github.js @@ -826,7 +826,7 @@ GithubLocation.prototype = { return checkMain(main, libDir) .then(function(hasMain) { if (hasMain) - return; + return hasMain; return asp(fs.readFile)(path.resolve(dir, 'bower.json')) .then(function(bowerJson) { @@ -844,11 +844,17 @@ GithubLocation.prototype = { return checkMain(main); }, function() {}) .then(function(hasBowerMain) { - if (!hasBowerMain) - return; + if (hasBowerMain) + return hasBrowserMain; - pjson.main = main; + main = 'index'; + return checkMain(main, libDir); }); + }) + .then(function(hasMain) { + if (hasMain) + packageConfig.main = main; + return packageConfig; }); } From 58103c883e724828458806c664e80d8939ba6bef Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 26 Nov 2015 22:37:03 +0200 Subject: [PATCH 03/38] remove releases API use, bluebird promises --- github.js | 332 ++++++++++----------------------------------------- package.json | 9 +- 2 files changed, 64 insertions(+), 277 deletions(-) diff --git a/github.js b/github.js index be730ec..f1ad20e 100644 --- a/github.js +++ b/github.js @@ -5,14 +5,12 @@ var rimraf = require('rimraf'); var request = require('request'); var expandTilde = require('expand-tilde'); -var Promise = require('rsvp').Promise; -var asp = require('rsvp').denodeify; +var Promise = require('bluebird'); +var asp = require('bluebird').Promise.promisify; var tar = require('tar'); var zlib = require('zlib'); -var yauzl = require('yauzl'); - var semver = require('semver'); var which = require('which'); @@ -263,31 +261,7 @@ function configureCredentials(config, ui) { }); } -function checkRateLimit(headers) { - if (headers.status.match(/^401/)) - throw 'Unauthorized response for GitHub API.\n' + - 'Use %jspm registry config github% to reconfigure the credentials, or update them in your ~/.netrc file.'; - if (headers.status.match(/^406/)) - throw 'Unauthorized response for GitHub API.\n' + - 'If using an access token ensure it has public_repo access.\n' + - 'Use %jspm registry config github% to configure the credentials, or add them to your ~/.netrc file.'; - - if (headers['x-ratelimit-remaining'] != '0') - return; - - var remaining = (headers['x-ratelimit-reset'] * 1000 - new Date(headers.date).getTime()) / 60000; - - if (this.auth) - return Promise.reject('\nGitHub rate limit reached, with authentication enabled.' + - '\nThe rate limit will reset in `' + Math.round(remaining) + ' minutes`.'); - - var err = new Error('GitHub rate limit reached.'); - err.config = true; - err.hideStack = true; - - return Promise.reject(err); -} - +var apiWarned = false; // static configuration function GithubLocation.configure = function(config, ui) { @@ -432,7 +406,10 @@ GithubLocation.prototype = { if (meta.vPrefix) version = 'v' + version; - return asp(request)(extend({ + var self = this; + var ui = this.ui; + + return asp(request)({ uri: this.apiRemoteString + 'repos/' + repo + '/contents/package.json', headers: { 'User-Agent': 'jspm', @@ -440,23 +417,37 @@ GithubLocation.prototype = { }, qs: { ref: version + }, + strictSSL: this.strictSSL + }).then(function(res) { + // API auth failure warnings + function apiFailWarn(reason, showAuthCommand) { + if (apiWarned) + return; + + ui.log('warn', 'Unable to use the GitHub API to speed up dependency downloads due to ' + reason + + (showAuthCommand ? '\nTo resolve use %jspm registry config github% to configure the credentials, or update them in your ~/.netrc file.' : '')); + apiWarned = true; } - }, this.defaultRequestOptions - )).then(function(res) { - var rateLimitResponse = checkRateLimit.call(this, res.headers); - if (rateLimitResponse) - return rateLimitResponse; - - if (res.statusCode == 404) { - // it is quite valid for a repo not to have a package.json - return {}; + + if (res.headers.status.match(/^401/)) + return apiFailWarn('lack of authorization', true); + if (res.headers.status.match(/^406/)) + return apiFailWarn('insufficient permissions. Ensure you have public_repo access.'); + if (res.headers['x-ratelimit-remaining'] == '0') { + if (self.auth) + return apiFailWarn('the rate limit being reached, which will be reset in `' + + Math.round((res.headers['x-ratelimit-reset'] * 1000 - new Date(res.headers.date).getTime()) / 60000) + ' minutes`.'); + return apiFailWarn('the rate limit being reached.', true); } - if (res.statusCode != 200) - throw 'Unable to check repo package.json for release, status code ' + res.statusCode; + return apiFailWarn('invalid response code ' + res.statusCode + '.'); - var packageJSON; + // it is quite valid for a repo not to have a package.json + if (res.statusCode == 404) + return {}; + var packageJSON; try { packageJSON = JSON.parse(res.body); } @@ -551,243 +542,40 @@ GithubLocation.prototype = { var self = this; - return this.checkReleases(repo, version) - .then(function(release) { - if (!release) - return true; - - // Download from the release archive - return new Promise(function(resolve, reject) { - var inPipe; - - if (release.type == 'tar') { - (inPipe = zlib.createGunzip()) - .pipe(tar.Extract({ - path: outDir, - strip: 0, - filter: function() { - return !this.type.match(/^.*Link$/); - } - })) - .on('end', function() { - resolve(); - }) - .on('error', reject); - } - else if (release.type == 'zip') { - var tmpDir = path.resolve(execOpt.cwd, 'release-' + repo.replace('/', '#') + '-' + version); - var tmpFile = tmpDir + '.' + release.type; - - var repoDir; - - inPipe = fs.createWriteStream(tmpFile) - .on('finish', function() { - return clearDir(tmpDir) - .then(function() { - return asp(fs.mkdir(tmpDir)); - }) - .then(function() { - return new Promise(function(resolve, reject) { - var files = []; - yauzl.open(tmpFile, function(err, zipFile) { - if (err) - return reject(err); - - zipFile.on('entry', function(entry) { - var fileName = tmpDir + '/' + entry.fileName; - - if (fileName[fileName.length - 1] == '/') - return; - - zipFile.openReadStream(entry, function(err, readStream) { - if (err) - return reject(err); - mkdirp(path.dirname(fileName), function(err) { - if (err) - return reject(err); - files.push(new Promise(function(_resolve, _reject) { - var p = fs.createWriteStream(fileName).on("close", function(err) { - if (err) _reject(err); - _resolve(); - }); - readStream.pipe(p); - })); - }); - }); - }); - zipFile.on('close', function() { - Promise.all(files).then(function() { - resolve(); - }).catch(function(e) { - reject(e); - }); - }); - }); - - - }) - }) - .then(function() { - return checkStripDir(tmpDir); - }) - .then(function(_repoDir) { - repoDir = _repoDir; - return asp(fs.rmdir)(outDir); - }) - .then(function() { - return asp(fs.rename)(repoDir, outDir); - }) - .then(function() { - return asp(fs.unlink)(tmpFile); - }) - .then(resolve, reject); - }) - .on('error', reject); - } - else { - throw 'GitHub release found, but no archive present.'; - } - - // now that the inPipe is ready, do the request - request(extend({ - uri: release.url, - headers: { - 'accept': 'application/octet-stream', - 'user-agent': 'jspm' - }, - followRedirect: false, - auth: self.auth && { - user: self.auth.username, - pass: self.auth.password - } - }, self.defaultRequestOptions - )).on('response', function(archiveRes) { - var rateLimitResponse = checkRateLimit.call(this, archiveRes.headers); - if (rateLimitResponse) - return rateLimitResponse.then(resolve, reject); - - if (archiveRes.statusCode != 302) - return reject('Bad response code ' + archiveRes.statusCode + '\n' + JSON.stringify(archiveRes.headers)); - - request(extend({ - uri: archiveRes.headers.location, headers: { - 'accept': 'application/octet-stream', - 'user-agent': 'jspm' - } - }, self.defaultRequestOptions - )) - .on('response', function(archiveRes) { - - if (max_repo_size && archiveRes.headers['content-length'] > max_repo_size) - return reject('Response too large.'); - - archiveRes.pause(); - - archiveRes.pipe(inPipe); - - archiveRes.on('error', reject); - - archiveRes.resume(); + // Download from the git archive + return new Promise(function(resolve, reject) { + request({ + uri: remoteString + repo + '/archive/' + version + '.tar.gz', + headers: { 'accept': 'application/octet-stream' }, + strictSSL: self.strictSSL + }) + .on('response', function(pkgRes) { + if (pkgRes.statusCode != 200) + return reject('Bad response code ' + pkgRes.statusCode); - }) - .on('error', reject); - }) - .on('error', reject); - }); - }) - .then(function(git) { - if (!git) - return; + if (max_repo_size && pkgRes.headers['content-length'] > max_repo_size) + return reject('Response too large.'); - // Download from the git archive - return new Promise(function(resolve, reject) { - request(extend({ - uri: remoteString + repo + '/archive/' + version + '.tar.gz', - headers: { 'accept': 'application/octet-stream' } - }, self.defaultRequestOptions - )) - .on('response', function(pkgRes) { - if (pkgRes.statusCode != 200) - return reject('Bad response code ' + pkgRes.statusCode); - - if (max_repo_size && pkgRes.headers['content-length'] > max_repo_size) - return reject('Response too large.'); - - pkgRes.pause(); - - var gzip = zlib.createGunzip(); - - pkgRes - .pipe(gzip) - .pipe(tar.Extract({ - path: outDir, - strip: 1, - filter: function() { - return !this.type.match(/^.*Link$/); - } - })) - .on('error', reject) - .on('end', resolve); + pkgRes.pause(); - pkgRes.resume(); + var gzip = zlib.createGunzip(); - }) - .on('error', reject); - }); - }); - }, + pkgRes + .pipe(gzip) + .pipe(tar.Extract({ + path: outDir, + strip: 1, + filter: function() { + return !this.type.match(/^.*Link$/); + } + })) + .on('error', reject) + .on('end', resolve); - checkReleases: function(repo, version) { - // NB cache this on disk with etags - var reqOptions = extend({ - uri: this.apiRemoteString + 'repos/' + repo + '/releases', - headers: { - 'User-Agent': 'jspm', - 'Accept': 'application/vnd.github.v3+json' - }, - followRedirect: false - }, this.defaultRequestOptions); + pkgRes.resume(); - return asp(request)(reqOptions) - .then(function(res) { - var rateLimitResponse = checkRateLimit.call(this, res.headers); - if (rateLimitResponse) - return rateLimitResponse; - return Promise.resolve() - .then(function() { - try { - return JSON.parse(res.body); - } - catch(e) { - throw 'Unable to parse GitHub API response'; - } }) - .then(function(releases) { - // run through releases list to see if we have this version tag - for (var i = 0; i < releases.length; i++) { - var tagName = (releases[i].tag_name || '').trim(); - - if (tagName == version) { - var firstAsset = releases[i].assets.filter(function(asset) { - if (asset.name.substr(asset.name.length - 7, 7) == '.tar.gz' || asset.name.substr(asset.name.length - 4, 4) == '.tgz') - asset.fileType = 'tar'; - else if (asset.name.substr(asset.name.length - 4, 4) == '.zip') - asset.fileType = 'zip'; - return !!asset.fileType; - }) - .sort(function(asset) { - // src.zip comes after file.zip - return asset.name.indexOf('src') == -1 ? -1 : 1; - })[0]; - - if (!firstAsset) - return false; - - return { url: firstAsset.url, type: firstAsset.fileType }; - } - } - return false; - }); + .on('error', reject); }); }, diff --git a/package.json b/package.json index f9c7c2c..d81a9ea 100644 --- a/package.json +++ b/package.json @@ -17,16 +17,15 @@ }, "dependencies": { "expand-tilde": "^1.2.0", - "graceful-fs": "^4.1.3", + "bluebird": "^3.0.5", + "graceful-fs": "^3.0.6", "mkdirp": "~0.5.0", "netrc": "^0.1.3", "request": "~2.53.0", "rimraf": "~2.3.2", - "rsvp": "^3.0.17", "semver": "^5.0.1", - "tar": "^2.2.1", - "which": "^1.0.9", - "yauzl": "^2.3.1" + "tar": "^2.1.1", + "which": "^1.0.9" }, "homepage": "https://github.com/jspm/github", "devDependencies": { From 645090d00bd70c80cdb63a706ffbb1b782f2e754 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 3 Dec 2015 19:50:47 +0200 Subject: [PATCH 04/38] remove use of rsvp --- exec-git.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exec-git.js b/exec-git.js index 0019457..1bd6edf 100644 --- a/exec-git.js +++ b/exec-git.js @@ -1,4 +1,4 @@ -var Promise = require('rsvp').Promise; +var Promise = require('bluebird').Promise; var exec = require('child_process').exec; var os = require('os'); From 4075f713e5ea1b2fd14a28de699f56e34a5eaf0b Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 5 Dec 2015 03:29:10 +0200 Subject: [PATCH 05/38] correct main handling --- github.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/github.js b/github.js index f1ad20e..59fac77 100644 --- a/github.js +++ b/github.js @@ -293,8 +293,7 @@ GithubLocation.configure = function(config, ui) { }); }; -// regular expression to verify package names -GithubLocation.packageFormat = /^[^\/]+\/[^\/]+/; +GithubLocation.packageNameFormats = ['*/*']; GithubLocation.prototype = { @@ -580,9 +579,9 @@ GithubLocation.prototype = { }, // check if the main entry point exists. If not, try the bower.json main. - build: function(pjson, dir) { - var main = pjson.main || ''; - var libDir = pjson.directories && (pjson.directories.dist || pjson.directories.lib) || '.'; + processPackage: function(packageConfig, packageName, dir) { + var main = packageConfig.main || ''; + var libDir = packageConfig.directories && (packageConfig.directories.dist || packageConfig.directories.lib) || '.'; if (main instanceof Array) main = main[0]; @@ -633,7 +632,7 @@ GithubLocation.prototype = { }, function() {}) .then(function(hasBowerMain) { if (hasBowerMain) - return hasBrowserMain; + return hasBowerMain; main = 'index'; return checkMain(main, libDir); From ace532c58fd4812920c462a0dc278dcd9f42595a Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 9 Jan 2016 00:31:57 +0200 Subject: [PATCH 06/38] dependency version fix --- github.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github.js b/github.js index 59fac77..5558a1e 100644 --- a/github.js +++ b/github.js @@ -514,8 +514,8 @@ GithubLocation.prototype = { return depName; if (depName.indexOf('@') != -1) { - depName = depName.substr(0, depName.indexOf('@')); depVersion = depName.substr(depName.indexOf('@') + 1); + depName = depName.substr(0, depName.indexOf('@')); } else { depVersion = depName; @@ -525,7 +525,7 @@ GithubLocation.prototype = { if (depName.split('/').length == 1) return 'jspm:' + depName + (depVersion && depVersion !== true ? '@' + depVersion : ''); - return depName; + return depName + '@' + depVersion; } } return packageConfig; From 8cd5f664016c5f989ffe509008f0798f746abe68 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 9 Jan 2016 21:40:04 +0200 Subject: [PATCH 07/38] 0.14.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d81a9ea..90fe8eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.13.13", + "version": "0.14.0", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From 7ba7b5a0b634eed64f81a9b753dc50ed134bf5ee Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 15 Jan 2016 15:16:56 +0200 Subject: [PATCH 08/38] directories.lib -> directories.dist --- github.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/github.js b/github.js index 5558a1e..d541ea3 100644 --- a/github.js +++ b/github.js @@ -499,6 +499,11 @@ GithubLocation.prototype = { } } + if (packageConfig.directories && packageConfig.directories.lib && !packageConfig.directories.dist) { + packageConfig.directories.dist = packageConfig.directories.lib; + this.ui.log('warn', 'Package `' + packageName + '` has a %directories.lib% override configuration which will work, but is deprecated for %directories.dist% in future jspm versions.\n'); + } + // on GitHub, single package names ('jquery') are from jspm registry // double package names ('components/jquery') are from github registry if (!packageConfig.registry || packageConfig.registry == 'github') { From b21d5de3f807d11053a7b0d98e9a02c05951b042 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 20 Jan 2016 01:15:58 +0200 Subject: [PATCH 09/38] 0.14.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 90fe8eb..daadc96 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.0", + "version": "0.14.1", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From 2cdbc5c7c49b8a07e6bbaff7d97176c60c2d931e Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 24 Jan 2016 22:07:19 +0200 Subject: [PATCH 10/38] windows fixes --- github.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github.js b/github.js index d541ea3..2638b40 100644 --- a/github.js +++ b/github.js @@ -645,7 +645,7 @@ GithubLocation.prototype = { }) .then(function(hasMain) { if (hasMain) - packageConfig.main = main; + packageConfig.main = main.replace(/\\/g, '/'); return packageConfig; }); } From 6b0156fdc1e8caa5a62e7b3b9ff52ee6521655c8 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 25 Jan 2016 13:03:18 +0200 Subject: [PATCH 11/38] 0.14.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index daadc96..825e474 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.1", + "version": "0.14.2", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From f05942b4da9204ffebaa4d5bce14d2a20cd95c23 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 2 Feb 2016 19:24:25 +0200 Subject: [PATCH 12/38] ensure github credentials are base64 encoded only --- github.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/github.js b/github.js index 2638b40..68a8b0d 100644 --- a/github.js +++ b/github.js @@ -46,12 +46,13 @@ function createRemoteStrings(auth, hostname) { // avoid storing passwords as plain text in config function encodeCredentials(auth) { - return new Buffer(encodeURIComponent(auth.username) + ':' + encodeURIComponent(auth.password)).toString('base64'); + return new Buffer(auth.username + ':' + auth.password).toString('base64'); } function decodeCredentials(str) { - var auth = new Buffer(str, 'base64').toString('ascii').split(':'); + var auth = new Buffer(str, 'base64').toString('utf8').split(':'); var username, password; + try { username = decodeURIComponent(auth[0]); password = decodeURIComponent(auth[1]); From 1451b9dc9a6f534cc3cbd5b5e56ffd2057a07579 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 4 Feb 2016 17:42:54 +0200 Subject: [PATCH 13/38] handle directories.lib deprecation path within jspm core --- github.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/github.js b/github.js index 68a8b0d..6e1ea4c 100644 --- a/github.js +++ b/github.js @@ -500,11 +500,6 @@ GithubLocation.prototype = { } } - if (packageConfig.directories && packageConfig.directories.lib && !packageConfig.directories.dist) { - packageConfig.directories.dist = packageConfig.directories.lib; - this.ui.log('warn', 'Package `' + packageName + '` has a %directories.lib% override configuration which will work, but is deprecated for %directories.dist% in future jspm versions.\n'); - } - // on GitHub, single package names ('jquery') are from jspm registry // double package names ('components/jquery') are from github registry if (!packageConfig.registry || packageConfig.registry == 'github') { From 643419bd05e2d3a16d94a44d3ceff6dc0280786d Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 4 Feb 2016 21:22:55 +0200 Subject: [PATCH 14/38] 0.14.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 825e474..03b86f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.2", + "version": "0.14.3", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From 4e92677e4492634f7066faf4168a3c308007d3b8 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 14 Feb 2016 17:08:48 +0200 Subject: [PATCH 15/38] bump graceful-fs --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 03b86f5..eff4895 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "dependencies": { "expand-tilde": "^1.2.0", "bluebird": "^3.0.5", - "graceful-fs": "^3.0.6", + "graceful-fs": "^4.1.3", "mkdirp": "~0.5.0", "netrc": "^0.1.3", "request": "~2.53.0", From 6f7d364a6e2c5a1c4f97784e38e70512de9a7fbd Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 25 Feb 2016 18:13:41 +0200 Subject: [PATCH 16/38] 0.14.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eff4895..e4121b6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.3", + "version": "0.14.4", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From bfa827ea4d218c78b984371ee882110253695249 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 9 Mar 2016 13:14:14 +0200 Subject: [PATCH 17/38] ensure github still tries repo name as the main --- github.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github.js b/github.js index 6e1ea4c..ed172f1 100644 --- a/github.js +++ b/github.js @@ -581,7 +581,7 @@ GithubLocation.prototype = { // check if the main entry point exists. If not, try the bower.json main. processPackage: function(packageConfig, packageName, dir) { - var main = packageConfig.main || ''; + var main = packageConfig.main || dir.split('/').pop().split('@').slice(0, -1).join('@') + (dir.substr(dir.length - 3, 3) != '.js' ? '.js' : ''); var libDir = packageConfig.directories && (packageConfig.directories.dist || packageConfig.directories.lib) || '.'; if (main instanceof Array) From c3cb4c2b959a518bebd42cdc957ab4512d3f2379 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 9 Mar 2016 16:23:14 +0200 Subject: [PATCH 18/38] 0.14.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e4121b6..b655a08 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.4", + "version": "0.14.5", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From 1de2b38a8768015c744a7e7cf71b8249d5a0a92c Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 10 Mar 2016 10:03:47 +0200 Subject: [PATCH 19/38] optionalDependencies handling --- github.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/github.js b/github.js index ed172f1..7d23bd2 100644 --- a/github.js +++ b/github.js @@ -465,12 +465,15 @@ GithubLocation.prototype = { var self = this; - if ((packageConfig.dependencies || packageConfig.peerDependencies) && !packageConfig.registry && (!packageConfig.jspm || !(packageConfig.jspm.dependencies || packageConfig.jspm.peerDependencies))) { + if ((packageConfig.dependencies || packageConfig.peerDependencies || packageConfig.optionalDependencies) && + !packageConfig.registry && (!packageConfig.jspm || !(packageConfig.jspm.dependencies || packageConfig.jspm.peerDependencies || packageConfig.jspm.optionalDependencies))) { var hasDependencies = false; for (var p in packageConfig.dependencies) hasDependencies = true; for (var p in packageConfig.peerDependencies) hasDependencies = true; + for (var p in packageConfig.optionalDependencies) + hasDependencies = true; if (packageName && hasDependencies) { var looksLikeNpm = packageConfig.name && packageConfig.version && (packageConfig.description || packageConfig.repository || packageConfig.author || packageConfig.license || packageConfig.scripts); @@ -491,12 +494,14 @@ GithubLocation.prototype = { if (noDepsMsg) { delete packageConfig.dependencies; delete packageConfig.peerDependencies; + delete packageConfig.optionalDependencies; this.ui.log('warn', '`' + packageName + '` dependency installs skipped as it\'s a GitHub package with no registry property set.\n' + noDepsMsg + '\n'); } } else { delete packageConfig.dependencies; delete packageConfig.peerDependencies; + delete packageConfig.optionalDependencies; } } @@ -507,6 +512,8 @@ GithubLocation.prototype = { packageConfig.dependencies[d] = convertDependency(d, packageConfig.dependencies[d]); for (var d in packageConfig.peerDependencies) packageConfig.peerDependencies[d] = convertDependency(d, packageConfig.peerDependencies[d]); + for (var d in packageConfig.optionalDependencies) + packageConfig.optionalDependencies[d] = convertDependency(d, packageConfig.optionalDependencies[d]); function convertDependency(d, depName) { var depVersion; From 9eda046300b322ca3732b3bb9aefe782a96172eb Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 10 Mar 2016 10:04:42 +0200 Subject: [PATCH 20/38] 0.14.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b655a08..2028091 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.5", + "version": "0.14.6", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From c9ea733424d28e237c0eb713229dbb3316baeefa Mon Sep 17 00:00:00 2001 From: Sebastian Fastner Date: Tue, 3 May 2016 11:41:33 +0200 Subject: [PATCH 21/38] Fix reference to strictSSL configuration settings --- github.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github.js b/github.js index 7d23bd2..916d17b 100644 --- a/github.js +++ b/github.js @@ -418,7 +418,7 @@ GithubLocation.prototype = { qs: { ref: version }, - strictSSL: this.strictSSL + strictSSL: this.defaultRequestOptions.strictSSL }).then(function(res) { // API auth failure warnings function apiFailWarn(reason, showAuthCommand) { @@ -554,7 +554,7 @@ GithubLocation.prototype = { request({ uri: remoteString + repo + '/archive/' + version + '.tar.gz', headers: { 'accept': 'application/octet-stream' }, - strictSSL: self.strictSSL + strictSSL: self.defaultRequestOptions.strictSSL }) .on('response', function(pkgRes) { if (pkgRes.statusCode != 200) From 83155a33c3a22c93eab1ff7f8150819e2c1968e0 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 23 May 2016 14:21:05 +0200 Subject: [PATCH 22/38] tar update --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2028091..236b897 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "request": "~2.53.0", "rimraf": "~2.3.2", "semver": "^5.0.1", - "tar": "^2.1.1", + "tar": "^2.2.1", "which": "^1.0.9" }, "homepage": "https://github.com/jspm/github", From b8c874993c789fa8b8777344fe9bc25ff15d66de Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 23 May 2016 14:22:12 +0200 Subject: [PATCH 23/38] 0.14.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 236b897..9ab3f09 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.6", + "version": "0.14.7", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From 0239f95e5e3420d217828a3b10689c6ee02ece74 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 1 Jun 2016 18:18:01 +0200 Subject: [PATCH 24/38] mark connection reset error as retriable --- github.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/github.js b/github.js index 916d17b..b2cb5ca 100644 --- a/github.js +++ b/github.js @@ -582,7 +582,11 @@ GithubLocation.prototype = { pkgRes.resume(); }) - .on('error', reject); + .on('error', function(err) { + if (err.code == 'ECONNRESET') + err.retriable = true; + throw err; + }); }); }, From 792567ca4ef8fc95b2365c1e1853db905114ff93 Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 10 Jun 2016 01:45:52 +0200 Subject: [PATCH 25/38] 0.14.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9ab3f09..91e711f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.7", + "version": "0.14.8", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From ba22b3c3a551cd6533e80786f7f283e4a5e59395 Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 10 Jun 2016 02:12:53 +0200 Subject: [PATCH 26/38] 0.14.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 91e711f..c9e71d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.8", + "version": "0.14.9", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From b30676533333c1dd4454cb7abc98a9f9f33d7b58 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 11 Jun 2016 20:43:04 -0400 Subject: [PATCH 27/38] Remove username/password support; always use tokens --- github.js | 74 +++++++++++++++++++++++++------------------------------ test.js | 4 +-- 2 files changed, 35 insertions(+), 43 deletions(-) diff --git a/github.js b/github.js index b2cb5ca..c169733 100644 --- a/github.js +++ b/github.js @@ -31,10 +31,11 @@ catch(e) {} var execGit = require('./exec-git'); function createRemoteStrings(auth, hostname) { - var authString = auth ? (encodeURIComponent(auth.username) + ':' + encodeURIComponent(auth.password) + '@') : ''; + var authString = auth.username ? (encodeURIComponent(auth.username) + ':' + encodeURIComponent(auth.password) + '@') : ''; hostname = hostname || 'github.com'; this.remoteString = 'https://' + authString + hostname + '/'; + this.authSuffix = auth.token ? '?access_token=' + auth.token : ''; if (hostname == 'github.com') this.apiRemoteString = 'https://' + authString + 'api.github.com/'; @@ -44,10 +45,6 @@ function createRemoteStrings(auth, hostname) { this.apiRemoteString = 'https://' + authString + hostname + '/api/v3/'; } -// avoid storing passwords as plain text in config -function encodeCredentials(auth) { - return new Buffer(auth.username + ':' + auth.password).toString('base64'); -} function decodeCredentials(str) { var auth = new Buffer(str, 'base64').toString('utf8').split(':'); @@ -80,6 +77,10 @@ function readNetrc(hostname) { } } +function isGithubToken(token) { + return token.match(/[0-9a-f]{40}/); +} + var GithubLocation = function(options, ui) { // ensure git is installed @@ -97,19 +98,15 @@ var GithubLocation = function(options, ui) { this.versionString = options.versionString + '.1'; // Give the environment precedence over options object - if(process.env.JSPM_GITHUB_AUTH_TOKEN) { - options.auth = process.env.JSPM_GITHUB_AUTH_TOKEN; - } else if (options.username && !options.auth) { - options.auth = encodeCredentials(options); - // NB deprecate old auth eventually - // delete options.username; - // delete options.password; - } + var auth = process.env.JSPM_GITHUB_AUTH_TOKEN || options.auth; - if (typeof options.auth == 'string') { - this.auth = decodeCredentials(options.auth); - } - else { + if (auth) { + if (isGithubToken(auth)) { + this.auth = { token: auth }; + } else { + this.auth = decodeCredentials(auth); + } + } else { this.auth = readNetrc(options.hostname); } @@ -147,7 +144,7 @@ var GithubLocation = function(options, ui) { this.remote = options.remote; - createRemoteStrings.call(this, this.auth, options.hostname); + createRemoteStrings.call(this, this.auth || {}, options.hostname); }; function clearDir(dir) { @@ -198,20 +195,14 @@ function configureCredentials(config, ui) { return Promise.resolve() .then(function() { - ui.log('info', 'If using two-factor authentication or to avoid using your password you can generate an access token at %https://' + (config.hostname || 'github.com') + '/settings/tokens%. Ensure it has `public_repo` scope access.'); - return ui.input('Enter your GitHub username'); - }) - .then(function(username) { - auth.username = username; - if (auth.username) - return ui.input('Enter your GitHub password or access token', null, true); + ui.log('info', 'You can generate an access token at %https://' + (config.hostname || 'github.com') + '/settings/tokens%.'); + return ui.input('Enter your GitHub access token'); }) - .then(function(password) { - auth.password = password; - if (!auth.username) - return false; - - return ui.confirm('Would you like to test these credentials?', true); + .then(function(token) { + auth.token = token; + if (auth.token) { + return ui.confirm('Would you like to test these credentials?', true); + } }) .then(function(test) { if (!test) @@ -223,7 +214,7 @@ function configureCredentials(config, ui) { createRemoteStrings.call(remotes, auth, config.hostname); return asp(request)({ - uri: remotes.apiRemoteString + 'user', + uri: remotes.apiRemoteString + 'user' + remotes.authSuffix, headers: { 'User-Agent': 'jspm', 'Accept': 'application/vnd.github.v3+json' @@ -234,7 +225,7 @@ function configureCredentials(config, ui) { }) .then(function(res) { if (res.statusCode == 401) { - ui.log('warn', 'Provided GitHub credentials are not authorized, try re-entering your password or access token.'); + ui.log('warn', 'Provided GitHub credentials are not authorized, try re-entering your access token.'); } else if (res.statusCode != 200) { ui.log('warn', 'Invalid response code, %' + res.statusCode + '%'); @@ -253,10 +244,10 @@ function configureCredentials(config, ui) { .then(function(redo) { if (redo) return configureCredentials(config, ui); - return encodeCredentials(auth); + return auth.token; }); - else if (auth.username) - return encodeCredentials(auth); + else if (auth.token) + return auth.token; else return null; }); @@ -302,6 +293,7 @@ GithubLocation.prototype = { locate: function(repo) { var self = this; var remoteString = this.remoteString; + var authSuffix = this.authSuffix; if (repo.split('/').length !== 2) throw "GitHub packages must be of the form `owner/repo`."; @@ -309,7 +301,7 @@ GithubLocation.prototype = { // request the repo to check that it isn't a redirect return new Promise(function(resolve, reject) { request(extend({ - uri: remoteString + repo, + uri: remoteString + repo + authSuffix, headers: { 'User-Agent': 'jspm' }, @@ -352,8 +344,7 @@ GithubLocation.prototype = { execGit('ls-remote ' + remoteString.replace(/(['"()])/g, '\\\$1') + repo + '.git refs/tags/* refs/heads/*', execOpt, function(err, stdout, stderr) { if (err) { if (err.toString().indexOf('not found') == -1) { - // dont show plain text passwords in error - var error = new Error(stderr.toString().replace(remoteString, '')); + var error = new Error(stderr); error.hideStack = true; error.retriable = true; reject(error); @@ -410,7 +401,7 @@ GithubLocation.prototype = { var ui = this.ui; return asp(request)({ - uri: this.apiRemoteString + 'repos/' + repo + '/contents/package.json', + uri: this.apiRemoteString + 'repos/' + repo + '/contents/package.json' + this.authSuffix, headers: { 'User-Agent': 'jspm', 'Accept': 'application/vnd.github.v3.raw' @@ -546,13 +537,14 @@ GithubLocation.prototype = { var execOpt = this.execOpt; var max_repo_size = this.max_repo_size; var remoteString = this.remoteString; + var authSuffix = this.authSuffix; var self = this; // Download from the git archive return new Promise(function(resolve, reject) { request({ - uri: remoteString + repo + '/archive/' + version + '.tar.gz', + uri: remoteString + repo + '/archive/' + version + '.tar.gz' + authSuffix, headers: { 'accept': 'application/octet-stream' }, strictSSL: self.defaultRequestOptions.strictSSL }) diff --git a/test.js b/test.js index 6ed821a..1dc8c8c 100644 --- a/test.js +++ b/test.js @@ -4,8 +4,8 @@ github = new github({ baseDir: '.', log: true, tmpDir: '.', - username: '', - password: '' + auth: '', + token: '' }); github.lookup('angular/bower-angular') From dd526b042d97cd1ad015372d3b43c08687f30831 Mon Sep 17 00:00:00 2001 From: Adam Burgess Date: Fri, 15 Jul 2016 19:45:29 +1000 Subject: [PATCH 28/38] replace tar with tar-fs: ~40% faster unpack --- github.js | 16 +++++++--------- package.json | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/github.js b/github.js index c169733..decab50 100644 --- a/github.js +++ b/github.js @@ -8,7 +8,7 @@ var expandTilde = require('expand-tilde'); var Promise = require('bluebird'); var asp = require('bluebird').Promise.promisify; -var tar = require('tar'); +var tar = require('tar-fs'); var zlib = require('zlib'); var semver = require('semver'); @@ -561,15 +561,13 @@ GithubLocation.prototype = { pkgRes .pipe(gzip) - .pipe(tar.Extract({ - path: outDir, - strip: 1, - filter: function() { - return !this.type.match(/^.*Link$/); + .pipe(tar.extract(outDir, { + strip: 1, + filter: function(_, header) { + return header.type !== 'file' && header.type !== 'directory' } - })) - .on('error', reject) - .on('end', resolve); + }).on('finish', resolve).on('error', reject)) + .on('error', reject); pkgRes.resume(); diff --git a/package.json b/package.json index c9e71d1..f0d13df 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "request": "~2.53.0", "rimraf": "~2.3.2", "semver": "^5.0.1", - "tar": "^2.2.1", + "tar-fs": "^1.13.0", "which": "^1.0.9" }, "homepage": "https://github.com/jspm/github", From 090d3316cd0c16ec4c24365de60e08472b585628 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 21 Aug 2016 20:14:23 +0200 Subject: [PATCH 29/38] 0.14.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f0d13df..a6048c1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.9", + "version": "0.14.10", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From ed86cbcaefbbd9a5eaac22459a15c8115f4d0b4b Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 6 Sep 2016 12:57:21 +0200 Subject: [PATCH 30/38] update rimraf --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index a6048c1..8585e4f 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,10 @@ "expand-tilde": "^1.2.0", "bluebird": "^3.0.5", "graceful-fs": "^4.1.3", - "mkdirp": "~0.5.0", + "mkdirp": "^0.5.1", "netrc": "^0.1.3", - "request": "~2.53.0", - "rimraf": "~2.3.2", + "request": "^2.74.0", + "rimraf": "^2.5.4", "semver": "^5.0.1", "tar-fs": "^1.13.0", "which": "^1.0.9" From c049079dac2f89f76a27ce04822fa82f72ba2719 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 19 Sep 2016 16:50:57 +0200 Subject: [PATCH 31/38] configuration correction --- github.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github.js b/github.js index decab50..ca5de95 100644 --- a/github.js +++ b/github.js @@ -589,7 +589,7 @@ GithubLocation.prototype = { main = main[0]; if (typeof main != 'string') - return; + return packageConfig; // convert to windows-style paths if necessary main = main.replace(/\//g, path.sep); From 689fc146060390110063757b6fa7fdcfff20b484 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 29 Sep 2016 16:25:10 +0200 Subject: [PATCH 32/38] Revert "Remove username/password support; always use tokens" This reverts commit b30676533333c1dd4454cb7abc98a9f9f33d7b58. --- github.js | 74 ++++++++++++++++++++++++++++++------------------------- test.js | 4 +-- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/github.js b/github.js index ca5de95..36c138a 100644 --- a/github.js +++ b/github.js @@ -31,11 +31,10 @@ catch(e) {} var execGit = require('./exec-git'); function createRemoteStrings(auth, hostname) { - var authString = auth.username ? (encodeURIComponent(auth.username) + ':' + encodeURIComponent(auth.password) + '@') : ''; + var authString = auth ? (encodeURIComponent(auth.username) + ':' + encodeURIComponent(auth.password) + '@') : ''; hostname = hostname || 'github.com'; this.remoteString = 'https://' + authString + hostname + '/'; - this.authSuffix = auth.token ? '?access_token=' + auth.token : ''; if (hostname == 'github.com') this.apiRemoteString = 'https://' + authString + 'api.github.com/'; @@ -45,6 +44,10 @@ function createRemoteStrings(auth, hostname) { this.apiRemoteString = 'https://' + authString + hostname + '/api/v3/'; } +// avoid storing passwords as plain text in config +function encodeCredentials(auth) { + return new Buffer(auth.username + ':' + auth.password).toString('base64'); +} function decodeCredentials(str) { var auth = new Buffer(str, 'base64').toString('utf8').split(':'); @@ -77,10 +80,6 @@ function readNetrc(hostname) { } } -function isGithubToken(token) { - return token.match(/[0-9a-f]{40}/); -} - var GithubLocation = function(options, ui) { // ensure git is installed @@ -98,15 +97,19 @@ var GithubLocation = function(options, ui) { this.versionString = options.versionString + '.1'; // Give the environment precedence over options object - var auth = process.env.JSPM_GITHUB_AUTH_TOKEN || options.auth; + if(process.env.JSPM_GITHUB_AUTH_TOKEN) { + options.auth = process.env.JSPM_GITHUB_AUTH_TOKEN; + } else if (options.username && !options.auth) { + options.auth = encodeCredentials(options); + // NB deprecate old auth eventually + // delete options.username; + // delete options.password; + } - if (auth) { - if (isGithubToken(auth)) { - this.auth = { token: auth }; - } else { - this.auth = decodeCredentials(auth); - } - } else { + if (typeof options.auth == 'string') { + this.auth = decodeCredentials(options.auth); + } + else { this.auth = readNetrc(options.hostname); } @@ -144,7 +147,7 @@ var GithubLocation = function(options, ui) { this.remote = options.remote; - createRemoteStrings.call(this, this.auth || {}, options.hostname); + createRemoteStrings.call(this, this.auth, options.hostname); }; function clearDir(dir) { @@ -195,14 +198,20 @@ function configureCredentials(config, ui) { return Promise.resolve() .then(function() { - ui.log('info', 'You can generate an access token at %https://' + (config.hostname || 'github.com') + '/settings/tokens%.'); - return ui.input('Enter your GitHub access token'); + ui.log('info', 'If using two-factor authentication or to avoid using your password you can generate an access token at %https://' + (config.hostname || 'github.com') + '/settings/tokens%. Ensure it has `public_repo` scope access.'); + return ui.input('Enter your GitHub username'); }) - .then(function(token) { - auth.token = token; - if (auth.token) { - return ui.confirm('Would you like to test these credentials?', true); - } + .then(function(username) { + auth.username = username; + if (auth.username) + return ui.input('Enter your GitHub password or access token', null, true); + }) + .then(function(password) { + auth.password = password; + if (!auth.username) + return false; + + return ui.confirm('Would you like to test these credentials?', true); }) .then(function(test) { if (!test) @@ -214,7 +223,7 @@ function configureCredentials(config, ui) { createRemoteStrings.call(remotes, auth, config.hostname); return asp(request)({ - uri: remotes.apiRemoteString + 'user' + remotes.authSuffix, + uri: remotes.apiRemoteString + 'user', headers: { 'User-Agent': 'jspm', 'Accept': 'application/vnd.github.v3+json' @@ -225,7 +234,7 @@ function configureCredentials(config, ui) { }) .then(function(res) { if (res.statusCode == 401) { - ui.log('warn', 'Provided GitHub credentials are not authorized, try re-entering your access token.'); + ui.log('warn', 'Provided GitHub credentials are not authorized, try re-entering your password or access token.'); } else if (res.statusCode != 200) { ui.log('warn', 'Invalid response code, %' + res.statusCode + '%'); @@ -244,10 +253,10 @@ function configureCredentials(config, ui) { .then(function(redo) { if (redo) return configureCredentials(config, ui); - return auth.token; + return encodeCredentials(auth); }); - else if (auth.token) - return auth.token; + else if (auth.username) + return encodeCredentials(auth); else return null; }); @@ -293,7 +302,6 @@ GithubLocation.prototype = { locate: function(repo) { var self = this; var remoteString = this.remoteString; - var authSuffix = this.authSuffix; if (repo.split('/').length !== 2) throw "GitHub packages must be of the form `owner/repo`."; @@ -301,7 +309,7 @@ GithubLocation.prototype = { // request the repo to check that it isn't a redirect return new Promise(function(resolve, reject) { request(extend({ - uri: remoteString + repo + authSuffix, + uri: remoteString + repo, headers: { 'User-Agent': 'jspm' }, @@ -344,7 +352,8 @@ GithubLocation.prototype = { execGit('ls-remote ' + remoteString.replace(/(['"()])/g, '\\\$1') + repo + '.git refs/tags/* refs/heads/*', execOpt, function(err, stdout, stderr) { if (err) { if (err.toString().indexOf('not found') == -1) { - var error = new Error(stderr); + // dont show plain text passwords in error + var error = new Error(stderr.toString().replace(remoteString, '')); error.hideStack = true; error.retriable = true; reject(error); @@ -401,7 +410,7 @@ GithubLocation.prototype = { var ui = this.ui; return asp(request)({ - uri: this.apiRemoteString + 'repos/' + repo + '/contents/package.json' + this.authSuffix, + uri: this.apiRemoteString + 'repos/' + repo + '/contents/package.json', headers: { 'User-Agent': 'jspm', 'Accept': 'application/vnd.github.v3.raw' @@ -537,14 +546,13 @@ GithubLocation.prototype = { var execOpt = this.execOpt; var max_repo_size = this.max_repo_size; var remoteString = this.remoteString; - var authSuffix = this.authSuffix; var self = this; // Download from the git archive return new Promise(function(resolve, reject) { request({ - uri: remoteString + repo + '/archive/' + version + '.tar.gz' + authSuffix, + uri: remoteString + repo + '/archive/' + version + '.tar.gz', headers: { 'accept': 'application/octet-stream' }, strictSSL: self.defaultRequestOptions.strictSSL }) diff --git a/test.js b/test.js index 1dc8c8c..6ed821a 100644 --- a/test.js +++ b/test.js @@ -4,8 +4,8 @@ github = new github({ baseDir: '.', log: true, tmpDir: '.', - auth: '', - token: '' + username: '', + password: '' }); github.lookup('angular/bower-angular') From ad22fbf0e8722dc5aeff0e59045501e57b3343ef Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 30 Sep 2016 13:42:05 +0200 Subject: [PATCH 33/38] 0.14.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8585e4f..367db30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.10", + "version": "0.14.11", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From f127bd89cc71742b1562666db7047d7fae276554 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 30 Mar 2017 07:49:02 +0200 Subject: [PATCH 34/38] fix timeout option --- github.js | 4 +++- package.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/github.js b/github.js index 36c138a..d0b8dbc 100644 --- a/github.js +++ b/github.js @@ -115,9 +115,11 @@ var GithubLocation = function(options, ui) { this.ui = ui; + console.log(options.timeouts.download); + this.execOpt = { cwd: options.tmpDir, - timeout: options.timeout * 1000, + timeout: options.timeouts.download * 1000, killSignal: 'SIGKILL', maxBuffer: this.max_repo_size || 2 * 1024 * 1024, env: extend({}, process.env) diff --git a/package.json b/package.json index 367db30..6673a14 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.11", + "version": "0.14.12", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From 4348bc126bccff8e8de12b7d7567cdf287ecf05c Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 30 Mar 2017 07:49:56 +0200 Subject: [PATCH 35/38] 0.14.13 --- github.js | 2 -- package.json | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/github.js b/github.js index d0b8dbc..163cfb4 100644 --- a/github.js +++ b/github.js @@ -115,8 +115,6 @@ var GithubLocation = function(options, ui) { this.ui = ui; - console.log(options.timeouts.download); - this.execOpt = { cwd: options.tmpDir, timeout: options.timeouts.download * 1000, diff --git a/package.json b/package.json index 6673a14..5660e53 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.12", + "version": "0.14.13", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": { From 748308acf0e0b526b27143e5cfd1eabd71b59767 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 21 Aug 2017 16:41:31 +0200 Subject: [PATCH 36/38] dep updates --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 5660e53..2fcdf3b 100644 --- a/package.json +++ b/package.json @@ -16,15 +16,15 @@ "url": "https://github.com/jspm/github/issues" }, "dependencies": { + "bluebird": "^3.5.0", "expand-tilde": "^1.2.0", - "bluebird": "^3.0.5", "graceful-fs": "^4.1.3", "mkdirp": "^0.5.1", "netrc": "^0.1.3", "request": "^2.74.0", - "rimraf": "^2.5.4", + "rimraf": "^2.6.1", "semver": "^5.0.1", - "tar-fs": "^1.13.0", + "tar-fs": "^1.15.3", "which": "^1.0.9" }, "homepage": "https://github.com/jspm/github", From 683116c749ac8294f8dec74204dc93e920eb26db Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 10 Feb 2021 18:21:20 +0200 Subject: [PATCH 37/38] github api fix --- github.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github.js b/github.js index 163cfb4..1a02af7 100644 --- a/github.js +++ b/github.js @@ -430,9 +430,9 @@ GithubLocation.prototype = { apiWarned = true; } - if (res.headers.status.match(/^401/)) + if (res.statusCode === 401) return apiFailWarn('lack of authorization', true); - if (res.headers.status.match(/^406/)) + if (res.statusCode === 406) return apiFailWarn('insufficient permissions. Ensure you have public_repo access.'); if (res.headers['x-ratelimit-remaining'] == '0') { if (self.auth) From aeefaff588a73e26d5a7381adb542a28c1677ea0 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 10 Feb 2021 18:21:30 +0200 Subject: [PATCH 38/38] 0.14.14 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2fcdf3b..54c021a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-github", - "version": "0.14.13", + "version": "0.14.14", "description": "jspm GitHub endpoint", "main": "github.js", "scripts": {