1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const chokidar = require("chokidar");
|
4 | const glob = require("fast-glob");
|
5 | const fs = require("fs-extra-plus");
|
6 | const p_spawn_1 = require("p-spawn");
|
7 | const Path = require("path");
|
8 | const processors_1 = require("./processors");
|
9 | const utils_1 = require("./utils");
|
10 | const vdev_config_1 = require("./vdev-config");
|
11 |
|
12 | async function updateVersions(config) {
|
13 | if (!config) {
|
14 | config = await vdev_config_1.loadVdevConfig();
|
15 | }
|
16 | const versionFiles = (config.version && config.version.files) ? config.version.files : null;
|
17 |
|
18 | if (versionFiles == null) {
|
19 | return;
|
20 | }
|
21 | let newAppVersion = config.version.appVersion;
|
22 |
|
23 | if (newAppVersion == null) {
|
24 | const packageJson = await fs.readJSON('./package.json');
|
25 |
|
26 | newAppVersion = packageJson.dropVersion;
|
27 | }
|
28 | let firstUpdate = false;
|
29 | try {
|
30 | for (let file of versionFiles) {
|
31 | const originalContent = (await fs.readFile(file, 'utf8')).toString();
|
32 | const isHTML = file.toLowerCase().endsWith('html');
|
33 | let fileAppVersion = getVersion(originalContent, isHTML);
|
34 | if (newAppVersion !== fileAppVersion) {
|
35 |
|
36 | if (!firstUpdate) {
|
37 | console.log(`----- Version Update: Updating new appVersion to ${newAppVersion} `);
|
38 | firstUpdate = true;
|
39 | }
|
40 | console.log(`Changing appVersion ${fileAppVersion} -> ${newAppVersion} in file: ${file}`);
|
41 | let newContent = replaceVersion(originalContent, newAppVersion, isHTML);
|
42 | await fs.writeFile(file, newContent, 'utf8');
|
43 | }
|
44 | else {
|
45 |
|
46 |
|
47 | }
|
48 | }
|
49 | }
|
50 | catch (ex) {
|
51 | throw new Error(`ERROR while doing versioning files - ${ex.message}`);
|
52 | }
|
53 |
|
54 | if (firstUpdate) {
|
55 | console.log('----- /Version Update: done');
|
56 | }
|
57 | }
|
58 | exports.updateVersions = updateVersions;
|
59 |
|
60 | async function cleanNodeFiles() {
|
61 | const filesToDelete = ['./package-lock.json', './node_blockules'];
|
62 | const blocks = await loadBlocks();
|
63 |
|
64 |
|
65 | for (const block of Object.values(blocks)) {
|
66 | const dir = block.dir;
|
67 | for (let fName of filesToDelete) {
|
68 | const fileToDelete = Path.join(dir, fName);
|
69 | if ((await fs.pathExists(fileToDelete))) {
|
70 | fs.saferRemove(fileToDelete);
|
71 | }
|
72 | }
|
73 | }
|
74 | }
|
75 | exports.cleanNodeFiles = cleanNodeFiles;
|
76 |
|
77 |
|
78 |
|
79 |
|
80 | async function buildBlocksOrBundles(names) {
|
81 | if (names.length === 0) {
|
82 | const blocks = await loadBlocks();
|
83 | for (let block of Object.values(blocks)) {
|
84 | await _buildBlock(block);
|
85 | }
|
86 | }
|
87 | else {
|
88 | for (let name of names) {
|
89 | const blockAndBundle = name.split('/');
|
90 |
|
91 | await buildBlock(blockAndBundle[0], blockAndBundle[1]);
|
92 | }
|
93 | }
|
94 | }
|
95 | exports.buildBlocksOrBundles = buildBlocksOrBundles;
|
96 |
|
97 |
|
98 | async function watchBlock(blockName) {
|
99 | const blocks = await loadBlocks();
|
100 | const block = blocks[blockName];
|
101 | const webBundles = (block) ? block.webBundles : null;
|
102 | if (webBundles == null) {
|
103 | throw new Error(`Block ${blockName} not found or does not have a '.webBundles'. As of now, can only watch webBundles`);
|
104 | }
|
105 | for (let bundle of webBundles) {
|
106 | await initWebBundle(block, bundle);
|
107 |
|
108 | if (bundle.type === 'js' || bundle.type === 'ts') {
|
109 | await _buildBlock(block, bundle, { watch: true });
|
110 | }
|
111 |
|
112 | else {
|
113 | await _buildBlock(block, bundle);
|
114 | let watcher = chokidar.watch(bundle.entries, { persistent: true });
|
115 | watcher.on('change', async function (filePath, stats) {
|
116 | if (filePath.endsWith(`.${bundle.type}`)) {
|
117 | await _buildBlock(block, bundle);
|
118 | }
|
119 | });
|
120 | }
|
121 | }
|
122 | }
|
123 | exports.watchBlock = watchBlock;
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 | async function buildBlock(blockName, onlyBundleName, opts) {
|
130 | const blockByName = await loadBlocks();
|
131 | const block = blockByName[blockName];
|
132 | if (!block) {
|
133 | throw new Error(`No block found for blockeName ${blockName}.`);
|
134 | }
|
135 | let bundle;
|
136 | if (onlyBundleName && block.webBundles) {
|
137 | bundle = block.webBundles.find((b) => (b.name == onlyBundleName));
|
138 | if (!bundle) {
|
139 | throw new Error(`No webBundle ${onlyBundleName} found in block ${block.name}`);
|
140 | }
|
141 | await initWebBundle(block, bundle);
|
142 | }
|
143 | await _buildBlock(block, bundle, opts);
|
144 | }
|
145 | exports.buildBlock = buildBlock;
|
146 | async function _buildBlock(block, bundle, opts) {
|
147 | const hasPomXml = await fs.pathExists(Path.join(block.dir, 'pom.xml'));
|
148 | const hasPackageJson = await fs.pathExists(Path.join(block.dir, 'package.json'));
|
149 | const hasDockerFile = await fs.pathExists(Path.join(block.dir, 'Dockerfile'));
|
150 | const hasTsConfig = await fs.pathExists(Path.join(block.dir, 'tsconfig.json'));
|
151 | const hasWebBundles = (block.webBundles) ? true : false;
|
152 |
|
153 | const start = utils_1.now();
|
154 | if (!bundle) {
|
155 | console.log(`------ Building Block ${block.name} ${block.dir}`);
|
156 | }
|
157 |
|
158 | if (hasPackageJson) {
|
159 | await npmInstall(block);
|
160 | }
|
161 |
|
162 | if (hasWebBundles) {
|
163 |
|
164 | await buildWebBundles(block, bundle, opts);
|
165 | }
|
166 |
|
167 | if (!hasWebBundles && hasTsConfig) {
|
168 | await buildTsSrc(block);
|
169 | }
|
170 | if (hasPomXml) {
|
171 | await runMvn(block, opts ? opts.full : false);
|
172 | }
|
173 | if (!bundle) {
|
174 | await utils_1.printLog(`------ Building Block ${block.name} DONE`, null, start);
|
175 | console.log();
|
176 | }
|
177 | }
|
178 | async function npmInstall(block) {
|
179 | await p_spawn_1.spawn('npm', ['install'], { cwd: block.dir });
|
180 | }
|
181 | async function buildTsSrc(block) {
|
182 | const distDirNeedsDelete = false;
|
183 | const distDir = Path.join(block.dir, '/dist/');
|
184 | const distDirExist = await fs.pathExists(distDir);
|
185 |
|
186 | if (distDirExist) {
|
187 | const tsconfigObj = await utils_1.readJsonFileWithComments(Path.join(block.dir, 'tsconfig.json'));
|
188 | let outDir = tsconfigObj.compilerOptions.outDir;
|
189 | outDir = (outDir) ? Path.join(block.dir, outDir, '/') : null;
|
190 | if (outDir === distDir) {
|
191 | console.log(`tsc prep - deleting tsc distDir ${distDir}`);
|
192 | await fs.saferRemove(distDir);
|
193 | }
|
194 | else {
|
195 | console.log(`tss prep - skipping tsc distDir ${distDir} because does not match tsconfig.json compilerOptions.outDir ${outDir}`);
|
196 | }
|
197 | }
|
198 | await p_spawn_1.spawn('tsc', [], { cwd: block.dir });
|
199 | }
|
200 | async function runMvn(block, full) {
|
201 | const args = ['clean', 'package'];
|
202 | if (!full) {
|
203 | args.push('-Dmaven.test.skip=true');
|
204 | }
|
205 | var start = utils_1.now();
|
206 | await p_spawn_1.spawn('mvn', args, {
|
207 | toConsole: false,
|
208 | cwd: block.dir,
|
209 | onStderr: function (data) {
|
210 | process.stdout.write(data);
|
211 | }
|
212 | });
|
213 | await utils_1.printLog(`maven build ${full ? 'with test' : ''}`, null, start);
|
214 | }
|
215 | const bundlers = {
|
216 | ts: buildTsBundler,
|
217 | pcss: buildPcssBundler,
|
218 | tmpl: buildTmplBundler,
|
219 | js: buildJsBundler
|
220 | };
|
221 | async function buildWebBundles(block, onlyBundle, opts) {
|
222 | let webBundles;
|
223 | if (onlyBundle) {
|
224 |
|
225 | webBundles = [onlyBundle];
|
226 | }
|
227 | else {
|
228 | webBundles = block.webBundles;
|
229 |
|
230 | for (let bundle of webBundles) {
|
231 | await initWebBundle(block, bundle);
|
232 | }
|
233 | }
|
234 | for (let bundle of webBundles) {
|
235 | await ensureDist(bundle);
|
236 | var start = utils_1.now();
|
237 | await bundlers[bundle.type](block, bundle, opts);
|
238 | await utils_1.printLog(`Building bundle ${block.name}/${bundle.name}`, bundle.dist, start);
|
239 | }
|
240 | }
|
241 | const rollupOptionsDefaults = {
|
242 | ts: {
|
243 | watch: false,
|
244 | ts: true,
|
245 | tsconfig: './tsconfig.json'
|
246 | },
|
247 | js: {
|
248 | watch: false,
|
249 | ts: false
|
250 | }
|
251 | };
|
252 |
|
253 |
|
254 |
|
255 |
|
256 | async function initWebBundle(block, bundle) {
|
257 | bundle.type = Path.extname(utils_1.asNames(bundle.entries)[0]).substring(1);
|
258 |
|
259 | bundle.dir = specialPathResolve('', block.dir, bundle.dir);
|
260 |
|
261 | bundle.entries = utils_1.asNames(bundle.entries).map((f) => specialPathResolve('', bundle.dir, f));
|
262 |
|
263 | bundle.dist = specialPathResolve('', block.baseDistDir, bundle.dist);
|
264 |
|
265 | if (bundle.type === 'ts' || bundle.type === 'js') {
|
266 |
|
267 | const rollupOptionsDefault = rollupOptionsDefaults[bundle.type];
|
268 |
|
269 | const rollupOptions = (bundle.rollupOptions) ? Object.assign(Object.assign({}, rollupOptionsDefault), bundle.rollupOptions) : Object.assign({}, rollupOptionsDefault);
|
270 |
|
271 | if (rollupOptions.tsconfig) {
|
272 | rollupOptions.tsconfig = specialPathResolve('', bundle.dir, rollupOptions.tsconfig);
|
273 | }
|
274 |
|
275 | bundle.rollupOptions = rollupOptions;
|
276 | }
|
277 |
|
278 | }
|
279 |
|
280 |
|
281 | async function buildTsBundler(block, bundle, opts) {
|
282 |
|
283 | try {
|
284 | if (opts && opts.watch) {
|
285 | bundle.rollupOptions.watch = true;
|
286 | }
|
287 |
|
288 | const allEntries = await resolveGlobs(bundle.entries);
|
289 | await processors_1.rollupFiles(allEntries, bundle.dist, bundle.rollupOptions);
|
290 | }
|
291 | catch (ex) {
|
292 |
|
293 | console.log("BUILD ERROR - something when wrong on rollup\n\t", ex);
|
294 | console.log("Empty string was save to the app bundle");
|
295 | console.log("Trying saving again...");
|
296 | return;
|
297 | }
|
298 | }
|
299 | async function buildPcssBundler(block, bundle, opts) {
|
300 | const allEntries = await resolveGlobs(bundle.entries);
|
301 | await processors_1.pcssFiles(allEntries, bundle.dist);
|
302 | }
|
303 | async function buildTmplBundler(block, bundle, opts) {
|
304 | const allEntries = await resolveGlobs(bundle.entries);
|
305 | await processors_1.tmplFiles(allEntries, bundle.dist);
|
306 | }
|
307 | async function buildJsBundler(block, bundle, opts) {
|
308 | if (opts && opts.watch) {
|
309 | bundle.rollupOptions.watch = true;
|
310 | }
|
311 | const allEntries = await resolveGlobs(bundle.entries);
|
312 | await processors_1.rollupFiles(allEntries, bundle.dist, bundle.rollupOptions);
|
313 | }
|
314 |
|
315 |
|
316 | async function loadDockerBlocks() {
|
317 | const blocks = await loadBlocks();
|
318 | const dockerBlocks = {};
|
319 | for (let block of Object.values(blocks)) {
|
320 | const hasDockerfile = await fs.pathExists(Path.join(block.dir, 'Dockerfile'));
|
321 | if (hasDockerfile) {
|
322 | dockerBlocks[block.name] = block;
|
323 | }
|
324 | }
|
325 | return dockerBlocks;
|
326 | }
|
327 | exports.loadDockerBlocks = loadDockerBlocks;
|
328 | async function loadBlocks() {
|
329 | const rawConfig = await vdev_config_1.loadVdevConfig();
|
330 | const rawBlocks = rawConfig.blocks;
|
331 |
|
332 | const blockByName = rawBlocks.map((item) => {
|
333 | let block;
|
334 | let name;
|
335 | if (typeof item === 'string') {
|
336 | block = {
|
337 | name: item
|
338 | };
|
339 | }
|
340 | else {
|
341 | if (!item.name) {
|
342 | throw new Error(`the build config file vdev.yaml has a block without '.name'`);
|
343 | }
|
344 |
|
345 | block = Object.assign({}, item);
|
346 | }
|
347 |
|
348 | if (!block.dir) {
|
349 | block.dir = Path.join(rawConfig.baseBlockDir, `${block.name}/`);
|
350 | }
|
351 | return block;
|
352 | }).reduce((map, block) => {
|
353 | map[block.name] = block;
|
354 | return map;
|
355 | }, {});
|
356 | return blockByName;
|
357 | }
|
358 | exports.loadBlocks = loadBlocks;
|
359 | async function loadBlock(name) {
|
360 | const blocks = await loadBlocks();
|
361 | const block = blocks[name];
|
362 | if (!block) {
|
363 | throw new Error(`Block ${name} not found`);
|
364 | }
|
365 | return block;
|
366 | }
|
367 | exports.loadBlock = loadBlock;
|
368 |
|
369 |
|
370 | async function resolveGlobs(globs) {
|
371 |
|
372 | return glob(globs);
|
373 | }
|
374 |
|
375 |
|
376 | function getVersion(content, isHtml = false) {
|
377 |
|
378 | if (isHtml) {
|
379 | const rgx = /<.*(href|src).*?v=(.*?)(\"|\&)/gm;
|
380 | const r = rgx.exec(content);
|
381 | if (r != null && r.length > 2) {
|
382 | return r[2];
|
383 | }
|
384 | else {
|
385 | return null;
|
386 | }
|
387 | }
|
388 |
|
389 | else {
|
390 | var rx = new RegExp('appVersion' + '\\s*[=:]\\s*"(.*)"', 'i');
|
391 | var match = content.match(rx);
|
392 | return (match) ? match[1] : null;
|
393 | }
|
394 | }
|
395 | function replaceVersion(content, value, isHtml = false) {
|
396 | if (isHtml) {
|
397 | const rgxRep = /(<.*(href|src).*?v=).*?(\"|\&.*)/g;
|
398 |
|
399 | return content.replace(rgxRep, '$1' + value + '$3');
|
400 | }
|
401 | else {
|
402 | var rx = new RegExp('(.*' + 'appVersion' + '\\s*[=:]\\s*").*(".*)', 'i');
|
403 | content = content.replace(rx, '$1' + value + '$2');
|
404 | return content;
|
405 | }
|
406 | }
|
407 |
|
408 | async function ensureDist(bundle) {
|
409 | const distDir = Path.dirname(bundle.dist);
|
410 | await fs.ensureDir(distDir);
|
411 | }
|
412 |
|
413 |
|
414 |
|
415 |
|
416 |
|
417 |
|
418 |
|
419 |
|
420 |
|
421 |
|
422 | function specialPathResolve(baseDir, dir, finalPath) {
|
423 | if (finalPath == null) {
|
424 | return dir;
|
425 | }
|
426 | if (finalPath.startsWith('/')) {
|
427 | return finalPath;
|
428 | }
|
429 | if (finalPath.startsWith('./') || finalPath.startsWith('../')) {
|
430 | return Path.join(dir, finalPath);
|
431 | }
|
432 | return Path.join(baseDir, finalPath);
|
433 | }
|
434 | exports.specialPathResolve = specialPathResolve;
|
435 |
|