Skip to content

Commit

Permalink
Refactor version handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
skewart committed Dec 30, 2015
1 parent 1eb3707 commit 9471bc6
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 74 deletions.
17 changes: 8 additions & 9 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ module.exports = function nuts(opts) {

platform = platforms.detect(platform);

return versions.filter({
return versions.newer({
tag: tag,
platform: platform,
channel: channel
Expand All @@ -183,7 +183,7 @@ module.exports = function nuts(opts) {
var releaseNotes = notes.merge(versions.slice(0, -1), { includeTag: false });

res.status(200).send({
"url": getBaseDownloadUrl(req) + '/version/' + latest.tag + '/' + platform + '?filetype=zip',
"url": getBaseDownloadUrl(req) + '/version/' + latest.tag + '/' + platform + '?filetype=zip',
"name": latest.tag,
"notes": releaseNotes,
"pub_date": latest.published_at.toISOString()
Expand All @@ -203,7 +203,7 @@ module.exports = function nuts(opts) {
.then(function() {
platform = platforms.detect(platform);

return versions.filter({
return versions.newer({
tag: tag,
platform: platform,
channel: channel
Expand Down Expand Up @@ -251,9 +251,8 @@ module.exports = function nuts(opts) {

Q()
.then(function() {
return versions.filter({
tag: tag? tag : '*',
channel: '*'
return versions.all({
tag: tag
});
})
.then(function(versions) {
Expand Down Expand Up @@ -303,9 +302,9 @@ module.exports = function nuts(opts) {

// List versions
router.get('/api/versions', function (req, res, next) {
versions.filter({
versions.all({
platform: req.query.platform,
channel: req.query.channel || '*'
channel: req.query.channel
})
.then(function(results) {
res.send(results);
Expand All @@ -331,7 +330,7 @@ module.exports = function nuts(opts) {
// Resolve a version using querystring parameters
router.get('/api/resolve', function (req, res, next) {
versions.resolve({
channel: req.query.channel,
channel: req.query.channel || 'stable',
platform: req.query.platform,
tag: req.query.tag
})
Expand Down
71 changes: 50 additions & 21 deletions lib/versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,42 @@ var semver = require('semver');

var platforms = require('./platforms');

function newVersionFilter(opts) {
return function(version) {
// Not available for requested paltform
if (!satisfiesPlatform(opts.platform, version.platforms)) return false;

if (opts.channel) {
// The user wants to stay on a specific channel
return (opts.channel === version.channel &&
semver.rcompare(version.tag, opts.tag) < 0);
} else {
// The user wants the latest available, up to their current channel
return opts.tag == 'latest' || semver.satisfies(version.tag, '>' + opts.tag);
}
}
}

function exactVersionFilter(opts) {
return function(version) {
return version.tag === opts.tag;
}
}

function allVersionFilter(opts) {
return function(version) {
if (opts.tag && version.tag !== opts.tag) return false;
if (opts.channel && version.channel !== opts.channel) return false;
if (!satisfiesPlatform(opts.platform, version.platforms)) return false;
return true;
}
}

function satisfiesPlatform(requestedPlatform, versionPlatforms) {
return (!requestedPlatform ||
platforms.satisfies(requestedPlatform, _.pluck(versionPlatforms, 'type')));
}

module.exports = function(github, opts) {
// Normalize tag name
function normalizeTag(tag) {
Expand Down Expand Up @@ -84,40 +120,31 @@ module.exports = function(github, opts) {
}

// Filter versions
function filterVersions(opts) {
opts = _.defaults(opts || {}, {
tag: 'latest',
platform: null,
channel: extractChannel(opts.tag)
});
function filterVersions(opts, filterBuilder) {
opts = opts || {};
if (opts.platform) opts.platform = platforms.detect(opts.platform);

return listVersions()
.then(function(versions) {
return _.chain(versions)
.filter(function(version) {
// Check channel
if (!channelsMatch(version.channel, opts.channel)) return false;

// Not available for requested paltform
if (opts.platform && !platforms.satisfies(opts.platform, _.pluck(version.platforms, 'type'))) return false;

// Check tag satisfies request version
return opts.tag == 'latest' || (semver.rcompare(version.tag, opts.tag) < 0);
})
.filter(filterBuilder(opts))
.value();
});
}

function channelsMatch(versionChannel, currentChannel) {
if ((currentChannel === '*') ||
(currentChannel === versionChannel) ||
(currentChannel != 'stable' && versionChannel == 'stable')) return true;
// Get new versions for updates
function getNewVersions(opts) {
return filterVersions(opts, newVersionFilter)
}

// Get all versions, subject to any options passed in
function getAllVersions(opts) {
return filterVersions(opts, allVersionFilter)
}

// Resolve a platform
function resolveVersion(opts) {
return filterVersions(opts)
return filterVersions(opts, allVersionFilter)
.then(function(versions) {
var version = _.first(versions);
if (!version) throw new Error('Version not found: '+opts.tag);
Expand Down Expand Up @@ -161,6 +188,8 @@ module.exports = function(github, opts) {
return {
list: listVersions,
get: getVersion,
newer: getNewVersions,
all: getAllVersions,
filter: filterVersions,
resolve: resolveVersion,
channels: listChannels
Expand Down
89 changes: 45 additions & 44 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,47 +1,48 @@
{
"name": "nuts-serve",
"version": "2.6.2",
"description": "Server to make GitHub releases (private) available to download with Squirrel support",
"main": "./lib/index.js",
"homepage": "https://github.com/GitbookIO/nuts",
"license": "Apache-2.0",
"main": "./lib/index.js",
"dependencies": {
"express": "^4.13.3",
"lodash": "3.7.0",
"q": "1.2.0",
"body-parser": "1.12.3",
"octonode": "0.7.1",
"semver": "5.0.1",
"request": "2.60.0",
"basic-auth": "1.0.3",
"express-useragent": "0.1.9",
"stores": "0.0.2",
"analytics-node": "1.2.2",
"uuid": "2.0.1",
"github-webhook-handler": "0.5.0",
"strip-bom": "2.0.0",
"destroy": "1.0.3"
},
"devDependencies": {
"mocha": "1.18.2",
"should": "7.0.4"
},
"bugs": {
"url": "https://github.com/GitbookIO/nuts/issues"
},
"authors": [
{
"name": "Samy Pesse",
"email": "[email protected]"
}
],
"repository": {
"type" : "git",
"url" : "https://github.com/GitbookIO/nuts.git"
},
"scripts": {
"start": "node bin/web.js",
"test": "mocha --reporter list"
"name": "nuts-serve",
"version": "2.6.2",
"description": "Server to make GitHub releases (private) available to download with Squirrel support",
"main": "./lib/index.js",
"homepage": "https://github.com/GitbookIO/nuts",
"license": "Apache-2.0",
"dependencies": {
"analytics-node": "1.2.2",
"basic-auth": "1.0.3",
"body-parser": "1.12.3",
"destroy": "1.0.3",
"express": "^4.13.3",
"express-useragent": "0.1.9",
"github-webhook-handler": "0.5.0",
"lodash": "3.7.0",
"octonode": "0.7.1",
"q": "1.2.0",
"request": "2.60.0",
"semver": "5.0.1",
"stores": "0.0.2",
"strip-bom": "2.0.0",
"uuid": "2.0.1"
},
"devDependencies": {
"mocha": "1.18.2",
"mockery": "^1.4.0",
"rewire": "^2.5.1",
"should": "7.0.4"
},
"bugs": {
"url": "https://github.com/GitbookIO/nuts/issues"
},
"authors": [
{
"name": "Samy Pesse",
"email": "[email protected]"
}
],
"repository": {
"type": "git",
"url": "https://github.com/GitbookIO/nuts.git"
},
"scripts": {
"start": "node bin/web.js",
"test": "mocha --reporter list"
}
}
131 changes: 131 additions & 0 deletions test/versions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
var
_ = require('lodash'),
should = require('should'),
rewire = require('rewire');

describe('Versions', function() {

var Versions = rewire('../lib/versions');
var versionChecker = Versions.__get__('newVersionFilter');

var testVersions = [
{ tag: '0.0.8-alpha.1',
channel: 'alpha',
notes: 'More placeholder text.',
published_at: 'Mon Dec 14 2015 12:13:58 GMT-0800 (PST)',
platforms: [ {
type: 'osx_64'
}, {
type: 'windows_32'
} ],
download_count: 3 },
{ tag: '0.0.7',
channel: 'stable',
notes: 'Kinda drifted away from the story thing and I\'m just writing random stuff now.',
published_at: 'Mon Dec 14 2015 11:41:30 GMT-0800 (PST)',
platforms: [ {
type: 'osx_64'
}, {
type: 'windows_32'
} ],
download_count: 0 },
{ tag: '0.0.7-beta.1',
channel: 'beta',
notes: 'A beautiful brand new release',
published_at: 'Fri Dec 11 2015 17:01:43 GMT-0800 (PST)',
platforms: [ {
type: 'osx_64'
}, {
type: 'windows_32'
} ],
download_count: 0 },
{ tag: '0.0.7-alpha.2',
channel: 'alpha',
notes: 'More excitement!!!',
published_at: 'Fri Dec 11 2015 17:21:08 GMT-0800 (PST)',
platforms: [ {
type: 'osx_64'
}, {
type: 'windows_32'
} ],
download_count: 0 },
{ tag: '0.0.7-alpha.1',
channel: 'alpha',
notes: 'A beautiful brand new release',
published_at: 'Fri Dec 11 2015 17:01:43 GMT-0800 (PST)',
platforms: [ {
type: 'osx_64'
}, {
type: 'windows_32'
} ],
download_count: 0 },
{ tag: '0.0.6',
channel: 'stable',
notes: 'A wonderful new release!',
published_at: 'Fri Dec 11 2015 15:55:45 GMT-0800 (PST)',
platforms: [ {
type: 'osx_64'
}, {
type: 'windows_32'
} ],
download_count: 2 }
];

function testFilterVersions(opts) {
return _.chain(testVersions)
.filter(versionChecker(opts))
.pluck('tag')
.value();
}

it(':: current tag: latest stable | channel param: none --> nothing', function() {
var opts = {
tag: '0.0.7',
platform: 'osx',
channel: undefined
}
console.log(testFilterVersions(opts))
_.isEqual(testFilterVersions(opts), []).should.be.true();
});

it(':: current tag: older stable | channel param: none --> new stable', function() {
var opts = {
tag: '0.0.6',
platform: 'osx',
channel: undefined
}
console.log(testFilterVersions(opts))
_.isEqual(testFilterVersions(opts), ['0.0.7']).should.be.true();
});

it(':: current tag: older beta | channel param: none --> new stable', function() {
var opts = {
tag: '0.0.7-beta.1',
platform: 'osx',
channel: undefined
}
console.log(testFilterVersions(opts))
_.isEqual(testFilterVersions(opts), ['0.0.7']).should.be.true();
});

it(':: current tag: older alpha | channel param: alpha --> new alpha', function() {
var opts = {
tag: '0.0.7-alpha.2',
platform: 'osx',
channel: 'alpha'
}
console.log(testFilterVersions(opts))
_.isEqual(testFilterVersions(opts), ['0.0.8-alpha.1']).should.be.true();
});

it(':: current tag: older beta | channel param: beta --> nothing', function() {
var opts = {
tag: '0.0.7-beta.1',
platform: 'osx',
channel: 'beta'
}
console.log(testFilterVersions(opts))
_.isEqual(testFilterVersions(opts), []).should.be.true();
});

});

0 comments on commit 9471bc6

Please sign in to comment.