Skip to content

Commit

Permalink
feat: add network diagnostic check (#828)
Browse files Browse the repository at this point in the history
* feat: add network diagnostic check

* docs: update ping check message

* chore: add custom registry check too

* refactor: without undefined, defers npm run

* refactor: change conditional

* refactor: env, env, or config

* chore: update output with env/config, npm ping suggestion

---------

Co-authored-by: mshanemc <[email protected]>
  • Loading branch information
WillieRuemmele and mshanemc authored May 23, 2024
1 parent 97d3b9a commit 4577086
Show file tree
Hide file tree
Showing 4 changed files with 245 additions and 3 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"@oclif/core": "^3.26.6",
"@salesforce/core": "^7.3.8",
"@salesforce/kit": "^3.1.1",
"@salesforce/plugin-info": "^3.2.7",
"@salesforce/sf-plugins-core": "^9.0.10",
"got": "^13.0.0",
"npm": "^10.7.0",
Expand Down Expand Up @@ -58,6 +59,7 @@
"oclif": {
"commands": "./lib/commands",
"hooks": {
"sf-doctor-@salesforce/plugin-trust": "./lib/hooks/diagnostics",
"plugins:preinstall:verify:signature": [
"./lib/hooks/verifyInstallSignature.js"
],
Expand Down
62 changes: 62 additions & 0 deletions src/hooks/diagnostics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2022, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { SfDoctor } from '@salesforce/plugin-info';
import { Lifecycle } from '@salesforce/core';
import { NpmModule } from '../shared/npmCommand.js';
type HookFunction = (options: { doctor: SfDoctor }) => Promise<[void]>;
export const hook: HookFunction = (options) => Promise.all([registryCheck(options)]);

const registryCheck = async (options: { doctor: SfDoctor }): Promise<void> => {
const pluginName = '@salesforce/plugin-trust';
// find npm install
const npm = new NpmModule('');
const env = process.env.npm_config_registry ?? process.env.NPM_CONFIG_REGISTRY;
if (env) {
options.doctor.addSuggestion(`using npm registry ${env} from environment variable`);
}

const config = npm.run('config get registry').stdout.trim();
if (config) {
options.doctor.addSuggestion(`using npm registry ${config} from npm config`);
}

await Promise.all(
[
...new Set([
// npm and yarn registries
'https://registry.npmjs.org',
'https://registry.yarnpkg.com',
env ?? config,
]),
]
// incase customRegistry is undefined, prevent printing an extra line
.filter((u) => u)
.map(async (url) => {
try {
const results = npm.ping(url);

// timeout after 5000ms, error
if (!results || results.time > 5000) {
// to trigger the catch/fail below
throw Error;
}
await Lifecycle.getInstance().emit('Doctor:diagnostic', {
testName: `[${pluginName}] can ping: ${url}`,
status: 'pass',
});
} catch (e) {
await Lifecycle.getInstance().emit('Doctor:diagnostic', {
testName: `[${pluginName}] can't ping: ${url}`,
status: 'fail',
});
options.doctor.addSuggestion(
`Cannot ping ${url} - potential network configuration error, check proxies, firewalls, environment variables. Verify this by running 'npm ping ${url}'`
);
}
})
);
};
14 changes: 13 additions & 1 deletion src/shared/npmCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { createRequire } from 'node:module';

import fs from 'node:fs';
import npmRunPath from 'npm-run-path';
import shelljs from 'shelljs';
import shelljs, { ShellString } from 'shelljs';
import { SfError } from '@salesforce/core';
import { sleep, parseJson } from '@salesforce/kit';
import { Ux } from '@salesforce/sf-plugins-core';
Expand Down Expand Up @@ -157,6 +157,18 @@ export class NpmModule {
};
}

public ping(registry?: string): { registry: string; time: number; details: Record<string, unknown> } {
return JSON.parse(NpmCommand.runNpmCmd(`ping ${registry} --json`, { json: true, cliRoot: this.cliRoot })) as {
registry: string;
time: number;
details: Record<string, unknown>;
};
}

public run(command: string): ShellString {
return NpmCommand.runNpmCmd(command, { cliRoot: this.cliRoot, json: command.includes('--json') });
}

public show(registry: string): NpmShowResults {
const showCmd = NpmCommand.runNpmCmd(`show ${this.module}@${this.version} --json`, {
registry,
Expand Down
Loading

0 comments on commit 4577086

Please sign in to comment.