diff --git a/packages/cli/src/commands/doctor/doctor.js b/packages/cli/src/commands/doctor/doctor.js index 0592dcfa5..474bd6e43 100644 --- a/packages/cli/src/commands/doctor/doctor.js +++ b/packages/cli/src/commands/doctor/doctor.js @@ -1,14 +1,13 @@ // @flow import chalk from 'chalk'; import envinfo from 'envinfo'; -import Ora from 'ora'; import {logger} from '@react-native-community/cli-tools'; import {getHealthchecks, HEALTHCHECK_TYPES} from './healthchecks'; import {getLoader} from '../../tools/loader'; import printFixOptions, {KEYS} from './printFixOptions'; import runAutomaticFix, {AUTOMATIC_FIX_LEVELS} from './runAutomaticFix'; import type {ConfigT} from 'types'; -import type {EnvironmentInfo} from './types'; +import type {HealthCheckInterface} from './types'; const printCategory = ({label, key}) => { if (key > 0) { @@ -74,18 +73,7 @@ export default (async function runDoctor( healthchecks, }: { label: string, - healthchecks: Array<{ - label: string, - visible: boolean, - isRequired: boolean, - getDiagnostics: ( - envInfor: EnvironmentInfo, - ) => {version: string, needsToBeFixed: boolean}, - getDiagnosticsAsync: ( - envInfor: EnvironmentInfo, - ) => Promise<{version: string, needsToBeFixed: boolean}>, - runAutomaticFix: (args: {loader: typeof Ora}) => Promise, - }>, + healthchecks: Array, }) => ({ label, healthchecks: (await Promise.all( @@ -94,9 +82,9 @@ export default (async function runDoctor( return; } - const {needsToBeFixed} = healthcheck.getDiagnostics - ? healthcheck.getDiagnostics(environmentInfo) - : await healthcheck.getDiagnosticsAsync(environmentInfo); + const {needsToBeFixed} = await healthcheck.getDiagnostics( + environmentInfo, + ); // Assume that it's required unless specified otherwise const isRequired = healthcheck.isRequired !== false; @@ -104,7 +92,7 @@ export default (async function runDoctor( return { label: healthcheck.label, - needsToBeFixed, + needsToBeFixed: Boolean(needsToBeFixed), runAutomaticFix: healthcheck.runAutomaticFix, isRequired, type: needsToBeFixed @@ -125,6 +113,7 @@ export default (async function runDoctor( ); const iterateOverCategories = categories => + // $FlowFixMe - bad Object.values typings Promise.all(categories.map(iterateOverHealthChecks)); const healthchecksPerCategory = await iterateOverCategories( @@ -167,6 +156,7 @@ export default (async function runDoctor( } const onKeyPress = async key => { + // $FlowFixMe process.stdin.setRawMode(false); process.stdin.removeAllListeners('data'); diff --git a/packages/cli/src/commands/doctor/healthchecks/androidHomeEnvVariable.js b/packages/cli/src/commands/doctor/healthchecks/androidHomeEnvVariable.js index 7572448de..410b9855d 100644 --- a/packages/cli/src/commands/doctor/healthchecks/androidHomeEnvVariable.js +++ b/packages/cli/src/commands/doctor/healthchecks/androidHomeEnvVariable.js @@ -2,6 +2,7 @@ import chalk from 'chalk'; import Ora from 'ora'; import {logManualInstallation} from './common'; +import type {HealthCheckInterface} from '../types'; // List of answers on how to set `ANDROID_HOME` for each platform const URLS = { @@ -12,9 +13,9 @@ const URLS = { const label = 'ANDROID_HOME'; -export default { +export default ({ label, - getDiagnostics: () => ({ + getDiagnostics: async () => ({ needsToBeFixed: !process.env.ANDROID_HOME, }), runAutomaticFix: async ({loader}: {loader: typeof Ora}) => { @@ -26,4 +27,4 @@ export default { )}.`, }); }, -}; +}: HealthCheckInterface); diff --git a/packages/cli/src/commands/doctor/healthchecks/androidNDK.js b/packages/cli/src/commands/doctor/healthchecks/androidNDK.js index 848994597..d3481e1fe 100644 --- a/packages/cli/src/commands/doctor/healthchecks/androidNDK.js +++ b/packages/cli/src/commands/doctor/healthchecks/androidNDK.js @@ -4,11 +4,11 @@ import Ora from 'ora'; import {logManualInstallation} from './common'; import versionRanges from '../versionRanges'; import {doesSoftwareNeedToBeFixed} from '../checkInstallation'; -import type {EnvironmentInfo} from '../types'; +import type {EnvironmentInfo, HealthCheckInterface} from '../types'; -export default { +export default ({ label: 'Android NDK', - getDiagnosticsAsync: async ({SDKs}: EnvironmentInfo) => ({ + getDiagnostics: async ({SDKs}: EnvironmentInfo) => ({ needsToBeFixed: doesSoftwareNeedToBeFixed({ version: SDKs['Android SDK']['Android NDK'], versionRange: versionRanges.ANDROID_NDK, @@ -39,4 +39,4 @@ export default { url: 'https://developer.android.com/ndk/downloads', }); }, -}; +}: HealthCheckInterface); diff --git a/packages/cli/src/commands/doctor/healthchecks/androidSDK.js b/packages/cli/src/commands/doctor/healthchecks/androidSDK.js index 1faa8d3cb..c82e0eaf5 100644 --- a/packages/cli/src/commands/doctor/healthchecks/androidSDK.js +++ b/packages/cli/src/commands/doctor/healthchecks/androidSDK.js @@ -5,14 +5,15 @@ import {logManualInstallation} from './common'; import versionRanges from '../versionRanges'; import {doesSoftwareNeedToBeFixed} from '../checkInstallation'; import execa from 'execa'; +import type {EnvironmentInfo, HealthCheckInterface} from '../types'; const installMessage = `Read more about how to update Android SDK at ${chalk.dim( 'https://developer.android.com/studio', )}`; -export default { +export default ({ label: 'Android SDK', - getDiagnosticsAsync: async ({SDKs}: EnvironmentInfo) => { + getDiagnostics: async ({SDKs}: EnvironmentInfo) => { let sdks = SDKs['Android SDK']; // This is a workaround for envinfo's Android SDK check not working on @@ -20,6 +21,7 @@ export default { // See the PR: https://github.com/tabrindle/envinfo/pull/119 if (sdks === 'Not Found' && process.platform !== 'darwin') { try { + // $FlowFixMe bad execa types const {stdout} = await execa( process.env.ANDROID_HOME ? `${process.env.ANDROID_HOME}/tools/bin/sdkmanager` @@ -31,7 +33,9 @@ export default { const regex = /build-tools;([\d|.]+)[\S\s]/g; let match = null; while ((match = regex.exec(stdout)) !== null) { - matches.push(match[1]); + if (match) { + matches.push(match[1]); + } } if (matches.length > 0) { sdks = { @@ -44,10 +48,11 @@ export default { return { needsToBeFixed: (sdks === 'Not Found' && installMessage) || - doesSoftwareNeedToBeFixed({ - version: sdks['Build Tools'][0], - versionRange: versionRanges.ANDROID_NDK, - }), + (sdks !== 'Not Found' && + doesSoftwareNeedToBeFixed({ + version: sdks['Build Tools'][0], + versionRange: versionRanges.ANDROID_NDK, + })), }; }, runAutomaticFix: async ({ @@ -73,4 +78,4 @@ export default { url: 'https://facebook.github.io/react-native/docs/getting-started', }); }, -}; +}: HealthCheckInterface); diff --git a/packages/cli/src/commands/doctor/healthchecks/cocoaPods.js b/packages/cli/src/commands/doctor/healthchecks/cocoaPods.js index dd8597b99..5644278c6 100644 --- a/packages/cli/src/commands/doctor/healthchecks/cocoaPods.js +++ b/packages/cli/src/commands/doctor/healthchecks/cocoaPods.js @@ -1,10 +1,12 @@ +// @flow import {isSoftwareInstalled} from '../checkInstallation'; import {installCocoaPods} from '../../../tools/installPods'; +import {type HealthCheckInterface} from '../types'; -export default { +export default ({ label: 'CocoaPods', - getDiagnosticsAsync: async () => ({ + getDiagnostics: async () => ({ needsToBeFixed: !(await isSoftwareInstalled('pod')), }), runAutomaticFix: async ({loader}) => await installCocoaPods(loader), -}; +}: HealthCheckInterface); diff --git a/packages/cli/src/commands/doctor/healthchecks/iosDeploy.js b/packages/cli/src/commands/doctor/healthchecks/iosDeploy.js index d4df9774b..7c104e240 100644 --- a/packages/cli/src/commands/doctor/healthchecks/iosDeploy.js +++ b/packages/cli/src/commands/doctor/healthchecks/iosDeploy.js @@ -4,6 +4,7 @@ import Ora from 'ora'; import {isSoftwareInstalled, PACKAGE_MANAGERS} from '../checkInstallation'; import {packageManager} from './packageManagers'; import {logManualInstallation} from './common'; +import type {HealthCheckInterface} from '../types'; const getInstallationCommand = () => { if (packageManager === PACKAGE_MANAGERS.YARN) { @@ -17,10 +18,10 @@ const getInstallationCommand = () => { return undefined; }; -export default { +export default ({ label: 'ios-deploy', isRequired: false, - getDiagnosticsAsync: async () => ({ + getDiagnostics: async () => ({ needsToBeFixed: !(await isSoftwareInstalled('ios-deploy')), }), runAutomaticFix: async ({loader}: {loader: typeof Ora}) => { @@ -53,4 +54,4 @@ export default { }); } }, -}; +}: HealthCheckInterface); diff --git a/packages/cli/src/commands/doctor/healthchecks/nodeJS.js b/packages/cli/src/commands/doctor/healthchecks/nodeJS.js index 562ed3d15..a4dfdd8eb 100644 --- a/packages/cli/src/commands/doctor/healthchecks/nodeJS.js +++ b/packages/cli/src/commands/doctor/healthchecks/nodeJS.js @@ -3,11 +3,11 @@ import Ora from 'ora'; import versionRanges from '../versionRanges'; import {doesSoftwareNeedToBeFixed} from '../checkInstallation'; import {logManualInstallation} from './common'; -import type {EnvironmentInfo} from '../types'; +import type {EnvironmentInfo, HealthCheckInterface} from '../types'; -export default { +export default ({ label: 'Node.js', - getDiagnostics: ({Binaries}: EnvironmentInfo) => ({ + getDiagnostics: async ({Binaries}: EnvironmentInfo) => ({ version: Binaries.Node.version, needsToBeFixed: doesSoftwareNeedToBeFixed({ version: Binaries.Node.version, @@ -22,4 +22,4 @@ export default { url: 'https://nodejs.org/en/download/', }); }, -}; +}: HealthCheckInterface); diff --git a/packages/cli/src/commands/doctor/healthchecks/packageManagers.js b/packages/cli/src/commands/doctor/healthchecks/packageManagers.js index 5ed9a2b26..92433c7ad 100644 --- a/packages/cli/src/commands/doctor/healthchecks/packageManagers.js +++ b/packages/cli/src/commands/doctor/healthchecks/packageManagers.js @@ -1,12 +1,13 @@ // @flow import fs from 'fs'; +import Ora from 'ora'; import versionRanges from '../versionRanges'; import { PACKAGE_MANAGERS, doesSoftwareNeedToBeFixed, } from '../checkInstallation'; import {install} from '../../../tools/install'; -import type {EnvironmentInfo} from '../types'; +import type {EnvironmentInfo, HealthCheckInterface} from '../types'; const packageManager = (() => { if (fs.existsSync('yarn.lock')) { @@ -20,9 +21,9 @@ const packageManager = (() => { return undefined; })(); -const yarn = { +const yarn: HealthCheckInterface = { label: 'yarn', - getDiagnostics: ({Binaries}: EnvironmentInfo) => ({ + getDiagnostics: async ({Binaries}: EnvironmentInfo) => ({ version: Binaries.Node.version, needsToBeFixed: doesSoftwareNeedToBeFixed({ version: Binaries.Yarn.version, @@ -33,13 +34,13 @@ const yarn = { // or if we can't identify that the user uses yarn or npm visible: packageManager === PACKAGE_MANAGERS.YARN || packageManager === undefined, - runAutomaticFix: async ({loader}) => + runAutomaticFix: async ({loader}: typeof Ora) => await install('yarn', 'https://yarnpkg.com/docs/install', loader), }; -const npm = { +const npm: HealthCheckInterface = { label: 'npm', - getDiagnostics: ({Binaries}: EnvironmentInfo) => ({ + getDiagnostics: async ({Binaries}: EnvironmentInfo) => ({ needsToBeFixed: doesSoftwareNeedToBeFixed({ version: Binaries.npm.version, versionRange: versionRanges.NPM, @@ -49,7 +50,7 @@ const npm = { // or if we can't identify that the user uses yarn or npm visible: packageManager === PACKAGE_MANAGERS.NPM || packageManager === undefined, - runAutomaticFix: async ({loader}) => + runAutomaticFix: async ({loader}: typeof Ora) => await install('node', 'https://nodejs.org/', loader), }; diff --git a/packages/cli/src/commands/doctor/healthchecks/watchman.js b/packages/cli/src/commands/doctor/healthchecks/watchman.js index d4857577b..798708a78 100644 --- a/packages/cli/src/commands/doctor/healthchecks/watchman.js +++ b/packages/cli/src/commands/doctor/healthchecks/watchman.js @@ -1,4 +1,5 @@ // @flow +import Ora from 'ora'; import versionRanges from '../versionRanges'; import {doesSoftwareNeedToBeFixed} from '../checkInstallation'; import {install} from '../../../tools/install'; @@ -12,7 +13,7 @@ export default { versionRange: versionRanges.WATCHMAN, }), }), - runAutomaticFix: async ({loader}) => + runAutomaticFix: async ({loader}: typeof Ora) => await install( 'watchman', 'https://facebook.github.io/watchman/docs/install.html', diff --git a/packages/cli/src/commands/doctor/healthchecks/xcode.js b/packages/cli/src/commands/doctor/healthchecks/xcode.js index 0cd01ded7..74ac04a7c 100644 --- a/packages/cli/src/commands/doctor/healthchecks/xcode.js +++ b/packages/cli/src/commands/doctor/healthchecks/xcode.js @@ -3,17 +3,17 @@ import Ora from 'ora'; import versionRanges from '../versionRanges'; import {doesSoftwareNeedToBeFixed} from '../checkInstallation'; import {logManualInstallation} from './common'; -import type {EnvironmentInfo} from '../types'; +import type {EnvironmentInfo, HealthCheckInterface} from '../types'; -export default { +export default ({ label: 'Xcode', - getDiagnostics: ({IDEs}: EnvironmentInfo) => ({ + getDiagnostics: async ({IDEs}: EnvironmentInfo) => ({ needsToBeFixed: doesSoftwareNeedToBeFixed({ version: IDEs.Xcode.version.split('/')[0], versionRange: versionRanges.XCODE, }), }), - runAutomaticFix: ({loader}: {loader: typeof Ora}) => { + runAutomaticFix: async ({loader}: {loader: typeof Ora}) => { loader.info(); logManualInstallation({ @@ -21,4 +21,4 @@ export default { url: 'https://developer.apple.com/xcode/', }); }, -}; +}: HealthCheckInterface); diff --git a/packages/cli/src/commands/doctor/runAutomaticFix.js b/packages/cli/src/commands/doctor/runAutomaticFix.js index 561f054a1..f954dd9b7 100644 --- a/packages/cli/src/commands/doctor/runAutomaticFix.js +++ b/packages/cli/src/commands/doctor/runAutomaticFix.js @@ -18,10 +18,10 @@ export default async ({ stats, loader, environmentInfo, -}:{ +}: { healthchecks: any, automaticFixLevel: $Values, - stats:{errors: any, warnings: any}, + stats: {errors: any, warnings: any}, loader: typeof ora, environmentInfo: EnvironmentInfo, }) => { diff --git a/packages/cli/src/commands/doctor/types.js b/packages/cli/src/commands/doctor/types.js index 9a58a8cd9..3793e8d9b 100644 --- a/packages/cli/src/commands/doctor/types.js +++ b/packages/cli/src/commands/doctor/types.js @@ -1,4 +1,6 @@ // @flow +import Ora from 'ora'; + export type EnvironmentInfo = { System: { OS: string, @@ -62,3 +64,16 @@ export type EnvironmentInfo = { }, }, }; + +export type HealthCheckInterface = { + label: string, + visible?: boolean | void, + isRequired?: boolean, + getDiagnostics: ( + environmentInfo: EnvironmentInfo, + ) => Promise<{version?: string, needsToBeFixed: boolean | string}>, + runAutomaticFix: (args: { + loader: typeof Ora, + environmentInfo: EnvironmentInfo, + }) => Promise | void, +};