| // Copyright 2022 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import * as esbuild from 'esbuild'; |
| import * as fs from 'fs/promises'; |
| |
| import { |
| peggyPlugin, syntaxPlugin, testsPlugin, generateFlags, |
| allSyntax, formatMachineOutput, makeWatch, resultsToXML |
| } from './build-helpers.mjs'; |
| |
| /// determines if we generate sourcemaps & such |
| const IS_DEV = process.env.NODE_ENV !== 'production'; |
| if (process.argv.length > 3 || (process.argv.length == 3 && process.argv[2] !== 'watch')) { |
| console.error("usage: node build.mjs [watch]"); |
| console.error(`(saw "${process.argv}")`); |
| } |
| const IS_MACHINE = process.env.MACHINE === 'true'; |
| |
| const logLevel = IS_MACHINE ? 'silent' : undefined; |
| |
| // our configs |
| // |
| // notice that we catch errors -- we don't want to bail the entire script if |
| // we fail, since we want to be able to convert to test xml |
| |
| let syntaxFiles = await allSyntax(); |
| const hostCfg = esbuild.build({ |
| bundle: true, |
| platform: 'node', |
| format: 'cjs', |
| entryPoints: ['./src/extension.ts'], |
| outfile: 'dist/extension.js', |
| external: ['vscode'], |
| sourcemap: IS_DEV ? 'linked' : '', |
| minify: !IS_DEV, |
| watch: makeWatch("host"), |
| logLevel, |
| }).catch((res) => res); |
| |
| const resCfg = esbuild.build({ |
| entryPoints: syntaxFiles, |
| entryNames: 'resources/[dir]/[name]', |
| plugins: [syntaxPlugin], |
| outbase: '.', |
| outdir: 'dist', |
| watch: makeWatch("res"), |
| logLevel, |
| }).catch((res) => res); |
| |
| const viewCfg = esbuild.build({ |
| bundle: true, |
| platform: 'browser', |
| entryPoints: ['./webviews/logging'], |
| outdir: 'dist', |
| outbase: '.', |
| plugins: [peggyPlugin], |
| entryNames: '[dir]-[name]', |
| sourcemap: IS_DEV ? 'linked' : '', |
| loader: { |
| '.ttf': 'file', |
| '.css': 'text', |
| }, |
| minify: !IS_DEV, |
| watch: makeWatch("view"), |
| logLevel, |
| }).catch((res) => res); |
| |
| // Export the logging view component as a re-usable UI module that can be used |
| // by any external project. |
| const viewModuleCfg = esbuild.build({ |
| bundle: true, |
| platform: 'node', |
| entryPoints: ['./webviews/logging/module.ts'], |
| outdir: 'dist', |
| outbase: '.', |
| plugins: [peggyPlugin], |
| entryNames: '[dir]-[name]', |
| sourcemap: IS_DEV ? 'linked' : '', |
| loader: { |
| '.ttf': 'file', |
| '.css': 'text', |
| }, |
| minify: !IS_DEV, |
| watch: makeWatch("view"), |
| logLevel, |
| }).catch((res) => res); |
| |
| |
| const testCfg = esbuild.build({ |
| bundle: true, |
| platform: 'node', |
| external: [ |
| 'vscode', |
| 'canvas' /* conditional import, not in use */, |
| 'mocha' /* does funky things */, |
| 'jsdom' /* does funky things */, |
| 'vscode-oniguruma', /* we import files from it via require.resolve */ |
| ], |
| entryPoints: ['./src/test/run_test.ts', './src/test/suite/index.ts', 'all-tests'], |
| outdir: 'test-dist', |
| sourcemap: true, |
| plugins: [peggyPlugin, testsPlugin('./src/**/*.test.ts')], |
| watch: makeWatch("test"), |
| logLevel, |
| }).catch((res) => res); |
| |
| const webviewTestCfg = (async () => { |
| return await esbuild.build({ |
| bundle: true, |
| platform: 'browser', |
| entryPoints: ['all-tests'], |
| external: [], |
| outdir: 'test-webview-dist', |
| sourcemap: true, |
| loader: { |
| '.ttf': 'file', |
| }, |
| plugins: [peggyPlugin, testsPlugin('./webviews/**/*.test.ts')], |
| watch: makeWatch('test-webview'), |
| logLevel, |
| }); |
| })(); |
| |
| // awaiting will print the results, but we want the results as objects (mapped |
| // to their names) in case we need to write test xml for CI |
| let mainPromises = [ |
| ['host', hostCfg], |
| ['view', viewCfg], |
| ['viewModule', viewModuleCfg], |
| ['resources', resCfg], |
| ['test', testCfg], |
| ['webview-test', webviewTestCfg] |
| ]; |
| let resultsWithoutName = await Promise.all(mainPromises.map(([_name, prom]) => prom)); |
| |
| // do the flags plugin afterwards, because it messes with package.json and |
| // doing it in paralell can cause issues. It doesn't generate any files, |
| // so it's not gonna cause bundling issues to do it later. |
| let flagsRes = await generateFlags() |
| .then(() => ({errors: [], warnings: []})) |
| .catch((res) => { |
| let wrapper = new Error("unable to convert flags to settings"); |
| wrapper.errors = [{ |
| text: res.toString(), |
| detail: res, |
| }]; |
| wrapper.warnings = []; |
| return wrapper; |
| }); |
| |
| // write the results as test XML if on CI |
| let results = mainPromises.map(([name, _p], i) => [name, resultsWithoutName[i]]); |
| results.push(['flags', flagsRes]); |
| |
| if (!!process.env.BUILD_XML_OUTPUT) { |
| console.debug('writing build results to test XML'); |
| await fs.writeFile(process.env.BUILD_XML_OUTPUT, resultsToXML(results)); |
| } |
| if (IS_MACHINE) { |
| for (const [name, res] of results) { |
| const out = formatMachineOutput(res, name); |
| if (!out) continue; |
| |
| if (res instanceof Error) { console.error(out); } |
| else { console.log(out); } |
| } |
| } |
| |
| // finally, check if we need to exit as unsuccesful |
| // (since swallow exceptions above) |
| if (results.some(([_n, res]) => res instanceof Error)) { |
| process.exit(1); |
| } |