Skip to content

Commit 748360b

Browse files
More useful build-time logging and writing of all output to file
1 parent 02c8246 commit 748360b

2 files changed

Lines changed: 100 additions & 52 deletions

File tree

build/gulpfile.esm.js

Lines changed: 93 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import browserifyDependencies from "@userfrosting/browserify-dependencies";
22
import Bundler, { MergeRawConfigs, ValidateRawConfig } from "@userfrosting/gulp-bundle-assets";
33
import { bower as mergeBowerDeps, npm as mergeNpmDeps } from "@userfrosting/merge-package-dependencies";
4-
import { execSync } from "child_process";
4+
import childProcess, { exec as _exec } from "child_process";
55
import { sync as deleteSync } from "del";
66
import { config as envConfig } from "dotenv";
77
import { existsSync, readFileSync, writeFileSync } from "fs";
@@ -13,36 +13,86 @@ import prune from "gulp-prune";
1313
import rev from "gulp-rev";
1414
import minifyJs from "gulp-uglify-es";
1515
import { info } from "gulplog";
16-
import { normalize as normalisePath, resolve as resolvePath } from "path";
16+
import { resolve as resolvePath } from "path";
17+
import stripAnsi from "strip-ansi";
18+
import { promisify } from "util";
19+
20+
// Promisify exec
21+
const exec = promisify(_exec);
22+
23+
// Path constants
24+
const rootDir = "..";
25+
const sprinklesDir = `${rootDir}/app/sprinkles/`;
26+
const sprinklesSchemaPath = `${rootDir}/app/sprinkles.json`;
27+
const publicAssetsDir = `${rootDir}/public/assets/`;
28+
const legacyVendorAssetsGlob = `${rootDir}/sprinkles/*/assets/vendor/**`;
29+
const sprinkleBundleFile = "asset-bundles.json";
30+
const vendorAssetsDir = `${rootDir}/app/assets/`;
31+
const logFile = `${rootDir}/app/logs/build.log`;
1732

1833
// Load environment variables
1934
envConfig({ path: "../app/.env" });
2035

2136
// Set up logging
22-
const doILog = (process.env.UF_MODE === "dev");
37+
38+
// Write starting command to log
39+
writeFileSync(logFile, "\n\n" + process.argv.join(" ") + "\n\n", {
40+
flag: 'a'
41+
});
42+
43+
// Verbosity
44+
const debug = (process.env.UF_MODE === "debug");
45+
46+
// Catch stdout and write to build log
47+
const write = process.stdout.write;
48+
const w = (...args) => {
49+
process.stdout.write = write;
50+
process.stdout.write(...args);
51+
52+
writeFileSync(logFile, stripAnsi(args[0]), {
53+
flag: 'a'
54+
});
55+
56+
process.stdout.write = w;
57+
};
58+
process.stdout.write = w;
2359

2460
/**
2561
* Prints to stdout with newline when UF_MODE is dev.
26-
* @param {any} message Message to log.
62+
* @param {string} message Message to log. If source specified, must be string.
63+
* @param {string} source Message source.
2764
*/
2865
function Logger(message, source) {
29-
if (doILog) {
66+
const messageLines = message.split("\n");
67+
messageLines.forEach(msg => {
3068
if (source)
31-
info(`${source}: ${message}`);
69+
info(`${source}: ${msg}`);
3270
else
33-
info(message);
34-
}
71+
info(msg);
72+
});
3573
}
3674

