1 |
|
2 |
|
3 | var walkdir = require('walkdir'),
|
4 | fs = require('fs'),
|
5 | readInstalled = require('read-installed'),
|
6 | emitter = require('events').EventEmitter;
|
7 |
|
8 |
|
9 | function listdep(parent, dep, level, deps) {
|
10 | var stack = [];
|
11 | var dedup = {};
|
12 | stack.push({parent: parent, dep: dep, level: level});
|
13 | while (typeof (o = stack.pop()) !== 'undefined') {
|
14 | for (var i in o.dep.dependencies) {
|
15 | cyclic = false;
|
16 | dep_parent = o.parent;
|
17 | while (typeof dep_parent !== 'undefined') {
|
18 | if (dep_parent.component === i) {
|
19 | cyclic = true;
|
20 | break;
|
21 | } else {
|
22 | dep_parent = dep_parent.parent;
|
23 | }
|
24 | }
|
25 | if (cyclic) {
|
26 | continue;
|
27 | }
|
28 | var id = i + "@" + o.dep.dependencies[i].version;
|
29 | if (dedup[id]) continue;
|
30 | dedup[id] = true;
|
31 | var d = {
|
32 | module: { component: i, version: o.dep.dependencies[i].version }
|
33 | };
|
34 | if (o.dep.dependencies[i].path) {
|
35 | d.file = "node_modules" + o.dep.dependencies[i].path.split("node_modules").slice(1).join("node_modules") + '/package.json';
|
36 | }
|
37 | deps.push(d);
|
38 | stack.push({parent: d, dep: o.dep.dependencies[i], level: o.level + 1});
|
39 | }
|
40 | }
|
41 | }
|
42 |
|
43 | function getNodeDependencies(path, limit) {
|
44 | var events = new emitter();
|
45 | readInstalled(path, {}, function (er, pkginfo) {
|
46 | var deps = [];
|
47 | if (limit) {
|
48 | var packages = JSON.parse(fs.readFileSync(path +'/package.json'));
|
49 | filter = [];
|
50 |
|
51 | var filter = packages.dependencies ? Object.keys(packages.dependencies) : [];
|
52 |
|
53 | Object.keys(pkginfo.dependencies)
|
54 | .filter(function(d) { return !pkginfo.dependencies[d]._requiredBy || pkginfo.dependencies[d]._requiredBy.indexOf("/") > -1 || pkginfo.dependencies[d]._requiredBy.indexOf("#DEV:/") > -1; })
|
55 | .filter(function(d) { return filter.indexOf(d) == -1; })
|
56 | .forEach(function(d) { delete pkginfo.dependencies[d]; });
|
57 | }
|
58 | var notInstalled = Object.keys(pkginfo.dependencies).filter(function (d) {
|
59 | return !pkginfo.dependencies[d].path;
|
60 | });
|
61 | if (notInstalled.length > 0) {
|
62 | return events.emit('error', 'Could not find dependencies: ' + notInstalled.join(', ') + '. You may need to run npm install');
|
63 | }
|
64 | listdep({file: 'package.json',component: pkginfo.name, version: pkginfo.version}, pkginfo, 1, deps);
|
65 | events.emit('done', deps);
|
66 | });
|
67 | return events;
|
68 | }
|
69 |
|
70 | function scanJsFiles(path, options) {
|
71 | var finder = walkdir.find(path, { "follow_symlinks" : false, "no_return": true });
|
72 | function onFile(file){
|
73 | if (file.match(/\.js$/)) {
|
74 | finder.emit('jsfile', file);
|
75 | }
|
76 | if (file.match(/\/bower.json$/)) {
|
77 | finder.emit('bowerfile', file);
|
78 | }
|
79 | }
|
80 | finder.on('file', onFile);
|
81 | finder.on('link', function(link) {
|
82 | if (fs.existsSync(link)) {
|
83 | var file = fs.realpathSync(link);
|
84 | if (fs.lstatSync(file).isFile()) {
|
85 | onFile(link);
|
86 | }
|
87 | } else {
|
88 | options.log.warn('Could not follow symlink: ' + link);
|
89 | }
|
90 | });
|
91 | return finder;
|
92 | }
|
93 |
|
94 | exports.scanJsFiles = function(path, options) {
|
95 | return scanJsFiles(path, options);
|
96 | };
|
97 |
|
98 | exports.getNodeDependencies = function(path, limit) {
|
99 | return getNodeDependencies(path, limit);
|
100 | };
|
101 |
|