fix: should sync missing public scoped package on install (#946)

* fix: should sync missing public scoped package on install

closes #938

* refactor: sync all scoped packages when config.scopes is empty

* test: test on node 6
This commit is contained in:
fengmk2
2016-06-05 23:34:10 +08:00
committed by Yiyu He
parent 9b572d77aa
commit 94dc13088c
12 changed files with 80 additions and 101 deletions

View File

@@ -2,7 +2,7 @@ sudo: false
language: node_js language: node_js
node_js: node_js:
- '4' - '4'
- '5' - '6'
addons: addons:
- postgresql: '9.3' - postgresql: '9.3'
script: 'make test-travis-all' script: 'make test-travis-all'

View File

@@ -1,6 +1,6 @@
This software is licensed under the MIT License. This software is licensed under the MIT License.
Copyright(c) cnpmjs.org and other contributors. Copyright(c) cnpm and other contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -12,7 +12,7 @@ install-production production:
@NODE_ENV=production $(MAKE) install @NODE_ENV=production $(MAKE) install
jshint: install jshint: install
@-node_modules/.bin/jshint ./ @node_modules/.bin/jshint .
init-database: init-database:
@node test/init_db.js @node test/init_db.js

View File

@@ -1,11 +1,3 @@
/**
* Copyright(c) cnpm and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
*/
'use strict'; 'use strict';
/** /**
@@ -99,7 +91,7 @@ module.exports = function* list() {
this.status = 404; this.status = 404;
this.body = { this.body = {
error: 'not_found', error: 'not_found',
reason: 'document not found' reason: 'document not found',
}; };
return; return;
} }

View File

@@ -1,12 +1,3 @@
/**!
* cnpmjs.org - middleware/proxy_to_npm.js
*
* Copyright(c) Alibaba Group Holding Limited.
*
* Authors:
* 苏千 <suqian.yf@alipay.com> (http://fengmk2.com)
*/
'use strict'; 'use strict';
/** /**
@@ -33,11 +24,11 @@ module.exports = function (options) {
} }
return function* proxyToNpm(next) { return function* proxyToNpm(next) {
if (config.syncModel !== 'none') { if (config.syncModel !== 'none') {
return yield* next; return yield next;
} }
// only proxy read requests // only proxy read requests
if (this.method !== 'GET' && this.method !== 'HEAD') { if (this.method !== 'GET' && this.method !== 'HEAD') {
return yield* next; return yield next;
} }
var pathname = this.path; var pathname = this.path;
@@ -49,7 +40,7 @@ module.exports = function (options) {
} }
} }
if (!match) { if (!match) {
return yield* next; return yield next;
} }
var url = redirectUrl + this.url; var url = redirectUrl + this.url;

View File

@@ -1,7 +1,5 @@
/**! /**
* cnpmjs.org - middleware/sync_by_install.js * Copyright(c) cnpm and other contributors.
*
* Copyright(c) cnpmjs.org and other contributors.
* MIT Licensed * MIT Licensed
* *
* Authors: * Authors:
@@ -17,33 +15,36 @@
var config = require('../config'); var config = require('../config');
/** /**
* this.allowSync - allow sync triggle by cnpm install * {Boolean} this.allowSync - allow sync triggle by cnpm install
*/ */
module.exports = function* syncByInstall(next) { module.exports = function* syncByInstall(next) {
this.allowSync = false; this.allowSync = false;
if (!config.syncByInstall) { if (!config.syncByInstall) {
// only config.enablePrivate should enable sync on install // only config.enablePrivate should enable sync on install
return yield* next; return yield next;
} }
// request not by node, consider it request from web, dont sync // request not by node, consider it request from web, don't sync
var ua = this.get('user-agent'); var ua = this.get('user-agent');
if (!ua || ua.indexOf('node') < 0) { if (!ua || ua.indexOf('node') < 0) {
return yield* next; return yield next;
} }
// if request with `/xxx?write=true`, meaning the read request using for write, dont sync // if request with `/xxx?write=true`, meaning the read request using for write, don't sync
if (this.query.write) { if (this.query.write) {
return yield* next; return yield next;
} }
var name = this.params.name || this.params[0]; var name = this.params.name || this.params[0];
// scoped package dont sync // private scoped package don't sync
if (name && name[0] === '@') { if (name && name[0] === '@') {
return yield* next; var scope = name.split('/')[0];
if (config.scopes.indexOf(scope) >= 0) {
return yield next;
}
} }
this.allowSync = true; this.allowSync = true;
yield* next; yield next;
}; };

View File

@@ -1,13 +1,3 @@
/**!
* 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'; 'use strict';
/** /**
@@ -21,7 +11,7 @@ var config = require('../../../../config');
var app = require('../../../../servers/registry'); var app = require('../../../../servers/registry');
var utils = require('../../../utils'); var utils = require('../../../utils');
describe('controllers/registry/module/scope_package.test.js', function () { describe('test/controllers/registry/module/scope_package.test.js', function () {
var pkgname = '@cnpm/test-scope-package'; var pkgname = '@cnpm/test-scope-package';
var pkgURL = '/@' + encodeURIComponent(pkgname.substring(1)); var pkgURL = '/@' + encodeURIComponent(pkgname.substring(1));
before(function (done) { before(function (done) {
@@ -52,16 +42,17 @@ describe('controllers/registry/module/scope_package.test.js', function () {
afterEach(mm.restore); afterEach(mm.restore);
it('should get 404 when do not support scope', function (done) { it('should get 302 when do not support scope', function (done) {
mm(config, 'scopes', []); mm(config, 'scopes', []);
request(app) request(app)
.get('/@invalid/test') .get('/@invalid/test')
.expect(404, done); .expect('Location', 'https://registry.npmjs.com/@invalid/test')
.expect(302, done);
}); });
it('should get 400 when scope not match', function (done) { it('should get 404 when scope is private', function (done) {
request(app) request(app)
.get('/@invalid/test') .get('/@cnpmtest/test')
.expect(404, done); .expect(404, done);
}); });

View File

@@ -1,11 +1,3 @@
/**!
* Copyright(c) cnpmjs.org and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.com)
*/
'use strict'; 'use strict';
/** /**
@@ -69,6 +61,7 @@ describe('test/controllers/sync_module_worker.test.js', function () {
var worker = new SyncModuleWorker({ var worker = new SyncModuleWorker({
name: '@sindresorhus/df', name: '@sindresorhus/df',
username: 'fengmk2', username: 'fengmk2',
noDep: true,
}); });
worker.start(); worker.start();
var end = thunkify.event(worker, 'end'); var end = thunkify.event(worker, 'end');

View File

@@ -1,13 +1,3 @@
/**!
* cnpmjs.org - test/init.js
*
* Copyright(c) fengmk2 and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
*/
'use strict'; 'use strict';
/** /**

View File

@@ -1,13 +1,3 @@
/**!
* cnpmjs.org - test/init_db.js
*
* Copyright(c) fengmk2 and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
*/
'use strict'; 'use strict';
/** /**
@@ -22,7 +12,7 @@ var config = require('../config');
// init db first // init db first
var initscript = path.join(__dirname, '..', 'models', 'init_script.js'); var initscript = path.join(__dirname, '..', 'models', 'init_script.js');
var cmd = ['node', '--harmony', initscript, 'true', var cmd = ['node', initscript, 'true',
config.database.dialect, config.database.port, config.database.username].join(' '); config.database.dialect, config.database.port, config.database.username].join(' ');
console.log('$ %s', cmd); console.log('$ %s', cmd);
var stdout = childProcess.execSync(cmd); var stdout = childProcess.execSync(cmd);

View File

@@ -1,13 +1,3 @@
/**!
* cnpmjs.org - test/middleware/proxy_to_npm.test.js
*
* Copyright(c) cnpmjs.org and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
*/
'use strict'; 'use strict';
/** /**
@@ -19,44 +9,51 @@ var mm = require('mm');
var app = require('../../servers/registry'); var app = require('../../servers/registry');
var config = require('../../config'); var config = require('../../config');
describe('middleware/proxy_to_npm.test.js', function () { describe('test/middleware/proxy_to_npm.test.js', () => {
beforeEach(function () { beforeEach(() => {
mm(config, 'syncModel', 'none'); mm(config, 'syncModel', 'none');
}); });
afterEach(mm.restore); afterEach(mm.restore);
describe('package', function () { describe('package', () => {
it('should proxy to source registry when package not exists', function (done) { it('should proxy to source registry when package not exists', done => {
request(app.listen()) request(app.listen())
.get('/ms') .get('/ms')
.expect('location', config.sourceNpmRegistry + '/ms') .expect('location', config.sourceNpmRegistry + '/ms')
.expect(302, done); .expect(302, done);
}); });
it('should proxy to source registry when package is not local', function (done) { it('should proxy to source registry when package is not local', done => {
request(app.listen()) request(app.listen())
.get('/baidu?write=true') .get('/baidu?write=true')
.expect('location', config.sourceNpmRegistry + '/baidu?write=true') .expect('location', config.sourceNpmRegistry + '/baidu?write=true')
.expect(302, done); .expect(302, done);
}); });
it('should not proxy to source registry when package is scoped', function (done) { it('should not proxy to source registry when package is private scoped', done => {
request(app.listen()) request(app.listen())
.get('/@scoped/test-package-name') .get('/@cnpmtest/test-package-name')
.expect(404, done); .expect(404, done);
}); });
it('should proxy to source registry when package is public scoped', done => {
request(app.listen())
.get('/@jkroso/type')
.expect('Location', 'https://registry.npmjs.com/@jkroso/type')
.expect(302, done);
});
}); });
describe('dist-tags', function () { describe('dist-tags', () => {
it('should proxy to source registry when package not exists', function (done) { it('should proxy to source registry when package not exists', done => {
request(app.listen()) request(app.listen())
.get('/-/package/ms/dist-tags') .get('/-/package/ms/dist-tags')
.expect('location', config.sourceNpmRegistry + '/-/package/ms/dist-tags') .expect('location', config.sourceNpmRegistry + '/-/package/ms/dist-tags')
.expect(302, done); .expect(302, done);
}); });
it('should dont proxy scoped package', function (done) { it('should dont proxy scoped package', done => {
request(app.listen()) request(app.listen())
.get('/-/package/@scoped/ms/dist-tags') .get('/-/package/@scoped/ms/dist-tags')
.expect(404, done); .expect(404, done);

View File

@@ -0,0 +1,34 @@
'use strict';
/**
* Module dependencies.
*/
var request = require('supertest');
var app = require('../../servers/registry');
var mm = require('mm');
var config = require('../../config');
var userService = require('../../services/user');
describe('test/middleware/sync_by_install.test.js', () => {
afterEach(mm.restore);
it('should ignore sync on install private scoped package', done => {
request(app.listen())
.get('/@cnpmtest/foo')
.set('User-Agent', 'node/v4.4.4')
.expect({
error: 'not_found',
reason: 'document not found',
})
.expect(404, done);
});
it('should sync and redirect to npmjs.com on install public scoped package', done => {
request(app.listen())
.get('/@jkroso/type')
.set('User-Agent', 'node/v4.4.4')
.expect('Location', 'https://registry.npmjs.com/@jkroso/type')
.expect(302, done);
});
});