From 177f2bfc8f5bbcefdbdc8e6ddecc574c6383661c Mon Sep 17 00:00:00 2001 From: Blake Friedman Date: Tue, 9 Apr 2024 10:00:14 -0700 Subject: [PATCH] react-native-info - added simple copy of @react-native-community's implementation Summary: This current consists of a bunch of TypeScript code, which will be ported to Flow in the stack. Changelog: [Internal] bypass-github-export-checks Reviewed By: huntie Differential Revision: D55741526 fbshipit-source-id: 1dc30d2ab63e0526dd6fed17ccf7cce9f57bdbee --- packages/react-native-info/package.json | 35 ++++++++ packages/react-native-info/src/envinfo.ts | 49 +++++++++++ packages/react-native-info/src/index.ts | 30 +++++++ packages/react-native-info/src/info.ts | 100 ++++++++++++++++++++++ packages/react-native-info/src/types.ts | 58 +++++++++++++ packages/react-native-info/tsconfig.json | 28 ++++++ yarn.lock | 87 +++++++++++++++++++ 7 files changed, 387 insertions(+) create mode 100644 packages/react-native-info/package.json create mode 100644 packages/react-native-info/src/envinfo.ts create mode 100644 packages/react-native-info/src/index.ts create mode 100644 packages/react-native-info/src/info.ts create mode 100644 packages/react-native-info/src/types.ts create mode 100644 packages/react-native-info/tsconfig.json diff --git a/packages/react-native-info/package.json b/packages/react-native-info/package.json new file mode 100644 index 00000000000000..2191d574027d5e --- /dev/null +++ b/packages/react-native-info/package.json @@ -0,0 +1,35 @@ +{ + "name": "react-native-info", + "version": "1.0.0", + "main": "build/index.js", + "license": "MIT", + "private": true, + "publishConfig": { + "access": "public" + }, + "types": "build/index.d.ts", + "files": [ + "build", + "!*.d.ts", + "!*.map" + ], + "homepage": "https://github.com/facebook//react-native/tree/main/packages/react-native-info", + "repository": { + "type": "git", + "url": "https://github.com/facebook/react-native.git", + "directory": "packages/react-native-info" + }, + "dependencies": { + "@react-native-community/cli-config": "^13.6.4", + "@react-native-community/cli-platform-apple": "^13.6.4", + "@react-native-community/cli-tools": "^13.6.4", + "@react-native-community/cli-types": "^13.6.4", + "commander": "^12.0.0", + "fs-extra": "^11.2.0", + "yaml": "^2.4.1" + }, + "devDependencies": { + "@types/envinfo": "^7.8.3", + "@types/fs-extra": "^11.0.4" + } +} diff --git a/packages/react-native-info/src/envinfo.ts b/packages/react-native-info/src/envinfo.ts new file mode 100644 index 00000000000000..3cd7b025f86117 --- /dev/null +++ b/packages/react-native-info/src/envinfo.ts @@ -0,0 +1,49 @@ +import envinfo from 'envinfo'; +import {platform} from 'os'; +import {EnvironmentInfo} from './types'; + +/** + * Returns information about the running system. + * If `json === true`, or no options are passed, + * the return type will be an `EnvironmentInfo`. + * If set to `false`, it will be a `string`. + */ +export async function getEnvironmentInfoAsString(): Promise { + return getEnvironmentInfo(false); +} + +export async function getEnvironmentInfoAsJson(): Promise { + return JSON.parse(await getEnvironmentInfo(true)); +} + +async function getEnvironmentInfo(json: boolean): Promise { + const options = {json, showNotFound: true}; + + const packages = ['react', 'react-native', '@react-native-community/cli']; + + const outOfTreePlatforms: {[key: string]: string} = { + darwin: 'react-native-macos', + win32: 'react-native-windows', + }; + + const outOfTreePlatformPackage = outOfTreePlatforms[platform()]; + if (outOfTreePlatformPackage) { + packages.push(outOfTreePlatformPackage); + } + + const info = await envinfo.run( + { + System: ['OS', 'CPU', 'Memory', 'Shell'], + Binaries: ['Node', 'Yarn', 'npm', 'Watchman'], + IDEs: ['Xcode', 'Android Studio', 'Visual Studio'], + Managers: ['CocoaPods'], + Languages: ['Java', 'Ruby'], + SDKs: ['iOS SDK', 'Android SDK', 'Windows SDK'], + npmPackages: packages, + npmGlobalPackages: ['*react-native*'], + }, + options, + ); + + return info.trim(); +} diff --git a/packages/react-native-info/src/index.ts b/packages/react-native-info/src/index.ts new file mode 100644 index 00000000000000..a2fd3c52409782 --- /dev/null +++ b/packages/react-native-info/src/index.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @oncall react_native + */ + +import loadConfig from '@react-native-community/cli-config'; + +import {program} from 'commander'; +import info from './info'; +import {CliOptions} from './types'; + +program + .name('react-native-info') + .description('Get relevant version info about OS, toolchain and libraries') + .version(require('../package.json').version) + .option('--json', 'Output in JSON format') + .parse(process.argv); + +async function main() { + const config = loadConfig(); + const options: CliOptions = program.opts(); + await info(options, config); +} + +main(); diff --git a/packages/react-native-info/src/info.ts b/packages/react-native-info/src/info.ts new file mode 100644 index 00000000000000..2cb7fed3dbb38a --- /dev/null +++ b/packages/react-native-info/src/info.ts @@ -0,0 +1,100 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {getEnvironmentInfoAsJson} from './envinfo'; +import {logger, version} from '@react-native-community/cli-tools'; +import {Config} from '@react-native-community/cli-types'; +import {getArchitecture} from '@react-native-community/cli-platform-apple'; +import {readFile} from 'fs-extra'; +import path from 'path'; +import {stringify} from 'yaml'; +import {CliOptions} from './types'; + +type PlatformValues = { + hermesEnabled: boolean | string; + newArchEnabled: boolean | string; +}; + +interface Platforms { + Android: PlatformValues; + iOS: PlatformValues; +} + +export default async function getInfo(options: CliOptions, ctx: Config) { + try { + logger.info('Fetching system and libraries information...'); + + const notFound = 'Not found'; + + const platforms: Platforms = { + Android: { + hermesEnabled: notFound, + newArchEnabled: notFound, + }, + iOS: { + hermesEnabled: notFound, + newArchEnabled: notFound, + }, + }; + + if (process.platform !== 'win32' && ctx.project.ios?.sourceDir) { + try { + const podfile = await readFile( + path.join(ctx.project.ios.sourceDir, '/Podfile.lock'), + 'utf8', + ); + + platforms.iOS.hermesEnabled = podfile.includes('hermes-engine'); + } catch (e) { + platforms.iOS.hermesEnabled = notFound; + } + + try { + const isNewArchitecture = await getArchitecture( + ctx.project.ios.sourceDir, + ); + + platforms.iOS.newArchEnabled = isNewArchitecture; + } catch { + platforms.iOS.newArchEnabled = notFound; + } + } + + if (ctx.project.android?.sourceDir) { + try { + const gradleProperties = await readFile( + path.join(ctx.project.android.sourceDir, '/gradle.properties'), + 'utf8', + ); + + platforms.Android.hermesEnabled = + gradleProperties.includes('hermesEnabled=true'); + platforms.Android.newArchEnabled = gradleProperties.includes( + 'newArchEnabled=true', + ); + } catch { + platforms.Android.hermesEnabled = notFound; + platforms.Android.newArchEnabled = notFound; + } + } + + const output = { + ...await getEnvironmentInfoAsJson(), + ...platforms, + }; + + if (options.json) { + logger.log(JSON.stringify(output, null, 2)); + } else { + logger.log(stringify(output)); + } + } catch (err) { + logger.error(`Unable to print environment info.\n${err}`); + } finally { + await version.logIfUpdateAvailable(ctx.root); + } +}; diff --git a/packages/react-native-info/src/types.ts b/packages/react-native-info/src/types.ts new file mode 100644 index 00000000000000..301bab680eba6b --- /dev/null +++ b/packages/react-native-info/src/types.ts @@ -0,0 +1,58 @@ +import type {Config} from '@react-native-community/cli-types'; + +export interface CliOptions { + json?: boolean; +} + +export type NotFound = 'Not Found'; + +type AvailableInformation = { + version: string; + path: string; +}; + +type Information = AvailableInformation | NotFound; + +export type EnvironmentInfo = { + System: { + OS: string; + CPU: string; + Memory: string; + Shell: AvailableInformation; + }; + Binaries: { + Node: AvailableInformation; + Yarn: AvailableInformation; + npm: AvailableInformation; + bun: AvailableInformation; + Watchman: AvailableInformation; + }; + Managers: { + CocoaPods: AvailableInformation; + }; + SDKs: { + 'iOS SDK': { + Platforms: string[]; + }; + 'Android SDK': + | { + 'API Levels': string[] | NotFound; + 'Build Tools': string[] | NotFound; + 'System Images': string[] | NotFound; + 'Android NDK': string | NotFound; + } + | NotFound; + }; + IDEs: { + 'Android Studio': AvailableInformation | NotFound; + Emacs: AvailableInformation; + Nano: AvailableInformation; + VSCode: AvailableInformation; + Vim: AvailableInformation; + Xcode: AvailableInformation; + }; + Languages: { + Java: Information; + Ruby: AvailableInformation; + }; +}; diff --git a/packages/react-native-info/tsconfig.json b/packages/react-native-info/tsconfig.json new file mode 100644 index 00000000000000..8d4a61c0727dda --- /dev/null +++ b/packages/react-native-info/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs", + "lib": ["es2017"], + "declaration": true, + "declarationMap": true, + "composite": true, + "emitDeclarationOnly": true, + + "strict": true, + + /* Additional Checks */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + + /* Module Resolution Options */ + "moduleResolution": "node", + "esModuleInterop": true, + "resolveJsonModule": true, + + "rootDir": "src", + "outDir": "build" + }, + "exclude": ["**/__tests__/**/*", "**/build/**/*"] +} diff --git a/yarn.lock b/yarn.lock index 603de4532f0c68..5721a7f1222ae3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2416,6 +2416,18 @@ fast-glob "^3.3.2" joi "^17.2.1" +"@react-native-community/cli-config@^13.6.4": + version "13.6.4" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-13.6.4.tgz#3004c7bca55cb384b3a99c38c1a48dad24533237" + integrity sha512-GGK415WoTx1R9FXtfb/cTnan9JIWwSm+a5UCuFd6+suzS0oIt1Md1vCzjNh6W1CK3b43rZC2e+3ZU7Ljd7YtyQ== + dependencies: + "@react-native-community/cli-tools" "13.6.4" + chalk "^4.1.2" + cosmiconfig "^5.1.0" + deepmerge "^4.3.0" + fast-glob "^3.3.2" + joi "^17.2.1" + "@react-native-community/cli-debugger-ui@14.0.0-alpha.2": version "14.0.0-alpha.2" resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-14.0.0-alpha.2.tgz#484847fb01eef67ea2c26cd35a88342112c15ff9" @@ -2469,6 +2481,18 @@ fast-xml-parser "^4.0.12" ora "^5.4.1" +"@react-native-community/cli-platform-apple@^13.6.4": + version "13.6.4" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-apple/-/cli-platform-apple-13.6.4.tgz#4912eaf519800a957745192718822b94655c8119" + integrity sha512-TLBiotdIz0veLbmvNQIdUv9fkBx7m34ANGYqr5nH7TFxdmey+Z+omoBqG/HGpvyR7d0AY+kZzzV4k+HkYHM/aQ== + dependencies: + "@react-native-community/cli-tools" "13.6.4" + chalk "^4.1.2" + execa "^5.0.0" + fast-glob "^3.3.2" + fast-xml-parser "^4.0.12" + ora "^5.4.1" + "@react-native-community/cli-platform-ios@14.0.0-alpha.2": version "14.0.0-alpha.2" resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-14.0.0-alpha.2.tgz#6651691421d57d4230ee8d0dcd309af94a8303a7" @@ -2491,6 +2515,23 @@ serve-static "^1.13.1" ws "^7.5.1" +"@react-native-community/cli-tools@13.6.4", "@react-native-community/cli-tools@^13.6.4": + version "13.6.4" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-13.6.4.tgz#ab396604b6dcf215790807fe89656e779b11f0ec" + integrity sha512-N4oHLLbeTdg8opqJozjClmuTfazo1Mt+oxU7mr7m45VCsFgBqTF70Uwad289TM/3l44PP679NRMAHVYqpIRYtQ== + dependencies: + appdirsjs "^1.2.4" + chalk "^4.1.2" + execa "^5.0.0" + find-up "^5.0.0" + mime "^2.4.1" + node-fetch "^2.6.0" + open "^6.2.0" + ora "^5.4.1" + semver "^7.5.2" + shell-quote "^1.7.3" + sudo-prompt "^9.0.0" + "@react-native-community/cli-tools@14.0.0-alpha.2": version "14.0.0-alpha.2" resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-14.0.0-alpha.2.tgz#fa898083fa48449d9a2a08624fa2d71057a37d2e" @@ -2515,6 +2556,13 @@ dependencies: joi "^17.2.1" +"@react-native-community/cli-types@^13.6.4": + version "13.6.4" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-13.6.4.tgz#e499a3691ee597aa4b93196ff182a4782fae7afb" + integrity sha512-NxGCNs4eYtVC8x0wj0jJ/MZLRy8C+B9l8lY8kShuAcvWTv5JXRqmXjg8uK1aA+xikPh0maq4cc/zLw1roroY/A== + dependencies: + joi "^17.2.1" + "@react-native-community/cli@14.0.0-alpha.2": version "14.0.0-alpha.2" resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-14.0.0-alpha.2.tgz#39ca31ebe0ff615398012bacdd3de710229707a1" @@ -2658,6 +2706,19 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/envinfo@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@types/envinfo/-/envinfo-7.8.3.tgz#6fccc3425e300ee377aad15423e555dc6fc12fa1" + integrity sha512-qzV1XMjmzgmndci6L5HlzExf4w9A5jQPNpW/t4sSljErKbS8y6231ToHO9ir2Xjf+2zG1C540+Wmh0zpUsGu0A== + +"@types/fs-extra@^11.0.4": + version "11.0.4" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-11.0.4.tgz#e16a863bb8843fba8c5004362b5a73e17becca45" + integrity sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ== + dependencies: + "@types/jsonfile" "*" + "@types/node" "*" + "@types/glob@^8.1.0": version "8.1.0" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-8.1.0.tgz#b63e70155391b0584dce44e7ea25190bbc38f2fc" @@ -2723,6 +2784,13 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== +"@types/jsonfile@*": + version "6.1.4" + resolved "https://registry.yarnpkg.com/@types/jsonfile/-/jsonfile-6.1.4.tgz#614afec1a1164e7d670b4a7ad64df3e7beb7b702" + integrity sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ== + dependencies: + "@types/node" "*" + "@types/keyv@^3.1.4": version "3.1.4" resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" @@ -3998,6 +4066,11 @@ command-exists@^1.2.8: resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== +commander@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-12.0.0.tgz#b929db6df8546080adfd004ab215ed48cf6f2592" + integrity sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA== + commander@^2.12.1, commander@^2.18.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -5208,6 +5281,15 @@ fs-extra@^11.1.1: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b" @@ -9579,6 +9661,11 @@ yaml@^2.2.1: resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== +yaml@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.1.tgz#2e57e0b5e995292c25c75d2658f0664765210eed" + integrity sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg== + yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"