Files: ca90b5ca0579ebdcc0635288bce4978e3fb200f5 / test / test-79-npm / main.js
10937 bytesRaw
1 | |
2 | |
3 | /* eslint-disable complexity */ |
4 | |
5 | 'use strict'; |
6 | |
7 | const UPM = false; // USE_PREINSTALLED_MODULES |
8 | |
9 | const fs = require('fs'); |
10 | const path = require('path'); |
11 | const assert = require('assert'); |
12 | const globby = require('globby'); |
13 | const utils = require('../utils.js'); |
14 | |
15 | assert(!module.parent); |
16 | assert(__dirname === process.cwd()); |
17 | |
18 | const hostVersion = process.version.match(/^v(\d+)/)[1]; |
19 | const host = 'node' + hostVersion; |
20 | const target = process.argv[2] || host; |
21 | const windows = process.platform === 'win32'; |
22 | const npm = { 0: 2, 4: 2, 6: 3, 7: 4, 8: 5, 9: 5, 10: 5, 12: 6 }[hostVersion]; |
23 | assert(npm !== undefined); |
24 | |
25 | function applyMetaToRight (right, meta) { |
26 | right = (meta.take === 'stderr' ? right.stderr : right.stdout); |
27 | if (meta.take === 'last-line') right = right.split('\n').slice(-2).join('\n'); |
28 | if (right.slice(-2) === '\r\n') right = right.slice(0, -2); |
29 | if (right.slice(-1) === '\n') right = right.slice(0, -1); |
30 | return right; |
31 | } |
32 | |
33 | let stamp = {}; |
34 | |
35 | const checklist = fs.readFileSync('checklist.js', 'utf-8'); |
36 | let table = checklist.split('const table = ')[1].split(';')[0]; |
37 | table = JSON.parse(table); |
38 | let changes = checklist.split('const changes = ')[1].split(';')[0]; |
39 | changes = JSON.parse(changes); |
40 | |
41 | function save () { |
42 | const t = utils.stringify(table, undefined, 2); |
43 | let c = utils.stringify(changes, undefined, 2); |
44 | if (c === '[]') c = '[\n]'; |
45 | fs.writeFileSync('checklist.js', |
46 | '/* eslint-disable no-unused-vars */\n' + |
47 | '/* eslint-disable quotes */\n' + |
48 | '\n' + |
49 | '\'use strict\';\n' + |
50 | '\n' + |
51 | 'const table = ' + t + ';\n' + |
52 | 'const changes = ' + c + ';\n' |
53 | ); |
54 | } |
55 | |
56 | function stamp2string (s) { |
57 | // platform, arch, modules |
58 | return s.p + '/' + s.a + '/m' + s.m.toString(); |
59 | } |
60 | |
61 | function update (p, r, v, note) { |
62 | if (!table[p]) table[p] = {}; |
63 | const row = table[p]; |
64 | const ss = stamp2string(stamp); |
65 | const o = row[ss]; |
66 | const rv = r + (v ? (',' + v) : ''); |
67 | const rn = r + (note ? (',' + note) : ''); |
68 | row[ss] = rv + (note ? (',' + note) : ''); |
69 | const o2 = o ? o.split(',')[0] : undefined; |
70 | if ((!o) && (r !== 'ok')) { |
71 | changes.push(p + ',' + ss + ': new ' + rn); |
72 | } else |
73 | if ((o2 !== undefined) && (o2 !== r)) { |
74 | changes.push(p + ',' + ss + ': ' + o + ' -> ' + rn); |
75 | } |
76 | save(); |
77 | } |
78 | |
79 | if (!UPM) { |
80 | console.log('Cleaning cache...'); |
81 | |
82 | if (windows) { |
83 | utils.vacuum.sync(path.join( |
84 | process.env.APPDATA, 'npm-cache' |
85 | )); |
86 | utils.mkdirp.sync(path.join( |
87 | process.env.APPDATA, 'npm-cache' |
88 | )); |
89 | } else { |
90 | if (npm >= 5) { |
91 | utils.exec.sync( |
92 | 'npm cache clean --force' |
93 | ); |
94 | } else { |
95 | utils.exec.sync( |
96 | 'npm cache clean' |
97 | ); |
98 | } |
99 | } |
100 | |
101 | utils.mkdirp.sync('_isolator'); |
102 | } |
103 | |
104 | (function () { |
105 | console.log('Getting stamp...'); |
106 | |
107 | const input = path.resolve('stamp.js'); |
108 | const lucky = path.basename(input).slice(0, -3); |
109 | const output = path.resolve('_isolator', lucky + '.exe'); |
110 | |
111 | utils.pkg.sync([ |
112 | '--target', target, |
113 | '--output', output, input |
114 | ]); |
115 | |
116 | stamp = utils.spawn.sync( |
117 | output |
118 | ); |
119 | |
120 | stamp = JSON.parse(stamp); |
121 | utils.vacuum.sync(output); |
122 | console.log('Stamp is ' + JSON.stringify(stamp)); |
123 | utils.pause(2); |
124 | }()); |
125 | |
126 | const inputs = globby.sync([ |
127 | './*/*.js', |
128 | '!./*/*.config.js', |
129 | '!./*/*.meta.js', |
130 | '!./*/gulpfile.js', |
131 | '!./*/*fixture*' |
132 | ]).map(function (result) { |
133 | return path.resolve(result); |
134 | }); |
135 | |
136 | let times = {}; |
137 | const ci = process.env.CI; |
138 | |
139 | if (ci) { |
140 | console.log('Getting latest times...'); |
141 | |
142 | const foldyNames = inputs.map(function (input) { |
143 | const foldy = path.dirname(input); |
144 | const foldyName = path.basename(foldy); |
145 | return foldyName; |
146 | }); |
147 | |
148 | times = JSON.parse(utils.exec.sync( |
149 | 'node times.js ' + foldyNames.join() |
150 | )); |
151 | } |
152 | |
153 | inputs.some(function (input) { |
154 | const foldy = path.dirname(input); |
155 | const foldyName = path.basename(foldy); |
156 | |
157 | const packy = path.basename(input).slice(0, -3); |
158 | const packyName = packy.split('@')[0]; |
159 | const packyWildcard = packy.split('@')[1]; |
160 | |
161 | let wordy = packy; |
162 | if (packyName !== foldyName) { |
163 | wordy = foldyName + '/' + wordy; |
164 | } |
165 | |
166 | const output = path.resolve('_isolator', packy + '.exe'); |
167 | |
168 | console.log(); |
169 | console.log('*********************************************************'); |
170 | console.log('*********************************************************'); |
171 | console.log('*********************************************************'); |
172 | |
173 | console.log('Testing ' + wordy + '...'); |
174 | |
175 | if (ci) { |
176 | const latestTime = times[foldyName]; |
177 | if (latestTime) { |
178 | const diff = Date.now() - latestTime; |
179 | const days = diff / 1000 / 60 / 60 / 24 | 0; |
180 | if (days >= 360) { |
181 | // no need to pollute changes with this |
182 | // update(wordy, 'nop', '', 'abandoned'); |
183 | console.log('Last published ' + days + ' days ago!'); |
184 | return; |
185 | } |
186 | } |
187 | } |
188 | |
189 | const flags = { ci }; |
190 | let metajs = path.join(foldy, packy + '.meta.js'); |
191 | metajs = fs.existsSync(metajs) ? require(metajs) : undefined; |
192 | |
193 | let meta; |
194 | |
195 | if (metajs) { |
196 | meta = metajs(stamp, flags) || {}; |
197 | } else { |
198 | meta = {}; |
199 | } |
200 | |
201 | let allow; |
202 | |
203 | if (typeof meta.allow !== 'undefined') { |
204 | allow = meta.allow; |
205 | } else { |
206 | allow = true; |
207 | } |
208 | |
209 | const note = meta.note; |
210 | |
211 | if (!allow) { |
212 | update(wordy, 'nop', '', note); |
213 | console.log('Not allowed here!'); |
214 | if (note) console.log('Note:', note); |
215 | return; |
216 | } |
217 | |
218 | let version = ''; |
219 | |
220 | if (!UPM) { |
221 | const build = meta.build; |
222 | const packages = [ packy ].concat(meta.packages || []); |
223 | console.log('Installing ' + packages + '...'); |
224 | let successful = false; |
225 | let counter = 10; |
226 | while ((!successful) && (counter > 0)) { |
227 | successful = true; |
228 | let command = 'npm install ' + packages.join(' '); |
229 | if (npm >= 5) command += ' --no-save'; |
230 | if (build) command += ' --build-from-source=' + build; |
231 | command += ' --unsafe-perm'; |
232 | try { |
233 | utils.exec.sync(command, { cwd: foldy }); |
234 | } catch (__) { |
235 | assert(__); |
236 | utils.vacuum.sync(path.join(foldy, 'node_modules')); |
237 | successful = false; |
238 | counter -= 1; |
239 | } |
240 | } |
241 | |
242 | let packyVersion; |
243 | |
244 | try { |
245 | packyVersion = JSON.parse(fs.readFileSync( |
246 | path.join(foldy, 'node_modules', packy.split('@')[0], 'package.json'), 'utf8' |
247 | )).version; |
248 | } catch (___) { |
249 | update(wordy, 'bad-npm-i', '', note); |
250 | console.log(wordy + ' failed to install here!'); |
251 | if (note) console.log('Note:', note); |
252 | return; |
253 | } |
254 | |
255 | console.log('Version of ' + packy + ' is ' + packyVersion); |
256 | version = packyVersion; |
257 | |
258 | if (packyWildcard) { |
259 | assert.equal(packyWildcard.split('.').length, 3); |
260 | assert.equal(packyVersion, packyWildcard); |
261 | } |
262 | } |
263 | |
264 | let right; |
265 | |
266 | console.log('Running non-compiled ' + wordy + '...'); |
267 | |
268 | try { |
269 | right = utils.spawn.sync( |
270 | 'node', [ input ], |
271 | { cwd: path.dirname(input), |
272 | stdio: 'pipe' } |
273 | ); |
274 | } catch (___) { |
275 | right = { |
276 | stdout: '', |
277 | stderr: ___.toString() |
278 | }; |
279 | } |
280 | |
281 | right = applyMetaToRight(right, meta); |
282 | |
283 | console.log('Result is \'' + right + '\''); |
284 | |
285 | if (right !== 'ok') { |
286 | update(wordy, 'bad-test', version, note); |
287 | } else { |
288 | console.log('Compiling ' + wordy + '...'); |
289 | const config = path.join(foldy, packy + '.config.json'); |
290 | |
291 | if (fs.existsSync(config)) { |
292 | const bin = JSON.parse(fs.readFileSync(config)).bin; |
293 | assert.equal(path.join(foldy, bin), input); |
294 | input = config; |
295 | } |
296 | |
297 | utils.pkg.sync([ |
298 | '--target', target, |
299 | '--output', output, input |
300 | ]); |
301 | |
302 | console.log('Copying addons...'); |
303 | |
304 | const deployFiles = []; |
305 | |
306 | if (!meta.deployFiles && |
307 | !meta.deployFilesFrom) { |
308 | globby.sync( |
309 | path.join(foldy, 'node_modules', '**', '*.node') |
310 | ).some(function (deployFrom) { |
311 | deployFiles.push([ |
312 | deployFrom, |
313 | path.join(path.dirname(output), path.basename(deployFrom)) |
314 | ]); |
315 | }); |
316 | } |
317 | |
318 | const deployFilesRelative = []; |
319 | |
320 | if (meta.deployFiles) { |
321 | meta.deployFiles.some(function (deployFile) { |
322 | deployFilesRelative.push(deployFile); |
323 | }); |
324 | } |
325 | |
326 | if (meta.deployFilesFrom) { |
327 | meta.deployFilesFrom.some(function (dictName) { |
328 | const dict = require('../../dictionary/' + dictName); |
329 | dict.pkg.deployFiles.some(function (deployFile) { |
330 | const deployFrom = 'node_modules/' + dictName + '/' + deployFile[0]; |
331 | const deployTo = deployFile[1]; |
332 | deployFilesRelative.push([ deployFrom, deployTo ]); |
333 | }); |
334 | }); |
335 | } |
336 | |
337 | deployFilesRelative.some(function (deployFile) { |
338 | let deployFrom; |
339 | let deployTo; |
340 | |
341 | if (Array.isArray(deployFile)) { |
342 | deployFrom = deployFile[0]; |
343 | deployTo = deployFile[1]; |
344 | } else { |
345 | deployFrom = deployFile; |
346 | deployTo = deployFile; |
347 | } |
348 | |
349 | // whole directory supported, glob not |
350 | assert(deployFrom.indexOf('*') < 0); |
351 | assert(deployTo.indexOf('*') < 0); |
352 | |
353 | deployFrom = path.join(foldy, deployFrom); |
354 | deployTo = path.join(path.dirname(output), deployTo); |
355 | |
356 | if (fs.existsSync(deployFrom)) { |
357 | const statFrom = fs.statSync(deployFrom); |
358 | if (statFrom.isFile()) { |
359 | deployFiles.push([ deployFrom, deployTo ]); |
360 | } else { |
361 | globby.sync( |
362 | path.join(deployFrom, '**', '*') |
363 | ).some(function (deployFrom2) { |
364 | const r = path.relative(deployFrom, deployFrom2); |
365 | const deployTo2 = path.join(deployTo, r); |
366 | if (fs.existsSync(deployFrom2)) { |
367 | const statFrom2 = fs.statSync(deployFrom2); |
368 | if (statFrom2.isFile()) { |
369 | deployFiles.push([ deployFrom2, deployTo2 ]); |
370 | } |
371 | } |
372 | }); |
373 | } |
374 | } |
375 | }); |
376 | |
377 | deployFiles.some(function (deployFile) { |
378 | const deployFrom = deployFile[0]; |
379 | const deployTo = deployFile[1]; |
380 | const statFrom = fs.statSync(deployFrom); |
381 | utils.mkdirp.sync(path.dirname(deployTo)); |
382 | fs.writeFileSync(deployTo, |
383 | fs.readFileSync(deployFrom)); |
384 | fs.chmodSync(deployTo, |
385 | statFrom.mode.toString(8).slice(-3)); |
386 | }); |
387 | |
388 | console.log('Running compiled ' + wordy + '...'); |
389 | |
390 | try { |
391 | right = utils.spawn.sync( |
392 | './' + path.basename(output), [], |
393 | { cwd: path.dirname(output), |
394 | stdio: 'pipe' } |
395 | ); |
396 | } catch (___) { |
397 | right = { |
398 | stdout: '', |
399 | stderr: ___.toString() |
400 | }; |
401 | } |
402 | |
403 | right = applyMetaToRight(right, meta); |
404 | console.log('Result is \'' + right + '\''); |
405 | |
406 | if (right !== 'ok') { |
407 | update(wordy, 'error', version, note); |
408 | } else { |
409 | update(wordy, 'ok', version); |
410 | } |
411 | } |
412 | |
413 | const rubbishes = globby.sync( |
414 | path.join(path.dirname(output), '**', '*') |
415 | ); |
416 | |
417 | rubbishes.some(function (rubbish) { |
418 | utils.vacuum.sync(rubbish); |
419 | }); |
420 | |
421 | if (!UPM) { |
422 | console.log('Cleanup...'); |
423 | utils.vacuum.sync(path.join(foldy, 'node_modules')); |
424 | } |
425 | }); |
426 | |
427 | console.log( |
428 | '\nChanges:\n' + |
429 | changes.join('\n') + |
430 | '\n' |
431 | ); |
432 |
Built with git-ssb-web