Compare commits

..

22 Commits
1.2.2 ... 1.4.0

Author SHA1 Message Date
fengmk2
71452f692e Release 1.4.0 2014-08-20 10:01:48 +08:00
dead_horse
c24526d7ff Merge pull request #429 from cnpm/badge
Badge version image
2014-08-20 09:56:48 +08:00
fengmk2
43dcd4b4f1 update readme for badge url desc 2014-08-20 09:53:37 +08:00
fengmk2
ff90c0f238 different version, different color badge 2014-08-20 09:47:06 +08:00
fengmk2
f85752e4bc add badge on package page 2014-08-20 00:25:26 +08:00
fengmk2
4b20c13a4f add version badge. fixed #427 2014-08-20 00:07:53 +08:00
dead_horse
ef61605e0c add download and node version badge 2014-08-18 21:32:52 +08:00
dead_horse
a5291d95dd Release 1.3.2 2014-08-18 11:45:25 +08:00
dead_horse
9de10e791c remove unused eventproxy 2014-08-18 11:27:25 +08:00
dead_horse
1162ed95b0 add custom config in tools/sync_not_exist.js 2014-08-18 11:25:09 +08:00
dead_horse
6cdbc0b058 Release 1.3.1 2014-08-18 10:15:49 +08:00
dead_horse
dc7239637d add sync not exist tools, close #424 2014-08-18 10:14:38 +08:00
dead_horse
b735c9c15c use gittip instand of alipay. close #425 2014-08-17 22:21:59 +08:00
dead_horse
417e19a330 update registry api doc 2014-08-16 16:01:06 +08:00
dead_horse
40ab0929e1 Release 1.3.0 2014-08-11 11:46:58 +08:00
dead_horse
6dabe60839 ignore config/config.js 2014-08-11 11:46:29 +08:00
fengmk2
2680512c71 Merge pull request #421 from cnpm/qn-cnpm
use simple fs storage in develop env
2014-08-10 08:59:40 +08:00
dead_horse
f444566a23 fix test case 2014-08-10 01:57:58 +08:00
dead_horse
99cb110ee2 use fs-cnpm 2014-08-10 01:27:08 +08:00
dead_horse
536704705c fix test 2014-08-09 21:32:36 +08:00
dead_horse
d919a81dae use qn-cnpm 2014-08-09 21:17:59 +08:00
dead_horse
fe8100ea30 bump cfork 2014-08-09 20:16:56 +08:00
25 changed files with 405 additions and 172 deletions

View File

@@ -19,3 +19,4 @@ coverage/
.DS_Store
config/web_readme.md
.dist/
config/config.js

View File

