microsoft/vscode-react-native
Publicmirrored fromhttps://github.com/microsoft/vscode-react-nativeAvailable
src/extension/commands/enableHermes.ts
95lines · modecode
| 1 | // Copyright (c) Microsoft Corporation. All rights reserved. |
| 2 | // Licensed under the MIT license. See LICENSE file in the project root for details. |
| 3 | |
| 4 | import assert = require("assert"); |
| 5 | import * as path from "path"; |
| 6 | import * as fs from "fs"; |
| 7 | import * as vscode from "vscode"; |
| 8 | import { ErrorHelper } from "../../common/error/errorHelper"; |
| 9 | import { InternalErrorCode } from "../../common/error/internalErrorCode"; |
| 10 | import { FileSystem } from "../../common/node/fileSystem"; |
| 11 | import { OutputChannelLogger } from "../log/OutputChannelLogger"; |
| 12 | import { CommandExecutor } from "../../common/commandExecutor"; |
| 13 | import { AppLauncher } from "../appLauncher"; |
| 14 | import { Command } from "./util/command"; |
| 15 | |
| 16 | const logger = OutputChannelLogger.getMainChannel(); |
| 17 | |
| 18 | export class EnableHermes extends Command { |
| 19 | codeName = "hermesEnable"; |
| 20 | label = "Enable Hermes"; |
| 21 | error = ErrorHelper.getInternalError(InternalErrorCode.FailedToEnableHermes); |
| 22 | private nodeFileSystem = new FileSystem(); |
| 23 | |
| 24 | async baseFn(): Promise<void> { |
| 25 | assert(this.project); |
| 26 | const type = await vscode.window.showQuickPick(["Android", "iOS"], { |
| 27 | placeHolder: "Select type for mobile OS", |
| 28 | }); |
| 29 | const isHermesEnabled = await vscode.window.showQuickPick(["true", "false"], { |
| 30 | placeHolder: "Whether to enable Hermes", |
| 31 | }); |
| 32 | const projectRoot = this.project.getPackager().getProjectPath(); |
| 33 | |
| 34 | if (type === undefined || isHermesEnabled === undefined) return; |
| 35 | if (type === "iOS") { |
| 36 | const podfilePath = path.join(projectRoot, "ios", "Podfile"); |
| 37 | if (!projectRoot || !fs.existsSync(podfilePath)) { |
| 38 | logger.warning("Podfile not found"); |
| 39 | return; |
| 40 | } |
| 41 | |
| 42 | const podfileContent = fs.readFileSync(podfilePath, "utf-8"); |
| 43 | const hermesMatches = podfileContent.match(/#?\s*:hermes_enabled\s*=>\s*\w*/); |
| 44 | const regex = /(use_react_native!\s*\([^)]*?)(\n\s*\))/; |
| 45 | const rnMatches = podfileContent.match(regex); |
| 46 | const nodeModulesRoot: string = |
| 47 | AppLauncher.getNodeModulesRootByProjectPath(projectRoot); |
| 48 | const commandExecutor = new CommandExecutor( |
| 49 | nodeModulesRoot, |
| 50 | `${projectRoot}/ios`, |
| 51 | logger, |
| 52 | ); |
| 53 | |
| 54 | if (hermesMatches && !hermesMatches[0].startsWith("#")) { |
| 55 | const updatedHermes = podfileContent.replace( |
| 56 | /:hermes_enabled\s*=>\s*\w+/, |
| 57 | `:hermes_enabled => ${isHermesEnabled}`, |
| 58 | ); |
| 59 | await this.nodeFileSystem.writeFile(podfilePath, updatedHermes); |
| 60 | await commandExecutor.spawn("pod", ["install"]); |
| 61 | } else if (rnMatches) { |
| 62 | let content = rnMatches[1]; |
| 63 | const closing = rnMatches[2]; |
| 64 | |
| 65 | if (!content.trim().endsWith(",")) { |
| 66 | content += ","; |
| 67 | } |
| 68 | content += `\n :hermes_enabled => ${isHermesEnabled}`; |
| 69 | const newData = podfileContent.replace(regex, content + closing); |
| 70 | await this.nodeFileSystem.writeFile(podfilePath, newData); |
| 71 | await commandExecutor.spawn("pod", ["install"]); |
| 72 | } |
| 73 | } |
| 74 | if (type === "Android") { |
| 75 | const gradleFilePath = path.join(projectRoot, "android", "gradle.properties"); |
| 76 | if (!projectRoot || !fs.existsSync(gradleFilePath)) { |
| 77 | logger.warning("gradle.properties file not found"); |
| 78 | return; |
| 79 | } |
| 80 | |
| 81 | const gradleFileContent = fs.readFileSync(gradleFilePath, "utf-8"); |
| 82 | const hermesMatches = gradleFileContent.match(/hermesEnabled\s*=\s*\w*/); |
| 83 | if (hermesMatches && !hermesMatches[0].startsWith("#")) { |
| 84 | const updatedHermes = gradleFileContent.replace( |
| 85 | /hermesEnabled\s*=\s*\w*/, |
| 86 | `hermesEnabled=${isHermesEnabled}`, |
| 87 | ); |
| 88 | await this.nodeFileSystem.writeFile(gradleFilePath, updatedHermes); |
| 89 | } else { |
| 90 | const updatedGradle = `${gradleFileContent} \nhermesEnabled=${isHermesEnabled}`; |
| 91 | await this.nodeFileSystem.writeFile(gradleFilePath, updatedGradle); |
| 92 | } |
| 93 | } |
| 94 | } |
| 95 | } |
| 96 | |