-
-
Save hmalphettes/aec519cec3aeaf11824d to your computer and use it in GitHub Desktop.
This file contains hidden or 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 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