Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions packages/browser-repl/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/browser-repl/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@leafygreen-ui/code": "^9.4.0",
"@leafygreen-ui/icon": "^11.6.1",
"@leafygreen-ui/palette": "^3.3.1",
"@leafygreen-ui/typography": "^8.1.0",
"@storybook/addon-knobs": "^5.3.10",
"@storybook/react": "^5.3.1",
"@types/classnames": "^2.2.11",
Expand Down Expand Up @@ -92,6 +93,7 @@
"@leafygreen-ui/code": "^9.4.0",
"@leafygreen-ui/icon": "^11.6.1",
"@leafygreen-ui/palette": "^3.3.1",
"@leafygreen-ui/typography": "^8.1.0",
"mongodb-ace-theme": "^0.0.1",
"prop-types": "^15.7.2",
"react": "^16.12.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Icon from '@leafygreen-ui/icon';
import { LineWithIcon } from './utils/line-with-icon';

import { HelpOutput } from './types/help-output';
import { ShowBannerResultOutput } from './types/show-banner-result-output';
import { ShowDbsOutput } from './types/show-dbs-output';
import { ShowCollectionsOutput } from './types/show-collections-output';
import { CursorOutput } from './types/cursor-output';
Expand Down Expand Up @@ -67,14 +68,18 @@ export class ShellOutputLine extends Component<ShellOutputLineProps> {
return <StatsResultOutput value={value} />;
}

if (type === 'ListCommandsResult)') {
if (type === 'ListCommandsResult') {
return <SimpleTypeOutput value={value} />;
}

if (type === 'ShowCollectionsResult') {
return <ShowCollectionsOutput value={value} />;
}

if (type === 'ShowBannerResult') {
return <ShowBannerResultOutput value={value} />;
}

if (type === 'Cursor' || type === 'AggregationCursor') {
return <CursorOutput value={value} />;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { H3 } from '@leafygreen-ui/typography';

interface ShowBannerResultOutputProps {
value: null | { header?: string, content: string };
}

export class ShowBannerResultOutput extends Component<ShowBannerResultOutputProps> {
static propTypes = {
value: PropTypes.any
};

render(): JSX.Element {
return (<>
{this.props.value?.header && <H3>{this.props.value.header}</H3>}
{this.props.value?.content && <pre>{this.props.value.content}</pre>}
</>);
}
}
14 changes: 14 additions & 0 deletions packages/cli-repl/src/format-output.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,5 +371,19 @@ test 558.79 GiB
});
}
});

context('when the result is ShowBannerResult', () => {
it('returns a formatted banner', () => {
const output = stripAnsiColors(format({
value: {
header: 'Header',
content: 'foo\nbar\n'
},
type: 'ShowBannerResult'
}));

expect(output).to.equal('------\n Header\n foo\n bar\n------\n');
});
});
});
}
20 changes: 20 additions & 0 deletions packages/cli-repl/src/format-output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export default function formatOutput(evaluationResult: EvaluationResult, options
return formatCollections(value, options);
}

if (type === 'ShowBannerResult') {
return formatBanner(value, options);
}

if (type === 'StatsResult') {
return formatStats(value, options);
}
Expand Down Expand Up @@ -147,6 +151,22 @@ function formatCollections(output: CollectionNamesWithTypes[], options: FormatOp
return textTable(tableEntries, { align: ['l', 'l'] });
}

function formatBanner(output: null | { header?: string, content: string }, options: FormatOptions): string {
if (!output?.content) {
return '';
}

let text = '';
text += `${clr('------', 'mongosh:section-header', options)}\n`;
if (output.header) {
text += ` ${clr(output.header, 'mongosh:section-header', options)}\n`;
}
// indent output.content with 3 spaces
text += output.content.trim().replace(/^/gm, ' ') + '\n';
text += `${clr('------', 'mongosh:section-header', options)}\n`;
return text;
}

