Skip to content

Instantly share code, notes, and snippets.

@hmalphettes
Forked from Y--/listDependencies.js
Last active September 23, 2015 07:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hmalphettes/aec519cec3aeaf11824d to your computer and use it in GitHub Desktop.
Save hmalphettes/aec519cec3aeaf11824d to your computer and use it in GitHub Desktop.
'use strict';
const cp = require('child_process');
const fs = require('fs');
const folders = foldersToProcess();
const allDeps = {};
var output = 'dependencies-report.csv';
readAllDependencies();
function readDependencies(folder, done) {
if (folder.indexOf('ui.stoic') !== -1) {
return done();
}
if (folder.charAt(0) !== '/') {
folder = __dirname + '/' + folder;
}
const compileCP = cp.spawn('npm', ['ls', '--json', '--long', '--prod'], { cwd: folder });
const errors = [];
const chunks = [];
compileCP.stderr.on('data', errors.push.bind(errors));
compileCP.stdout.on('data', chunks.push.bind(chunks));
compileCP.on('close', function (code) {
if (code || errors.length) {
return done(new Error(Buffer.concat(errors).toString()));
}
return done(null, Buffer.concat(chunks).toString());
});
}
function foldersToProcess() {
const folders = [];
// https://nodejs.org/api/process.html#process_process_argv
// node process-2.js one two=three four
for (let i = 2; i < process.argv.length; i++) {
let a = process.argv[i];
if (a === '.') {
folders.push(a);
} else if (a.indexOf('--output=') === 0) {
output = a.substring('--output='.length);
console.log('output in ' + output);
} else if (a.indexOf('-o=') === 0) {
output = a.substring('-o='.length);
console.log('output in ' + output);
} else {
try {
let s = fs.lstatSync(a);
if (s.isDirectory()) {
folders.push(a);
} else {
console.warn('The folder ' + a + ' is not a directory.');
}
} catch (x) {
console.warn('The folder ' + a + ' does not exist');
}
}
}
if (!folders.length) {
folders.push('.');
}
return folders;
}
function toCsv() {
let report = [['name', 'version', 'license', 'repository', 'tb', 'description'].join(';')];
const sk = Object.keys(allDeps).sort();
for (let keys of sk) {
let d = allDeps[keys];
report.push([d.name, d.version, d.license, d.repository, d.tb, d.description].join(';'));
}
fs.writeFileSync(output, report.join('\n'));
console.log('Dependencies report generated in ' + output);
}
function readAllDependencies() {
let folder = folders.shift();
if (!folder) {
return toCsv();
}
readDependencies(folder, function(err, data) {
if (err) { throw err; }
if (data) {
const jsonData = JSON.parse(data);
walkDependencies(jsonData, allDeps);
}
parseJspmConfig(folder, allDeps, function(e) {
if (e) {
console.error(e.message, e.stack);
return process.exit(1);
}
setImmediate(readAllDependencies);
})
});
}
function walkDependencies(o, allDeps) {
for (let k of Object.keys(o.dependencies)) {
const oo = o.dependencies[k];
putOneDependency(oo, allDeps);
walkDependencies(o.dependencies[k], allDeps);
}
}
function putOneDependency(oo, allDeps) {
let k = oo.name;
if (!allDeps[k]) {
allDeps[k] = {
name : oo.name,
tb : oo.dist && oo.dist.tarball,
version : oo.version,
description : oo.description,
repository : oo.repository && oo.repository.url,
license : oo.license
};
} else {
allDeps[k].name = allDeps[k].name || oo.name;
allDeps[k].tb = allDeps[k].tb || oo.dist && oo.dist.tarball;
allDeps[k].description = allDeps[k].description || oo.description;
allDeps[k].version = allDeps[k].version || oo.version;
allDeps[k].repository = allDeps[k].repository || oo.repository && oo.repository.url;
allDeps[k].license = allDeps[k].license || oo.license;
}
}
function parseJspmConfig(folder, allDeps, done) {
let configExists = false;
try {
let s = fs.lstatSync(folder + '/config.js');
configExists = s.isFile();
} catch(x) {}
if (!configExists) { return done(); }
fs.readFile(folder + '/config.js', function(err, content) {
if (err) { return done(err); }
let config = {};
try {
let asStr = content.toString('utf-8');
asStr = asStr.substring('System.config('.length, asStr.length - ');\n'.length)
eval('config = ' + asStr); // cheap JSON5 parser
} catch(e) {
return done(e);
}
let otherFolders = {};
for (let k in config.map) {
if (!config.map.hasOwnProperty(k)) { continue; }
let p = config.map[k];
if (typeof p === 'string') {
parseConfigReference(folder, p, otherFolders);
} else {
for (let i in p) {
if (!p.hasOwnProperty(i)) { continue; }
parseConfigReference(folder, p[i], otherFolders);
}
}
}
let extras = [];
for (let p in otherFolders) {
if (!otherFolders.hasOwnProperty(p)) { continue; }
let v = otherFolders[p];
if (v) {
extras.push(p);
} else {
let oo = {
name: p
};
let m = p.match(/jspm_packages\/github\/([^\/]*)\/([^\/]*)@([^\/]*)$/);
if (m && m[2]) {
oo.repository = 'https://github.com/' + m[1] + '/' + m[2];
oo.version = m[3];
}
if (p.indexOf('mbostock') !== 0) {
oo.license = 'BSD-3-Clause';
} else if (p.indexOf('/twbs/bootstrap') !== -1 ||
p.indexOf('/jquery.event.drag-drop') !== -1 ||
p.indexOf('/moment/moment') !== -1 ||
p.indexOf('/dubrox/Multiple-Dates-Picker-for-jQuery-UI') !== -1 ||
p.indexOf('/danialfarid/ng-file-upload-bower') !== -1 ||
p.indexOf('/mleibman/SlickGrid') !== -1 ||
p.indexOf('/angular-ui/ui-codemirror') !== -1) {
oo.license = 'MIT';
} else if (p.indexOf('MathJax') !== -1) {
oo.license = 'Apache, Version 2.0';
} else {
console.error('------ Unknown license for ' + p);
}
putOneDependency(oo, allDeps);
// console.log('Missing ' + p);
}
}
if (extras.length === 0) { return done(); }
(function doOne() {
let folder = extras.shift();
if (!folder) { return done(); }
jspmLoadLicenseFromPackage(folder, allDeps, doOne);
})();
});
}
function parseConfigReference(folder, p, otherFolders) {
p = p.replace(/^github\:/, 'jspm_packages/github/').replace(/^npm\:/, 'jspm_packages/npm/');
if (p.indexOf('jspm_packages') !== 0) { return; } // skip our own source code
let potentialFolder = folder + '/' + p;
if (typeof otherFolders[potentialFolder] === 'boolean') { return; }
let loc = potentialFolder + '/package.json';
let isFile = false;
try {
let s = fs.lstatSync(loc);
isFile = s.isFile();
if (!isFile) {
// console.warn(loc + ' was expected to be a file');
} else {
// console.log('found', loc);
}
} catch(x) {
// console.warn('could not find ' + loc);
}
otherFolders[potentialFolder] = isFile;
}
function jspmLoadLicenseFromPackage(folder, allDeps, done) {
fs.readFile(folder + '/package.json', function(err, data) {
let oo = JSON.parse(data.toString('utf-8'));
putOneDependency(oo, allDeps);
setImmediate(done);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment