diff --git a/README.md b/README.md
index 3df3d34c9..0b3e64047 100644
--- a/README.md
+++ b/README.md
@@ -540,6 +540,16 @@ Type: `boolean`
Allow BrighterScript features (classes, interfaces, etc...) to be included in BrightScript (`.brs`) files, and force those files to be transpiled.
+#### `bslibDestinationDir`
+
+Type: `string`
+
+Override the destination directory for the bslib.brs file. Use this if you want
+to customize where the bslib.brs file is located in the staging directory. Note
+that using a location outside of `source` will break scripts inside `source`
+that depend on bslib.brs. Defaults to `source`.
+
+
## Ignore errors and warnings on a per-line basis
In addition to disabling an entire class of errors in `bsconfig.json` by using `ignoreErrorCodes`, you may also disable errors for a subset of the complier rules within a file with the following comment flags:
- `bs:disable-next-line`
diff --git a/src/BsConfig.ts b/src/BsConfig.ts
index 40fd49cc9..8dc633e7a 100644
--- a/src/BsConfig.ts
+++ b/src/BsConfig.ts
@@ -182,4 +182,12 @@ export interface BsConfig {
* @default false
*/
allowBrighterScriptInBrightScript?: boolean;
+
+ /**
+ * Override the destination directory for the bslib.brs file. Use this if
+ * you want to customize where the bslib.brs file is located in the staging
+ * directory. Note that using a location outside of `source` will break
+ * scripts inside `source` that depend on bslib.brs. Defaults to `source`.
+ */
+ bslibDestinationDir?: string;
}
diff --git a/src/Program.spec.ts b/src/Program.spec.ts
index 4f1c54848..7e559757e 100644
--- a/src/Program.spec.ts
+++ b/src/Program.spec.ts
@@ -1785,6 +1785,16 @@ describe('Program', () => {
expect(fsExtra.pathExistsSync(s`${stagingDir}/source/bslib.brs`)).is.true;
});
+ it('copies the bslib.brs file to optionally specified directory', async () => {
+ fsExtra.ensureDirSync(program.options.stagingDir);
+ program.options.bslibDestinationDir = 'source/opt';
+ program.validate();
+
+ await program.transpile([], program.options.stagingDir);
+
+ expect(fsExtra.pathExistsSync(s`${stagingDir}/source/opt/bslib.brs`)).is.true;
+ });
+
describe('getTranspiledFileContents', () => {
it('fires plugin events', async () => {
const file = program.setFile('source/main.brs', trim`
@@ -2079,6 +2089,24 @@ describe('Program', () => {
`);
});
+ it('uses custom bslib path when specified in .xml file', async () => {
+ program.options.bslibDestinationDir = 'source/opt';
+ program.setFile('components/Component1.xml', trim`
+
+
+
+ `);
+ await program.transpile([], program.options.stagingDir);
+ expect(trimMap(
+ fsExtra.readFileSync(s`${stagingDir}/components/Component1.xml`).toString()
+ )).to.eql(trim`
+
+
+
+
+ `);
+ });
+
it('uses sourceRoot when provided for brs files', async () => {
let sourceRoot = s`${tempDir}/sourceRootFolder`;
program = new Program({
diff --git a/src/Program.ts b/src/Program.ts
index 6cad08a06..6eb765688 100644
--- a/src/Program.ts
+++ b/src/Program.ts
@@ -136,7 +136,7 @@ export class Program {
//default to the embedded version
} else {
- return `source${path.sep}bslib.brs`;
+ return `${this.options.bslibDestinationDir}${path.sep}bslib.brs`;
}
}
@@ -1244,7 +1244,7 @@ export class Program {
//if there's no bslib file already loaded into the program, copy it to the staging directory
if (!this.getFile(bslibAliasedRokuModulesPkgPath) && !this.getFile(s`source/bslib.brs`)) {
- promises.push(util.copyBslibToStaging(stagingDir));
+ promises.push(util.copyBslibToStaging(stagingDir, this.options.bslibDestinationDir));
}
await Promise.all(promises);
diff --git a/src/util.spec.ts b/src/util.spec.ts
index 3c0ec7adb..9aab50b0b 100644
--- a/src/util.spec.ts
+++ b/src/util.spec.ts
@@ -349,6 +349,16 @@ describe('util', () => {
let config = util.normalizeAndResolveConfig({ watch: true });
expect(config.watch).to.be.true;
});
+
+ it('sets default value for bslibDestinationDir', () => {
+ expect(util.normalizeConfig({ }).bslibDestinationDir).to.equal('source');
+ });
+
+ it('strips leading and/or trailing slashes from bslibDestinationDir', () => {
+ ['source/opt', '/source/opt', 'source/opt/', '/source/opt/'].forEach(input => {
+ expect(util.normalizeConfig({ bslibDestinationDir: input }).bslibDestinationDir).to.equal('source/opt');
+ });
+ });
});
describe('areArraysEqual', () => {
@@ -556,6 +566,16 @@ describe('util', () => {
)
).not.to.be.null;
});
+
+ it('copies from local bslib dependency to optionally specified destination directory', async () => {
+ await util.copyBslibToStaging(tempDir, 'source/opt');
+ expect(fsExtra.pathExistsSync(`${tempDir}/source/opt/bslib.brs`)).to.be.true;
+ expect(
+ /^function bslib_toString\(/mg.exec(
+ fsExtra.readFileSync(`${tempDir}/source/opt/bslib.brs`).toString()
+ )
+ ).not.to.be.null;
+ });
});
describe('rangesIntersect', () => {
diff --git a/src/util.ts b/src/util.ts
index 29e0b29bc..9fb8d575d 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -349,6 +349,11 @@ export class Util {
config.logLevel = LogLevel[(config.logLevel as string).toLowerCase()];
}
config.logLevel = config.logLevel ?? LogLevel.log;
+ config.bslibDestinationDir = config.bslibDestinationDir ?? 'source';
+ if (config.bslibDestinationDir !== 'source') {
+ // strip leading and trailing slashes
+ config.bslibDestinationDir = config.bslibDestinationDir.replace(/^(\/*)(.*?)(\/*)$/, '$2');
+ }
return config;
}
@@ -1223,9 +1228,9 @@ export class Util {
/**
* Copy the version of bslib from local node_modules to the staging folder
*/
- public async copyBslibToStaging(stagingDir: string) {
+ public async copyBslibToStaging(stagingDir: string, bslibDestinationDir = 'source') {
//copy bslib to the output directory
- await fsExtra.ensureDir(standardizePath(`${stagingDir}/source`));
+ await fsExtra.ensureDir(standardizePath(`${stagingDir}/${bslibDestinationDir}`));
// eslint-disable-next-line
const bslib = require('@rokucommunity/bslib');
let source = bslib.source as string;
@@ -1243,7 +1248,7 @@ export class Util {
const position = positions[i];
source = source.slice(0, position) + 'bslib_' + source.slice(position);
}
- await fsExtra.writeFile(`${stagingDir}/source/bslib.brs`, source);
+ await fsExtra.writeFile(`${stagingDir}/${bslibDestinationDir}/bslib.brs`, source);
}
/**