@@ -1,4 +1,34 @@
1.4.0 / 2014-08-20
==================
* different version, different color badge, add version badge. fixed #427
* add download and node version badge
1.3.2 / 2014-08-18
==================
* remove unused eventproxy
* add custom config in tools/sync_not_exist.js
1.3.1 / 2014-08-18
==================
* add sync not exist tools, close [#424](https://github.com/cnpm/cnpmjs.org/issues/424)
* use gittip instand of alipay. close [#425](https://github.com/cnpm/cnpmjs.org/issues/425)
* update registry api doc
1.3.0 / 2014-08-11
==================
* ignore config/config.js
* Merge pull request [#421](https://github.com/cnpm/cnpmjs.org/issues/421) from cnpm/qn-cnpm
* fix test case
* use fs-cnpm
* fix test
* use qn-cnpm
* bump cfork
1.2.2 / 2014-08-08
==================
@@ -14,17 +44,17 @@
* show deprecated message
* Sync deprecated field if it missing
* Support $ cnpm deprecate [pkgname]@[version] "message". fixed #415
* Support $ cnpm deprecate [pkgname]@[version] "message". fixed [#415](https://github.com/cnpm/cnpmjs.org/issues/415)
1.1.0 / 2014-08-07
==================
* Add user to maintainers when publish. fixed #395
* List all npm registry api. close #413
* Add user to maintainers when publish. fixed [#395](https://github.com/cnpm/cnpmjs.org/issues/395)
* List all npm registry api. close [#413](https://github.com/cnpm/cnpmjs.org/issues/413)
* limit list since
* change deps by "~"
* use cfork to make sure worker fork and restart
* handle master uncaughtException. fixed #403
* handle master uncaughtException. fixed [#403](https://github.com/cnpm/cnpmjs.org/issues/403)
1.0.6 / 2014-08-02
==================
@@ -34,12 +64,12 @@
1.0.5 / 2014-08-02
==================
* unpublish pkg@version bug hotfix. fixed #400
* unpublish pkg@version bug hotfix. fixed [#400](https://github.com/cnpm/cnpmjs.org/issues/400)
1.0.4 / 2014-08-01
==================
* hotfix #399 use not exists
* hotfix [#399](https://github.com/cnpm/cnpmjs.org/issues/399) use not exists
1.0.3 / 2014-08-01
==================
@@ -54,7 +84,7 @@
1.0.1 / 2014-08-01
==================
* Merge pull request #398 from cnpm/fix-auth
* Merge pull request [#398](https://github.com/cnpm/cnpmjs.org/issues/398) from cnpm/fix-auth
* hot fix auth error
1.0.0 / 2014-08-01
@@ -85,7 +115,7 @@
* remove session middleware
* add DefaultUserService
* check scopes in module.getAdapt
* test public mode, fix some logic, close #382
* test public mode, fix some logic, close [#382](https://github.com/cnpm/cnpmjs.org/issues/382)
* move scope.js into publishable.js, add forcePublishWithScope
* config.scopes not exist, means do not support scope
* add assert scope middleware
@@ -98,12 +128,12 @@
0.8.6 / 2014-07-23
==================
* show unpublished info on web package page. fixes #381
* show unpublished info on web package page. fixes [#381](https://github.com/cnpm/cnpmjs.org/issues/381)
0.8.5 / 2014-07-22
==================
* Only private package support default scoped. fixed #378
* Only private package support default scoped. fixed [#378](https://github.com/cnpm/cnpmjs.org/issues/378)
0.8.4 / 2014-07-22
==================
@@ -124,20 +154,20 @@
==================
* add more test cases
* support default @org. close #376
* support default @org. close [#376](https://github.com/cnpm/cnpmjs.org/issues/376)
* hotfix redis init error
0.8.0 / 2014-07-21
==================
* support "scoped" packages. close #352
* support "scoped" packages. close [#352](https://github.com/cnpm/cnpmjs.org/issues/352)
* use safe jsonp
* Stop support old publish flow. fix #368
* Stop support old publish flow. fix [#368](https://github.com/cnpm/cnpmjs.org/issues/368)
* update SQLs
* use sync_info and sync_error categories
* add categories to loggers. fix #370
* add categories to loggers. fix [#370](https://github.com/cnpm/cnpmjs.org/issues/370)
* fix get latest tag always not exists bug
* support `npm publish --tag beta`. fix #366
* support `npm publish --tag beta`. fix [#366](https://github.com/cnpm/cnpmjs.org/issues/366)
* use mini-logger and error-formater
0.7.0 / 2014-07-07
@@ -145,7 +175,7 @@
* use module_maintainers on GET /pakcage/:name page
* use new module_maintainers on GET /:name
* admin user should never publish to other user's packages. fix #363
* admin user should never publish to other user's packages. fix [#363](https://github.com/cnpm/cnpmjs.org/issues/363)
* Add a new table for module-maintainers.
* gravatar use https
* support https
@@ -160,8 +190,8 @@
0.6.0 / 2014-06-16
==================
* sync unpublished info. close #353
* Delete not exists versions on sync worker. #353
* sync unpublished info. close [#353](https://github.com/cnpm/cnpmjs.org/issues/353)
* Delete not exists versions on sync worker. [#353](https://github.com/cnpm/cnpmjs.org/issues/353)
0.5.3 / 2014-06-13
==================

View File

@@ -16,6 +16,7 @@ pretest:
@mysql -uroot -e 'CREATE DATABASE cnpmjs_test;'
@mysql -uroot 'cnpmjs_test' < ./docs/db.sql
@mysql -uroot 'cnpmjs_test' -e 'show tables;'
@rm -rf .tmp/dist
test: install pretest
@NODE_ENV=test ./node_modules/.bin/mocha \

View File

@@ -6,17 +6,23 @@ cnpmjs.org
[![Test coverage][coveralls-image]][coveralls-url]
[![Gittip][gittip-image]][gittip-url]
[![David deps][david-image]][david-url]
[![node version][node-image]][node-url]
[![npm download][download-image]][download-url]
[npm-image]: https://img.shields.io/npm/v/cnpmjs.org.svg?style=flat
[npm-url]: https://npmjs.org/package/cnpmjs.org
[travis-image]: https://img.shields.io/travis/cnpm/cnpmjs.org.svg?style=flat
[npm-image]: http://cnpmjs.org/badge/v/cnpmjs.org.svg?style=flat-square
[npm-url]: http://cnpmjs.org/package/cnpmjs.org
[travis-image]: https://img.shields.io/travis/cnpm/cnpmjs.org.svg?style=flat-square
[travis-url]: https://travis-ci.org/cnpm/cnpmjs.org
[coveralls-image]: https://img.shields.io/coveralls/cnpm/cnpmjs.org.svg?style=flat
[coveralls-image]: https://img.shields.io/coveralls/cnpm/cnpmjs.org.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/cnpm/cnpmjs.org?branch=master
[gittip-image]: https://img.shields.io/gittip/fengmk2.svg?style=flat
[gittip-image]: https://img.shields.io/gittip/fengmk2.svg?style=flat-square
[gittip-url]: https://www.gittip.com/fengmk2/
[david-image]: https://img.shields.io/david/cnpm/cnpmjs.org.svg?style=flat
[david-image]: https://img.shields.io/david/cnpm/cnpmjs.org.svg?style=flat-square
[david-url]: https://david-dm.org/cnpm/cnpmjs.org
[node-image]: https://img.shields.io/badge/node.js-%3E=_0.11-red.svg?style=flat-square
[node-url]: http://nodejs.org/download/
[download-image]: https://img.shields.io/npm/dm/cnpmjs.org.svg?style=flat-square
[download-url]: https://npmjs.org/package/cnpmjs.org
![logo](https://raw.github.com/cnpm/cnpmjs.org/master/logo.png)
@@ -48,6 +54,7 @@ to extend `npm` with more features(`sync` command, [gzip](https://github.com/npm
And it easy to wrap for your own registry which build with `cnpmjs.org`.
* **Compatible with NPM client**: you can use the origin NPM client with `cnpmjs.org`,
only need to change the registry in config. Even include manual synchronization (through `install` command).
* **Version badge**: base on [shields.io](http://shields.io/) ![cnpm-badge](http://cnpmjs.org/badge/v/cnpmjs.org.svg?style=flat-square)
## Getting Start
@@ -104,24 +111,6 @@ $ node --harmony_generators dispatch.js
Tips: make sure your code is following the [node-style-guide](https://github.com/felixge/node-style-guide).
## Authors
```bash
$ git summary
project : cnpmjs.org
repo age : 4 months ago
commits : 472
active : 167 days
files : 104
authors :
272 fengmk2 57.6%
195 dead_horse 41.3%
2 4simple 0.4%
2 Stanley Zheng 0.4%
1 Alsotang 0.2%
```
## License
(The MIT License)

View File

@@ -15,11 +15,5 @@
*/
var config = require('../config');
var nfs = config.nfs;
if (!nfs) {
// use qnfs by default
nfs = require('./qnfs');
}
module.exports = nfs;
module.exports = config.nfs;

View File

@@ -1,83 +0,0 @@
/*!
* cnpmjs.org - common/qnfs.js
*
* Copyright(c) cnpmjs.org and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
*/
'use strict';
/**
* Module dependencies.
*/
var thunkify = require('thunkify-wrap');
var qn = require('qn');
var fs = require('fs');
var config = require('../config');
var client = qn.create(config.qn);
thunkify(client, ['delete', 'uploadFile', 'upload', 'download']);
exports._client = client;
/**
* Upload file
*
* @param {String} filepath
* @param {Object} options
* - {String} key
* - {Number} size
*/
exports.upload = function *(filepath, options) {
try {
yield client.delete(options.key);
} catch (err) {
// ignore error here
}
var res = yield client.uploadFile(filepath, {
key: options.key,
size: options.size
});
var url = res && res[0] ? res[0].url : '';
return { url: url };
};
exports.uploadBuffer = function *(buf, options) {
try {
yield client.delete(options.key);
} catch (err) {
// ignore error here
}
var res = yield client.upload(buf, {key: options.key});
var url = res && res[0] ? res[0].url : '';
return { url: url };
};
exports.url = function (key) {
return client.resourceURL(key);
};
exports.download = function* (key, filepath, options) {
var writeStream = fs.createWriteStream(filepath);
yield client.download(key, {
timeout: options.timeout,
writeStream: writeStream
});
};
exports.remove = function *(key) {
try {
return yield client.delete(key);
} catch (err) {
if (err.name === 'QiniuFileNotExistsError') {
return;
}
throw err;
}
};

View File

@@ -126,14 +126,10 @@ var config = {
// use for koa-limit module as storage
redis: null,
// package tarball store in qn by default
// qiniu cdn: http://www.qiniu.com/, it free for dev.
qn: {
accessKey: "5UyUq-l6jsWqZMU6tuQ85Msehrs3Dr58G-mCZ9rE",
secretKey: "YaRsPKiYm4nGUt8mdz2QxeV5Q_yaUzVxagRuWTfM",
bucket: "qiniu-sdk-test",
domain: "http://qiniu-sdk-test.qiniudn.com",
},
// package tarball store in local filesystem by default
nfs: require('fs-cnpm')({
dir: path.join(root, '.tmp', 'dist')
}),
// registry url name
registryHost: 'r.cnpmjs.org',
@@ -190,6 +186,9 @@ var config = {
syncConcurrency: 1,
// sync interval, default is 10 minutes
syncInterval: '10m',
// badge subject on http://shields.io/
badgeSubject: 'cnpm',
};
// load config/config.js, everything in config.js will cover the same key in index.js

View File

@@ -24,9 +24,9 @@ exports.total = function (name, callback) {
name = null;
}
var end = moment();
var start = end.clone().subtract('months', 1).startOf('month');
var lastday = end.clone().subtract('days', 1).format('YYYY-MM-DD');
var lastweekStart = end.clone().subtract('weeks', 1).startOf('week');
var start = end.clone().subtract(1, 'months').startOf('month');
var lastday = end.clone().subtract(1, 'days').format('YYYY-MM-DD');
var lastweekStart = end.clone().subtract(1, 'weeks').startOf('week');
var lastweekEnd = lastweekStart.clone().endOf('week').format('YYYY-MM-DD');
var lastmonthEnd = start.clone().endOf('month').format('YYYY-MM-DD');
var thismonthStart = end.clone().startOf('month').format('YYYY-MM-DD');

View File

@@ -32,7 +32,7 @@ exports.show = function *() {
total.instance_start_time = startTime;
total.node_version = process.version;
total.app_version = version;
total.donate = 'https://me.alipay.com/imk2';
total.donate = 'https://www.gittip.com/fengmk2';
total.sync_model = config.syncModel;
this.body = total;

47
controllers/web/badge.js Normal file
View File

@@ -0,0 +1,47 @@
/**!
* cnpmjs.org - controllers/web/badge.js
*
* Copyright(c) fengmk2 and other contributors.
* MIT Licensed
*
* Authors:
* fengmk2 <fengmk2@gmail.com> (http://fengmk2.github.com)
*/
'use strict';
/**
* Module dependencies.
*/
var config = require('../../config');
var Module = require('../../proxy/module');
exports.version = function* (next) {
var color = 'lightgrey';
var version = 'invalid';
var name = this.params[0];
var latestTag = yield* Module.getTag(name, 'latest');
if (latestTag) {
version = latestTag.version;
if (/^0\.0\./.test(version)) {
// <0.1.0 & >=0.0.0
color = 'red';
} else if (/^0\./.test(version)) {
// <1.0.0 & >=0.1.0
color = 'green';
} else {
// >=1.0.0
color = 'blue';
}
}
var url = 'https://img.shields.io/badge/' + config.badgeSubject + '-' + version + '-' + color + '.svg';
if (this.querystring) {
url += '?' + this.querystring;
} else {
url += '?style=flat-square';
}
this.redirect(url);
};

View File

@@ -161,6 +161,41 @@ exports.display = function* (next) {
pkg.name = orginalName;
}
// pkg.engines = {
// "python": ">= 0.11.9",
// "node": ">= 0.11.9",
// "node1": ">= 0.8.9",
// "node2": ">= 0.10.9",
// "node3": ">= 0.6.9",
// };
if (pkg.engines) {
for (var k in pkg.engines) {
var engine = String(pkg.engines[k] || '').trim();
var color = 'blue';
if (k.indexOf('node') === 0) {
color = 'yellowgreen';
var version = /(\d+\.\d+\.\d+)/.exec(engine);
if (version) {
version = version[0];
if (/^0\.11\.\d+/.test(version)) {
color = 'red';
} else if (/^0\.10\./.test(version) ||
/^0\.12\./.test(version) ||
/^0\.14\./.test(version) ||
/^[^0]+\./.test(version)) {
color = 'brightgreen';
}
}
}
pkg.engines[k] = {
version: engine,
title: k + ': ' + engine,
badgeURL: 'https://img.shields.io/badge/' + encodeURIComponent(k) +
'-' + encodeURIComponent(engine) + '-' + color + '.svg?style=flat-square',
};
}
}
yield this.render('package', {
title: 'Package - ' + pkg.name,
package: pkg,

View File

@@ -245,7 +245,9 @@ Content-Length: 2243
}
```
### Get a special version or tag package
### ~~Get a special version or tag package~~
__deprecated__
```
GET /:package/:tag_or_version
@@ -505,6 +507,7 @@ Status: 201 Created
### Remove one version from package
* Authentication required.
* In any delete, note that __the version number still cannot be reused__.
```
PUT /:package/-rev/:rev
@@ -512,6 +515,8 @@ PUT /:package/-rev/:rev
#### Input
Remove that specific version from the versions hash in the `PUT` body.
Example for removing `0.0.1` version:
```json
@@ -551,6 +556,25 @@ Status: 201 Created
}
```
### Remove all versions of a package
* Authentication required.
* In any delete, note that __the version number still cannot be reused__.
```
DELETE /:package/-rev/:rev
```
#### Response
```json
Status: 201 Created
{
"ok": true
}
```
### Remove a tgz file from package
* Authentication required.

View File

@@ -104,6 +104,16 @@ $(function () {
});
</script>
## Version Badge
Default style is `flat-square`.
Badge URL: `http://cnpmjs.org/badge/v/cnpmjs.org.svg` ![cnpmjs.org-badge](http://cnpmjs.org/badge/v/cnpmjs.org.svg)
* `<0.1.0 & >=0.0.0`: ![red-badge](https://img.shields.io/badge/cnpm-0.0.1-red.svg?style=flat-square)
* `<1.0.0 & >=0.1.0`: ![red-badge](https://img.shields.io/badge/cnpm-0.1.0-green.svg?style=flat-square)
* `>=1.0.0`: ![red-badge](https://img.shields.io/badge/cnpm-1.0.0-blue.svg?style=flat-square)
## Usage
use our npm client [cnpm](https://github.com/cnpm/cnpm)(More suitable with cnpmjs.org and gzip support), you can get our client through npm:

View File

@@ -1,6 +1,6 @@
{
"name": "cnpmjs.org",
"version": "1.2.2",
"version": "1.4.0",
"description": "Private npm registry and web for Enterprise, base on MySQL and Simple Store Service",
"main": "index.js",
"scripts": {
@@ -11,7 +11,7 @@
},
"dependencies": {
"bytes": "~1.0.0",
"cfork": "~1.0.1",
"cfork": "~1.1.0",
"cheerio": "~0.17.0",
"co": "~3.1.0",
"co-defer": "~0.1.0",
@@ -24,11 +24,12 @@
"debug": "~1.0.4",
"error-formater": "~1.0.3",
"eventproxy": "~0.3.1",
"fs-cnpm": "~1.0.2",
"giturl": "~0.0.3",
"graceful": "~0.1.0",
"gravatar": "~1.0.6",
"humanize-number": "~0.0.2",
"koa": "~0.9.0",
"koa": "~0.10.0",
"koa-limit": "~1.0.2",
"koa-markdown": "~0.0.3",
"koa-middlewares": "~1.2.0",
@@ -38,12 +39,11 @@
"mkdirp": "~0.5.0",
"moment": "~2.8.1",
"ms": "~0.6.2",
"multiline": "~0.3.4",
"multiline": "~1.0.0",
"mysql": "~2.4.2",
"nodemailer": "0.7.1",
"qn": "~0.2.2",
"ready": "~0.1.1",
"redis": "~0.11.0",
"redis": "~0.12.1",
"semver": "~3.0.1",
"thunkify-wrap": "~1.0.2",
"utility": "~1.0.0"

View File

@@ -762,3 +762,7 @@ exports.updateReadme = function* (id, readme) {
data.package.readme = readme;
return yield* exports.updatePackage(id, data.package);
};
exports.getTag = function* (name, tag) {
return yield mysql.queryOne(SELECT_TAG_SQL, [name, tag]);
};

View File

@@ -20,6 +20,7 @@ var user = require('../controllers/web/user');
var sync = require('../controllers/sync');
var total = require('../controllers/total');
var dist = require('../controllers/web/dist');
var badge = require('../controllers/web/badge');
function routes(app) {
app.get('/total', total.show);
@@ -51,6 +52,8 @@ function routes(app) {
app.get('/_list/search/search', pkg.rangeSearch);
app.get(/^\/dist(\/.*)?/, dist.list);
app.get(/^\/badge\/v\/([@\w\-\.\/]+)\.svg$/, badge.version);
}
module.exports = routes;

View File

@@ -15,7 +15,6 @@
*/
var debug = require('debug')('cnpmjs.org:sync:sync_all');
var eventproxy = require('eventproxy');
var ms = require('ms');
var utility = require('utility');
var config = require('../config');

View File

@@ -18,9 +18,8 @@ var config = require('../config');
var Npm = require('../proxy/npm');
var Module = require('../proxy/module');
var Total = require('../proxy/total');
var eventproxy = require('eventproxy');
var SyncModuleWorker = require('../proxy/sync_module_worker');
var debug = require('debug')('cnpmjs.org:sync:sync_hot');
var debug = require('debug')('cnpmjs.org:sync:sync_exist');
var utility = require('utility');
var Status = require('./status');
var ms = require('ms');

View File

@@ -779,11 +779,10 @@ describe('controllers/registry/module.test.js', function () {
});
describe('GET /:name/download/:filename', function () {
it('should download a file with 302 redirect', function (done) {
it('should download a file with 200', function (done) {
request(app)
.get('/cutter/download/cutter-0.0.2.tgz')
.expect('Location', config.qn.domain + '/cutter/-/cutter-0.0.2.tgz')
.expect(302, done);
.get('/mk2testmodule/download/mk2testmodule-0.0.1.tgz')
.expect(200, done);
});
});

View File

@@ -145,8 +145,7 @@ describe('controllers/registry/module/scope_package.test.js', function () {
it('should download work', function (done) {
request(app)
.get('/@cnpm/test-scope-package/download/@cnpm/test-scope-package-0.0.2.tgz')
.expect('Location', /\.tgz$/)
.expect(302, done);
.expect(200, done);
});
describe('support adaptScope', function () {

View File

@@ -0,0 +1,93 @@
/*!
* cnpmjs.org - test/controllers/web/badge.test.js
*
* Copyright(c) cnpmjs.org 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 mm = require('mm');
var path = require('path');
var pedding = require('pedding');
var mysql = require('../../../common/mysql');
var app = require('../../../servers/web');
var registry = require('../../../servers/registry');
var pkg = require('../../../controllers/web/package');
var utils = require('../../utils');
var config = require('../../../config');
var fixtures = path.join(path.dirname(path.dirname(__dirname)), 'fixtures');
describe('controllers/web/badge.test.js', function () {
before(function (done) {
done = pedding(2, done);
registry = registry.listen(0, done);
app = app.listen(0, done);
});
afterEach(mm.restore);
describe('GET /badge/v/:name.svg', function () {
it('should show blue version on >=1.0.0 when package exists', function (done) {
var pkg = utils.getPackage('badge-test-module', '1.0.1', utils.admin);
request(registry)
.put('/' + pkg.name)
.set('authorization', utils.adminAuth)
.send(pkg)
.end(function (err) {
should.not.exists(err);
request(app)
.get('/badge/v/badge-test-module.svg?style=flat-square')
.expect('Location', 'https://img.shields.io/badge/cnpm-1.0.1-blue.svg?style=flat-square')
.expect(302, done);
});
});
it('should show green version on <1.0.0 & >=0.1.0 when package exists', function (done) {
var pkg = utils.getPackage('badge-test-module', '0.1.0', utils.admin);
request(registry)
.put('/' + pkg.name)
.set('authorization', utils.adminAuth)
.send(pkg)
.end(function (err) {
should.not.exists(err);
request(app)
.get('/badge/v/badge-test-module.svg?style=flat-square')
.expect('Location', 'https://img.shields.io/badge/cnpm-0.1.0-green.svg?style=flat-square')
.expect(302, done);
});
});
it('should show green version on <0.1.0 & >=0.0.0 when package exists', function (done) {
var pkg = utils.getPackage('badge-test-module', '0.0.0', utils.admin);
request(registry)
.put('/' + pkg.name)
.set('authorization', utils.adminAuth)
.send(pkg)
.end(function (err) {
should.not.exists(err);
request(app)
.get('/badge/v/badge-test-module.svg?style=flat-square')
.expect('Location', 'https://img.shields.io/badge/cnpm-0.0.0-red.svg?style=flat-square')
.expect(302, done);
});
});
it('should show invalid when package not exists', function (done) {
request(app)
.get('/badge/v/badge-test-module-not-exists.svg?style=flat')
.expect('Location', 'https://img.shields.io/badge/cnpm-invalid-lightgrey.svg?style=flat')
.expect(302, done);
});
});
});

View File

@@ -18,6 +18,8 @@ var should = require('should');
var request = require('supertest');
var pedding = require('pedding');
var mm = require('mm');
var fs = require('fs');
var nfs = require('../../../common/nfs');
var app = require('../../../servers/web');
var Dist = require('../../../proxy/dist');
@@ -127,7 +129,7 @@ describe('controllers/web/dist.test.js', function () {
url: '/dist/v0.10.28/SHASUMS.txt'
};
});
fs.writeFileSync(nfs._getpath('/dist/v0.10.28/SHASUMS.txt'), '6eff580cc8460741155d42ef1ef537961194443f');
request(app)
.get('/dist/v0.10.28/SHASUMS.txt')
.expect(200)

View File

@@ -16,34 +16,40 @@
var should = require('should');
var Dist = require('../../proxy/dist');
var fs = require('fs');
var nfs = require('../../common/nfs');
describe('proxy/dist.test.js', function () {
describe('savefile() and getfile', function () {
it('should save and get /npm-versions.txt', function* () {
var name = 'npm-versions.txt';
var info = {
name: 'npm-versions.txt',
name: name,
parent: '/',
date: '15-Sep-2011 23:48',
size: 1676,
url: 'http://cnpmjs.org/dist/npm-versions.txt',
url: name,
sha1: '104731881047318810473188'
};
yield* Dist.savefile(info);
fs.writeFileSync(nfs._getpath('npm-versions.txt'), 'npm version');
var got = yield* Dist.getfile('/npm-versions.txt');
should.exist(got);
got.should.eql(info);
});
it('should save and get /v1.0.0/npm-versions.txt', function* () {
var name = 'v1.0.0/npm-versions.txt';
var info = {
name: 'npm-versions.txt',
parent: '/v1.0.0/',
date: '15-Sep-2011 23:48',
size: 1676,
url: 'http://cnpmjs.org/dist/v1.0.0/npm-versions.txt',
url: 'v1.0.0/npm-versions.txt',
sha1: '104731881047318810473188'
};
yield* Dist.savefile(info);
fs.writeFileSync(nfs._getpath('npm-versions.txt'), 'npm version 1.0.0');
var got = yield* Dist.getfile('/v1.0.0/npm-versions.txt');
should.exist(got);
got.should.eql(info);

83
tools/sync_not_exist.js Normal file
View File

@@ -0,0 +1,83 @@
/*!
* cnpmjs.org - tools/sync_not_exist.js
*
* Copyright(c) cnpmjs.org and other contributors.
* MIT Licensed
*
* Authors:
* dead_horse <dead_horse@qq.com> (http://deadhorse.me)
*/
'use strict';
/**
* Module dependencies.
*/
var debug = require('debug')('cnpmjs.org:tools:sync_not_exist');
var SyncModuleWorker = require('../proxy/sync_module_worker');
var thunkify = require('thunkify-wrap');
var Module = require('../proxy/module');
var config = require('../config');
var Npm = require('../proxy/npm');
var utility = require('utility');
var co = require('co');
function subtraction(arrOne, arrTwo) {
arrOne = arrOne || [];
arrTwo = arrTwo || [];
var map = {};
var results = [];
arrTwo.forEach(function (name) {
map[name] = true;
});
arrOne.forEach(function (name) {
!map[name] && results.push(name);
});
return results;
}
function *sync(conf) {
if (conf) {
debug('load custom config');
config.loadConfig(conf);
}
var allExists = yield Module.listShort();
var existPackages = allExists.map(function (p) {
return p.name;
});
var allPackages = yield Npm.getShort();
var packages = subtraction(allPackages, existPackages);
if (!packages.length) {
debug('no packages need be sync');
return;
}
debug('Total %d packages to sync', packages.length);
var worker = new SyncModuleWorker({
username: 'admin',
name: packages,
concurrency: config.syncConcurrency
});
worker.start();
var end = thunkify.event(worker);
yield end();
debug('All packages sync done, successes %d, fails %d',
worker.successes.length, worker.fails.length);
return {
successes: worker.successes,
fails: worker.fails
};
}
module.exports = function (config, callback) {
co(sync(config))(callback);
};
if (!module.parent) {
console.log('[tools/sync_not_exist.js] start sync not exist modules');
module.exports();
}

View File

@@ -1,6 +1,7 @@
<div id="package">
<h1>
<%= package.name %>
<img title="<%= package.version %>" src="/badge/v/<%= package.name %>.svg?style=flat-square">
<small>
<% if (package._publish_on_cnpm) { %>
(Private package)
@@ -76,9 +77,7 @@
<tr>
<th>Version</th>
<td>
<b>
<%= package.version %>
</b>
<img title="<%= package.version %>" src="/badge/v/<%= package.name %>.svg?style=flat-square">
<% if (package.fromNow) { %>
last updated
<%= package.fromNow %>
@@ -89,11 +88,11 @@
<tr>
<th>Engines</th>
<td>
<ul>
<% for (var k in package.engines) { %>
<li><%= k %>: <%= package.engines[k] %></li>
<% } %>
</ul>
<% for (var k in package.engines) {
var engine = package.engines[k];
%>
<img title="<%= engine.title %>" src="<%- engine.badgeURL %>">
<% } %>
</td>
</tr>
<% } %>