UNPKG

3.77 kBJavaScriptView Raw
1'use strict';
2
3var glob = require('glob')
4 , path = require('path')
5 , fs = require('fs')
6 , runnel = require('runnel')
7
8function arraysEqual(a, b) {
9 if (!a && !b) return true;
10 if (!a || !b) return false;
11 if (a.length !== b.length) return false;
12 for (var i = 0; i < a.length; i++) {
13 if (a[i] !== b[i]) return false;
14 }
15 return true;
16}
17
18function addTransform(front, transform, packfile) {
19 var pack = require(packfile);
20 if (!pack.browserify) pack.browserify = {};
21 if (!pack.browserify.transform) pack.browserify.transform = [];
22
23 var before = [].concat(pack.browserify.transform);
24
25 transform.forEach(function (tx) {
26 // remove previously injected transform (i.e. may have been added at the end, but now needs to be in front)
27 // other option would be to only add it if it's not there already, but then front/back switching wouldn' work
28 var idx = pack.browserify.transform.indexOf(tx);
29 if (~idx) pack.browserify.transform.splice(idx, 1);
30 });
31
32 if (front) pack.browserify.transform = transform.concat(pack.browserify.transform);
33 else pack.browserify.transform = pack.browserify.transform.concat(transform);
34
35 var changed = !arraysEqual(before, pack.browserify.transform);
36
37 return { file: packfile, pack: pack, changed: changed };
38}
39
40function packsWithTransforms(root, transform, front, relPaths) {
41 return relPaths
42 .map(function (x) { return path.resolve(root, x) })
43 .map(addTransform.bind(null, front, transform))
44 .filter(function (p) { return p.changed });
45}
46
47
48var go = module.exports =
49
50/**
51 * Injects the given transform(s) into the `browserify.transform` field of all `package.json`s
52 * at and below the given `root`.
53 *
54 * If the transform(s) were contained in the `package.json` already, no changes are made and no writes performed.
55 * This means that all viralify runs succeeding the first one will be much faster.
56 *
57 * @name viralify
58 * @function
59 * @param {String} root of the package
60 * @param {Array.<String>} transform one or more transforms to be added to the transform field
61 * @param {Boolean=} front if set transforms are added to the front of the transform field so they run first
62 * @param {Function(Error)} cb called when the transform injection is complete
63 */
64function viralify(root, transform, front, cb) {
65 if (!Array.isArray(transform)) transform = [ transform ];
66
67 if (typeof front === 'function') {
68 cb = front;
69 front = false;
70 }
71
72 glob('**/package.json', { cwd: root }, function (err, relPaths) {
73 if (err) return cb(err);
74
75 // nothing to do
76 if (!relPaths.length) return cb();
77
78 var packs = packsWithTransforms(root, transform, front, relPaths);
79
80 // none of the packages changed due to adding the transform, which means they already contained it at the same position
81 if (!packs.length) return cb();
82
83 var tasks = packs
84 .map(function (p) {
85 return function (cb) {
86 fs.writeFile(p.file, JSON.stringify(p.pack, null, 2), 'utf8', cb);
87 }
88 })
89 .concat(cb);
90
91 runnel(tasks);
92 });
93};
94
95module.exports.sync =
96
97/**
98 * Same as `viralify` but performed synchronously.
99 *
100 * @name viralivy.sync
101 * @function
102 * @param {String} root of the package
103 * @param {Array.<String>} transform one or more transforms to be added to the transform field
104 * @param {Boolean=} front if set transforms are added to the front of the transform field so they run first
105 */
106function sync(root, transform, front) {
107 if (!Array.isArray(transform)) transform = [ transform ];
108
109 var relPaths = glob.sync('**/package.json', { cwd: root })
110 var packs = packsWithTransforms(root, transform, front, relPaths);
111 packs.forEach(function (p) {
112 fs.writeFileSync(p.file, JSON.stringify(p.pack, null, 2), 'utf8');
113 })
114}