Skip to content

Commit

Permalink
Load bsconfig sync cuz async yields little benefit
Browse files Browse the repository at this point in the history
  • Loading branch information
TwitchBronBron committed Jan 21, 2021
1 parent 6aec490 commit cc6ea83
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 76 deletions.
2 changes: 1 addition & 1 deletion src/LanguageServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ export class LanguageServer {
let configFilePath = await util.findClosestConfigFile(filePathAbsolute);
let project: BsConfig = {};
if (configFilePath) {
project = await util.normalizeAndResolveConfig({ project: configFilePath });
project = util.normalizeAndResolveConfig({ project: configFilePath });
}
//override the rootDir and files array
project.rootDir = cwd;
Expand Down
4 changes: 2 additions & 2 deletions src/ProgramBuilder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ describe('ProgramBuilder', () => {
});

let builder: ProgramBuilder;
beforeEach(async () => {
beforeEach(() => {
builder = new ProgramBuilder();
builder.options = await util.normalizeAndResolveConfig({
builder.options = util.normalizeAndResolveConfig({
rootDir: rootDir
});
builder.program = new Program(builder.options);
Expand Down
2 changes: 1 addition & 1 deletion src/ProgramBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class ProgramBuilder {
}
this.isRunning = true;
try {
this.options = await util.normalizeAndResolveConfig(options);
this.options = util.normalizeAndResolveConfig(options);
this.loadPlugins();
} catch (e) {
if (e?.file && e.message && e.code) {
Expand Down
106 changes: 43 additions & 63 deletions src/util.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,21 @@ describe('util', () => {
});

describe('loadConfigFile', () => {
it('returns undefined when no path is provided', async () => {
expect(await util.loadConfigFile(undefined)).to.be.undefined;
it('returns undefined when no path is provided', () => {
expect(util.loadConfigFile(undefined)).to.be.undefined;
});

it('returns undefined when the path does not exist', async () => {
expect(await util.loadConfigFile(`?${rootDir}/donotexist.json`)).to.be.undefined;
it('returns undefined when the path does not exist', () => {
expect(util.loadConfigFile(`?${rootDir}/donotexist.json`)).to.be.undefined;
});

it('returns proper list of ancestor project paths', async () => {
it('returns proper list of ancestor project paths', () => {
fsExtra.outputFileSync(s`${rootDir}/child.json`, `{"extends": "parent.json"}`);
fsExtra.outputFileSync(s`${rootDir}/parent.json`, `{"extends": "grandparent.json"}`);
fsExtra.outputFileSync(s`${rootDir}/grandparent.json`, `{"extends": "greatgrandparent.json"}`);
fsExtra.outputFileSync(s`${rootDir}/greatgrandparent.json`, `{}`);
expect(
(await util.loadConfigFile(s`${rootDir}/child.json`))._ancestors.map(x => s(x))
util.loadConfigFile(s`${rootDir}/child.json`)._ancestors.map(x => s(x))
).to.eql([
s`${rootDir}/child.json`,
s`${rootDir}/parent.json`,
Expand All @@ -67,9 +67,9 @@ describe('util', () => {
]);
});

it('returns empty ancestors list for non-extends files', async () => {
it('returns empty ancestors list for non-extends files', () => {
fsExtra.outputFileSync(s`${rootDir}/child.json`, `{}`);
let config = await util.loadConfigFile(s`${rootDir}/child.json`);
let config = util.loadConfigFile(s`${rootDir}/child.json`);
expect(
config._ancestors.map(x => s(x))
).to.eql([
Expand Down Expand Up @@ -114,34 +114,34 @@ describe('util', () => {
});

describe('getConfigFilePath', () => {
it('returns undefined when it does not find the file', async () => {
let configFilePath = await util.getConfigFilePath(s`${process.cwd()}/testProject/project1`);
it('returns undefined when it does not find the file', () => {
let configFilePath = util.getConfigFilePath(s`${process.cwd()}/testProject/project1`);
expect(configFilePath).not.to.exist;
});

it('returns path to file when found', async () => {
it('returns path to file when found', () => {
fsExtra.outputFileSync(s`${tempDir}/rootDir/bsconfig.json`, '');
expect(
await util.getConfigFilePath(s`${tempDir}/rootDir`)
util.getConfigFilePath(s`${tempDir}/rootDir`)
).to.equal(
s`${tempDir}/rootDir/bsconfig.json`
);
});

it('finds config file in parent directory', async () => {
it('finds config file in parent directory', () => {
const bsconfigPath = s`${tempDir}/rootDir/bsconfig.json`;
fsExtra.outputFileSync(bsconfigPath, '');
fsExtra.ensureDirSync(`${tempDir}/rootDir/source`);
expect(
await util.getConfigFilePath(s`${tempDir}/rootDir/source`)
util.getConfigFilePath(s`${tempDir}/rootDir/source`)
).to.equal(
s`${tempDir}/rootDir/bsconfig.json`
);
});

it('uses cwd when not provided', async () => {
it('uses cwd when not provided', () => {
//sanity check
expect(await util.getConfigFilePath()).not.to.exist;
expect(util.getConfigFilePath()).not.to.exist;

const rootDir = s`${tempDir}/rootDir`;

Expand All @@ -151,7 +151,7 @@ describe('util', () => {
process.chdir(rootDir);
try {
expect(
await util.getConfigFilePath()
util.getConfigFilePath()
).to.equal(
s`${rootDir}/bsconfig.json`
);
Expand Down Expand Up @@ -205,39 +205,39 @@ describe('util', () => {
});

describe('normalizeAndResolveConfig', () => {
it('throws for missing project file', async () => {
await expectThrowAsync(async () => {
await util.normalizeAndResolveConfig({ project: 'path/does/not/exist/bsconfig.json' });
});
it('throws for missing project file', () => {
expect(() => {
util.normalizeAndResolveConfig({ project: 'path/does/not/exist/bsconfig.json' });
}).to.throw;
});

it('does not throw for optional missing', async () => {
await expectNotThrowAsync(async () => {
await util.normalizeAndResolveConfig({ project: '?path/does/not/exist/bsconfig.json' });
it('does not throw for optional missing', () => {
expect(() => {
util.normalizeAndResolveConfig({ project: '?path/does/not/exist/bsconfig.json' });

});
}).not.to.throw;
});

it('throws for missing extends file', async () => {
it('throws for missing extends file', () => {
try {
fsExtra.outputFileSync(s`${rootDir}/bsconfig.json`, `{ "extends": "path/does/not/exist/bsconfig.json" }`);
await expectThrowAsync(async () => {
await util.normalizeAndResolveConfig({
expect(() => {
util.normalizeAndResolveConfig({
project: s`${rootDir}/bsconfig.json`
});
});
}).to.throw;
} finally {
process.chdir(cwd);
}
});

it('throws for missing extends file', async () => {
it('throws for missing extends file', () => {
fsExtra.outputFileSync(s`${rootDir}/bsconfig.json`, `{ "extends": "?path/does/not/exist/bsconfig.json" }`);
await expectNotThrowAsync(async () => {
await util.normalizeAndResolveConfig({
expect(() => {
util.normalizeAndResolveConfig({
project: s`${rootDir}/bsconfig.json`
});
});
}).not.to.throw;
});
});

Expand All @@ -250,9 +250,9 @@ describe('util', () => {
expect(util.normalizeConfig(<any>{ emitDefinitions: 'true' }).emitDefinitions).to.be.false;
});

it('loads project from disc', async () => {
it('loads project from disc', () => {
fsExtra.outputFileSync(s`${tempDir}/rootDir/bsconfig.json`, `{ "outFile": "customOutDir/pkg.zip" }`);
let config = await util.normalizeAndResolveConfig({
let config = util.normalizeAndResolveConfig({
project: s`${tempDir}/rootDir/bsconfig.json`
});
expect(
Expand All @@ -262,7 +262,7 @@ describe('util', () => {
);
});

it('loads project from disc and extends it', async () => {
it('loads project from disc and extends it', () => {
//the extends file
fsExtra.outputFileSync(s`${tempDir}/rootDir/bsconfig.base.json`, `{
"outFile": "customOutDir/pkg1.zip",
Expand All @@ -275,14 +275,14 @@ describe('util', () => {
"watch": true
}`);

let config = await util.normalizeAndResolveConfig({ project: s`${tempDir}/rootDir/bsconfig.json` });
let config = util.normalizeAndResolveConfig({ project: s`${tempDir}/rootDir/bsconfig.json` });

expect(config.outFile).to.equal(s`${tempDir}/rootDir/customOutDir/pkg1.zip`);
expect(config.rootDir).to.equal(s`${tempDir}/rootDir/core`);
expect(config.watch).to.equal(true);
});

it('overrides parent files array with child files array', async () => {
it('overrides parent files array with child files array', () => {
//the parent file
fsExtra.outputFileSync(s`${tempDir}/rootDir/bsconfig.parent.json`, `{
"files": ["base.brs"]
Expand All @@ -294,12 +294,12 @@ describe('util', () => {
"files": ["child.brs"]
}`);

let config = await util.normalizeAndResolveConfig({ project: s`${tempDir}/rootDir/bsconfig.json` });
let config = util.normalizeAndResolveConfig({ project: s`${tempDir}/rootDir/bsconfig.json` });

expect(config.files).to.eql(['child.brs']);
});

it('catches circular dependencies', async () => {
it('catches circular dependencies', () => {
fsExtra.outputFileSync(s`${rootDir}/bsconfig.json`, `{
"extends": "bsconfig2.json"
}`);
Expand All @@ -309,7 +309,7 @@ describe('util', () => {

let threw = false;
try {
await util.normalizeAndResolveConfig({ project: s`${rootDir}/bsconfig.json` });
util.normalizeAndResolveConfig({ project: s`${rootDir}/bsconfig.json` });
} catch (e) {
threw = true;
}
Expand All @@ -318,8 +318,8 @@ describe('util', () => {
//the test passed
});

it('properly handles default for watch', async () => {
let config = await util.normalizeAndResolveConfig({ watch: true });
it('properly handles default for watch', () => {
let config = util.normalizeAndResolveConfig({ watch: true });
expect(config.watch).to.be.true;
});
});
Expand Down Expand Up @@ -631,23 +631,3 @@ describe('util', () => {
});
});
});

async function expectThrowAsync(callback) {
let ex;
try {
await Promise.resolve(callback());
} catch (e) {
ex = e;
}
expect(ex, 'Expected to throw error').to.exist;
}

async function expectNotThrowAsync(callback) {
let ex;
try {
await Promise.resolve(callback());
} catch (e) {
ex = e;
}
expect(ex, 'Expected not to throw error').not.to.exist;
}
18 changes: 9 additions & 9 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ export class Util {
* If the config file path doesn't exist
* @param configFilePath
*/
public async getConfigFilePath(cwd?: string) {
public getConfigFilePath(cwd?: string) {
cwd = cwd ?? process.cwd();
let configPath = path.join(cwd, 'bsconfig.json');
//find the nearest config file path
for (let i = 0; i < 100; i++) {
if (await this.pathExists(configPath)) {
if (this.pathExistsSync(configPath)) {
return configPath;
} else {
let parentDirPath = path.dirname(path.dirname(configPath));
Expand Down Expand Up @@ -130,13 +130,13 @@ export class Util {
* @param configFilePath
* @param parentProjectPaths
*/
public async loadConfigFile(configFilePath: string, parentProjectPaths?: string[], cwd = process.cwd()) {
public loadConfigFile(configFilePath: string, parentProjectPaths?: string[], cwd = process.cwd()) {
if (configFilePath) {
//if the config file path starts with question mark, then it's optional. return undefined if it doesn't exist
if (configFilePath.startsWith('?')) {
//remove leading question mark
configFilePath = configFilePath.substring(1);
if (await fsExtra.pathExists(path.resolve(cwd, configFilePath)) === false) {
if (fsExtra.pathExistsSync(path.resolve(cwd, configFilePath)) === false) {
return undefined;
}
}
Expand All @@ -149,7 +149,7 @@ export class Util {
throw new Error('Circular dependency detected: "' + parentProjectPaths.join('" => ') + '"');
}
//load the project file
let projectFileContents = (await fsExtra.readFile(configFilePath)).toString();
let projectFileContents = fsExtra.readFileSync(configFilePath).toString();
let parseErrors = [] as ParseError[];
let projectConfig = parseJsonc(projectFileContents, parseErrors) as BsConfig;
if (parseErrors.length > 0) {
Expand All @@ -170,7 +170,7 @@ export class Util {
let result: BsConfig;
//if the project has a base file, load it
if (projectConfig && typeof projectConfig.extends === 'string') {
let baseProjectConfig = await this.loadConfigFile(projectConfig.extends, [...parentProjectPaths, configFilePath], projectFileCwd);
let baseProjectConfig = this.loadConfigFile(projectConfig.extends, [...parentProjectPaths, configFilePath], projectFileCwd);
//extend the base config with the current project settings
result = { ...baseProjectConfig, ...projectConfig };
} else {
Expand Down Expand Up @@ -253,18 +253,18 @@ export class Util {
* merge with bsconfig.json and the provided options.
* @param config
*/
public async normalizeAndResolveConfig(config: BsConfig) {
public normalizeAndResolveConfig(config: BsConfig) {
let result = this.normalizeConfig({});

//if no options were provided, try to find a bsconfig.json file
if (!config || !config.project) {
result.project = await this.getConfigFilePath(config?.cwd);
result.project = this.getConfigFilePath(config?.cwd);
} else {
//use the config's project link
result.project = config.project;
}
if (result.project) {
let configFile = await this.loadConfigFile(result.project, null, config?.cwd);
let configFile = this.loadConfigFile(result.project, null, config?.cwd);
result = Object.assign(result, configFile);
}

Expand Down

0 comments on commit cc6ea83

Please sign in to comment.