function formatDatabases(output: any[], options: FormatOptions): string {
const tableEntries = output.map(
(db) => [clr(db.name, 'bold', options), formatBytes(db.sizeOnDisk)]
Expand Down
3 changes: 2 additions & 1 deletion packages/cli-repl/src/mongosh-repl.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { StubbedInstance, stubInterface } from 'ts-sinon';
import { promisify } from 'util';
import { expect, fakeTTYProps, tick, useTmpdir, waitEval } from '../test/repl-helpers';
import MongoshNodeRepl, { MongoshIOProvider, MongoshNodeReplOptions } from './mongosh-repl';
import { parseAnyLogEntry } from './log-entry';
import { parseAnyLogEntry } from '../../shell-api/src/log-entry';
import stripAnsi from 'strip-ansi';

const delay = promisify(setTimeout);
Expand Down Expand Up @@ -64,6 +64,7 @@ describe('MongoshNodeRepl', () => {
version: '4.4.1'
}
});
sp.runCommandWithCheck.resolves({ ok: 1 });
serviceProvider = sp;

mongoshReplOptions = {
Expand Down
62 changes: 19 additions & 43 deletions packages/cli-repl/src/mongosh-repl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import completer from '@mongosh/autocomplete';
import { MongoshCommandFailed, MongoshInternalError, MongoshWarning } from '@mongosh/errors';
import { MongoshInternalError, MongoshWarning } from '@mongosh/errors';
import { changeHistory } from '@mongosh/history';
import type { AutoEncryptionOptions, ServiceProvider } from '@mongosh/service-provider-core';
import { EvaluationListener, OnLoadResult, ShellCliOptions, ShellInstanceState, getShellApiType, toShellResult } from '@mongosh/shell-api';
Expand All @@ -20,7 +20,6 @@ import { MONGOSH_WIKI, TELEMETRY_GREETING_MESSAGE } from './constants';
import formatOutput, { formatError } from './format-output';
import { makeMultilineJSIntoSingleLine } from '@mongosh/js-multiline-to-singleline';
import { LineByLineInput } from './line-by-line-input';
import { LogEntry, parseAnyLogEntry } from './log-entry';

/**
* All CLI flags that are useful for {@link MongoshNodeRepl}.
Expand Down Expand Up @@ -186,7 +185,6 @@ class MongoshNodeRepl implements EvaluationListener {
mongodVersion = (mongodVersion ? mongodVersion + ' ' : '') + `(API Version ${apiVersion})`;
}
await this.greet(mongodVersion);
await this.printStartupLog(instanceState);
await this.printBasicConnectivityWarning(instanceState);

this.inspectCompact = await this.getConfig('inspectCompact');
Expand Down Expand Up @@ -380,6 +378,24 @@ class MongoshNodeRepl implements EvaluationListener {
});

instanceState.setCtx(repl.context);

if (!this.shellCliOptions.nodb && !this.shellCliOptions.quiet) {
// cf. legacy shell:
// https://github.com/mongodb/mongo/blob/a6df396047a77b90bf1ce9463eecffbee16fb864/src/mongo/shell/mongo_main.cpp#L1003-L1026
const { shellApi } = instanceState;
const banners = await Promise.all([
(async() => await shellApi.show('startupWarnings'))(),
(async() => await shellApi.show('freeMonitoring'))(),
(async() => await shellApi.show('automationNotices'))()
]);
for (const banner of banners) {
if (banner.value) {
await shellApi.print(banner);
}
}
// Omitted, see MONGOSH-57: 'show nonGenuineMongoDBCheck'
}

return { __initialized: 'yes' };
}

Expand Down Expand Up @@ -421,46 +437,6 @@ class MongoshNodeRepl implements EvaluationListener {
this.output.write(text);
}

/**
* Print warnings from the server startup log, if any.
*/
async printStartupLog(instanceState: ShellInstanceState): Promise<void> {
if (this.shellCliOptions.nodb || this.shellCliOptions.quiet) {
return;
}

type GetLogResult = { ok: number, totalLinesWritten: number, log: string[] | undefined };
let result;
try {
result = await instanceState.currentDb.adminCommand({ getLog: 'startupWarnings' }) as GetLogResult;
if (!result) {
throw new MongoshCommandFailed('adminCommand getLog unexpectedly returned no result');
}
} catch (error: any) {
this.bus.emit('mongosh:error', error, 'repl');
return;
}

if (!result.log || !result.log.length) {
return;
}

let text = '';
text += `${this.clr('------', 'mongosh:section-header')}\n`;
text += ` ${this.clr('The server generated these startup warnings when booting:', 'mongosh:warning')}\n`;
result.log.forEach(logLine => {
try {
const entry: LogEntry = parseAnyLogEntry(logLine);
text += ` ${entry.timestamp}: ${entry.message}\n`;
} catch (e: any) {
text += ` Unexpected log line format: ${logLine}\n`;
}
});
text += `${this.clr('------', 'mongosh:section-header')}\n`;
text += '\n';
this.output.write(text);
}

/**
* Print a warning if the server is not able to respond to commands.
* This can happen in load balanced mode, for example.
Expand Down
Loading