diff --git a/docs/error-propagation.md b/docs/error-propagation.md index 7850d6eaa9..0be9843a47 100644 --- a/docs/error-propagation.md +++ b/docs/error-propagation.md @@ -26,9 +26,9 @@ Error contains information of where in the file error occurred and what kind of Because `ember-cli-htmlbars` is based on `broccoli-persistent-filter`, technically `broccoli-persistent-filter` will catch the exception first. For example, we attach `file` and `treeDir` information to errors [here](https://github.com/stefanpenner/broccoli-persistent-filter/blob/v1.3.1/index.js#L267-L272). -+ `broccoli-builder` catches the error ++ `broccoli` catches the error -Ember CLI uses `broccoli-builder` to build its trees so if `broccoli-builder` throws an error, +Ember CLI uses `broccoli` to build its trees so if `broccoli` throws an error, Ember CLI is aware and can act accordingly. At this level, we can attach more information to the error, like `broccoli` node/annotation. @@ -36,7 +36,7 @@ At this level, we can attach more information to the error, like `broccoli` node + `broccoli-middleware` catches the error This is where we return an error page for the browser. Given all the information, we get from `ember-cli-htmlbars` -and `broccoli-builder`, we show an error page. +and `broccoli`, we show an error page. ## Error object diff --git a/lib/models/builder.js b/lib/models/builder.js index e016467055..39d01f81ca 100644 --- a/lib/models/builder.js +++ b/lib/models/builder.js @@ -24,9 +24,6 @@ class Builder extends CoreObject { constructor(options) { super(options); - // Use Broccoli 2.0 by default, if this fails due to .read/.rebuild API, fallback to broccoli-builder - this.broccoliBuilderFallback = false; - this._instantiationStack = new Error().stack.replace(/[^\n]*\n/, ''); this._cleanup = this.cleanup.bind(this); @@ -67,31 +64,8 @@ class Builder extends CoreObject { this.tree = await this.readBuildFile(this.project.root); - let broccoli = require('broccoli'); - - try { - this.builder = new broccoli.Builder(this.tree); - return; - } catch (e) { - // Catch here to trap InvalidNodeError. If this is thrown, it's because the node provided is not valid - // and likely uses the old .read/.rebuild API, so fallback to broccoli-builder that supports that API - if ( - !(e instanceof broccoli.Builder.InvalidNodeError) || - e.message.indexOf('The .read/.rebuild API is no longer supported as of Broccoli 1.0') === -1 - ) { - throw e; - } + const broccoli = require('broccoli'); - // Fallback to broccoli-builder - let error = `Invalid Broccoli2 node detected, falling back to broccoli-builder. Broccoli error:\n`; - error += `---------------\n`; - error += e.message; - error += `---------------\n`; - this.ui.writeWarnLine(error); - } - - broccoli = require('broccoli-builder'); - this.broccoliBuilderFallback = true; this.builder = new broccoli.Builder(this.tree); } @@ -179,7 +153,7 @@ class Builder extends CoreObject { try { this.project._instrumentation.start('build'); - if (addWatchDirCallback && !this.broccoliBuilderFallback) { + if (addWatchDirCallback) { for (let path of this.builder.watchedPaths) { addWatchDirCallback(path); } @@ -193,24 +167,16 @@ class Builder extends CoreObject { await this.processAddonBuildSteps('preBuild'); - if (this.broccoliBuilderFallback) { - try { - buildResults = await this.builder.build(addWatchDirCallback); - } catch (error) { - this.throwFormattedBroccoliError(error); - } - } else { - try { - await this.builder.build(); - - // build legacy style results object (this is passed to various addon APIs) - buildResults = { - directory: this.builder.outputPath, - graph: this.builder.outputNodeWrapper, - }; - } catch (error) { - this.throwFormattedBroccoliError(error); - } + try { + await this.builder.build(); + + // build legacy style results object (this is passed to various addon APIs) + buildResults = { + directory: this.builder.outputPath, + graph: this.builder.outputNodeWrapper, + }; + } catch (error) { + this.throwFormattedBroccoliError(error); } await this.processAddonBuildSteps('postBuild', buildResults); @@ -316,12 +282,8 @@ class Builder extends CoreObject { }; } if (!broccoliPayload.versions) { - let builderVersion = this.broccoliBuilderFallback - ? require('broccoli-builder/package').version - : require('broccoli/package').version; - broccoliPayload.versions = { - 'broccoli-builder': builderVersion, + broccoli: require('broccoli/package').version, node: process.version, }; } diff --git a/package.json b/package.json index 839e743f53..bef0c5fe6f 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ "@pnpm/find-workspace-dir": "^7.0.2", "babel-remove-types": "^1.0.0", "broccoli": "^3.5.2", - "broccoli-builder": "^0.18.14", "broccoli-concat": "^4.2.5", "broccoli-config-loader": "^1.0.1", "broccoli-config-replace": "^1.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7f1b17a1d8..dde056c060 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,9 +17,6 @@ importers: broccoli: specifier: ^3.5.2 version: 3.5.2 - broccoli-builder: - specifier: ^0.18.14 - version: 0.18.14 broccoli-concat: specifier: ^4.2.5 version: 4.2.5 @@ -241,7 +238,7 @@ importers: version: 0.9.4 testem: specifier: ^3.15.2 - version: 3.15.2 + version: 3.15.2(bufferutil@4.0.8)(handlebars@4.7.8)(underscore@1.13.7)(utf-8-validate@5.0.10) tiny-lr: specifier: ^2.0.0 version: 2.0.0 @@ -305,13 +302,13 @@ importers: version: 16.6.2(eslint@8.57.1) eslint-plugin-prettier: specifier: ^4.2.1 - version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.1)(prettier@2.8.7) + version: 4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.7) fixturify: specifier: ^3.0.0 version: 3.0.0 jsdom: specifier: ^21.1.1 - version: 21.1.2 + version: 21.1.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) latest-version: specifier: ^5.1.0 version: 5.1.0 @@ -1067,10 +1064,6 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - broccoli-builder@0.18.14: - resolution: {integrity: sha512-YoUHeKnPi4xIGZ2XDVN9oHNA9k3xF5f5vlA+1wvrxIIDXqQU97gp2FxVAF503Zxdtt0C5CRB5n+47k2hlkaBzA==} - engines: {node: '>= 0.10.0'} - broccoli-caching-writer@3.0.3: resolution: {integrity: sha512-g644Kb5uBPsy+6e2DvO3sOc+/cXZQQNgQt64QQzjA9TSdP0dl5qvetpoNIx4sy/XIjrPYG1smEidq9Z9r61INw==} @@ -2769,7 +2762,7 @@ packages: engines: {node: '>= 0.4'} hawk@1.1.1: - resolution: {integrity: sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=} + resolution: {integrity: sha512-am8sVA2bCJIw8fuuVcKvmmNnGFUGW8spTkVtj2fXTEZVkfN42bwFZFtDem57eFi+NSxurJB8EQ7Jd3uCHLn8Vw==} engines: {node: '>=0.8.0'} deprecated: This module moved to @hapi/hawk. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues. @@ -6272,18 +6265,6 @@ snapshots: dependencies: fill-range: 7.1.1 - broccoli-builder@0.18.14: - dependencies: - broccoli-node-info: 1.1.0 - heimdalljs: 0.2.6 - promise-map-series: 0.2.3 - quick-temp: 0.1.8 - rimraf: 2.7.1 - rsvp: 3.6.2 - silent-error: 1.1.1 - transitivePeerDependencies: - - supports-color - broccoli-caching-writer@3.0.3: dependencies: broccoli-kitchen-sink-helpers: 0.3.1 @@ -6908,11 +6889,14 @@ snapshots: ora: 3.4.0 through2: 3.0.2 - consolidate@0.16.0(lodash@4.17.21)(mustache@4.2.0): + consolidate@0.16.0(handlebars@4.7.8)(lodash@4.17.21)(mustache@4.2.0)(underscore@1.13.7): dependencies: bluebird: 3.7.2 + optionalDependencies: + handlebars: 4.7.8 lodash: 4.17.21 mustache: 4.2.0 + underscore: 1.13.7 content-disposition@0.5.4: dependencies: @@ -7038,6 +7022,7 @@ snapshots: debug@4.4.0(supports-color@8.1.1): dependencies: ms: 2.1.3 + optionalDependencies: supports-color: 8.1.1 decamelize@1.2.0: {} @@ -7255,7 +7240,7 @@ snapshots: engine.io-parser@5.2.3: {} - engine.io@6.6.2: + engine.io@6.6.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.17 @@ -7266,7 +7251,7 @@ snapshots: cors: 2.8.5 debug: 4.3.7 engine.io-parser: 5.2.3 - ws: 8.17.1 + ws: 8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - supports-color @@ -7464,12 +7449,13 @@ snapshots: resolve: 1.22.9 semver: 7.6.3 - eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0)(eslint@8.57.1)(prettier@2.8.7): + eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.7): dependencies: eslint: 8.57.1 - eslint-config-prettier: 8.10.0(eslint@8.57.1) prettier: 2.8.7 prettier-linter-helpers: 1.0.0 + optionalDependencies: + eslint-config-prettier: 8.10.0(eslint@8.57.1) eslint-scope@7.2.2: dependencies: @@ -7757,7 +7743,7 @@ snapshots: bser: 2.1.1 fdir@6.4.2(picomatch@4.0.2): - dependencies: + optionalDependencies: picomatch: 4.0.2 fetch-blob@3.2.0: @@ -8913,7 +8899,7 @@ snapshots: jsbn@1.1.0: {} - jsdom@21.1.2: + jsdom@21.1.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: abab: 2.0.6 acorn: 8.14.0 @@ -8939,7 +8925,7 @@ snapshots: whatwg-encoding: 2.0.0 whatwg-mimetype: 3.0.0 whatwg-url: 12.0.1 - ws: 8.18.0 + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) xml-name-validator: 4.0.0 transitivePeerDependencies: - bufferutil @@ -10393,10 +10379,10 @@ snapshots: hoek: 0.9.1 optional: true - socket.io-adapter@2.5.5: + socket.io-adapter@2.5.5(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: debug: 4.3.7 - ws: 8.17.1 + ws: 8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - supports-color @@ -10409,14 +10395,14 @@ snapshots: transitivePeerDependencies: - supports-color - socket.io@4.8.1: + socket.io@4.8.1(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: accepts: 1.3.8 base64id: 2.0.0 cors: 2.8.5 debug: 4.3.7 - engine.io: 6.6.2 - socket.io-adapter: 2.5.5 + engine.io: 6.6.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + socket.io-adapter: 2.5.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) socket.io-parser: 4.2.4 transitivePeerDependencies: - bufferutil @@ -10671,7 +10657,7 @@ snapshots: stringify-object-es5: 2.5.0 theredoc: 1.0.0 - testem@3.15.2: + testem@3.15.2(bufferutil@4.0.8)(handlebars@4.7.8)(underscore@1.13.7)(utf-8-validate@5.0.10): dependencies: '@xmldom/xmldom': 0.8.10 backbone: 1.6.0 @@ -10679,7 +10665,7 @@ snapshots: charm: 1.0.2 commander: 2.20.3 compression: 1.7.5 - consolidate: 0.16.0(lodash@4.17.21)(mustache@4.2.0) + consolidate: 0.16.0(handlebars@4.7.8)(lodash@4.17.21)(mustache@4.2.0)(underscore@1.13.7) execa: 1.0.0 express: 4.21.2 fireworm: 0.7.2 @@ -10693,7 +10679,7 @@ snapshots: npmlog: 6.0.2 printf: 0.6.1 rimraf: 3.0.2 - socket.io: 4.8.1 + socket.io: 4.8.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) spawn-args: 0.2.0 styled_string: 0.0.1 tap-parser: 7.0.0 @@ -11268,9 +11254,15 @@ snapshots: signal-exit: 3.0.7 typedarray-to-buffer: 3.1.5 - ws@8.17.1: {} + ws@8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 - ws@8.18.0: {} + ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 xdg-basedir@4.0.0: {} diff --git a/tests/unit/broccoli/builder-test.js b/tests/unit/broccoli/builder-test.js deleted file mode 100644 index 908485d1f8..0000000000 --- a/tests/unit/broccoli/builder-test.js +++ /dev/null @@ -1,100 +0,0 @@ -'use strict'; - -const broccoliTestHelper = require('broccoli-test-helper'); -const { expect } = require('chai'); - -const MockProject = require('../../helpers/mock-project'); -const Builder = require('../../../lib/models/builder'); - -const { createTempDir, fromBuilder } = broccoliTestHelper; -const ROOT = process.cwd(); - -describe('Builder - broccoli tests', function () { - let projectRoot, builderOutputPath, output, project, builder; - - beforeEach(async function () { - projectRoot = await createTempDir(); - builderOutputPath = await createTempDir(); - - project = new MockProject({ root: projectRoot.path() }); - }); - - afterEach(async function () { - // this is needed because lib/utilities/find-build-file.js does a - // `process.chdir` when it looks for the `ember-cli-build.js` - process.chdir(ROOT); - - await projectRoot.dispose(); - await builderOutputPath.dispose(); - await output.dispose(); - }); - - it('falls back to broccoli-builder@0.18 when legacy plugins exist in build', async function () { - projectRoot.write({ - 'ember-cli-build.js': ` - const fs = require('fs'); - const os = require('os'); - const crypto = require('crypto'); - - function randomString() { - return crypto - .randomBytes(20) - .toString('base64') - .replace('+', '0') - .replace('/', '0'); - } - - function LegacyPlugin (inputTree) { - this.inputTree = inputTree; - this.tmpDestDir = os.tmpdir() + '/' + randomString(); - } - - LegacyPlugin.prototype.read = function(readTree) { - fs.mkdirSync(this.tmpDestDir); // doesn't handle rebuilds, yolo - - return readTree(this.inputTree).then(inputDir => { - let sourceFile = inputDir + '/hello.txt'; - let destFile = this.tmpDestDir + '/hello.txt'; - let sourceContent = fs.readFileSync(sourceFile, 'utf-8'); - - fs.writeFileSync(destFile, sourceContent); - - return this.tmpDestDir; - }); - } - - module.exports = function () { - return new LegacyPlugin(__dirname + '/app'); - } - `, - app: { - 'hello.txt': '// hello!', - }, - }); - - builder = new Builder({ - project, - ui: project.ui, - onProcessInterrupt: { - addHandler() {}, - removeHandler() {}, - }, - outputPath: builderOutputPath.path(), - }); - - output = fromBuilder(builder); - await output.build(); - - expect(output.read()).to.deep.equal({ - 'hello.txt': '// hello!', - }); - - expect(builder.broccoliBuilderFallback).to.be.true; - expect(builder.ui.output).to.include( - 'WARNING: Invalid Broccoli2 node detected, falling back to broccoli-builder. Broccoli error:' - ); - expect(builder.ui.output).to.include( - 'LegacyPlugin: The .read/.rebuild API is no longer supported as of Broccoli 1.0. Plugins must now derive from broccoli-plugin. https://github.com/broccolijs/broccoli/blob/master/docs/broccoli-1-0-plugin-api.md' - ); - }); -}); diff --git a/tests/unit/models/addon-test.js b/tests/unit/models/addon-test.js index 4c594db171..2e2844d3f8 100644 --- a/tests/unit/models/addon-test.js +++ b/tests/unit/models/addon-test.js @@ -9,7 +9,7 @@ const MockUI = require('console-ui/mock'); const MockCLI = require('../../helpers/mock-cli'); const mkTmpDirIn = require('../../helpers/mk-tmp-dir-in'); -const broccoli = require('broccoli-builder'); +const broccoli = require('broccoli'); const walkSync = require('walk-sync'); const td = require('testdouble'); @@ -722,9 +722,9 @@ describe('models/addon.js', function () { it('should move files in the root of the addons app/styles tree into the app/styles path', async function () { builder = new broccoli.Builder(addon.treeFor('styles')); - let results = await builder.build(); - let outputPath = results.directory; + await builder.build(); + let outputPath = builder.outputPath; let expected = ['app/', 'app/styles/', 'app/styles/foo-bar.css']; expect(walkSync(outputPath)).to.eql(expected); diff --git a/tests/unit/models/builder-test.js b/tests/unit/models/builder-test.js index 3352c7081a..1eb7cc4b5f 100644 --- a/tests/unit/models/builder-test.js +++ b/tests/unit/models/builder-test.js @@ -20,7 +20,6 @@ describe('models/builder.js', function () { let addon, builder, buildResults, tmpdir; async function setupBroccoliBuilder() { - this.broccoliBuilderFallback = false; this.builder = { outputPath: 'build results', outputNodeWrapper: { @@ -518,43 +517,4 @@ describe('models/builder.js', function () { expect(error).to.haveOwnProperty('isBuilderError', true); }); }); - - describe('fallback from broccoli 2 to broccoli-builder', function () { - it('falls back to broccoli-builder if an InvalidNode error is thrown for read/rebuild api', async function () { - let project = new MockProject(); - const builder = new Builder({ - project, - ui: project.ui, - readBuildFile() { - return { - read() {}, - rebuild() {}, - }; - }, - }); - - await builder.setupBroccoliBuilder(); - expect(builder.broccoliBuilderFallback).to.be.true; - - expect(project.ui.output).to.include( - 'WARNING: Invalid Broccoli2 node detected, falling back to broccoli-builder. Broccoli error:' - ); - expect(project.ui.output).to.include( - 'Object: The .read/.rebuild API is no longer supported as of Broccoli 1.0. Plugins must now derive from broccoli-plugin. https://github.com/broccolijs/broccoli/blob/master/docs/broccoli-1-0-plugin-api.md' - ); - }); - - it('errors for an invalid node', function () { - let project = new MockProject(); - expect( - new Builder({ - project, - ui: project.ui, - readBuildFile() { - return {}; - }, - }).setupBroccoliBuilder() - ).to.be.rejectedWith('[object Object] is not a Broccoli node\nused as output node'); - }); - }); });