Skip to content

Commit

Permalink
Adds support for requiring external modules on startup (#550)
Browse files Browse the repository at this point in the history
* Adds support for requiring external modules on startup

* Add a test to verify the `--require` flag works. Only run it in full mode.
  • Loading branch information
TwitchBronBron authored Mar 30, 2022
1 parent eb15d1a commit aecec56
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 2 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -24,6 +24,7 @@
"ts-node/register"
],
"fullTrace": true,
"timeout": 987654321,
"watchExtensions": [
"ts"
]
Expand Down
37 changes: 37 additions & 0 deletions src/cli.spec.ts
Original file line number Diff line number Diff line change
@@ -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;
});
}
});
17 changes: 16 additions & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.' })
Expand All @@ -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;
Expand All @@ -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(<any>options).then(() => {
//if this is a single run (i.e. not watch mode) and there are error diagnostics, return an error code
Expand All @@ -51,3 +65,4 @@ builder.run(<any>options).then(() => {
console.error(error);
process.exit(1);
});

0 comments on commit aecec56

Please sign in to comment.