Skip to content

Commit

Permalink
chore(cli-repl): adds deprecation warnings on startup for mongosh 2.x…
Browse files Browse the repository at this point in the history
….x when running on unsupported platforms - MONGOSH-1553 (#1576)
  • Loading branch information
himanshusinghs committed Aug 16, 2023
1 parent 9baa20a commit 336e649
Show file tree
Hide file tree
Showing 2 changed files with 247 additions and 0 deletions.
171 changes: 171 additions & 0 deletions packages/cli-repl/src/cli-repl.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2242,4 +2242,175 @@ describe('CliRepl', function () {
expect(o.parentHandle).to.equal('foo-bar');
});
});

context('mongosh 2.x deprecation warnings', function () {
const actualReport = process.report;
const actualVersions = process.versions;
beforeEach(function () {
cliReplOptions.shellCliOptions = { nodb: true };
});

afterEach(function () {
delete (process as any).report;
(process as any).report = actualReport;

delete (process.versions as any).openssl;
(process.versions as any).openssl = actualVersions.openssl;

delete (process as any).version;
(process as any).version = actualVersions.node;
});

it('prints a deprecation warning when running on platforms with GLIBC < 2.28, otherwise not', async function () {
for (const { version, deprecated } of [
{ version: '3.0+glibcstring', deprecated: false },
{ version: '2.28.2', deprecated: false },
{ version: '2.28', deprecated: false },
// This might look like is deprecated but since this is not a valid
// semver even after co-ercion, we don't push warnings for such versions
{ version: '1.08', deprecated: false },
{ version: '2.21', deprecated: true },
{ version: '2.21-glibcstring', deprecated: true },
{ version: '2.21.4', deprecated: true },
{ version: '1.3.8', deprecated: true },
]) {
delete (process as any).report;
(process.report as any) = {
getReport() {
return {
header: {
glibcVersionRuntime: version,
},
};
},
};
cliRepl = new CliRepl(cliReplOptions);
await cliRepl.start('', {});

if (deprecated) {
expect(output).to.include('Deprecation warnings:');
expect(output).to.include(
'Using mongosh on the current operating system is deprecated, and support may be removed in a future release.'
);
expect(output).to.include(
'See https://www.mongodb.com/docs/mongodb-shell/ for documentation on supported platforms.'
);
} else {
expect(output).to.not.include(
'Using mongosh on the current operating system is deprecated, and support may be removed in a future release.'
);
}
}
});

it('does not print a platform unsupported deprecation warning when GLIBC information is not present (non-linux systems)', async function () {
delete (process as any).report;
(process.report as any) = {
getReport() {
return {
header: {},
};
},
};
cliRepl = new CliRepl(cliReplOptions);
await cliRepl.start('', {});

expect(output).to.not.include(
'Using mongosh on the current operating system is deprecated, and support may be removed in a future release.'
);
});

it('prints a deprecation warning when running with OpenSSL < 3.0.0, otherwise not', async function () {
for (const { version, deprecated } of [
{ version: '4.0.1+uniqssl', deprecated: false },
{ version: '4.0', deprecated: false },
{ version: '3.0+uniqssl', deprecated: false },
{ version: '3.0', deprecated: false },
{ version: '2.21', deprecated: true },
{ version: '2.21-uniqssl', deprecated: true },
{ version: '2.21.4', deprecated: true },
{ version: '1.3.8', deprecated: true },
]) {
delete (process.versions as any).openssl;
(process.versions as any).openssl = version;

cliRepl = new CliRepl(cliReplOptions);
await cliRepl.start('', {});
if (deprecated) {
expect(output).to.include('Deprecation warnings:');
expect(output).to.include(
'Using mongosh with OpenSSL versions lower than 3.0.0 is deprecated, and support may be removed in a future release.'
);
expect(output).to.include(
'See https://www.mongodb.com/docs/mongodb-shell/ for documentation on supported platforms.'
);
} else {
expect(output).to.not.include(
'Using mongosh with OpenSSL versions lower than 3.0.0 is deprecated, and support may be removed in a future release.'
);
}
}
});

it('prints a deprecation warning when running on Node.js < 20.0.0', async function () {
for (const { version, deprecated } of [
{ version: 'v20.5.1', deprecated: false },
{ version: '20.0.0', deprecated: false },
{ version: '18.0.0', deprecated: true },
{ version: '16.20.3', deprecated: true },
]) {
delete (process as any).version;
(process as any).version = version;

cliRepl = new CliRepl(cliReplOptions);
await cliRepl.start('', {});

if (deprecated) {
expect(output).to.include('Deprecation warnings:');
expect(output).to.include(
'Using mongosh with Node.js versions lower than 20.0.0 is deprecated, and support may be removed in a future release.'
);
expect(output).to.include(
'See https://www.mongodb.com/docs/mongodb-shell/ for documentation on supported platforms.'
);
} else {
expect(output).to.not.include(
'Using mongosh with Node.js versions lower than 20.0.0 is deprecated, and support may be removed in a future release.'
);
}
}
});

it('does not print any deprecation warning when CLI is ran with --quiet flag', async function () {
// Setting all the possible situation for a deprecation warning
process.version = '16.20.3';
process.versions.openssl = '1.1.11';
(process.report as any) = {
getReport() {
return {
header: {
glibcVersionRuntime: '1.27',
},
};
},
};

cliReplOptions.shellCliOptions.quiet = true;
cliRepl = new CliRepl(cliReplOptions);
await cliRepl.start('', {});
expect(output).not.to.include('Deprecation warnings:');
expect(output).not.to.include(
'Using mongosh on the current operating system is deprecated, and support may be removed in a future release.'
);
expect(output).not.to.include(
'Using mongosh with Node.js versions lower than 20.0.0 is deprecated, and support will be removed in a future release.'
);
expect(output).not.to.include(
'Using mongosh with OpenSSL versions lower than 3.0.0 is deprecated, and support may be removed in a future release.'
);
expect(output).not.to.include(
'See https://www.mongodb.com/docs/mongodb-shell/ for documentation on supported platforms.'
);
});
});
});
76 changes: 76 additions & 0 deletions packages/cli-repl/src/cli-repl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ export class CliRepl implements MongoshIOProvider {
await snippetManager?.loadAllSnippets();
}
await this.loadRcFiles();

