0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-16 21:56:25 -05:00

Merge remote-tracking branch 'origin/0.9.x'

Conflicts:
	lib/local-storage.js
This commit is contained in:
Alex Kocharin 2014-08-08 05:12:42 +04:00
commit 57d6fe7150
8 changed files with 193 additions and 43 deletions

View file

@ -49,7 +49,12 @@ Storage.prototype._internal_error = function(err, file, message) {
}
Storage.prototype.add_package = function(name, info, callback) {
this.storage(name).create_json(info_file, get_boilerplate(name), function(err) {
var storage = this.storage(name)
if (!storage) return callback(new UError({
status: 404,
message: 'this package cannot be added'
}))
storage.create_json(info_file, get_boilerplate(name), function(err) {
if (err && err.code === 'EEXISTS') {
return callback(new UError({
status: 409,
@ -67,7 +72,13 @@ Storage.prototype.add_package = function(name, info, callback) {
Storage.prototype.remove_package = function(name, callback) {
var self = this
self.logger.info({name: name}, 'unpublishing @{name} (all)')
self.storage(name).read_json(info_file, function(err, data) {
var storage = self.storage(name)
if (!storage) return callback(new UError({
status: 404,
message: 'no such package available',
}))
storage.read_json(info_file, function(err, data) {
if (err) {
if (err.code === 'ENOENT') {
return callback(new UError({
@ -80,7 +91,7 @@ Storage.prototype.remove_package = function(name, callback) {
}
self._normalize_package(data)
self.storage(name).unlink(info_file, function(err) {
storage.unlink(info_file, function(err) {
if (err) return callback(err)
var files = Object.keys(data._attachments)
@ -89,14 +100,14 @@ Storage.prototype.remove_package = function(name, callback) {
if (files.length === 0) return cb()
var file = files.shift()
self.storage(name).unlink(file, function() {
storage.unlink(file, function() {
unlinkNext(cb)
})
}
unlinkNext(function() {
// try to unlink the directory, but ignore errors because it can fail
self.storage(name).rmdir('.', function(err) {
storage.rmdir('.', function(err) {
callback(err)
});
});
@ -109,7 +120,13 @@ Storage.prototype.remove_package = function(name, callback) {
Storage.prototype._read_create_package = function(name, callback) {
var self = this
self.storage(name).read_json(info_file, function(err, data) {
var storage = self.storage(name)
if (!storage) {
var data = get_boilerplate(name)
self._normalize_package(data)
return callback(null, data)
}
storage.read_json(info_file, function(err, data) {
// TODO: race condition
if (err) {
if (err.code === 'ENOENT') {
@ -303,7 +320,8 @@ Storage.prototype.remove_tarball = function(name, filename, revision, callback)
}
}, function(err) {
if (err) return callback(err)
self.storage(name).unlink(filename, callback)
var storage = self.storage(name)
if (storage) storage.unlink(filename, callback)
})
}
@ -315,6 +333,8 @@ Storage.prototype.add_tarball = function(name, filename) {
, length = 0
, shasum = crypto.createHash('sha1')
stream.abort = stream.done = function(){}
stream._transform = function(data) {
shasum.update(data)
length += data.length
@ -323,13 +343,27 @@ Storage.prototype.add_tarball = function(name, filename) {
var self = this
if (name === info_file || name === '__proto__') {
stream.emit('error', new UError({
status: 403,
message: 'can\'t use this filename'
}))
process.nextTick(function() {
stream.emit('error', new UError({
status: 403,
message: 'can\'t use this filename'
}))
})
return stream
}
var wstream = this.storage(name).write_stream(filename)
var storage = self.storage(name)
if (!storage) {
process.nextTick(function() {
stream.emit('error', new UError({
status: 404,
message: 'can\'t upload this package'
}))
})
return stream
}
var wstream = storage.write_stream(filename)
wstream.on('error', function(err) {
if (err.code === 'EEXISTS') {
@ -425,13 +459,25 @@ Storage.prototype.get_readme = function(name, version, callback) {
Storage.prototype.get_tarball = function(name, filename, callback) {
assert(utils.validate_name(filename))
var self = this
var stream = new mystreams.ReadTarballStream()
stream.abort = function() {
rstream.abort()
if (rstream) rstream.abort()
}
var rstream = this.storage(name).read_stream(filename)
var storage = self.storage(name)
if (!storage) {
process.nextTick(function() {
stream.emit('error', new UError({
status: 404,
message: 'no such file available',
}))
})
return stream
}
var rstream = storage.read_stream(filename)
rstream.on('error', function(err) {
if (err && err.code === 'ENOENT') {
stream.emit('error', new UError({
@ -457,8 +503,13 @@ Storage.prototype.get_package = function(name, options, callback) {
if (typeof(options) === 'function') callback = options, options = {}
var self = this
var storage = self.storage(name)
if (!storage) return callback(new UError({
status: 404,
message: 'no such package available'
}))
self.storage(name).read_json(info_file, function(err, result) {
storage.read_json(info_file, function(err, result) {
if (err) {
if (err.code === 'ENOENT') {
return callback(new UError({
@ -478,13 +529,17 @@ Storage.prototype.get_recent_packages = function(startkey, callback) {
var self = this
var i = 0
var list = []
fs.readdir(self.storage('').path, function(err, files) {
var storage = self.storage('')
if (!storage) return callback(null, [])
fs.readdir(storage.path, function(err, files) {
if (err) return callback(null, [])
var filesL = files.length
files.forEach(function(file) {
fs.stat(self.storage(file).path, function(err, stats) {
fs.stat(storage.path, function(err, stats) {
if (err) return callback(err)
if (stats.mtime > startkey) {
list.push({
@ -519,7 +574,12 @@ Storage.prototype.get_recent_packages = function(startkey, callback) {
//
Storage.prototype.update_package = function(name, updateFn, _callback) {
var self = this
self.storage(name).lock_and_read_json(info_file, function(err, fd, json) {
var storage = self.storage(name)
if (!storage) return callback(new UError({
status: 404,
message: 'no such package available',
}))
storage.lock_and_read_json(info_file, function(err, fd, json) {
function callback() {
var _args = arguments
if (fd) {
@ -571,16 +631,21 @@ Storage.prototype._write_package = function(name, json, callback) {
var rev = json._rev.split('-')
json._rev = ((+rev[0] || 0) + 1) + '-' + crypto.pseudoRandomBytes(8).toString('hex')
this.storage(name).write_json(info_file, json, callback)
var storage = this.storage(name)
if (!storage) return callback()
storage.write_json(info_file, json, callback)
}
Storage.prototype.storage = function(package) {
var path = this.config.get_package_setting(package, 'storage')
if (path == null) path = this.config.storage
if (path == null || path === false) {
this.logger.debug({name: package}, 'this package has no storage defined: @{name}')
return null
}
return new Path_Wrapper(
Path.join(
Path.resolve(
Path.dirname(this.config.self_path),
this.config.get_package_setting(package, 'storage') || this.config.storage
),
Path.resolve(Path.dirname(this.config.self_path), path),
package
)
)

View file

@ -255,26 +255,32 @@ Storage.prototype.get_tarball = function(name, filename) {
}
var savestream = self.local.add_tarball(name, filename)
savestream.on('error', function(err) {
savestream.abort()
stream.emit('error', err)
})
savestream.on('open', function() {
function on_open() {
var rstream2 = uplink.get_url(file.url)
rstream2.on('error', function(err) {
savestream.abort()
if (savestream) savestream.abort()
savestream = null
stream.emit('error', err)
})
rstream2.on('end', function() {
savestream.done()
if (savestream) savestream.done()
})
rstream2.on('content-length', function(v) {
stream.emit('content-length', v)
savestream.emit('content-length', v)
if (savestream) savestream.emit('content-length', v)
})
rstream2.pipe(stream)
rstream2.pipe(savestream)
if (savestream) rstream2.pipe(savestream)
}
savestream.on('open', function() {
on_open()
})
savestream.on('error', function() {
if (savestream) savestream.abort()
savestream = null
on_open()
})
}
}

View file

@ -75,7 +75,7 @@ keywords:
- server
scripts:
test: mocha ./test/functional ./test/unit
test: mocha -R dot ./test/functional ./test/unit
lint: eslint -c ./.eslint.yaml ./lib
prepublish: js-yaml package.yaml > package.json

View file

@ -37,6 +37,12 @@ packages:
allow_publish: all
proxy_access: express
'test-nullstorage*':
allow_access: all
allow_publish: all
proxy_access: server2
storage: false
'baduplink':
allow_access: all
allow_publish: all

View file

@ -28,6 +28,10 @@ packages:
allow_publish: test anonymous
proxy_access: server1
'test-nullstorage*':
allow_access: all
allow_publish: all
'*':
allow_access: test anonymous
allow_publish: test anonymous

View file

@ -43,6 +43,7 @@ describe('Func', function() {
require('./incomplete')()
require('./mirror')()
require('./newnpmreg')()
require('./nullstorage')()
require('./race')()
require('./racycrash')()
require('./security')()

View file

@ -0,0 +1,78 @@
require('./lib/startup')
var assert = require('assert')
, async = require('async')
, crypto = require('crypto')
function readfile(x) {
return require('fs').readFileSync(__dirname + '/' + x)
}
module.exports = function() {
var server = process.server
var server2 = process.server2
it('trying to fetch non-existent package / null storage', function(cb) {
server.get_package('test-nullstorage-nonexist', function(res, body) {
assert.equal(res.statusCode, 404)
assert(~body.error.indexOf('no such package'))
cb()
})
})
describe('test-nullstorage on server2', function() {
before(server2.add_package.bind(server2, 'test-nullstorage2'))
it('creating new package - server2', function(){/* test for before() */})
it('downloading non-existent tarball', function(cb) {
server.get_tarball('test-nullstorage2', 'blahblah', function(res, body) {
assert.equal(res.statusCode, 404)
assert(~body.error.indexOf('no such file'))
cb()
})
})
describe('tarball', function() {
before(function(cb) {
server2.put_tarball('test-nullstorage2', 'blahblah', readfile('fixtures/binary'), function(res, body) {
assert.equal(res.statusCode, 201)
assert(body.ok)
cb()
})
})
before(function(cb) {
var pkg = require('./lib/package')('test-nullstorage2')
pkg.dist.shasum = crypto.createHash('sha1').update(readfile('fixtures/binary')).digest('hex')
server2.put_version('test-nullstorage2', '0.0.1', pkg, function(res, body) {
assert.equal(res.statusCode, 201)
assert(~body.ok.indexOf('published'))
cb()
})
})
it('uploading new tarball', function(){/* test for before() */})
it('downloading newly created tarball', function(cb) {
server.get_tarball('test-nullstorage2', 'blahblah', function(res, body) {
assert.equal(res.statusCode, 200)
assert.deepEqual(body, readfile('fixtures/binary').toString('utf8'))
cb()
})
})
it('downloading newly created package', function(cb) {
server.get_package('test-nullstorage2', function(res, body) {
assert.equal(res.statusCode, 200)
assert.equal(body.name, 'test-nullstorage2')
assert.equal(body.versions['0.0.1'].name, 'test-nullstorage2')
assert.equal(body.versions['0.0.1'].dist.tarball, 'http://localhost:55551/test-nullstorage2/-/blahblah')
assert.deepEqual(body['dist-tags'], {latest: '0.0.1'})
cb()
})
})
})
})
}

View file

@ -1,10 +0,0 @@
#!/bin/sh
CWD=$(pwd)
PATH='../node_modules/.bin':$PATH
TESTDIR=$(dirname $0)
cd $TESTDIR
mocha ./functional ./unit
TESTRES=$?
cd $CWD
exit $TESTRES