Skip to content
This repository has been archived by the owner on Oct 25, 2023. It is now read-only.

fix: call requirePackage in doctor #118

Closed
wants to merge 4 commits into from
Closed
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
29 changes: 13 additions & 16 deletions lib/general.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ok, nok, okOptional, nokOptional, resolveExecutablePath, getNpmPackageInfo } from './utils';
import { ok, nok, okOptional, nokOptional, resolveExecutablePath } from './utils';
import { exec } from 'teen_process';
import { DoctorCheck } from './doctor';
import NodeDetector from './node-detector';
import { util } from 'appium-support';
import { util, node } from 'appium-support';
import { EOL } from 'os';
import 'colors';

Expand Down Expand Up @@ -48,15 +48,18 @@ class NodeVersionCheck extends DoctorCheck {
}
checks.push(new NodeVersionCheck());

async function requirePackageCheck (packageName) {
try {
await node.requirePackage(packageName);
return okOptional(`${packageName} is installed.`);
} catch (ign) {
return nokOptional(`${packageName} cannot be found.`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would still prefer to show the original error here. Some packages just error out after being imported , even though after it looks like they were installed properly (hello opencv4nodejs 👋 )

}
}

class OptionalOpencv4nodejsCommandCheck extends DoctorCheck {
async diagnose () {
const packageName = 'opencv4nodejs';
const packageInfo = await getNpmPackageInfo(packageName);

if (packageInfo) {
return okOptional(`${packageName} is installed at: ${packageInfo.path}. Installed version is: ${packageInfo.version}`);
}
return nokOptional(`${packageName} cannot be found.`);
return await requirePackageCheck('opencv4nodejs');
}

async fix () { // eslint-disable-line require-await
Expand All @@ -82,13 +85,7 @@ checks.push(new OptionalFfmpegCommandCheck());

class OptionalMjpegConsumerCommandCheck extends DoctorCheck {
async diagnose () {
const packageName = 'mjpeg-consumer';
const packageInfo = await getNpmPackageInfo(packageName);

if (packageInfo) {
return okOptional(`${packageName} is installed at: ${packageInfo.path}. Installed version is: ${packageInfo.version}`);
}
return nokOptional(`${packageName} cannot be found.`);
return await requirePackageCheck('mjpeg-consumer');
}

async fix () { // eslint-disable-line require-await
Expand Down
37 changes: 2 additions & 35 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import path from 'path';
import _inquirer from 'inquirer';
import log from '../lib/logger';
import authorize from 'authorize-ios';
import { fs, system } from 'appium-support';
import { exec } from 'teen_process';
import { fs } from 'appium-support';
import { isFunction } from 'lodash';

// rename to make more sense
Expand Down Expand Up @@ -73,37 +72,5 @@ async function resolveExecutablePath (cmd) {
return null;
}

/**
* @typedef {Object} NpmPackageInfo
* @property {string} version - version
* @property {string} path - A path to npm root
*/
/**
* Returns the path and version of given package name
* @param {string} packageName A package name to get path and version data
* @return {?NpmPackageInfo}
*/
async function getNpmPackageInfo (packageName) {
const npmPath = await resolveExecutablePath(`npm${system.isWindows() ? `.cmd` : ''}`);
if (!npmPath) {
return nokOptional(`'npm' binary not found in PATH: ${process.env.PATH}`);
}

let pJson = {};
try {
const {stdout} = await exec(npmPath, ['list', '-g', '-l', '-j', packageName]);
pJson = JSON.parse(stdout);
} catch (err) {
log.debug(err);
return null;
}

if (pJson.dependencies && pJson.dependencies[packageName]) {
return {version: pJson.dependencies[packageName].version, path: pJson.path};
}

return null;
}

export { pkgRoot, ok, nok, okOptional, nokOptional, inquirer, configureBinaryLog,
authorizeIos, resolveExecutablePath, getNpmPackageInfo};
authorizeIos, resolveExecutablePath};
39 changes: 9 additions & 30 deletions test/general-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import NodeDetector from '../lib/node-detector';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import { withMocks } from 'appium-test-support';
import { node } from 'appium-support';
import B from 'bluebird';
import { removeColors } from './helper';

Expand Down Expand Up @@ -83,33 +84,22 @@ describe('general', function () {
});
}));

describe('OptionalOpencv4nodejsCommandCheck', withMocks({tp}, (mocks) => {
describe('OptionalOpencv4nodejsCommandCheck', withMocks({node, tp}, (mocks) => {
let check = new OptionalOpencv4nodejsCommandCheck();
it('autofix', function () {
check.autofix.should.not.be.ok;
});
it('diagnose - success', async function () {
mocks.tp.expects('exec').once().returns({stdout: `
{
"dependencies": {
"opencv4nodejs": {
"version": "4.13.0",
"from": "opencv4nodejs",
"resolved": "https://registry.npmjs.org/opencv4nodejs/-/opencv4nodejs-4.14.1.tgz"
}
},
"path": "/path/to/node/node/v11.4.0/lib"
}
`, stderr: ''});
mocks.node.expects('requirePackage').once().returns();
(await check.diagnose()).should.deep.equal({
ok: true,
optional: true,
message: 'opencv4nodejs is installed at: /path/to/node/node/v11.4.0/lib. Installed version is: 4.13.0'
message: 'opencv4nodejs is installed.'
});
mocks.verify();
});
it('diagnose - failure', async function () {
mocks.tp.expects('exec').once().returns({stdout: '{}', stderr: ''});
mocks.node.expects('requirePackage').once().throws();
(await check.diagnose()).should.deep.equal({
ok: false,
optional: true,
Expand Down Expand Up @@ -156,33 +146,22 @@ describe('general', function () {
});
}));

describe('OptionalMjpegConsumerCommandCheck', withMocks({tp}, (mocks) => {
describe('OptionalMjpegConsumerCommandCheck', withMocks({node}, (mocks) => {
let check = new OptionalMjpegConsumerCommandCheck();
it('autofix', function () {
check.autofix.should.not.be.ok;
});
it('diagnose - success', async function () {
mocks.tp.expects('exec').once().returns({stdout: `
{
"dependencies": {
"mjpeg-consumer": {
"version": "1.1.0",
"from": "mjpeg-consumer",
"resolved": "https://registry.npmjs.org/mjpeg-consumer/-/mjpeg-consumer-1.1.0.tgz"
}
},
"path": "/path/to/node/node/v11.4.0/lib"
}
`, stderr: ''});
mocks.node.expects('requirePackage').once().returns();
(await check.diagnose()).should.deep.equal({
ok: true,
optional: true,
message: 'mjpeg-consumer is installed at: /path/to/node/node/v11.4.0/lib. Installed version is: 1.1.0'
message: 'mjpeg-consumer is installed.'
});
mocks.verify();
});
it('diagnose - failure', async function () {
mocks.tp.expects('exec').once().returns({stdout: '{}', stderr: ''});
mocks.node.expects('requirePackage').once().throws();
(await check.diagnose()).should.deep.equal({
ok: false,
optional: true,
Expand Down