this.verifyPlatformSupport();

// We only enable/disable here, since the rc file/command line scripts
// can disable the telemetry setting.
this.setTelemetryEnabled(await this.getConfig('enableTelemetry'));
Expand Down Expand Up @@ -801,6 +804,79 @@ export class CliRepl implements MongoshIOProvider {
}
}

verifyPlatformSupport(): void {
if (this.cliOptions.quiet) {
return;
}

// Typings for process.getReport haven't been updated
// (https://github.com/DefinitelyTyped/DefinitelyTyped/issues/40140)
const processReport = process.report?.getReport() as unknown as
| {
header: {
glibcVersionRuntime?: string;
};
}
| undefined;
if (!processReport) {
return;
}

const warnings: string[] = [];
const RECOMMENDED_GLIBC = '>=2.28.0';
const RECOMMENDED_OPENSSL = '>=3.0.0';
const RECOMMENDED_NODEJS = '>=20.0.0';
const semverRangeCheck = (
semverLikeVersion: string,
range: string
): boolean => {
const semverVersion = semver.valid(semver.coerce(semverLikeVersion));
// We don't push warnings for versions where we can't reliably get a
// semver like version string
if (!semverVersion) {
return true;
}

return semver.satisfies(semverVersion, range);
};
const satisfiesGLIBCRequirement = (glibcVersion: string) =>
semverRangeCheck(glibcVersion, RECOMMENDED_GLIBC);
if (
processReport.header.glibcVersionRuntime !== undefined &&
!satisfiesGLIBCRequirement(processReport.header.glibcVersionRuntime)
) {
warnings.push(
' - Using mongosh on the current operating system is deprecated, and support may be removed in a future release.'
);
}

const satisfiesOpenSSLRequirement = (opensslVersion: string) =>
semverRangeCheck(opensslVersion, RECOMMENDED_OPENSSL);
if (!satisfiesOpenSSLRequirement(process.versions.openssl)) {
warnings.push(
' - Using mongosh with OpenSSL versions lower than 3.0.0 is deprecated, and support may be removed in a future release.'
);
}

if (!semver.satisfies(process.version, RECOMMENDED_NODEJS)) {
warnings.push(
' - Using mongosh with Node.js versions lower than 20.0.0 is deprecated, and support may be removed in a future release.'
);
}

if (warnings.length) {
const deprecationWarning = [
'Deprecation warnings:',
...warnings,
'See https://www.mongodb.com/docs/mongodb-shell/ for documentation on supported platforms.',
].join('\n');

this.output.write(
this.clr(`\n${deprecationWarning}\n`, 'mongosh:warning')
);
}
}

/**
* Is the password missing from the connection string?
*
Expand Down

0 comments on commit 336e649

Please sign in to comment.