37-
// Path constants
38-
const rootDir = "../";
39-
const sprinklesDir = rootDir + "app/sprinkles/";
40-
const sprinklesSchemaPath = rootDir + "app/sprinkles.json";
41-
const publicAssetsDir = rootDir + "public/assets/";
42-
const legacyVendorAssetsGlob = rootDir + "sprinkles/*/assets/vendor/**";
43-
const sprinkleBundleFile = "asset-bundles.json";
44-
const vendorAssetsDir = rootDir + "app/assets/";
45-
const buildDirFromVendorAssetsDir = "../../build/";
75+
/**
76+
* Runs the provided command and captures output.
77+
* @param {string} cmd Command to execute.
78+
* @param {childProcess.ExecOptions} options Options to pass to `exec`.
79+
*/
80+
async function RunCommand(cmd, options) {
81+
Logger(`Running command "${cmd}"`, "CMD");
82+
83+
try {
84+
const result = await exec(cmd, options);
85+
if (result.stdout) Logger(result.stdout, `CMD> ${cmd}`);
86+
if (result.stderr) Logger(result.stderr, `CMD> ${cmd}`);
87+
} catch (e) {
88+
if (e.stdout) Logger(e.stdout, `CMD> ${cmd}`);
89+
if (e.stderr) Logger(e.stderr, `CMD> ${cmd}`);
90+
Logger(`Command "${cmd}" has completed with an error`, "CMD");
91+
throw e;
92+
}
93+
94+
Logger(`Command "${cmd}" has completed successfully`, "CMD");
95+
}
4696

4797
// Load sprinkles
4898
let sprinkles;
@@ -84,29 +134,28 @@ export async function assetsInstall() {
84134
private: true
85135
};
86136
Logger("Collating dependencies...");
87-
const pkg = mergeNpmDeps(npmTemplate, npmPaths, vendorAssetsDir, doILog);
137+
const pkg = mergeNpmDeps(npmTemplate, npmPaths, vendorAssetsDir, true);
88138
Logger("Dependency collation complete.");
89139

