@ -3,11 +3,10 @@
/ *
/ *
adding a folder :
adding a folder :
1. tar into tmp / random / package . tgz
1. tar into tmp / random / package . tgz
2. untar into tmp / random / contents / { blah }
2. untar into tmp / random / contents / package , stripping one dir piece
3. rename { blah } to "package"
3. tar tmp / random / contents / package to cache / n / v / package . tgz
4. tar tmp / random / contents / package to cache / n / v / package . tgz
4. untar cache / n / v / package . tgz into cache / n / v / package
5. untar cache / n / v / package . tgz into cache / n / v / package
5. rm tmp / random
6. rm tmp / random
Adding a url :
Adding a url :
1. fetch to tmp / random / package . tgz
1. fetch to tmp / random / package . tgz
@ -32,7 +31,7 @@ exports.read = read
exports . clean = clean
exports . clean = clean
exports . unpack = unpack
exports . unpack = unpack
var mkdir = require ( "./utils/ mkdir- p.js " )
var mkdir = require ( "mkdirp" )
, exec = require ( "./utils/exec.js" )
, exec = require ( "./utils/exec.js" )
, fetch = require ( "./utils/fetch.js" )
, fetch = require ( "./utils/fetch.js" )
, npm = require ( "./npm.js" )
, npm = require ( "./npm.js" )
@ -50,6 +49,7 @@ var mkdir = require("./utils/mkdir-p.js")
, tar = require ( "./utils/tar.js" )
, tar = require ( "./utils/tar.js" )
, fileCompletion = require ( "./utils/completion/file-completion.js" )
, fileCompletion = require ( "./utils/completion/file-completion.js" )
, url = require ( "url" )
, url = require ( "url" )
, chownr = require ( "chownr" )
cache . usage = "npm cache add <tarball file>"
cache . usage = "npm cache add <tarball file>"
+ "\nnpm cache add <folder>"
+ "\nnpm cache add <folder>"
@ -95,12 +95,10 @@ function cache (args, cb) {
// if the pkg and ver are in the cache, then
// if the pkg and ver are in the cache, then
// just do a readJson and return.
// just do a readJson and return.
// if they're not, then fetch them from the registry.
// if they're not, then fetch them from the registry.
var cacheSeen = { }
function read ( name , ver , forceBypass , cb ) {
function read ( name , ver , forceBypass , cb ) {
if ( typeof cb !== "function" ) cb = forceBypass , forceBypass = true
if ( typeof cb !== "function" ) cb = forceBypass , forceBypass = true
var jsonFile = path . join ( npm . cache , name , ver , "package" , "package.json" )
var jsonFile = path . join ( npm . cache , name , ver , "package" , "package.json" )
function c ( er , data ) {
function c ( er , data ) {
if ( ! er ) cacheSeen [ data . _ id ] = data
if ( data ) deprCheck ( data )
if ( data ) deprCheck ( data )
return cb ( er , data )
return cb ( er , data )
}
}
@ -110,10 +108,6 @@ function read (name, ver, forceBypass, cb) {
return addNamed ( name , ver , c )
return addNamed ( name , ver , c )
}
}
if ( name + "@" + ver in cacheSeen ) {
return cb ( null , cacheSeen [ name + "@" + ver ] )
}
readJson ( jsonFile , function ( er , data ) {
readJson ( jsonFile , function ( er , data ) {
if ( er ) return addNamed ( name , ver , c )
if ( er ) return addNamed ( name , ver , c )
deprCheck ( data )
deprCheck ( data )
@ -126,9 +120,13 @@ function ls (args, cb) {
output = output || require ( "./utils/output.js" )
output = output || require ( "./utils/output.js" )
args = args . join ( "/" ) . split ( "@" ) . join ( "/" )
args = args . join ( "/" ) . split ( "@" ) . join ( "/" )
if ( args . substr ( - 1 ) === "/" ) args = args . substr ( 0 , args . length - 1 )
if ( args . substr ( - 1 ) === "/" ) args = args . substr ( 0 , args . length - 1 )
var prefix = npm . config . get ( "cache" )
if ( 0 === prefix . indexOf ( process . env . HOME ) ) {
prefix = "~" + prefix . substr ( process . env . HOME . length )
}
ls_ ( args , npm . config . get ( "depth" ) , function ( er , files ) {
ls_ ( args , npm . config . get ( "depth" ) , function ( er , files ) {
output . write ( files . map ( function ( f ) {
output . write ( files . map ( function ( f ) {
return path . join ( "~/.npm" , f )
return path . join ( prefix , f )
} ) . join ( "\n" ) . trim ( ) , function ( er ) {
} ) . join ( "\n" ) . trim ( ) , function ( er ) {
return cb ( er , files )
return cb ( er , files )
} )
} )
@ -212,7 +210,7 @@ function add (args, cb) {
// see if the spec is a url
// see if the spec is a url
// otherwise, treat as name@version
// otherwise, treat as name@version
var p = url . parse ( spec . replace ( /^git\+/ , "git" ) ) || { }
var p = url . parse ( spec ) || { }
log . verbose ( p , "parsed url" )
log . verbose ( p , "parsed url" )
// it could be that we got name@http://blah
// it could be that we got name@http://blah
@ -230,11 +228,11 @@ function add (args, cb) {
case "https:" :
case "https:" :
return addRemoteTarball ( spec , null , name , cb )
return addRemoteTarball ( spec , null , name , cb )
case "git:" :
case "git:" :
case "githttp:" :
case "git+ http:" :
case "githttps:" :
case "git+ https:" :
case "gitrsync:" :
case "git+ rsync:" :
case "gitftp:" :
case "git+ ftp:" :
case "gitssh:" :
case "git+ ssh:" :
//p.protocol = p.protocol.replace(/^git([^:])/, "$1")
//p.protocol = p.protocol.replace(/^git([^:])/, "$1")
return addRemoteGit ( spec , p , name , cb )
return addRemoteGit ( spec , p , name , cb )
default :
default :
@ -636,7 +634,7 @@ function getCacheStat (cb) {
}
}
function makeCacheDir ( cb ) {
function makeCacheDir ( cb ) {
if ( ! process . getuid ) return mkdir ( npm . cache , npm . modes . exec , cb )
if ( ! process . getuid ) return mkdir ( npm . cache , cb )
var uid = + process . getuid ( )
var uid = + process . getuid ( )
, gid = + process . getgid ( )
, gid = + process . getgid ( )
@ -647,18 +645,28 @@ function makeCacheDir (cb) {
}
}
if ( uid !== 0 || ! process . env . HOME ) {
if ( uid !== 0 || ! process . env . HOME ) {
cacheStat = { uid : uid , gid : gid }
cacheStat = { uid : uid , gid : gid }
return mkdir ( npm . cache , npm . modes . exec , uid , gid , function ( er ) {
return mkdir ( npm . cache , afterMkdir )
return cb ( er , cacheStat )
} )
}
}
fs . stat ( process . env . HOME , function ( er , st ) {
fs . stat ( process . env . HOME , function ( er , st ) {
if ( er ) return log . er ( cb , "homeless?" ) ( er )
if ( er ) return log . er ( cb , "homeless?" ) ( er )
cacheStat = st
cacheStat = st
log . silly ( [ st . uid , st . gid ] , "uid, gid for cache dir" )
log . silly ( [ st . uid , st . gid ] , "uid, gid for cache dir" )
return mkdir ( npm . cache , npm . modes . exec , st . uid , st . gid , function ( er ) {
return mkdir ( npm . cache , afterMkdir )
} )
function afterMkdir ( er , made ) {
if ( er || ! cacheStat || isNaN ( cacheStat . uid ) || isNaN ( cacheStat . gid ) ) {
return cb ( er , cacheStat )
}
if ( ! made ) return cb ( er , cacheStat )
// ensure that the ownership is correct.
chownr ( made , cacheStat . uid , cacheStat . gid , function ( er ) {
return cb ( er , cacheStat )
return cb ( er , cacheStat )
} )
} )
} )
}
}
}
@ -736,9 +744,20 @@ function addLocalDirectory (p, name, cb) {
, tgz = placeDirect ? placed : tmptgz
, tgz = placeDirect ? placed : tmptgz
, doFancyCrap = p . indexOf ( npm . tmp ) !== 0
, doFancyCrap = p . indexOf ( npm . tmp ) !== 0
&& p . indexOf ( npm . cache ) !== 0
&& p . indexOf ( npm . cache ) !== 0
tar . pack ( tgz , p , data , doFancyCrap , function ( er ) {
getCacheStat ( function ( er , cs ) {
if ( er ) return log . er ( cb , "couldn't pack " + p + " to " + tgz ) ( er )
mkdir ( path . dirname ( tgz ) , function ( er , made ) {
addLocalTarball ( tgz , name , cb )
if ( er ) return cb ( er )
tar . pack ( tgz , p , data , doFancyCrap , function ( er ) {
if ( er ) return log . er ( cb , "couldn't pack " + p + " to " + tgz ) ( er )
if ( er || ! cs || isNaN ( cs . uid ) || isNaN ( cs . gid ) ) return cb ( )
chownr ( made || tgz , cs . uid , cs . gid , function ( er ) {
if ( er ) return cb ( er )
addLocalTarball ( tgz , name , cb )
} )
} )
} )
} )
} )
} )
} )
}
}
@ -747,38 +766,15 @@ function addTmpTarball (tgz, name, cb) {
if ( ! cb ) cb = name , name = ""
if ( ! cb ) cb = name , name = ""
getCacheStat ( function ( er , cs ) {
getCacheStat ( function ( er , cs ) {
if ( er ) return cb ( er )
if ( er ) return cb ( er )
return addTmpTarball_ ( tgz , name , cs . uid , cs . gid , cb )
var contents = path . dirname ( tgz )
} )
tar . unpack ( tgz , path . resolve ( contents , "package" )
}
, null , null
, cs . uid , cs . gid
function addTmpTarball_ ( tgz , name , uid , gid , cb ) {
, function ( er ) {
var contents = path . dirname ( tgz )
if ( er ) {
tar . unpack ( tgz , path . resolve ( contents , "package" )
return cb ( er )
, null , null
, uid , gid
, function ( er ) {
if ( er ) {
return cb ( er )
}
fs . readdir ( contents , function ( er , folder ) {
if ( er ) return log . er ( cb , "couldn't readdir " + contents ) ( er )
log . verbose ( folder , "tarball contents" )
if ( folder . length > 1 ) {
folder = folder . filter ( function ( f ) {
return ! f . match ( /^\.|^tmp\.tgz$/ )
} )
}
if ( folder . length > 1 ) {
log . warn ( folder . slice ( 1 ) . join ( "\n" )
, "extra junk in folder, ignoring" )
}
}
if ( ! folder . length ) return cb ( new Error ( "Empty package tarball" ) )
addLocalDirectory ( path . resolve ( contents , "package" ) , name , cb )
folder = path . join ( contents , folder [ 0 ] )
var newName = path . join ( contents , "package" )
fs . rename ( folder , newName , function ( er ) {
if ( er ) return log . er ( cb , "couldn't rename " + folder + " to package" ) ( er )
addLocalDirectory ( newName , name , cb )
} )
} )
} )
} )
} )
}
}