microsoft/vscode-react-native
Publicmirrored from https://github.com/microsoft/vscode-react-nativeAvailable
src/extension/exponent/exponentHelper.ts
398lines · modeblame
1c32fe84Patricio Beltran9 years ago | 1 | // Copyright (c) Microsoft Corporation. All rights reserved. |
| 2 | // Licensed under the MIT license. See LICENSE file in the project root for details. | |
| 3 | | |
94cd5149Artem Egorov8 years ago | 4 | /// <reference path="exponentHelper.d.ts" /> |
| 5 | | |
1c32fe84Patricio Beltran9 years ago | 6 | import * as path from "path"; |
7059d307Patricio Beltran9 years ago | 7 | import * as XDL from "./xdlInterface"; |
66412fdfRuslan Bikkinin7 years ago | 8 | import { Package, IPackageInformation } from "../../common/node/package"; |
e3706a1cRedMickey6 years ago | 9 | import { ProjectVersionHelper } from "../../common/projectVersionHelper"; |
34472878RedMickey5 years ago | 10 | import { OutputChannelLogger } from "../log/OutputChannelLogger"; |
94cd5149Artem Egorov8 years ago | 11 | import stripJSONComments = require("strip-json-comments"); |
d7d405aeYuri Skorokhodov7 years ago | 12 | import * as nls from "vscode-nls"; |
| 13 | import { ErrorHelper } from "../../common/error/errorHelper"; | |
| 14 | import { InternalErrorCode } from "../../common/error/internalErrorCode"; | |
ce5e88eeYuri Skorokhodov5 years ago | 15 | import { FileSystem } from "../../common/node/fileSystem"; |
34472878RedMickey5 years ago | 16 | nls.config({ |
| 17 | messageFormat: nls.MessageFormat.bundle, | |
| 18 | bundleFormat: nls.BundleFormat.standalone, | |
| 19 | })(); | |
d7d405aeYuri Skorokhodov7 years ago | 20 | const localize = nls.loadMessageBundle(); |
1c32fe84Patricio Beltran9 years ago | 21 | |
94cd5149Artem Egorov8 years ago | 22 | const APP_JSON = "app.json"; |
| 23 | const EXP_JSON = "exp.json"; | |
1c32fe84Patricio Beltran9 years ago | 24 | |
| 25 | const EXPONENT_INDEX = "exponentIndex.js"; | |
94cd5149Artem Egorov8 years ago | 26 | const DEFAULT_EXPONENT_INDEX = "index.js"; |
1c32fe84Patricio Beltran9 years ago | 27 | const DEFAULT_IOS_INDEX = "index.ios.js"; |
| 28 | const DEFAULT_ANDROID_INDEX = "index.android.js"; | |
| 29 | | |
94cd5149Artem Egorov8 years ago | 30 | const DBL_SLASHES = /\\/g; |
1c32fe84Patricio Beltran9 years ago | 31 | |
| 32 | export class ExponentHelper { | |
38edb09eAlexander Sorokin9 years ago | 33 | private workspaceRootPath: string; |
94cd5149Artem Egorov8 years ago | 34 | private projectRootPath: string; |
2956dba4Yuri Skorokhodov7 years ago | 35 | private fs: FileSystem; |
a57e740bPatricio Beltran9 years ago | 36 | private hasInitialized: boolean; |
0a68f8dbArtem Egorov8 years ago | 37 | private logger: OutputChannelLogger = OutputChannelLogger.getMainChannel(); |
1c32fe84Patricio Beltran9 years ago | 38 | |
34472878RedMickey5 years ago | 39 | public constructor( |
| 40 | workspaceRootPath: string, | |
| 41 | projectRootPath: string, | |
| 42 | fs: FileSystem = new FileSystem(), | |
| 43 | ) { | |
38edb09eAlexander Sorokin9 years ago | 44 | this.workspaceRootPath = workspaceRootPath; |
| 45 | this.projectRootPath = projectRootPath; | |
2956dba4Yuri Skorokhodov7 years ago | 46 | this.fs = fs; |
a57e740bPatricio Beltran9 years ago | 47 | this.hasInitialized = false; |
| 48 | // Constructor is slim by design. This is to add as less computation as possible | |
| 49 | // to the initialization of the extension. If a public method is added, make sure | |
b0af599cJimmy Thomson9 years ago | 50 | // to call this.lazilyInitialize() at the begining of the code to be sure all variables |
a57e740bPatricio Beltran9 years ago | 51 | // are correctly initialized. |
1c32fe84Patricio Beltran9 years ago | 52 | } |
| 53 | | |
ce5e88eeYuri Skorokhodov5 years ago | 54 | public configureExponentEnvironment(): Promise<void> { |
d1d77244Jimmy Thomson9 years ago | 55 | this.lazilyInitialize(); |
34472878RedMickey5 years ago | 56 | this.logger.info( |
| 57 | localize( | |
| 58 | "MakingSureYourProjectUsesCorrectExponentDependencies", | |
| 59 | "Making sure your project uses the correct dependencies for Expo. This may take a while...", | |
| 60 | ), | |
| 61 | ); | |
d7d405aeYuri Skorokhodov7 years ago | 62 | this.logger.logStream(localize("CheckingIfThisIsExpoApp", "Checking if this is Expo app.")); |
66412fdfRuslan Bikkinin7 years ago | 63 | let isExpo: boolean; |
| 64 | return this.isExpoApp(true) | |
| 65 | .then(result => { | |
| 66 | isExpo = result; | |
| 67 | if (!isExpo) { | |
34472878RedMickey5 years ago | 68 | return this.appHasExpoInstalled().then(expoInstalled => { |
66412fdfRuslan Bikkinin7 years ago | 69 | if (!expoInstalled) { |
| 70 | // Expo requires expo package to be installed inside RN application in order to be able to run it | |
| 71 | // https://github.com/expo/expo-cli/issues/255#issuecomment-453214632 | |
| 72 | this.logger.logStream("\n"); | |
34472878RedMickey5 years ago | 73 | this.logger.logStream( |
| 74 | localize( | |
| 75 | "ExpoPackageIsNotInstalled", | |
| 76 | '[Warning] Please make sure that expo package is installed locally for your project, otherwise further errors may occur. Please, run "npm install expo --save-dev" inside your project to install it.', | |
| 77 | ), | |
| 78 | ); | |
66412fdfRuslan Bikkinin7 years ago | 79 | this.logger.logStream("\n"); |
| 80 | } | |
| 81 | }); | |
| 82 | } | |
| 83 | return; | |
34472878RedMickey5 years ago | 84 | }) |
| 85 | .then(() => { | |
0a68f8dbArtem Egorov8 years ago | 86 | this.logger.logStream(".\n"); |
94cd5149Artem Egorov8 years ago | 87 | return this.patchAppJson(isExpo); |
| 88 | }); | |
d1d77244Jimmy Thomson9 years ago | 89 | } |
| 90 | | |
| 91 | /** | |
| 92 | * Returns the current user. If there is none, asks user for username and password and logins to exponent servers. | |
| 93 | */ | |
5c8365a6Artem Egorov8 years ago | 94 | public loginToExponent( |
ce5e88eeYuri Skorokhodov5 years ago | 95 | promptForInformation: (message: string, password: boolean) => Promise<string>, |
34472878RedMickey5 years ago | 96 | showMessage: (message: string) => Promise<string>, |
ce5e88eeYuri Skorokhodov5 years ago | 97 | ): Promise<XDL.IUser> { |
d1d77244Jimmy Thomson9 years ago | 98 | this.lazilyInitialize(); |
| 99 | return XDL.currentUser() | |
34472878RedMickey5 years ago | 100 | .then(user => { |
d1d77244Jimmy Thomson9 years ago | 101 | if (!user) { |
| 102 | let username = ""; | |
34472878RedMickey5 years ago | 103 | return showMessage( |
| 104 | localize( | |
| 105 | "YouNeedToLoginToExpo", | |
| 106 | "You need to login to Expo. Please provide your Expo account username and password in the input boxes after closing this window. If you don't have an account, please go to https://expo.io to create one.", | |
| 107 | ), | |
| 108 | ) | |
d1d77244Jimmy Thomson9 years ago | 109 | .then(() => |
34472878RedMickey5 years ago | 110 | promptForInformation(localize("ExpoUsername", "Expo username"), false), |
| 111 | ) | |
| 112 | .then((name: string) => { | |
d1d77244Jimmy Thomson9 years ago | 113 | username = name; |
34472878RedMickey5 years ago | 114 | return promptForInformation( |
| 115 | localize("ExpoPassword", "Expo password"), | |
| 116 | true, | |
| 117 | ); | |
d1d77244Jimmy Thomson9 years ago | 118 | }) |
34472878RedMickey5 years ago | 119 | .then((password: string) => XDL.login(username, password)); |
d1d77244Jimmy Thomson9 years ago | 120 | } |
| 121 | return user; | |
| 122 | }) | |
| 123 | .catch(error => { | |
ce5e88eeYuri Skorokhodov5 years ago | 124 | return Promise.reject<XDL.IUser>(error); |
d1d77244Jimmy Thomson9 years ago | 125 | }); |
| 126 | } | |
| 127 | | |
ce5e88eeYuri Skorokhodov5 years ago | 128 | public getExpPackagerOptions(): Promise<ExpConfigPackager> { |
6458f408Nikita Matrosov9 years ago | 129 | this.lazilyInitialize(); |
34472878RedMickey5 years ago | 130 | return this.getFromExpConfig("packagerOpts").then(opts => opts || {}); |
6458f408Nikita Matrosov9 years ago | 131 | } |
| 132 | | |
ce5e88eeYuri Skorokhodov5 years ago | 133 | public appHasExpoInstalled(): Promise<boolean> { |
34472878RedMickey5 years ago | 134 | return this.getAppPackageInformation().then((packageJson: IPackageInformation) => { |
| 135 | if (packageJson.dependencies && packageJson.dependencies.expo) { | |
| 136 | this.logger.debug( | |
| 137 | "'expo' package is found in 'dependencies' section of package.json", | |
| 138 | ); | |
| 139 | return true; | |
| 140 | } else if (packageJson.devDependencies && packageJson.devDependencies.expo) { | |
| 141 | this.logger.debug( | |
| 142 | "'expo' package is found in 'devDependencies' section of package.json", | |
| 143 | ); | |
| 144 | return true; | |
| 145 | } | |
| 146 | return false; | |
| 147 | }); | |
66412fdfRuslan Bikkinin7 years ago | 148 | } |
| 149 | | |
ce5e88eeYuri Skorokhodov5 years ago | 150 | public appHasExpoRNSDKInstalled(): Promise<boolean> { |
34472878RedMickey5 years ago | 151 | return this.getAppPackageInformation().then((packageJson: IPackageInformation) => { |
| 152 | const reactNativeValue: string | undefined = | |
| 153 | packageJson.dependencies && packageJson.dependencies["react-native"]; | |
| 154 | if (reactNativeValue) { | |
| 155 | this.logger.debug( | |
| 156 | `'react-native' package with value '${reactNativeValue}' is found in 'dependencies' section of package.json`, | |
| 157 | ); | |
| 158 | if ( | |
| 159 | reactNativeValue.startsWith("https://github.com/expo/react-native/archive/sdk") | |
| 160 | ) { | |
| 161 | return true; | |
66412fdfRuslan Bikkinin7 years ago | 162 | } |
34472878RedMickey5 years ago | 163 | } |
| 164 | return false; | |
| 165 | }); | |
66412fdfRuslan Bikkinin7 years ago | 166 | } |
| 167 | | |
ce5e88eeYuri Skorokhodov5 years ago | 168 | public isExpoApp(showProgress: boolean = false): Promise<boolean> { |
db6fd42aRuslan Bikkinin7 years ago | 169 | if (showProgress) { |
| 170 | this.logger.logStream("..."); | |
| 171 | } | |
| 172 | | |
34472878RedMickey5 years ago | 173 | return Promise.all([this.appHasExpoInstalled(), this.appHasExpoRNSDKInstalled()]) |
| 174 | .then(([expoInstalled, expoRNSDKInstalled]) => { | |
ce5e88eeYuri Skorokhodov5 years ago | 175 | if (showProgress) this.logger.logStream("."); |
| 176 | return expoInstalled && expoRNSDKInstalled; | |
34472878RedMickey5 years ago | 177 | }) |
| 178 | .catch(e => { | |
66412fdfRuslan Bikkinin7 years ago | 179 | this.logger.error(e.message, e, e.stack); |
db6fd42aRuslan Bikkinin7 years ago | 180 | if (showProgress) { |
| 181 | this.logger.logStream("."); | |
| 182 | } | |
| 183 | // Not in a react-native project | |
| 184 | return false; | |
| 185 | }); | |
| 186 | } | |
| 187 | | |
1c32fe84Patricio Beltran9 years ago | 188 | /** |
94cd5149Artem Egorov8 years ago | 189 | * Path to a given file inside the .vscode directory |
1c32fe84Patricio Beltran9 years ago | 190 | */ |
66412fdfRuslan Bikkinin7 years ago | 191 | private dotvscodePath(filename: string, isAbsolute: boolean): string { |
| 192 | let paths = [".vscode", filename]; | |
| 193 | if (isAbsolute) { | |
| 194 | paths = [this.workspaceRootPath].concat(...paths); | |
| 195 | } | |
| 196 | return path.join(...paths); | |
94cd5149Artem Egorov8 years ago | 197 | } |
| 198 | | |
ce5e88eeYuri Skorokhodov5 years ago | 199 | private createExpoEntry(name: string): Promise<void> { |
b0af599cJimmy Thomson9 years ago | 200 | this.lazilyInitialize(); |
34472878RedMickey5 years ago | 201 | return this.detectEntry().then((entryPoint: string) => { |
| 202 | const content = this.generateFileContent(name, entryPoint); | |
| 203 | return this.fs.writeFile(this.dotvscodePath(EXPONENT_INDEX, true), content); | |
| 204 | }); | |
94cd5149Artem Egorov8 years ago | 205 | } |
1c32fe84Patricio Beltran9 years ago | 206 | |
ce5e88eeYuri Skorokhodov5 years ago | 207 | private detectEntry(): Promise<string> { |
94cd5149Artem Egorov8 years ago | 208 | this.lazilyInitialize(); |
ce5e88eeYuri Skorokhodov5 years ago | 209 | return Promise.all([ |
94cd5149Artem Egorov8 years ago | 210 | this.fs.exists(this.pathToFileInWorkspace(DEFAULT_EXPONENT_INDEX)), |
| 211 | this.fs.exists(this.pathToFileInWorkspace(DEFAULT_IOS_INDEX)), | |
| 212 | this.fs.exists(this.pathToFileInWorkspace(DEFAULT_ANDROID_INDEX)), | |
ce5e88eeYuri Skorokhodov5 years ago | 213 | ]).then(([expo, ios]) => { |
34472878RedMickey5 years ago | 214 | return expo |
| 215 | ? this.pathToFileInWorkspace(DEFAULT_EXPONENT_INDEX) | |
| 216 | : ios | |
| 217 | ? this.pathToFileInWorkspace(DEFAULT_IOS_INDEX) | |
| 218 | : this.pathToFileInWorkspace(DEFAULT_ANDROID_INDEX); | |
ce5e88eeYuri Skorokhodov5 years ago | 219 | }); |
94cd5149Artem Egorov8 years ago | 220 | } |
1c32fe84Patricio Beltran9 years ago | 221 | |
94cd5149Artem Egorov8 years ago | 222 | private generateFileContent(name: string, entryPoint: string): string { |
| 223 | return `// This file is automatically generated by VS Code | |
| 224 | // Please do not modify it manually. All changes will be lost. | |
| 225 | var React = require('${this.pathToFileInWorkspace("/node_modules/react")}'); | |
| 226 | var { Component } = React; | |
| 227 | var ReactNative = require('${this.pathToFileInWorkspace("/node_modules/react-native")}'); | |
| 228 | var { AppRegistry } = ReactNative; | |
f6b41bbfAlexander Sorokin9 years ago | 229 | AppRegistry.registerRunnable('main', function(appParameters) { |
94cd5149Artem Egorov8 years ago | 230 | AppRegistry.runApplication('${name}', appParameters); |
253b6e8eRedMickey5 years ago | 231 | }); |
| 232 | var entryPoint = require('${entryPoint}');`; | |
1c32fe84Patricio Beltran9 years ago | 233 | } |
| 234 | | |
ce5e88eeYuri Skorokhodov5 years ago | 235 | private patchAppJson(isExpo: boolean = true): Promise<void> { |
94cd5149Artem Egorov8 years ago | 236 | return this.readAppJson() |
| 237 | .catch(() => { | |
| 238 | // if app.json doesn't exist but it's ok, we will create it | |
| 239 | return {}; | |
| 240 | }) | |
| 241 | .then((config: AppJson) => { | |
| 242 | let expoConfig = <ExpConfig>(config.expo || {}); | |
| 243 | if (!expoConfig.name || !expoConfig.slug) { | |
34472878RedMickey5 years ago | 244 | return this.getPackageName().then((name: string) => { |
| 245 | expoConfig.slug = expoConfig.slug || config.name || name.replace(" ", "-"); | |
| 246 | expoConfig.name = expoConfig.name || config.name || name; | |
| 247 | config.expo = expoConfig; | |
| 248 | return config; | |
| 249 | }); | |
b0af599cJimmy Thomson9 years ago | 250 | } |
| 251 | | |
94cd5149Artem Egorov8 years ago | 252 | return config; |
| 253 | }) | |
66412fdfRuslan Bikkinin7 years ago | 254 | .then((config: AppJson) => { |
| 255 | if (!config.name) { | |
34472878RedMickey5 years ago | 256 | return this.getPackageName().then((name: string) => { |
| 257 | config.name = name; | |
| 258 | return config; | |
| 259 | }); | |
66412fdfRuslan Bikkinin7 years ago | 260 | } |
| 261 | | |
| 262 | return config; | |
| 263 | }) | |
94cd5149Artem Egorov8 years ago | 264 | .then((config: AppJson) => { |
| 265 | if (!config.expo.sdkVersion) { | |
34472878RedMickey5 years ago | 266 | return this.exponentSdk(true).then(sdkVersion => { |
| 267 | config.expo.sdkVersion = sdkVersion; | |
| 268 | return config; | |
| 269 | }); | |
1c32fe84Patricio Beltran9 years ago | 270 | } |
66412fdfRuslan Bikkinin7 years ago | 271 | |
94cd5149Artem Egorov8 years ago | 272 | return config; |
1c32fe84Patricio Beltran9 years ago | 273 | }) |
94cd5149Artem Egorov8 years ago | 274 | .then((config: AppJson) => { |
| 275 | if (!isExpo) { | |
66412fdfRuslan Bikkinin7 years ago | 276 | // entryPoint must be relative |
| 277 | // https://docs.expo.io/versions/latest/workflow/configuration/#entrypoint | |
| 278 | config.expo.entryPoint = this.dotvscodePath(EXPONENT_INDEX, false); | |
94cd5149Artem Egorov8 years ago | 279 | } |
1c32fe84Patricio Beltran9 years ago | 280 | |
94cd5149Artem Egorov8 years ago | 281 | return config; |
| 282 | }) | |
| 283 | .then((config: AppJson) => { | |
5c8365a6Artem Egorov8 years ago | 284 | return config ? this.writeAppJson(config) : config; |
1c32fe84Patricio Beltran9 years ago | 285 | }) |
94cd5149Artem Egorov8 years ago | 286 | .then((config: AppJson) => { |
ce5e88eeYuri Skorokhodov5 years ago | 287 | return isExpo ? Promise.resolve() : this.createExpoEntry(config.expo.name); |
1c32fe84Patricio Beltran9 years ago | 288 | }); |
27710197Vladimir Kotikov8 years ago | 289 | } |
1c32fe84Patricio Beltran9 years ago | 290 | |
| 291 | /** | |
| 292 | * Exponent sdk version that maps to the current react-native version | |
| 293 | * If react native version is not supported it returns null. | |
| 294 | */ | |
ce5e88eeYuri Skorokhodov5 years ago | 295 | private exponentSdk(showProgress: boolean = false): Promise<string> { |
94cd5149Artem Egorov8 years ago | 296 | if (showProgress) { |
0a68f8dbArtem Egorov8 years ago | 297 | this.logger.logStream("..."); |
1c32fe84Patricio Beltran9 years ago | 298 | } |
94cd5149Artem Egorov8 years ago | 299 | |
34472878RedMickey5 years ago | 300 | return ProjectVersionHelper.getReactNativeVersions(this.projectRootPath).then(versions => { |
| 301 | if (showProgress) this.logger.logStream("."); | |
| 302 | return XDL.mapVersion(versions.reactNativeVersion).then(sdkVersion => { | |
| 303 | if (!sdkVersion) { | |
| 304 | return XDL.supportedVersions().then(versions => { | |
| 305 | return Promise.reject<string>( | |
| 306 | ErrorHelper.getInternalError( | |
| 307 | InternalErrorCode.RNVersionNotSupportedByExponent, | |
| 308 | versions.join(", "), | |
| 309 | ), | |
| 310 | ); | |
1c32fe84Patricio Beltran9 years ago | 311 | }); |
34472878RedMickey5 years ago | 312 | } |
| 313 | return sdkVersion; | |
1c32fe84Patricio Beltran9 years ago | 314 | }); |
34472878RedMickey5 years ago | 315 | }); |
1c32fe84Patricio Beltran9 years ago | 316 | } |
| 317 | | |
| 318 | /** | |
94cd5149Artem Egorov8 years ago | 319 | * Name specified on user's package.json |
1c32fe84Patricio Beltran9 years ago | 320 | */ |
ce5e88eeYuri Skorokhodov5 years ago | 321 | private getPackageName(): Promise<string> { |
94cd5149Artem Egorov8 years ago | 322 | return new Package(this.projectRootPath, { fileSystem: this.fs }).name(); |
| 323 | } | |
| 324 | | |
ce5e88eeYuri Skorokhodov5 years ago | 325 | private getExpConfig(): Promise<ExpConfig> { |
34472878RedMickey5 years ago | 326 | return this.readExpJson().catch(err => { |
| 327 | if (err.code === "ENOENT") { | |
| 328 | return this.readAppJson().then((config: AppJson) => { | |
| 329 | return config.expo || {}; | |
| 330 | }); | |
| 331 | } | |
| 332 | | |
| 333 | return err; | |
| 334 | }); | |
1c32fe84Patricio Beltran9 years ago | 335 | } |
| 336 | | |
ce5e88eeYuri Skorokhodov5 years ago | 337 | private getFromExpConfig(key: string): Promise<any> { |
34472878RedMickey5 years ago | 338 | return this.getExpConfig().then((config: ExpConfig) => config[key]); |
1c32fe84Patricio Beltran9 years ago | 339 | } |
| 340 | | |
| 341 | /** | |
94cd5149Artem Egorov8 years ago | 342 | * Returns the specified setting from exp.json if it exists |
1c32fe84Patricio Beltran9 years ago | 343 | */ |
ce5e88eeYuri Skorokhodov5 years ago | 344 | private readExpJson(): Promise<ExpConfig> { |
94cd5149Artem Egorov8 years ago | 345 | const expJsonPath = this.pathToFileInWorkspace(EXP_JSON); |
34472878RedMickey5 years ago | 346 | return this.fs.readFile(expJsonPath).then(content => { |
| 347 | return JSON.parse(stripJSONComments(content.toString())); | |
| 348 | }); | |
1c32fe84Patricio Beltran9 years ago | 349 | } |
| 350 | | |
ce5e88eeYuri Skorokhodov5 years ago | 351 | private readAppJson(): Promise<AppJson> { |
94cd5149Artem Egorov8 years ago | 352 | const appJsonPath = this.pathToFileInWorkspace(APP_JSON); |
34472878RedMickey5 years ago | 353 | return this.fs.readFile(appJsonPath).then(content => { |
| 354 | return JSON.parse(stripJSONComments(content.toString())); | |
| 355 | }); | |
1c32fe84Patricio Beltran9 years ago | 356 | } |
| 357 | | |
ce5e88eeYuri Skorokhodov5 years ago | 358 | private writeAppJson(config: AppJson): Promise<AppJson> { |
94cd5149Artem Egorov8 years ago | 359 | const appJsonPath = this.pathToFileInWorkspace(APP_JSON); |
34472878RedMickey5 years ago | 360 | return this.fs.writeFile(appJsonPath, JSON.stringify(config, null, 2)).then(() => config); |
1c32fe84Patricio Beltran9 years ago | 361 | } |
| 362 | | |
ce5e88eeYuri Skorokhodov5 years ago | 363 | private getAppPackageInformation(): Promise<IPackageInformation> { |
66412fdfRuslan Bikkinin7 years ago | 364 | return new Package(this.projectRootPath, { fileSystem: this.fs }).parsePackageInformation(); |
| 365 | } | |
| 366 | | |
1c32fe84Patricio Beltran9 years ago | 367 | /** |
38edb09eAlexander Sorokin9 years ago | 368 | * Path to a given file from the workspace root |
1c32fe84Patricio Beltran9 years ago | 369 | */ |
| 370 | private pathToFileInWorkspace(filename: string): string { | |
94cd5149Artem Egorov8 years ago | 371 | return path.join(this.projectRootPath, filename).replace(DBL_SLASHES, "/"); |
1c32fe84Patricio Beltran9 years ago | 372 | } |
| 373 | | |
a57e740bPatricio Beltran9 years ago | 374 | /** |
| 375 | * Works as a constructor but only initiliazes when it's actually needed. | |
| 376 | */ | |
b0af599cJimmy Thomson9 years ago | 377 | private lazilyInitialize(): void { |
a57e740bPatricio Beltran9 years ago | 378 | if (!this.hasInitialized) { |
| 379 | this.hasInitialized = true; | |
| 380 | | |
| 381 | XDL.configReactNativeVersionWargnings(); | |
38edb09eAlexander Sorokin9 years ago | 382 | XDL.attachLoggerStream(this.projectRootPath, { |
a57e740bPatricio Beltran9 years ago | 383 | stream: { |
| 384 | write: (chunk: any) => { | |
| 385 | if (chunk.level <= 30) { | |
0a68f8dbArtem Egorov8 years ago | 386 | this.logger.logStream(chunk.msg); |
a57e740bPatricio Beltran9 years ago | 387 | } else if (chunk.level === 40) { |
0a68f8dbArtem Egorov8 years ago | 388 | this.logger.warning(chunk.msg); |
a57e740bPatricio Beltran9 years ago | 389 | } else { |
0a68f8dbArtem Egorov8 years ago | 390 | this.logger.error(chunk.msg); |
a57e740bPatricio Beltran9 years ago | 391 | } |
| 392 | }, | |
| 393 | }, | |
| 394 | type: "raw", | |
| 395 | }); | |
| 396 | } | |
| 397 | } | |
5c8365a6Artem Egorov8 years ago | 398 | } |