From 44b31f326b486b9c849e3b802004f9209c24034a Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Mon, 8 Jun 2015 18:56:24 -0700 Subject: [PATCH] build(broccoli): log the build tree after each build into tmp/build.*.log This log can then be used to visualize the build tree and map paths in the tmp/ dir to individual nodes in the build tree. --- tools/broccoli/angular_builder.ts | 63 +++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/tools/broccoli/angular_builder.ts b/tools/broccoli/angular_builder.ts index 4f7f6a10b0..e1c8983dab 100644 --- a/tools/broccoli/angular_builder.ts +++ b/tools/broccoli/angular_builder.ts @@ -1,5 +1,5 @@ var broccoli = require('broccoli'); -var fse = require('fs-extra'); +var fs = require('fs'); var makeBrowserTree = require('./trees/browser_tree'); var makeNodeTree = require('./trees/node_tree'); var makeDartTree = require('./trees/dart_tree'); @@ -16,31 +16,32 @@ export class AngularBuilder { private browserProdBuilder: BroccoliBuilder; private dartBuilder: BroccoliBuilder; private outputPath: string; + private firstResult: BuildResult; constructor(public options: AngularBuilderOptions) { this.outputPath = options.outputPath; } public rebuildBrowserDevTree(): Promise { this.browserDevBuilder = this.browserDevBuilder || this.makeBrowserDevBuilder(); - return this.rebuild(this.browserDevBuilder); + return this.rebuild(this.browserDevBuilder, 'js.dev'); } public rebuildBrowserProdTree(): Promise { this.browserProdBuilder = this.browserProdBuilder || this.makeBrowserProdBuilder(); - return this.rebuild(this.browserProdBuilder); + return this.rebuild(this.browserProdBuilder, 'js.prod'); } public rebuildNodeTree(): Promise { this.nodeBuilder = this.nodeBuilder || this.makeNodeBuilder(); - return this.rebuild(this.nodeBuilder); + return this.rebuild(this.nodeBuilder, 'js.cjs'); } public rebuildDartTree(): Promise { this.dartBuilder = this.dartBuilder || this.makeDartBuilder(); - return this.rebuild(this.dartBuilder); + return this.rebuild(this.dartBuilder, 'dart'); } @@ -84,7 +85,55 @@ export class AngularBuilder { } - private rebuild(builder) { - return builder.build().then((result) => { printSlowTrees(result.graph); }); + private rebuild(builder, name) { + return builder.build().then( + (result) => { + if (!this.firstResult) { + this.firstResult = result; + } + + printSlowTrees(result.graph); + writeBuildLog(result, name); + }, + (error) => { + // the build tree is the same during rebuilds, only leaf properties of the nodes change + // so let's traverse it and get updated values for input/cache/output paths + if (this.firstResult) { + writeBuildLog(this.firstResult, name); + } + throw error; + }); + } +} + + +function writeBuildLog(result: BuildResult, name: string) { + let logPath = `tmp/build.${name}.log`; + let prevLogPath = logPath + '.previous'; + let formattedLogContent = JSON.stringify(broccoliNodeToBuildNode(result.graph), null, 2); + + if (fs.existsSync(prevLogPath)) fs.unlinkSync(prevLogPath); + if (fs.existsSync(logPath)) fs.renameSync(logPath, prevLogPath); + fs.writeFileSync(logPath, formattedLogContent, {encoding: 'utf-8'}); +} + + +function broccoliNodeToBuildNode(broccoliNode) { + let tree = broccoliNode.tree.newStyleTree || broccoliNode.tree; + + return new BuildNode( + tree.description || tree.constructor.name, + tree.inputPath ? [tree.inputPath] : tree.inputPaths, + tree.cachePath, + tree.outputPath, + broccoliNode.subtrees.map(broccoliNodeToBuildNode) + ); +} + + +class BuildNode { + + constructor(public pluginName:string, public inputPaths: string[], public cachePath: string, + public outputPath: string, public inputNodes: BroccoliNode[]) { } }