Repository navigation
build(broccoli): add tree-stabilizer plugin to deal with unstable trees #2143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7b1e928
c1157d6
533c64d
9b0fa0d
160c38b
05becf8
b144174
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| /// <reference path="broccoli.d.ts" /> | ||
| /// <reference path="../typings/node/node.d.ts" /> | ||
|
|
||
| import fs = require('fs'); | ||
| let symlinkOrCopy = require('symlink-or-copy'); | ||
|
|
||
|
|
||
| /** | ||
| * Stabilizes the inputPath for the following plugins in the build tree. | ||
| * | ||
| * All broccoli plugins that inherit from `broccoli-writer` or `broccoli-filter` change their | ||
| * outputPath during each rebuild. | ||
| * | ||
| * This means that all following plugins in the build tree can't rely on their inputPath being | ||
| * immutable. This results in breakage of any plugin that is not expecting such behavior. | ||
| * | ||
| * For example all `DiffingBroccoliPlugin`s expect their inputPath to be stable. | ||
| * | ||
| * By inserting this plugin into the tree after any misbehaving plugin, we can stabilize the | ||
| * inputPath for the following plugin in the tree and correct the surprising behavior. | ||
| */ | ||
| class TreeStabilizer implements BroccoliTree { | ||
| inputPath: string; | ||
| outputPath: string; | ||
|
|
||
|
|
||
| constructor(public inputTree: BroccoliTree) {} | ||
|
|
||
|
|
||
| rebuild() { | ||
| fs.rmdirSync(this.outputPath); | ||
|
|
||
| // TODO: investigate if we can use rename the directory instead to improve performance on | ||
| // Windows | ||
| symlinkOrCopy.sync(this.inputPath, this.outputPath); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This extra tree is just moving the workaround that's already happening elsewhere, which sort of seems like a non-solution, to be honest. I think we're better off talking to @joliss about making sure the contracts of the inputPath(s) and outputPath/cachePath properties make sense, are well established, and are stable across versions
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to be clear, this change is just a workaround for incorrect behavior in some broccoli plugins. my goal is to replace all of the significant plugins in our build chain with diffing plugins, and for those we can skip this operation. as @joliss confirmed, eventually this should not be a problem for any plugins as they'll get rewritten to work differently. |
||
| } | ||
|
|
||
|
|
||
| cleanup() {} | ||
| } | ||
|
|
||
|
|
||
| export default function stabilizeTree(inputTree) { | ||
| return new TreeStabilizer(inputTree); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rmdirSync will fail if non-empty, which it probably is. use rimraf or fs-extra instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, (using rimraf), if outputPath is a symlink of inputPath, isn't that going to remove everything in the inputPath? That seems like a not good thing to happen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: Calling rimraf (or fs-extra, which calls rimraf) on a symlink will only remove the symlink, not descend into the target directory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@caitp unless there is a bug in the system, we can't get into a situation where the underlying directory doesn't exist. output path is created by broccoli builder for each rebuild unless it already exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That doesn't address what my comment is saying. "rmdirSync" will fail (read: throw) if the directory is non-empty. We aren't talking about whether it exists or not, we're talking about it being non-empty, which it probably is. This most likely works correctly on unix systems where symlinkOrCopy is not copying, but on windows machines it's likely to break