Skip to content
This repository has been archived by the owner on Aug 11, 2022. It is now read-only.

Multiple registry support (re: #1401) #3093

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 13 additions & 1 deletion lib/config.js
Expand Up @@ -48,6 +48,12 @@ config.completion = function (opts, cb) {
// npm config list
function config (args, cb) {
var action = args.shift()

// Config for registry can be whitespace separated, support that here by treating them as one 'value'
if (action=='set' && args[0] === 'registry' && args.length >2){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just require that the user quote the value? npm config set registry "http://foo.com http://bar.com" etc?

args = [args[0], args.slice(1, args.length).join(' ')]
}

switch (action) {
case "set": return set(args[0], args[1], cb)
case "get": return get(args[0], cb)
Expand Down Expand Up @@ -129,11 +135,17 @@ function set (key, val, cb) {
}

function get (key, cb) {
debugger;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this, please.

if (!key) return list(cb)
if (key.charAt(0) === "_") {
return cb(new Error("---sekretz---"))
}
console.log(npm.config.get(key))
var val = npm.config.get(key)
// TODO: Add support to npmconf for whitespace separated URls..
if (val && val.indexOf('%20')!==-1){
val = val.replace('%20', ' ')
}
console.log(val)
cb()
}

Expand Down
17 changes: 16 additions & 1 deletion lib/npm.js
Expand Up @@ -30,6 +30,7 @@ var EventEmitter = require("events").EventEmitter
, slide = require("slide")
, chain = slide.chain
, RegClient = require("npm-registry-client")
, RegManager = require('./registry-manager.js')

npm.config = {loaded: false}

Expand Down Expand Up @@ -313,7 +314,21 @@ function load (npm, cli, cb) {
} catch (e) { token = null }
}

npm.registry = new RegClient(npm.config)
// split registries here, then pass each new RegClient a registry, cache, log config
var registries = npm.config.get('registry')
registries = registries.split(/%20+| /)

npm.registries = []
var r
for (var i=0; i<registries.length; i++){
r = registries[i],
npm.registries.push(new RegClient({
cache: npm.config.get('cache'),
log : npm.config.get('log'),
registry : r
}));
}
npm.registry = new RegManager(npm.registries)

// save the token cookie in the config file
if (npm.registry.couchLogin) {
Expand Down
44 changes: 44 additions & 0 deletions lib/registry-manager.js
@@ -0,0 +1,44 @@

// Registry manager - makes npm.registry's functions allow a retry

module.exports = RegManager


function RegManager(registries) {
if (!registries || registries.length<1){
throw new Error("No registries have been supplied to the registry manager")
}

var idx = 0,
primaryRegistry = registries[0],
i;

for (var key in primaryRegistry){
// No .hasOwnProperty check - we want the prototype chain!
this[key] = primaryRegistry[key];
}
this.get = function(){
// First attempt at overriding get function - long term this
// may not be enough. Maybe, the whole NPM install|search|whatever
// command needs to be retried from scratch if it's falling back to
// another registry..
var args = arguments,
i, _cb
// Pluck out the callback from the arguments & intercept it
for (i=0; i<arguments.length; i++){
if (typeof arguments[i] == 'function'){
_cb = arguments[i]
arguments[i] = function(err, data){
// If the error is 'just' a 404, and there are registries still left to try, let's try them
if (err && err.code && err.code === "E404" && ++idx<registries.length){
return registries[idx].get.apply(registries[idx], args);
}else{
// Either we've succeeded, we're out of registries, or it's an error we can't deal with
return _cb(err, data)
}
}
}
}
registries[idx].get.apply(this, arguments)
}
}