3 owner.usage = "npm owner add <username> <pkg>"
4 + "\nnpm owner rm <username> <pkg>"
5 + "\nnpm owner ls <pkg>"
7 var npm = require("./npm.js")
8 , log = require("npmlog")
9 , mapToRegistry = require("./utils/map-to-registry.js")
10 , readLocalPkg = require("./utils/read-local-package.js")
12 owner.completion = function (opts, cb) {
13 var argv = opts.conf.argv.remain
14 if (argv.length > 4) return cb()
15 if (argv.length <= 2) {
16 var subs = ["add", "rm"]
17 if (opts.partialWord === "l") subs.push("ls")
18 else subs.push("ls", "list")
22 npm.commands.whoami([], true, function (er, username) {
25 var un = encodeURIComponent(username)
29 // FIXME: there used to be registry completion here, but it stopped
30 // making sense somewhere around 50,000 packages on the registry
34 if (argv.length > 3) {
35 theUser = encodeURIComponent(argv[3])
36 byUser = "-/by-user/" + theUser + "|" + un
37 return mapToRegistry(byUser, npm.config, function (er, uri, auth) {
41 npm.registry.get(uri, { auth : auth }, function (er, d) {
43 // return the intersection
44 return cb(null, d[theUser].filter(function (p) {
45 // kludge for server adminery.
46 return un === "isaacs" || d[un].indexOf(p) === -1
53 if (argv.length > 3) {
54 theUser = encodeURIComponent(argv[3])
55 byUser = "-/by-user/" + theUser + "|" + un
56 return mapToRegistry(byUser, npm.config, function (er, uri, auth) {
60 npm.registry.get(uri, { auth : auth }, function (er, d) {
61 console.error(uri, er || d)
62 // return mine that they're not already on.
64 var mine = d[un] || []
65 , theirs = d[theUser] || []
66 return cb(null, mine.filter(function (p) {
67 return theirs.indexOf(p) === -1
72 // just list all users who aren't me.
73 return mapToRegistry("-/users", npm.config, function (er, uri, auth) {
76 npm.registry.get(uri, { auth : auth }, function (er, list) {
78 return cb(null, Object.keys(list).filter(function (n) {
90 function owner (args, cb) {
91 var action = args.shift()
93 case "ls": case "list": return ls(args[0], cb)
94 case "add": return add(args[0], args[1], cb)
95 case "rm": case "remove": return rm(args[0], args[1], cb)
96 default: return unknown(action, cb)
100 function ls (pkg, cb) {
101 if (!pkg) return readLocalPkg(function (er, pkg) {
102 if (er) return cb(er)
103 if (!pkg) return cb(owner.usage)
107 mapToRegistry(pkg, npm.config, function (er, uri, auth) {
108 if (er) return cb(er)
110 npm.registry.get(uri, { auth : auth }, function (er, data) {
113 log.error("owner ls", "Couldn't get owner data", pkg)
116 var owners = data.maintainers
117 if (!owners || !owners.length) msg = "admin party!"
118 else msg = owners.map(function (o) {
119 return o.name + " <" + o.email + ">"
127 function add (user, pkg, cb) {
128 if (!user) return cb(owner.usage)
129 if (!pkg) return readLocalPkg(function (er, pkg) {
130 if (er) return cb(er)
131 if (!pkg) return cb(new Error(owner.usage))
135 log.verbose("owner add", "%s to %s", user, pkg)
136 mutate(pkg, user, function (u, owners) {
137 if (!owners) owners = []
138 for (var i = 0, l = owners.length; i < l; i ++) {
140 if (o.name === u.name) {
141 log.info( "owner add"
142 , "Already a package owner: " + o.name + " <" + o.email + ">")
151 function rm (user, pkg, cb) {
152 if (!pkg) return readLocalPkg(function (er, pkg) {
153 if (er) return cb(er)
154 if (!pkg) return cb(new Error(owner.usage))
158 log.verbose("owner rm", "%s from %s", user, pkg)
159 mutate(pkg, user, function (u, owners) {
161 , m = owners.filter(function (o) {
162 var match = (o.name === user)
163 found = found || match
167 log.info("owner rm", "Not a package owner: " + user)
170 if (!m.length) return new Error(
171 "Cannot remove all owners of a package. Add someone else first.")
176 function mutate (pkg, user, mutation, cb) {
178 var byUser = "-/user/org.couchdb.user:" + user
179 mapToRegistry(byUser, npm.config, function (er, uri, auth) {
180 if (er) return cb(er)
182 npm.registry.get(uri, { auth : auth }, mutate_)
188 function mutate_ (er, u) {
189 if (!er && user && (!u || u.error)) er = new Error(
190 "Couldn't get user data for " + user + ": " + JSON.stringify(u))
193 log.error("owner mutate", "Error getting user data for %s", user)
197 if (u) u = { "name" : u.name, "email" : u.email }
198 mapToRegistry(pkg, npm.config, function (er, uri, auth) {
199 if (er) return cb(er)
201 npm.registry.get(uri, { auth : auth }, function (er, data) {
203 log.error("owner mutate", "Error getting package data for %s", pkg)
207 // save the number of maintainers before mutation so that we can figure
208 // out if maintainers were added or removed
209 var beforeMutation = data.maintainers.length
211 var m = mutation(u, data.maintainers)
212 if (!m) return cb() // handled
213 if (m instanceof Error) return cb(m) // error
220 var dataPath = pkg.replace("/", "%2f") + "/-rev/" + data._rev
221 mapToRegistry(dataPath, npm.config, function (er, uri, auth) {
222 if (er) return cb(er)
229 npm.registry.request(uri, params, function (er, data) {
230 if (!er && data.error) {
231 er = new Error("Failed to update package metadata: "+JSON.stringify(data))
235 log.error("owner mutate", "Failed to update package metadata")
237 else if (m.length > beforeMutation) {
238 console.log("+ %s (%s)", user, pkg)
240 else if (m.length < beforeMutation) {
241 console.log("- %s (%s)", user, pkg)
252 function unknown (action, cb) {
253 cb("Usage: \n" + owner.usage)