UNPKG

3.08 kBJavaScriptView Raw
1import npath from 'path';
2import { promisify } from 'util';
3
4import _glob from 'glob';
5import _ from 'underscore';
6
7import getBuild from './get-build.js';
8import maybeWrite from './maybe-write.js';
9import setExt from './set-ext.js';
10import sortObj from './sort-obj.js';
11import writeBuffer from './write-buffer.js';
12
13const glob = promisify(_glob);
14
15const flattenBuilds = build =>
16 [].concat(build, ..._.map(build.builds, flattenBuilds));
17
18const saveManifest = async ({ env, manifest, onError, onResult }) => {
19 const { manifestPath } = env;
20 if (!manifestPath) return;
21
22 const buffer = Buffer.from(JSON.stringify(sortObj(manifest)));
23 const size = buffer.length;
24 const sourcePath = `[manifest:${env.name}]`;
25 const targetPath = manifestPath;
26 try {
27 const didChange = await maybeWrite({ buffer, targetPath });
28 await onResult({ didChange, size, sourcePath, targetPath });
29 } catch (error) {
30 await onError({ error, sourcePath });
31 }
32};
33
34const saveBuild = async ({
35 build: { buffers, path },
36 manifest,
37 onError,
38 onResult,
39 target
40}) => {
41 manifest[path] = await Promise.all(
42 buffers.map(async (buffer, i) => {
43 const size = buffer.length;
44 const sourcePath =
45 i === 0 ? path : setExt(path, `~${i + 1}${npath.extname(path)}`);
46 try {
47 const { didChange, targetPath } = await writeBuffer({
48 buffer,
49 path: sourcePath,
50 target
51 });
52 await onResult({ didChange, size, sourcePath, targetPath });
53 return targetPath;
54 } catch (error) {
55 await onError({ error, sourcePath });
56 }
57 })
58 );
59};
60
61const saveBuilds = ({ env, manifest, onError, onResult }) =>
62 Promise.all(
63 _.map(env.builds, async (target, pattern) => {
64 return Promise.all(
65 _.map(await glob(pattern, { nodir: true }), async path => {
66 try {
67 const builds = flattenBuilds(await getBuild({ env, path, target }));
68 await Promise.all(
69 _.map(builds, async build => {
70 await saveBuild({ build, manifest, onError, onResult, target });
71 })
72 );
73 } catch (error) {
74 await onError({ error, sourcePath: path });
75 }
76 })
77 );
78 })
79 );
80
81const buildConfig = async ({ built, config, onResult, started }) => {
82 let failed = false;
83
84 const onError = async ({ error, sourcePath }) => {
85 failed = true;
86 await onResult({ error, sourcePath });
87 };
88
89 await Promise.all(
90 _.map(config, async env => {
91 if (started.has(env) || !_.all(env.requires, env => built.has(env))) {
92 return;
93 }
94
95 started.add(env);
96 const manifest = {};
97
98 await saveBuilds({ env, manifest, onError, onResult });
99 if (failed) return;
100
101 await saveManifest({ env, manifest, onError, onResult });
102 if (failed) return;
103
104 built.add(env);
105 await buildConfig({ built, config, onResult, started });
106 })
107 );
108};
109
110export default ({ config, onResult = _.noop }) =>
111 buildConfig({ built: new Set(), config, onResult, started: new Set() });