From 981d6b7ee5aa5c1b7b0bc9827828bc9a46bd5b7d Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 31 May 2021 12:13:30 +0200 Subject: [PATCH] feat(cli-repl): only store non-default config keys on disk MONGOSH-794 For context, the original motivation here was that for snippets, if we change the default index URL, users should receive that change if they have not explicitly changed the config themselves. --- packages/cli-repl/src/cli-repl.spec.ts | 23 +++++++++++++++++++++++ packages/cli-repl/src/cli-repl.ts | 22 +++++++++++++--------- 2 files changed, 36 insertions(+), 9 deletions(-) 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'); }