Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

Commit

Permalink
support "scoped" packages. close #352
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 committed Jul 21, 2014
1 parent 20fce9f commit 1c0d4fd
Show file tree
Hide file tree
Showing 23 changed files with 613 additions and 20 deletions.
9 changes: 5 additions & 4 deletions controllers/registry/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var downloadAsReadStream = require('../utils').downloadAsReadStream;
* GET /:name
*/
exports.show = function* (next) {
var name = this.params.name;
var name = this.params.name || this.params[0];
var rs = yield [
Module.getLastModified(name),
Module.listTags(name)
Expand Down Expand Up @@ -234,12 +234,13 @@ exports.show = function* (next) {
* GET /:name/:version
* GET /:name/:tag
*/
exports.get = function *(next) {
var name = this.params.name;
var tag = this.params.version;
exports.get = function* (next) {
var name = this.params.name || this.params[0];
var tag = this.params.version || this.params[1];
var version = semver.valid(tag);
var method = version ? 'get' : 'getByTag';
var queryLabel = version ? version : tag;
debug('%s %s with %j', method, name, this.params);

var rs = yield [
Module[method](name, queryLabel),
Expand Down
14 changes: 9 additions & 5 deletions controllers/sync.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**!
* cnpmjs.org - controllers/download.js
* cnpmjs.org - controllers/sync.js
*
* Copyright(c) cnpmjs.org and other contributors.
* MIT Licensed
Expand All @@ -14,14 +14,16 @@
* Module dependencies.
*/

var debug = require('debug')('cnpmjs.org:controllers:sync');
var Log = require('../proxy/module_log');
var SyncModuleWorker = require('../proxy/sync_module_worker');

exports.sync = function *() {
exports.sync = function* () {
var username = this.user.name || 'anonymous';
var name = this.params.name;
var name = this.params.name || this.params[0];
var publish = this.query.publish === 'true';
var noDep = this.query.nodeps === 'true';
debug('sync %s with query: %j', name, this.query);
if (publish && !this.user.isAdmin) {
this.status = 403;
this.body = {
Expand All @@ -37,6 +39,7 @@ exports.sync = function *() {
};

var result = yield SyncModuleWorker.sync(name, username, options);
debug('sync %s got %j', name, result);

// friendly 404 reason info
if (result.statusCode === 404) {
Expand All @@ -59,8 +62,9 @@ exports.sync = function *() {
};
};

exports.getSyncLog = function *(next) {
var logId = this.params.id;
exports.getSyncLog = function* (next) {
// params: [$name, $id] on scope package
var logId = this.params.id || this.params[1];
var offset = Number(this.query.offset) || 0;
var row = yield Log.get(logId);
if (!row) {
Expand Down
17 changes: 11 additions & 6 deletions controllers/web/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* Module dependencies.
*/

var debug = require('debug')('cnpmjs.org:controllers:web:package');
var bytes = require('bytes');
var giturl = require('giturl');
var moment = require('moment');
Expand All @@ -32,10 +33,13 @@ var setDownloadURL = require('../../lib/common').setDownloadURL;
var ModuleStar = require('../../proxy/module_star');
var packageService = require('../../services/package');

exports.display = function *(next) {
exports.display = function* (next) {
var params = this.params;
var name = params.name;
var tag = params.version;
// normal: {name: $name, version: $version}
// scope: [$name, $version]
var name = params.name || params[0];
var tag = params.version || params[1];
debug('display %s with %j', name, params);

var getPackageMethod;
var getPackageArgs;
Expand Down Expand Up @@ -129,7 +133,8 @@ exports.display = function *(next) {

exports.search = function *(next) {
var params = this.params;
var word = params.word;
var word = params.word || params[0];
debug('search %j', word);
var result = yield Module.search(word);

var match = null;
Expand Down Expand Up @@ -192,8 +197,8 @@ exports.rangeSearch = function *(next) {
};
};

exports.displaySync = function *(next) {
var name = this.params.name || this.query.name;
exports.displaySync = function* (next) {
var name = this.params.name || this.params[0] || this.query.name;
yield this.render('sync', {
name: name,
title: 'Sync - ' + name
Expand Down
3 changes: 3 additions & 0 deletions middleware/web_not_found.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ module.exports = function *notFound(next) {
if (this.status && this.status !== 404) {
return;
}
if (this.body) {
return;
}

var m = /^\/([\w\-\_\.]+)\/?$/.exec(this.url);
debug('%s match %j', this.url, m);
Expand Down
5 changes: 5 additions & 0 deletions routes/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ function routes(app) {
app.get('/-/short', mod.listAllModuleNames);

// module
// scope package: params: [$name]
app.get(/\/(@[\w\-\.]+\/[\w\-\.]+)$/, syncByInstall, mod.show);
// scope package: params: [$name, $version]
app.get(/\/(@[\w\-\.]+\/[\w\-\.]+)\/([\w\.\-]+)$/, syncByInstall, mod.get);

app.get('/:name', syncByInstall, mod.show);
app.get('/:name/:version', syncByInstall, mod.get);
// try to add module
Expand Down
14 changes: 14 additions & 0 deletions routes/web.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,29 @@ var dist = require('../controllers/web/dist');

function routes(app) {
app.get('/total', total.show);

// scope package without version
app.get(/\/package\/(@[\w\-\.]+\/[\w\-\.]+)$/, pkg.display);
// scope package with version
app.get(/\/package\/(@[\w\-\.]+\/[\w\-\.]+)\/([\w\d\.]+)$/, pkg.display);
app.get('/package/:name', pkg.display);
app.get('/package/:name/:version', pkg.display);

app.get(/\/browse\/keyword\/(@[\w\-\.]+\/[\w\-\.]+)$/, pkg.search);
app.get('/browse/keyword/:word', pkg.search);

app.get('/~:name', user.display);

app.get(/\/sync\/(@[\w\-\.]+\/[\w\-\.]+)$/, pkg.displaySync);
app.get('/sync/:name', pkg.displaySync);

app.put(/\/sync\/(@[\w\-\.]+\/[\w\-\.]+)$/, sync.sync);
app.put('/sync/:name', sync.sync);

// params: [$name, $id]
app.get(/\/sync\/(@[\w\-\.]+\/[\w\-\.]+)\/log\/(\d+)$/, sync.getSyncLog);
app.get('/sync/:name/log/:id', sync.getSyncLog);

app.get('/sync', pkg.displaySync);

app.get('/_list/search/search', pkg.rangeSearch);
Expand Down
6 changes: 3 additions & 3 deletions test/controllers/registry/module.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,9 @@ describe('controllers/registry/module.test.js', function () {
should.not.exist(err);
var body = res.body;
body.name.should.equal('mk2testmodule');
body.version.should.equal('0.0.1');
body._id.should.equal('mk2testmodule@0.0.1');
body.dist.tarball.should.containEql('/mk2testmodule/download/mk2testmodule-0.0.1.tgz');
body.version.should.equal('0.0.2');
body._id.should.equal('mk2testmodule@0.0.2');
body.dist.tarball.should.containEql('/mk2testmodule/download/mk2testmodule-0.0.2.tgz');
done();
});
});
Expand Down
120 changes: 120 additions & 0 deletions test/controllers/registry/module/scope_package.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**!
* cnpmjs.org - test/controllers/registry/module/scope_package.test.js
*
* Copyright(c) fengmk2 and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
*/

'use strict';

/**
* Module dependencies.
*/

var should = require('should');
var request = require('supertest');
var app = require('../../../../servers/registry');
var utils = require('../../../utils');

describe('controllers/registry/module/scope_package.test.js', function () {
var pkgname = '@cnpm/test-scope-package';
var pkgURL = '/@' + encodeURIComponent(pkgname.substring(1));
before(function (done) {
// add scope package
var pkg = utils.getPackage(pkgname, '0.0.1', utils.admin);

request(app.listen())
.put(pkgURL)
.set('authorization', utils.adminAuth)
.send(pkg)
.expect(201, function (err) {
should.not.exist(err);
pkg = utils.getPackage(pkgname, '0.0.2', utils.admin);
// publish 0.0.2
request(app.listen())
.put(pkgURL)
.set('authorization', utils.adminAuth)
.send(pkg)
.expect(201, done);
});
});

it('should get scope package info: /@scope%2Fname', function (done) {
request(app.listen())
.get(pkgURL)
.expect(200, function (err, res) {
should.not.exist(err);
var pkg = res.body;
pkg.name.should.equal(pkgname);
pkg.versions.should.have.keys('0.0.1', '0.0.2');
pkg['dist-tags'].latest.should.equal('0.0.2');
pkg.versions['0.0.1'].name.should.equal(pkgname);
pkg.versions['0.0.1'].dist.tarball
.should.containEql('/@cnpm/test-scope-package/download/@cnpm/test-scope-package-0.0.1.tgz');
done();
});
});

it('should get scope package info: /@scope/name', function (done) {
request(app.listen())
.get('/' + pkgname)
.expect(200, function (err, res) {
should.not.exist(err);
var pkg = res.body;
pkg.name.should.equal(pkgname);
pkg.versions.should.have.keys('0.0.1', '0.0.2');
pkg['dist-tags'].latest.should.equal('0.0.2');
pkg.versions['0.0.1'].name.should.equal(pkgname);
pkg.versions['0.0.1'].dist.tarball
.should.containEql('/@cnpm/test-scope-package/download/@cnpm/test-scope-package-0.0.1.tgz');
done();
});
});

it('should get scope package info: /%40scope%2Fname', function (done) {
request(app.listen())
.get('/' + encodeURIComponent(pkgname))
.expect(200, function (err, res) {
should.not.exist(err);
var pkg = res.body;
pkg.name.should.equal(pkgname);
pkg.versions.should.have.keys('0.0.1', '0.0.2');
pkg['dist-tags'].latest.should.equal('0.0.2');
pkg.versions['0.0.1'].name.should.equal(pkgname);
pkg.versions['0.0.1'].dist.tarball
.should.containEql('/@cnpm/test-scope-package/download/@cnpm/test-scope-package-0.0.1.tgz');
done();
});
});

it('should get scope package with version', function (done) {
request(app.listen())
.get('/' + pkgname + '/0.0.1')
.expect(200, function (err, res) {
should.not.exist(err);
var pkg = res.body;
pkg.name.should.equal(pkgname);
pkg.version.should.equal('0.0.1');
pkg.dist.tarball
.should.containEql('/@cnpm/test-scope-package/download/@cnpm/test-scope-package-0.0.1.tgz');
done();
});
});

it('should get scope package with tag', function (done) {
request(app.listen())
.get('/' + pkgname + '/latest')
.expect(200, function (err, res) {
should.not.exist(err);
var pkg = res.body;
pkg.name.should.equal(pkgname);
pkg.version.should.equal('0.0.2');
pkg.dist.tarball
.should.containEql('/@cnpm/test-scope-package/download/@cnpm/test-scope-package-0.0.2.tgz');
done();
});
});
});
16 changes: 14 additions & 2 deletions test/controllers/sync.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ var webApp = require('../../servers/web');
describe('controllers/sync.test.js', function () {
before(function (done) {
done = pedding(2, done);
registryApp.listen(0, done);
webApp.listen(0, done);
registryApp = registryApp.listen(0, done);
webApp = webApp.listen(0, done);
});

afterEach(mm.restore);
Expand Down Expand Up @@ -116,4 +116,16 @@ describe('controllers/sync.test.js', function () {
});
});
});

describe('scope package', function () {
it('should sync scope package not found', function (done) {
request(webApp)
.put('/sync/@cnpm/not-exists-package')
.expect({
"ok":false,
"reason":"can not found @cnpm/not-exists-package in the source registry"
})
.expect(404, done);
});
});
});
Loading

0 comments on commit 1c0d4fd

Please sign in to comment.