From e50fdd00cfdb26512cf26a56ea8f8771b240dfd6 Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Tue, 29 Mar 2022 14:35:50 -0400 Subject: [PATCH 1/2] Adds support for requiring external modules on startup --- src/cli.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/cli.ts b/src/cli.ts index 380dd0646..618478078 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -12,7 +12,7 @@ let options = yargs .option('cwd', { type: 'string', description: 'Override the current working directory.' }) .option('copy-to-staging', { type: 'boolean', defaultDescription: 'true', description: 'Copy project files into the staging folder, ready to be packaged.' }) .option('diagnostic-level', { type: 'string', defaultDescription: '"warn"', description: 'Specify what diagnostic types should be printed to the console. Value can be "error", "warn", "hint", "info".' }) - .option('plugins', { type: 'array', description: 'A list of scripts or modules to add extra diagnostics or transform the AST.' }) + .option('plugins', { type: 'array', alias: 'plugin', description: 'A list of scripts or modules to add extra diagnostics or transform the AST.' }) .option('deploy', { type: 'boolean', defaultDescription: 'false', description: 'Deploy to a Roku device if compilation succeeds. When in watch mode, this will deploy on every change.' }) .option('emit-full-paths', { type: 'boolean', defaultDescription: 'false', description: 'Emit full paths to files when encountering diagnostics.' }) .option('files', { type: 'array', description: 'The list of files (or globs) to include in your project. Be sure to wrap these in double quotes when using globs.' }) @@ -28,6 +28,7 @@ let options = yargs .option('username', { type: 'string', defaultDescription: '"rokudev"', description: 'The username for deploying to a Roku.' }) .option('source-root', { type: 'string', description: 'Override the root directory path where debugger should locate the source files. The location will be embedded in the source map to help debuggers locate the original source files. This only applies to files found within rootDir. This is useful when you want to preprocess files before passing them to BrighterScript, and want a debugger to open the original files.' }) .option('watch', { type: 'boolean', defaultDescription: 'false', description: 'Watch input files.' }) + .option('require', { type: 'array', description: 'A list of modules to require() on startup. Useful for doing things like ts-node registration.' }) .strict() .check(argv => { const diagnosticLevel = argv.diagnosticLevel as string; @@ -40,6 +41,19 @@ let options = yargs }) .argv; +/** + * load any node modules that the user passed in via CLI. Useful for doing things like ts-node registration + */ +function handleRequire() { + const cwd = options.cwd ?? process.cwd(); + const modules = (options?.require ?? []) as string[]; + for (const dep of modules) { + util.resolveRequire(cwd, dep); + } +} + +handleRequire(); + let builder = new ProgramBuilder(); builder.run(options).then(() => { //if this is a single run (i.e. not watch mode) and there are error diagnostics, return an error code @@ -51,3 +65,4 @@ builder.run(options).then(() => { console.error(error); process.exit(1); }); + From 3d9ac0d764208e2411d5d458b29b0e95f779bc15 Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Tue, 29 Mar 2022 15:46:55 -0400 Subject: [PATCH 2/2] Add a test to verify the `--require` flag works. Only run it in full mode. --- package.json | 3 ++- src/cli.spec.ts | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/cli.spec.ts diff --git a/package.json b/package.json index f76149af7..4f22efc00 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "prepublishOnly": "npm run build", "lint": "eslint \"src/**\"", "format": "tsfmt -r", - "test": "nyc mocha", + "test": "nyc mocha --all", "test:nocover": "mocha", "test:watch": "mocha --watch", "publish-coverage": "nyc report --reporter=text-lcov | coveralls", @@ -24,6 +24,7 @@ "ts-node/register" ], "fullTrace": true, + "timeout": 987654321, "watchExtensions": [ "ts" ] diff --git a/src/cli.spec.ts b/src/cli.spec.ts new file mode 100644 index 000000000..28109ba4e --- /dev/null +++ b/src/cli.spec.ts @@ -0,0 +1,37 @@ +import { standardizePath as s } from './util'; +import * as fsExtra from 'fs-extra'; +import { execSync } from 'child_process'; +import { expect } from 'chai'; + +const tempDir = s`${process.cwd()}/.tmp`; +const cliPath = s`${__dirname}/cli.ts`; + +describe('cli', () => { + let idx = 0; + let cwd: string; + beforeEach(() => { + cwd = s`${tempDir}/cli-test-${idx}`; + fsExtra.ensureDirSync(cwd); + }); + afterEach(() => { + fsExtra.emptyDirSync(cwd); + }); + + if (process.argv.includes('--all')) { + it('loads ts-node from the --require flag', () => { + fsExtra.outputFileSync(s`${cwd}/manifest`, ''); + const modulePath = s`${cwd}/module.js`; + //simple plugin that writes a file. If the file exists, we know the require syntax works + fsExtra.outputFileSync(modulePath, ` + var fs = require('fs'); + fs.writeFileSync('./testResult.txt', ''); + `); + execSync(`npx ts-node-transpile-only "${cliPath}" --require "${modulePath}"`, { + cwd: cwd + }); + expect( + fsExtra.pathExistsSync(s`${cwd}/testResult.txt`) + ).to.be.true; + }); + } +});