Skip to content

Commit

Permalink
Merges cotap#9
Browse files Browse the repository at this point in the history
Merges cotap#1
  • Loading branch information
Jan Penning committed Jun 22, 2016
1 parent 4dba203 commit a3ee19d
Show file tree
Hide file tree
Showing 7 changed files with 386 additions and 38 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ node_modules
.env

docs/_book/
.idea/
4 changes: 2 additions & 2 deletions lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ module.exports = {
},

'versions': function (req) {
return this.versions.filter({
return this.versions.select({
platform: req.query.platform,
channel: req.query.channel || '*'
channel: req.query.channel
});
},

Expand Down
21 changes: 11 additions & 10 deletions lib/nuts.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ Nuts.prototype.onUpdate = function(req, res, next) {
var fullUrl = getFullUrl(req);
var platform = req.params.platform;
var tag = req.params.version;
var channel = req.query.channel;
var filetype = req.query.filetype ? req.query.filetype : "zip";

Q()
Expand All @@ -220,10 +221,10 @@ Nuts.prototype.onUpdate = function(req, res, next) {

platform = platforms.detect(platform);

return that.versions.filter({
tag: '>='+tag,
return that.versions.newer({
tag: tag,
platform: platform,
channel: '*'
channel: channel
});
})
.then(function(versions) {
Expand Down Expand Up @@ -255,15 +256,16 @@ Nuts.prototype.onUpdateWin = function(req, res, next) {
var fullUrl = getFullUrl(req);
var platform = 'win_32';
var tag = req.params.version;
var channel = req.query.channel;

that.init()
.then(function() {
platform = platforms.detect(platform);

return that.versions.filter({
tag: '>='+tag,
return that.versions.newer({
tag: tag,
platform: platform,
channel: '*'
channel: channel
});
})
.then(function(versions) {
Expand All @@ -285,7 +287,7 @@ Nuts.prototype.onUpdateWin = function(req, res, next) {

// Change filename to use download proxy
.map(function(entry) {
entry.filename = urljoin(fullUrl, '/../../../../', '/download/'+entry.semver+'/'+entry.filename);
entry.filename = urljoin(fullUrl, '/../../../../', '/download/'+entry.version+'/'+entry.filename);

return entry;
})
Expand All @@ -309,9 +311,8 @@ Nuts.prototype.onServeNotes = function(req, res, next) {

Q()
.then(function() {
return that.versions.filter({
tag: tag? '>='+tag : '*',
channel: '*'
return that.versions.select({
tag: tag
});
})
.then(function(versions) {
Expand Down
24 changes: 18 additions & 6 deletions lib/utils/win-releases.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ var CHANNELS = [

// RELEASES parsing
var releaseRe = /^([0-9a-fA-F]{40})\s+(\S+)\s+(\d+)[\r]*$/;
var suffixRe = /(-full|-delta)?\.nupkg/;
var versionRe = /\d+(\.\d+){0,3}(-[a-z][0-9a-z-\.]*$)?$/;
var prereleaseRe = /-[a-z][0-9a-z-\.]*$/;


// Hash a prerelease
Expand Down Expand Up @@ -73,13 +76,22 @@ function parseRELEASES(content) {
.split(/\.|-/)
.reverse();

var version = _.chain(filenameParts)
.filter(function(x) {
return /^\d+$/.exec(x);
var version = _.chain(
filename
.replace(suffixRe, '')
.match(versionRe)
)
.thru(function(matchResult) {
return matchResult ? matchResult[0] : '';
})
.reverse()
.value()
.join('.');
.replace(prereleaseRe, function(prerelease) {
// NuGet doesn't support dots in prereleases
// https://docs.nuget.org/create/versioning#user-content-prerelease-versions
return prerelease.replace(/\./g, '');
})
.value();

if (!version) throw new Error('Release missing valid version: ' + filename);

return {
sha: parts[1],
Expand Down
83 changes: 63 additions & 20 deletions lib/versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ var semver = require('semver');

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

var channelRe = /^[a-z]*/;

// Normalize tag name
function normalizeTag(tag) {
if (tag[0] == 'v') tag = tag.slice(1);
Expand All @@ -15,7 +17,7 @@ function extractChannel(tag) {
var suffix = tag.split('-')[1];
if (!suffix) return 'stable';

return suffix.split('.')[0];
return suffix.match(channelRe)[0] || suffix.split('.')[0];
}

// Normalize a release to a version
Expand All @@ -36,6 +38,8 @@ function normalizeVersion(release) {
filename: asset.name,
size: asset.size,
content_type: asset.content_type,
download_url: asset.url,
download_count: asset.download_count,
raw: asset
};
})
Expand All @@ -47,7 +51,8 @@ function normalizeVersion(release) {
channel: extractChannel(release.tag_name),
notes: release.body || "",
published_at: new Date(release.published_at),
platforms: releasePlatforms
platforms: releasePlatforms,
download_count: downloadCount
};
}

Expand All @@ -62,6 +67,45 @@ function compareVersions(v1, v2) {
return 0;
}

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

function matchingChannel(requestedChannel, versionChannel) {
return (!requestedChannel ||
requestedChannel === '*' ||
versionChannel === requestedChannel);
}

// Creates filter function that checks for updates
function newVersionFilter(opts) {
return function(version) {
// Not available for requested paltform
if (!supportsPlatform(opts.platform, version.platforms)) {
return false;
}

// If the caller specifies a channel then stay on that channel. Otherwise
// look for anything closer to the main release.
if (opts.channel) {
return (opts.channel === version.channel &&
semver.rcompare(version.tag, opts.tag) <= 0);
} else {
return semver.satisfies(version.tag, '>=' + opts.tag);
}
}
}

// Creates generic filter function for all versions
function allVersionFilter(opts) {
return function(version) {
return ((!opts.tag || opts.tag === version.tag) &&
matchingChannel(opts.channel, version.channel) &&
supportsPlatform(opts.platform, version.platforms));
}
}

function Versions(backend) {
this.backend = backend;

Expand All @@ -87,34 +131,33 @@ Versions.prototype.get = function(tag) {
};

// Filter versions with criterias
Versions.prototype.filter = function(opts) {
opts = _.defaults(opts || {}, {
tag: 'latest',
platform: null,
channel: 'stable'
});
Versions.prototype.filter = function(opts, filterBuilder) {
opts = opts || {};
if (opts.platform) opts.platform = platforms.detect(opts.platform);

return this.list()
.then(function(versions) {
return _.chain(versions)
.filter(function(version) {
// Check channel
if (opts.channel != '*' && 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.satisfies(version.tag, opts.tag);
})
.filter(filterBuilder(opts))
.value();
});
};

Versions.prototype.newer = function (opts) {
return this.filter(opts, newVersionFilter);
};

Versions.prototype.select = function (opts) {
return this.filter(opts, allVersionFilter);
};

// Resolve a platform, by filtering then taking the first result
Versions.prototype.resolve = function(opts) {
return this.filter(opts)
opts = opts || {};
opts.channel = opts.channel || 'stable';
if (opts.tag === 'latest') opts.tag = null;

return this.filter(opts, allVersionFilter)
.then(function(versions) {
var version = _.first(versions);
if (!version) throw new Error('Version not found: '+opts.tag);
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
},
"devDependencies": {
"mocha": "1.18.2",
"mockery": "^1.4.0",
"rewire": "^2.5.1",
"should": "7.0.4"
},
"bugs": {
Expand Down
Loading

0 comments on commit a3ee19d

Please sign in to comment.