140+
Logger("Using npm from PATH variable");
141+
90142
// Remove any existing unneeded dependencies
91-
Logger("Running npm prune (using npm from PATH)");
92-
execSync("npm prune", {
93-
cwd: vendorAssetsDir,
94-
stdio: doILog ? "inherit" : ""
143+
Logger("Removing extraneous dependencies");
144+
await RunCommand("npm prune", {
145+
cwd: vendorAssetsDir
95146
});
96147

97148
// Perform installation
98-
Logger("Running npm install (using npm from PATH)");
99-
execSync("npm install", {
100-
cwd: vendorAssetsDir,
101-
stdio: doILog ? "inherit" : ""
149+
Logger("Installing dependencies");
150+
await RunCommand("npm install", {
151+
cwd: vendorAssetsDir
102152
});
103153

104154
// Conduct audit
105-
Logger("Running npm audit (using npm from PATH)");
155+
Logger("Running audit");
106156
try {
107-
execSync("npm audit", {
108-
cwd: vendorAssetsDir,
109-
stdio: doILog ? "inherit" : ""
157+
await RunCommand("npm audit", {
158+
cwd: vendorAssetsDir
110159
});
111160
}
112161
catch {
@@ -156,23 +205,22 @@ export async function assetsInstall() {
156205
name: "uf-vendor-assets"
157206
};
158207
Logger("Collating dependencies...");
159-
mergeBowerDeps(bowerTemplate, bowerPaths, vendorAssetsDir, doILog);
208+
mergeBowerDeps(bowerTemplate, bowerPaths, vendorAssetsDir, true);
160209
Logger("Dependency collation complete.");
161210

162211
// Perform installation
163-
Logger("Running bower install -q --allow-root");
212+
Logger("Installed dependencies");
164213
// --allow-root stops bower from complaining about being in 'sudo' in various situations
165-
execSync(normalisePath(buildDirFromVendorAssetsDir + "node_modules/.bin/bower") + " install -q --allow-root", {
166-
cwd: vendorAssetsDir,
167-
stdio: doILog ? "inherit" : ""
214+
await RunCommand("bower install -q --allow-root", {
215+
cwd: vendorAssetsDir
168216
});
217+
169218

170219
// Prune any unnecessary dependencies
171-
Logger("Running bower prune -q --allow-root");
220+
Logger("Removing extraneous dependencies");
172221
// --allow-root stops bower from complaining about being in 'sudo' in various situations
173-
execSync("bower prune -q --allow-root", {
174-
cwd: vendorAssetsDir,
175-
stdio: doILog ? "inherit" : ""
222+
await RunCommand("bower prune -q --allow-root", {
223+
cwd: vendorAssetsDir
176224
});
177225
}
178226
else {
@@ -222,10 +270,10 @@ export function bundle() {
222270
let fileContent;
223271
try {
224272
fileContent = readFileSync(sprinklesDir + sprinkle + "/" + sprinkleBundleFile);
225-
Logger(` Read '${sprinkleBundleFile}'.`);
273+
Logger(`Read '${sprinkleBundleFile}'.`, sprinkle);
226274
}
227275
catch (error) {
228-
Logger(` No '${sprinkleBundleFile}' detected, or can't be read.`);
276+
Logger(`No '${sprinkleBundleFile}' detected, or can't be read.`, sprinkle);
229277
continue;
230278
}
231279

@@ -235,10 +283,10 @@ export function bundle() {
235283
rawConfig = JSON.parse(fileContent);
236284
ValidateRawConfig(rawConfig);
237285
rawConfigs.push(rawConfig);
238-
Logger(" Asset bundles validated and loaded.");
286+
Logger("Asset bundles validated and loaded.", sprinkle);
239287
}
240288
catch (error) {
241-
Logger(" Asset bundle is invalid.");
289+
Logger("Asset bundle is invalid.", sprinkle);
242290
throw error;
243291
}
244292
}
@@ -260,9 +308,8 @@ export function bundle() {
260308
// Set base path for bundle resources to align with virtual paths
261309
rawConfig.BundlesVirtualBasePath = "./assets/";
262310

263-
// Bundle results callback
264311
/**
265-
*
312+
* Bundle results callback.
266313
* @param {Map<string, any[]} results
267314
*/
268315
function bundleResults(results) {
@@ -321,7 +368,7 @@ export function bundle() {
321368
// Logger adapter
322369
function LoggerAdapter(message, loglevel) {
323370
// Normal level and above
324-
if (loglevel > 0) {
371+
if (loglevel > 0 || debug) {
325372
Logger(message, "gulp-bundle-assets");
326373
}
327374
}

build/package.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,24 @@
55
"@userfrosting/gulp-bundle-assets": "^3.0.0-rc.2",
66
"@userfrosting/merge-package-dependencies": "^1.2.1",
77
"bower": "^1.8.8",
8-
"esm": "^3.2.5",
98
"del": "^3.0.0",
109
"dotenv": "^6.2.0",
10+
"esm": "^3.2.6",
1111
"gulp": "^4.0.0",
1212
"gulp-clean-css": "^4.0.0",
1313
"gulp-concat": "^2.6.1",
1414
"gulp-concat-css": "^3.1.0",
1515
"gulp-prune": "^0.2.0",
1616
"gulp-rev": "^9.0.0",
1717
"gulp-uglify-es": "^1.0.4",
18-
"gulplog": "^1.0.0"
18+
"gulplog": "^1.0.0",
19+
"strip-ansi": "^5.0.0"
1920
},
2021
"scripts": {
21-
"uf-bundle": "gulp bundle",
22-
"uf-assets-install": "gulp assetsInstall",
23-
"uf-frontend": "gulp frontend",
24-
"uf-clean": "gulp clean"
22+
"uf-bundle": "./node_modules/.bin/gulp bundle",
23+
"uf-assets-install": "./node_modules/.bin/gulp assetsInstall",
24+
"uf-frontend": "./node_modules/.bin/gulp frontend",
25+
"uf-clean": "./node_modules/.bin/gulp clean"
2526
},
2627
"engines": {
2728
"node": ">=10.12.0",

0 commit comments

Comments
 (0)