diff --git a/packages/cli-repl/src/cli-repl.spec.ts b/packages/cli-repl/src/cli-repl.spec.ts index c8240d0406..078eb5d41b 100644 --- a/packages/cli-repl/src/cli-repl.spec.ts +++ b/packages/cli-repl/src/cli-repl.spec.ts @@ -111,6 +111,29 @@ describe('CliRepl', () => { expect(JSON.parse(content).enableTelemetry).to.be.false; }); + it('does not store config options on disk that have not been changed', async() => { + let content = await fs.readFile(path.join(tmpdir.path, 'config'), { encoding: 'utf8' }); + expect(Object.keys(JSON.parse(content))).to.deep.equal([ + 'userId', 'enableTelemetry', 'disableGreetingMessage' + ]); + + input.write('config.set("inspectDepth", config.get("inspectDepth"))\n'); + + await waitEval(cliRepl.bus); + content = await fs.readFile(path.join(tmpdir.path, 'config'), { encoding: 'utf8' }); + expect(Object.keys(JSON.parse(content))).to.deep.equal([ + 'userId', 'enableTelemetry', 'disableGreetingMessage', 'inspectDepth' + ]); + + // When a new REPL is created: + cliRepl = new CliRepl(cliReplOptions); + await cliRepl.start('', {}); + content = await fs.readFile(path.join(tmpdir.path, 'config'), { encoding: 'utf8' }); + expect(Object.keys(JSON.parse(content))).to.deep.equal([ + 'userId', 'enableTelemetry', 'disableGreetingMessage', 'inspectDepth' + ]); + }); + it('emits exit when asked to, Node.js-style', async() => { input.write('.exit\n'); await exitPromise; diff --git a/packages/cli-repl/src/cli-repl.ts b/packages/cli-repl/src/cli-repl.ts index a050980bba..9b659ed8b7 100644 --- a/packages/cli-repl/src/cli-repl.ts +++ b/packages/cli-repl/src/cli-repl.ts @@ -42,6 +42,8 @@ export type CliReplOptions = { analyticsOptions?: AnalyticsOptions; } & Pick; +type CliUserConfigOnDisk = Partial & Pick; + /** * The REPL used from the terminal. */ @@ -51,8 +53,8 @@ class CliRepl { cliOptions: CliOptions; mongocryptdManager: MongocryptdManager; shellHomeDirectory: ShellHomeDirectory; - configDirectory: ConfigManager; - config: CliUserConfig = new CliUserConfig(); + configDirectory: ConfigManager; + config: CliUserConfigOnDisk; input: Readable; output: Writable; logId: string; @@ -73,15 +75,19 @@ class CliRepl { this.analyticsOptions = options.analyticsOptions; this.logId = new bson.ObjectId().toString(); this.onExit = options.onExit; + this.config = { + userId: new bson.ObjectId().toString(), + enableTelemetry: true + }; this.shellHomeDirectory = new ShellHomeDirectory(options.shellHomePaths); - this.configDirectory = new ConfigManager( + this.configDirectory = new ConfigManager( this.shellHomeDirectory) .on('error', (err: Error) => this.bus.emit('mongosh:error', err)) - .on('new-config', (config: CliUserConfig) => + .on('new-config', (config: CliUserConfigOnDisk) => this.bus.emit('mongosh:new-user', config.userId, config.enableTelemetry)) - .on('update-config', (config: CliUserConfig) => + .on('update-config', (config: CliUserConfigOnDisk) => this.bus.emit('mongosh:update-user', config.userId, config.enableTelemetry)); this.mongocryptdManager = new MongocryptdManager( @@ -147,8 +153,6 @@ class CliRepl { return this.analytics; }); - this.config.userId = new bson.ObjectId().toString(); - this.config.enableTelemetry = true; try { this.config = await this.configDirectory.generateOrReadConfig(this.config); } catch (err) { @@ -309,7 +313,7 @@ class CliRepl { } async getConfig(key: K): Promise { - return this.config[key]; + return (this.config as CliUserConfig)[key] ?? (new CliUserConfig())[key]; } async setConfig(key: K, value: CliUserConfig[K]): Promise<'success'> { @@ -326,7 +330,7 @@ class CliRepl { } listConfigOptions(): string[] { - const keys = Object.keys(this.config) as (keyof CliUserConfig)[]; + const keys = Object.keys(new CliUserConfig()) as (keyof CliUserConfig)[]; return keys.filter(key => key !== 'userId' && key !== 'disableGreetingMessage'); }