4 var fs
= require('fs');
5 var path
= require('path');
7 // Note, this script can't use any third-party dependencies
8 // as we don't know the status of the package when we
12 console
.error(err
.stack
);
16 var basePackage
= require(path
.join(__dirname
, '..', 'package.json'));
18 function stat(baseDirectory
, files
, callback
) {
19 if (!files
.length
) return callback(null, {});
23 files
.forEach(function(file
) {
24 var fileName
= path
.join(baseDirectory
, file
);
25 fs
.stat(fileName
, function(err
, stat
) {
26 if (err
) return callback(err
);
29 if (count
=== files
.length
) {
30 callback(null, stats
);
36 function checkDirectory(baseDirectory
, callback
) {
37 fs
.readdir(baseDirectory
, function(err
, files
) {
38 if (err
) return die(err
);
40 stat(baseDirectory
, files
, function(err
, filesStat
) {
41 if (filesStat
['package.json']) {
42 return callback(null, path
.join(baseDirectory
, 'package.json'));
44 var directories
= files
46 if (f
=== 'node_modules') return false;
47 return filesStat
[f
].isDirectory();
50 return path
.join(baseDirectory
, f
);
53 return callback(null, null, directories
);
59 function searchNext(queue
, results
, callback
) {
60 var next
= queue
.pop();
61 checkDirectory(next
, function(err
, packageJson
, subDirectories
) {
62 if (err
) return callback(err
);
64 results
.push(packageJson
);
66 queue
= queue
.concat(subDirectories
);
70 searchNext(queue
, results
, callback
);
72 callback(null, results
);
77 function findChildModulePackages(queue
, callback
) {
78 if (queue
.length
=== 0) return callback(null, []);
79 searchNext(queue
, [], callback
);
82 function findBaseDependency(name
) {
83 if (basePackage
.dependencies
[name
]) {
84 return basePackage
.dependencies
[name
];
87 if (basePackage
.devDependencies
[name
]) {
88 return basePackage
.devDependencies
[name
];
92 function normalise(version
, relativeTo
) {
93 if (version
.indexOf('file:') !== 0) return version
;
94 var location
= version
.substring(5);
95 var j
= path
.normalize(path
.join(__dirname
, '../', location
));
96 var relLocation
= path
.relative(path
.dirname(relativeTo
), j
);
97 return 'file:' + relLocation
;
100 function processDepsHash(hash
, packageFile
) {
102 if (!hash
) return results
;
103 Object
.keys(hash
).forEach(function(dependency
) {
104 var baseVersion
= findBaseDependency(dependency
);
106 var baseVersionNormalised
= normalise(baseVersion
, packageFile
);
107 if (baseVersionNormalised
!== hash
[dependency
]) {
110 correctVersion
: baseVersionNormalised
,
111 currentVersion
: hash
[dependency
]
119 function installUpdates(packageFile
, isDev
, changes
) {
120 var wd
= path
.dirname(packageFile
);
122 if (!changes
|| !changes
.length
) return;
124 var versions
= changes
126 var correctVersion
= c
.correctVersion
;
127 if (correctVersion
.charAt(0) === '^') {
128 correctVersion
= correctVersion
.substring(1);
130 return c
.name
+ '@' + correctVersion
;
139 (isDev
? ' --save-dev' : ' --save') +
140 '; rm -rf node_modules)'
144 function updateDependenciesForPackage(packageFile
) {
145 var packageJson
= require(packageFile
);
146 var prodChanges
= processDepsHash(packageJson
.dependencies
, packageFile
);
147 var devChanges
= processDepsHash(packageJson
.devDependencies
, packageFile
);
149 installUpdates(packageFile
, false, prodChanges
);
150 installUpdates(packageFile
, true, devChanges
);
153 findChildModulePackages(
154 [path
.join(__dirname
, '..', 'shared'), path
.join(__dirname
, '..', 'modules')],
155 function(err
, results
) {
156 if (err
) return die(err
);
158 results
.forEach(function(packageFile
) {
159 updateDependenciesForPackage(packageFile
);