Created
October 10, 2018 06:56
-
-
Save w-vi/b9b25fcd0d5ff8d9ea6df4bf90138c1a to your computer and use it in GitHub Desktop.
libnpm usage to inspect the dependency tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const fs = require('fs'); | |
const pkg = require('./package'); | |
const _ = require('lodash'); | |
const npm = require('libnpm'); | |
const async = require('neo-async'); | |
const kv = require('./kv'); | |
function check (pkgjson) => { | |
let cache = kv(); | |
let queue = []; | |
const pkgJSON = JSON.parse(fs.readFileSync(pkgjson)); | |
_.each(pkgJSON.dependencies, (v, d) => { | |
queue.push(`${d}@${v}`); | |
}); | |
console.log(`Direct dependecies for ${pkgJSON.name}: ${queue.length}`); | |
let count = 0; | |
async.whilst ( | |
() => {return (queue.length > 0 || count > 0);}, | |
(cb) => { | |
let dep = queue.pop(); | |
console.log(`Retrieve manifest for package, pkgversion=${dep}`); | |
npm.manifest(dep).then(m => { | |
const pkgid = pkg.getID(m); | |
console.log(`Inspect package, pkg=${pkgid}`); | |
if (!cache.get(pkgid)) { | |
count++; | |
pkg.inspect(m, (err, pkginfo) => { | |
if (err) { | |
console.error(err); | |
} else { | |
cache.push(pkginfo.id, pkginfo); | |
_.each(pkginfo.dependencies, (v, d) => { | |
queue.push(`${d}@${v}`); | |
}); | |
} | |
count--; | |
return cb(); | |
}); | |
} else { | |
console.log(`Package found in cache, pkg=${pkgid}`); | |
return cb(); | |
} | |
}); | |
}, | |
(err) => {console.log(`Cache stats, size=${cache.size()}, hits=${cache.hits()}, misses=${cache.misses()}`)}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
function KV (debug=false) { | |
const kv = {debug: debug}; | |
const store = {}; | |
let hits = 0; | |
let misses = 0; | |
let size = 0; | |
kv.push = function(k, v) { | |
if (debug) console.log(`KV push, key=${k}, value=${JSON.stringify(v)}`); | |
const o = store[k]; | |
size++; | |
store[k] = v; | |
return o; | |
}; | |
kv.pop = function(k) { | |
if (debug) console.log(`KV pop, key=${k}`); | |
const o = store[k]; | |
size--; | |
delete store[k]; | |
return o; | |
}; | |
kv.clear = function() { | |
if (debug) console.log(`KV clear, size=${size}, hitcount=${hits}, misscount=${misses}`); | |
for (let k in store) { | |
delete store[k]; | |
} | |
size = 0; | |
hits = 0; | |
misses = 0; | |
}; | |
kv.get = function(k) { | |
const v = store[k]; | |
if (typeof v != "undefined") { | |
if (debug) console.log(`KV hit, key=${k}`); | |
hits++; | |
} else { | |
if (debug) console.log(`KV miss, key=${k}`); | |
misses++; | |
} | |
return v; | |
}; | |
kv.size = function() { | |
return size; | |
}; | |
kv.hits = function() { | |
return hits; | |
}; | |
kv.misses = function() { | |
return misses; | |
}; | |
kv.keys = function() { | |
return Object.keys(store); | |
}; | |
return kv; | |
} | |
module.exports = KV; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const path = require('path'); | |
const fs = require('fs'); | |
const os = require('os'); | |
const npm = require('libnpm'); | |
const _ = require('lodash'); | |
const rmf = require('rimraf'); | |
// tmpdir work kdir | |
const DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'depc-')); | |
const LICENSE_FILEPATTERNS = [ | |
/^LICENSE$/, | |
/^LICENSE.*$/, // e.g. LICENSE.md or LICENSE.txt | |
/^LICENSE\-\w+$/, // e.g. LICENSE-MIT | |
/^\w+LICENSE.*$/, // MIT-LICENSE.txt or MIT_LICENSE | |
/^LICENCE$/, | |
/^LICENCE.*$/, | |
/^LICENCE\-\w+$/, // e.g. LICENCE-MIT | |
/^\w+LICENCE.*$/, | |
/^COPYING$/, | |
/^README$/, | |
]; | |
function getID(manifest) { | |
return `${manifest.name}-${manifest.version}`; | |
} | |
function inspect(manifest, cb) { | |
const pkgid = getID(manifest); | |
const dir = path.join(DIR, pkgid); | |
npm.extract(manifest._id, dir).then(() => { | |
// check the package.json for the license info | |
const pkginfo = _.omit( | |
JSON.parse(fs.readFileSync(path.join(dir, 'package.json'))), | |
['_resolved', '_integrity', '_from']); | |
pkginfo.id = pkgid; | |
fs.readdir(dir, (err, files) => { | |
if (err) return cb(err); | |
// collect possible license files in probability order defined by | |
// LICENSE_FILEPATTERNS | |
const licenseFiles = _.filter(files, (f) => { | |
return _.find(LICENSE_FILEPATTERNS, (pat) => { | |
return pat.test(path.basename(f, path.extname(f)).toUpperCase()); | |
}); | |
}); | |
return cb(null, pkginfo); | |
}); | |
}); | |
}; | |
function clean(cb) { rmf(DIR, cb); } | |
module.exports = {inspect, clean, getID}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment