From 685f10363a53b6858f0841b20b75baad5e6f7b07 Mon Sep 17 00:00:00 2001 From: Tom Underhill Date: Fri, 3 Apr 2020 20:53:43 -0700 Subject: [PATCH 1/9] Update scripts to publish react-native-macos-init --- .ado/publish.yml | 33 ++++++++ .ado/versionUtils.js | 20 +++++ packages/react-native-macos-init/package.json | 82 +++++++++---------- 3 files changed, 94 insertions(+), 41 deletions(-) diff --git a/.ado/publish.yml b/.ado/publish.yml index eccfa3821fc5fd..4a7c05c54376ea 100644 --- a/.ado/publish.yml +++ b/.ado/publish.yml @@ -49,6 +49,39 @@ jobs: command: 'publish' publishEndpoint: 'npmjs' + - job: RNMacOSInitNpmJSPublish + displayName: react-native-macos-init Publish to npmjs.org + pool: + vmImage: vs2017-win2016 + timeoutInMinutes: 90 # how long to run the job before automatically cancelling + cancelTimeoutInMinutes: 5 # how much time to give 'run always even if cancelled tasks' before killing them + steps: + - checkout: self # self represents the repo where the initial Pipelines YAML file was found + clean: true # whether to fetch clean each time + # fetchDepth: 2 # the depth of commits to ask Git to fetch + lfs: false # whether to download Git-LFS files + submodules: recursive # set to 'true' for a single level of submodules or 'recursive' to get submodules of submodules + persistCredentials: true # set to 'true' to leave the OAuth token in the Git config after the initial fetch + + - task: CmdLine@2 + displayName: npm install + inputs: + script: | + cd packages/react-native-macos-init + npm install + + - task: CmdLine@2 + displayName: Bump package version + inputs: + script: node .ado/bumpFileVersions.js + + - task: Npm@1 + displayName: "Publish react-native-macos-init to npmjs.org" + inputs: + command: 'publish' + workingDir: 'packages/react-native-macos-init' + publishEndpoint: 'npmjs' + - job: RNGithubOfficePublish displayName: React-Native GitHub Publish to Office pool: diff --git a/.ado/versionUtils.js b/.ado/versionUtils.js index cda5beaa13023a..bdfa0f0f4b2a63 100644 --- a/.ado/versionUtils.js +++ b/.ado/versionUtils.js @@ -14,6 +14,23 @@ function gatherVersionInfo() { return {pkgJson, releaseVersion, branchVersionSuffix}; } +function updateReactNativeMacOSInitVersionInFile() { + const rnMacOSInitPkgJsonPath = path.resolve(__dirname, "../packages/react-native-macos-init/package.json"); + const rnMacOSInitPkgJson = JSON.parse(fs.readFileSync(rnMacOSInitPkgJsonPath, "utf8")); + let rnMacOSInitReleaseVersion = rnMacOSInitPkgJson.version; + const rnMacOSInitVersionStringRegEx = new RegExp(`([0-9]*)\\.([0-9]*)\\.([0-9]*)`); + const rnMacOSInitVersionGroups = rnMacOSInitVersionStringRegEx.exec(rnMacOSInitReleaseVersion); + if (rnMacOSInitVersionGroups) { + rnMacOSInitReleaseVersion = rnMacOSInitVersionGroups[1] + '.' + rnMacOSInitVersionGroups[2] + '.' + (parseInt(rnMacOSInitVersionGroups[3]) + 1); + } else { + console.log("Invalid react-native-macos-init version to publish"); + process.exit(1); + } + rnMacOSInitPkgJson.version = rnMacOSInitReleaseVersion; + fs.writeFileSync(rnMacOSInitPkgJsonPath, JSON.stringify(rnMacOSInitPkgJson, null, 2)); + console.log(`Updating ${rnMacOSInitPkgJsonPath} to version ${rnMacOSInitReleaseVersion}`); +} + function updateVersionsInFiles() { let {pkgJson, releaseVersion, branchVersionSuffix} = gatherVersionInfo(); @@ -34,6 +51,9 @@ function updateVersionsInFiles() { pkgJson.version = releaseVersion; fs.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2)); console.log(`Updating package.json to version ${releaseVersion}`); + + updateReactNativeMacOSInitVersionInFile(); + return {releaseVersion, branchVersionSuffix}; } diff --git a/packages/react-native-macos-init/package.json b/packages/react-native-macos-init/package.json index 6ea151ab56411f..3efc8802671405 100644 --- a/packages/react-native-macos-init/package.json +++ b/packages/react-native-macos-init/package.json @@ -1,42 +1,42 @@ { - "name": "react-native-macos-init", - "version": "0.0.9", - "description": "CLI to add react-native-macos to an existing react-native project", - "main": "index.js", - "repository": "https://github.com/microsoft/react-native-macos", - "license": "MIT", - "private": false, - "scripts": { - "build": "just-scripts build", - "clean": "just-scripts clean", - "lint": "just-scripts lint", - "lint:fix": "just-scripts lint:fix", - "prepublishOnly": "npm run build" - }, - "bin": { - "react-native-macos-init": "./bin.js" - }, - "dependencies": { - "chalk": "^3", - "npm-registry": "^0.1.13", - "prompts": "^2.3.0", - "find-up": "^4.1.0", - "semver": "^7.1.3", - "valid-url": "^1.0.9", - "yargs": "^15.1.0" - }, - "devDependencies": { - "@types/chalk": "^2.2.0", - "@types/prompts": "^2.0.3", - "@types/semver": "^7.1.0", - "@types/valid-url": "^1.0.2", - "@types/yargs": "^15.0.3", - "just-scripts": "^0.36.1", - "typescript": "3.5.3" - }, - "files": [ - "bin.js", - "lib-commonjs", - "README.md" - ] - } \ No newline at end of file + "name": "react-native-macos-init", + "version": "0.0.0", + "description": "CLI to add react-native-macos to an existing react-native project", + "main": "index.js", + "repository": "https://github.com/microsoft/react-native-macos", + "license": "MIT", + "private": false, + "scripts": { + "build": "just-scripts build", + "clean": "just-scripts clean", + "lint": "just-scripts lint", + "lint:fix": "just-scripts lint:fix", + "prepublishOnly": "npm run build" + }, + "bin": { + "react-native-macos-init": "./bin.js" + }, + "dependencies": { + "chalk": "^3", + "npm-registry": "^0.1.13", + "prompts": "^2.3.0", + "find-up": "^4.1.0", + "semver": "^7.1.3", + "valid-url": "^1.0.9", + "yargs": "^15.1.0" + }, + "devDependencies": { + "@types/chalk": "^2.2.0", + "@types/prompts": "^2.0.3", + "@types/semver": "^7.1.0", + "@types/valid-url": "^1.0.2", + "@types/yargs": "^15.0.3", + "just-scripts": "^0.36.1", + "typescript": "3.5.3" + }, + "files": [ + "bin.js", + "lib-commonjs", + "README.md" + ] +} \ No newline at end of file From 1e2c329a34a980d10c4124c4027713a41d51563a Mon Sep 17 00:00:00 2001 From: Tom Underhill Date: Sat, 4 Apr 2020 15:51:32 -0700 Subject: [PATCH 2/9] Clean up merge markers --- .ado/versionUtils.js | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/.ado/versionUtils.js b/.ado/versionUtils.js index bd2441fdbf7113..8abed9b6c41882 100644 --- a/.ado/versionUtils.js +++ b/.ado/versionUtils.js @@ -14,23 +14,6 @@ function gatherVersionInfo() { return {pkgJson, releaseVersion, branchVersionSuffix}; } -function updateReactNativeMacOSInitVersionInFile() { - const rnMacOSInitPkgJsonPath = path.resolve(__dirname, "../packages/react-native-macos-init/package.json"); - const rnMacOSInitPkgJson = JSON.parse(fs.readFileSync(rnMacOSInitPkgJsonPath, "utf8")); - let rnMacOSInitReleaseVersion = rnMacOSInitPkgJson.version; - const rnMacOSInitVersionStringRegEx = new RegExp(`([0-9]*)\\.([0-9]*)\\.([0-9]*)`); - const rnMacOSInitVersionGroups = rnMacOSInitVersionStringRegEx.exec(rnMacOSInitReleaseVersion); - if (rnMacOSInitVersionGroups) { - rnMacOSInitReleaseVersion = rnMacOSInitVersionGroups[1] + '.' + rnMacOSInitVersionGroups[2] + '.' + (parseInt(rnMacOSInitVersionGroups[3]) + 1); - } else { - console.log("Invalid react-native-macos-init version to publish"); - process.exit(1); - } - rnMacOSInitPkgJson.version = rnMacOSInitReleaseVersion; - fs.writeFileSync(rnMacOSInitPkgJsonPath, JSON.stringify(rnMacOSInitPkgJson, null, 2)); - console.log(`Updating ${rnMacOSInitPkgJsonPath} to version ${rnMacOSInitReleaseVersion}`); -} - function updateVersionsInFiles() { let {pkgJson, releaseVersion, branchVersionSuffix} = gatherVersionInfo(); @@ -51,11 +34,6 @@ function updateVersionsInFiles() { pkgJson.version = releaseVersion; fs.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2)); console.log(`Updating package.json to version ${releaseVersion}`); -<<<<<<< HEAD - - updateReactNativeMacOSInitVersionInFile(); -======= ->>>>>>> ms/master return {releaseVersion, branchVersionSuffix}; } From eb84be81c745c4eb69c807e9c0d819a25b3da6ff Mon Sep 17 00:00:00 2001 From: Tom Underhill Date: Tue, 7 Apr 2020 12:28:42 -0700 Subject: [PATCH 3/9] Start of run-macos cli --- local-cli/runMacOS/findXcodeProject.js | 34 ++++ local-cli/runMacOS/runMacOS.js | 272 +++++++++++++++++++++++++ package.json | 4 +- react-native.config.js | 3 +- 4 files changed, 310 insertions(+), 3 deletions(-) create mode 100644 local-cli/runMacOS/findXcodeProject.js create mode 100644 local-cli/runMacOS/runMacOS.js diff --git a/local-cli/runMacOS/findXcodeProject.js b/local-cli/runMacOS/findXcodeProject.js new file mode 100644 index 00000000000000..8916af1483ff14 --- /dev/null +++ b/local-cli/runMacOS/findXcodeProject.js @@ -0,0 +1,34 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +const path = require('path'); + +function findXcodeProject(files) { + const sortedFiles = files.sort(); + for (let i = sortedFiles.length - 1; i >= 0; i--) { + const fileName = files[i]; + const ext = path.extname(fileName); + + if (ext === '.xcworkspace') { + return { + name: fileName, + isWorkspace: true, + }; + } + if (ext === '.xcodeproj') { + return { + name: fileName, + isWorkspace: false, + }; + } + } + + return null; +} + +module.exports = findXcodeProject; diff --git a/local-cli/runMacOS/runMacOS.js b/local-cli/runMacOS/runMacOS.js new file mode 100644 index 00000000000000..4d7a12d974ed6b --- /dev/null +++ b/local-cli/runMacOS/runMacOS.js @@ -0,0 +1,272 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + * @format + */ +// @ts-check +'use strict'; + +const child_process = require('child_process'); +const fs = require('fs'); +const path = require('path'); +const chalk = require('chalk'); +const findXcodeProject = require('./findXcodeProject'); +const { + logger, + CLIError, + getDefaultUserTerminal, +} = require('@react-native-community/cli-tools'); + +function runMacOS(_, ctx, args) { + if (!fs.existsSync(args.projectPath)) { + throw new CLIError( + 'macOS project folder not found. Are you sure this is a React Native project?', + ); + } + + process.chdir(args.projectPath); + + const xcodeProject = findXcodeProject(fs.readdirSync('.')); + if (!xcodeProject) { + throw new CLIError( + `Could not find Xcode project files in "${args.projectPath}" folder`, + ); + } + + const inferredSchemeName = path.basename( + xcodeProject.name, + path.extname(xcodeProject.name), + ); + const scheme = args.scheme || inferredSchemeName; + + logger.info( + `Found Xcode ${ + xcodeProject.isWorkspace ? 'workspace' : 'project' + } "${chalk.bold(xcodeProject.name)}"`, + ); + + return run(xcodeProject, scheme, args); +} + +async function run(xcodeProject, scheme, args) { + const appName = await buildProject(xcodeProject, scheme, args); + + const appPath = getBuildPath( + xcodeProject, + args.configuration, + appName, + scheme, + ); + + const bundleID = child_process + .execFileSync( + '/usr/libexec/PlistBuddy', + ['-c', 'Print:CFBundleIdentifier', path.join(appPath, 'Info.plist')], + {encoding: 'utf8'}, + ) + .trim(); + + logger.info(`Launching "${chalk.bold(bundleID)}"`); + + // TODO +} + +function buildProject(xcodeProject, scheme, args) { + return new Promise((resolve, reject) => { + const xcodebuildArgs = [ + xcodeProject.isWorkspace ? '-workspace' : '-project', + xcodeProject.name, + '-configuration', + args.configuration, + '-scheme', + scheme, + '-destination', + 'macosx', + ]; + logger.info( + `Building ${chalk.dim( + `(using "xcodebuild ${xcodebuildArgs.join(' ')}")`, + )}`, + ); + let xcpretty; + if (!args.verbose) { + xcpretty = + xcprettyAvailable() && + child_process.spawn('xcpretty', [], { + stdio: ['pipe', process.stdout, process.stderr], + }); + } + const buildProcess = child_process.spawn( + 'xcodebuild', + xcodebuildArgs, + getProcessOptions(args), + ); + let buildOutput = ''; + let errorOutput = ''; + buildProcess.stdout.on('data', data => { + const stringData = data.toString(); + buildOutput += stringData; + if (xcpretty) { + xcpretty.stdin.write(data); + } else { + if (logger.isVerbose()) { + logger.debug(stringData); + } else { + process.stdout.write('.'); + } + } + }); + buildProcess.stderr.on('data', data => { + errorOutput += data; + }); + buildProcess.on('close', code => { + if (xcpretty) { + xcpretty.stdin.end(); + } else { + process.stdout.write('\n'); + } + if (code !== 0) { + reject( + new CLIError( + ` + Failed to build macOS project. + + We ran "xcodebuild" command but it exited with error code ${code}. To debug build + logs further, consider building your app with Xcode.app, by opening + ${xcodeProject.name}. + `, + buildOutput + '\n' + errorOutput, + ), + ); + return; + } + resolve(getProductName(buildOutput) || scheme); + }); + }); +} + +function getTargetBuildDir(buildSettings) { + const settings = JSON.parse(buildSettings); + + // Find app in all building settings - look for WRAPPER_EXTENSION: 'app', + for (const i in settings) { + const wrapperExtension = settings[i].buildSettings.WRAPPER_EXTENSION; + if (wrapperExtension === 'app') { + return settings[i].buildSettings.TARGET_BUILD_DIR; + } + } + + return null; +} + +function getBuildPath(xcodeProject, configuration, appName, scheme) { + const buildSettings = child_process.execFileSync( + 'xcodebuild', + [ + xcodeProject.isWorkspace ? '-workspace' : '-project', + xcodeProject.name, + '-scheme', + scheme, + '-sdk', + 'macosx', + '-configuration', + configuration, + '-showBuildSettings', + '-json', + ], + {encoding: 'utf8'}, + ); + const targetBuildDir = getTargetBuildDir(buildSettings); + if (!targetBuildDir) { + throw new CLIError('Failed to get the target build directory.'); + } + + return `${targetBuildDir}/${appName}.app`; +} + +function getProductName(buildOutput) { + const productNameMatch = /export FULL_PRODUCT_NAME="?(.+).app"?$/m.exec( + buildOutput, + ); + return productNameMatch ? productNameMatch[1] : null; +} + +function xcprettyAvailable() { + try { + child_process.execSync('xcpretty --version', { + stdio: [0, 'pipe', 'ignore'], + }); + } catch (error) { + return false; + } + return true; +} + +function getProcessOptions({packager, terminal, port}) { + if (packager) { + return { + env: { + ...process.env, + RCT_TERMINAL: terminal, + RCT_METRO_PORT: port.toString(), + }, + }; + } + + return { + env: { + ...process.env, + RCT_TERMINAL: terminal, + RCT_NO_LAUNCH_PACKAGER: 'true', + }, + }; +} + +module.exports = { + name: 'run-macos', + description: 'builds your app and starts it', + func: runMacOS, + examples: [ + { + desc: 'Run the macOS app', + cmd: 'react-native run-macos', + }, + ], + options: [ + { + name: '--configuration [string]', + description: 'Explicitly set the scheme configuration to use', + default: 'Debug', + }, + { + name: '--scheme [string]', + description: 'Explicitly set Xcode scheme to use', + }, + { + name: '--project-path [string]', + description: + 'Path relative to project root where the Xcode project ' + + '(.xcodeproj) lives.', + default: 'ios', + }, + { + name: '--no-packager', + description: 'Do not launch packager while building', + }, + { + name: '--verbose', + description: 'Do not use xcpretty even if installed', + }, + { + name: '--port [number]', + default: process.env.RCT_METRO_PORT || 8081, + parse: val => Number(val), + }, + { + name: '--terminal [string]', + description: + 'Launches the Metro Bundler in a new window using the specified terminal path.', + default: getDefaultUserTerminal, + }, + ], +}; diff --git a/package.json b/package.json index 72027fec42c492..d4dbfd010a7fa0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "react-native", - "version": "0.60.0-microsoft.68", + "name": "react-native-macos", + "version": "0.60.0-microsoft.70", "description": "[Microsoft Fork] A framework for building native apps using React", "license": "MIT", "repository": { diff --git a/react-native.config.js b/react-native.config.js index 5d0dd83bc72f6a..8c1195d3f1d666 100644 --- a/react-native.config.js +++ b/react-native.config.js @@ -16,9 +16,10 @@ const path = require('path'); const isReactNativeMacOS = path.basename(__dirname) === 'react-native-macos'; const iosCommands = isReactNativeMacOS ? [] : ios.commands; const androidCommands = isReactNativeMacOS ? [] : android.commands; +const macosCommands = [require('./local-cli/runMacOS/runMacOS')]; module.exports = { - commands: [...iosCommands, ...androidCommands], + commands: [...iosCommands, ...androidCommands, ...macosCommands], platforms: { ios: { linkConfig: ios.linkConfig, From 276b5116fea4b80c96ae59f41a5f82af44686470 Mon Sep 17 00:00:00 2001 From: Tom Underhill Date: Sat, 11 Apr 2020 14:04:19 -0700 Subject: [PATCH 4/9] run-macos working --- local-cli/generator-macos/index.js | 12 ++++++---- .../HelloWorld.xcodeproj/project.pbxproj | 8 +++---- local-cli/runMacOS/runMacOS.js | 24 +++++++++++-------- scripts/packager.sh | 4 ++-- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/local-cli/generator-macos/index.js b/local-cli/generator-macos/index.js index 7b406dd2b81d01..de97222c78db09 100644 --- a/local-cli/generator-macos/index.js +++ b/local-cli/generator-macos/index.js @@ -59,10 +59,14 @@ function copyProjectTemplateAndReplace( { from: path.join(srcRootPath, 'metro.config.macos.js'), to: 'metro.config.macos.js' }, ].forEach((mapping) => copyAndReplaceWithChangedCallback(mapping.from, destPath, mapping.to, templateVars, options.overwrite)); - console.log(chalk.white.bold('To run your app on macOS:')); - console.log(chalk.white(` open ${macOSDir}/${xcodeProjName}`)); - console.log(chalk.white(' yarn start:macos')); - console.log(chalk.white.bold(`In Xcode switch to the ${projectNameMacOS} scheme then click Run.`)); + console.log(` + ${chalk.blue(`Run instructions for ${chalk.bold('macOS')}`)}: + • npx react-native run-macos + ${chalk.dim('- or -')} + • Open ${macOSDir}/${xcodeProjName} in Xcode or run "xed -b ${macOSDir}" + • yarn start:macos + • Hit the Run button +`); } function installDependencies(options) { diff --git a/local-cli/generator-macos/templates/macos/HelloWorld.xcodeproj/project.pbxproj b/local-cli/generator-macos/templates/macos/HelloWorld.xcodeproj/project.pbxproj index c18882a55b02b8..67304bf2f9abf4 100644 --- a/local-cli/generator-macos/templates/macos/HelloWorld.xcodeproj/project.pbxproj +++ b/local-cli/generator-macos/templates/macos/HelloWorld.xcodeproj/project.pbxproj @@ -1299,7 +1299,7 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.HelloWorld.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = HelloWorld; VERSIONING_SYSTEM = "apple-generic"; }; @@ -1317,7 +1317,7 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.HelloWorld.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = HelloWorld; VERSIONING_SYSTEM = "apple-generic"; }; @@ -1337,7 +1337,7 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.HelloWorld.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = HelloWorld; SDKROOT = macosx; TARGETED_DEVICE_FAMILY = 1; @@ -1358,7 +1358,7 @@ "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.HelloWorld.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = HelloWorld; SDKROOT = macosx; TARGETED_DEVICE_FAMILY = 1; diff --git a/local-cli/runMacOS/runMacOS.js b/local-cli/runMacOS/runMacOS.js index 4d7a12d974ed6b..e4f657e7fea0f9 100644 --- a/local-cli/runMacOS/runMacOS.js +++ b/local-cli/runMacOS/runMacOS.js @@ -33,10 +33,9 @@ function runMacOS(_, ctx, args) { ); } - const inferredSchemeName = path.basename( - xcodeProject.name, - path.extname(xcodeProject.name), - ); + const inferredSchemeName = + path.basename(xcodeProject.name, path.extname(xcodeProject.name)) + + '-macOS'; const scheme = args.scheme || inferredSchemeName; logger.info( @@ -61,14 +60,20 @@ async function run(xcodeProject, scheme, args) { const bundleID = child_process .execFileSync( '/usr/libexec/PlistBuddy', - ['-c', 'Print:CFBundleIdentifier', path.join(appPath, 'Info.plist')], + [ + '-c', + 'Print:CFBundleIdentifier', + path.join(appPath, 'Contents/Info.plist'), + ], {encoding: 'utf8'}, ) .trim(); - logger.info(`Launching "${chalk.bold(bundleID)}"`); + logger.info( + `Launching app "${chalk.bold(bundleID)}" from "${chalk.bold(appPath)}"`, + ); - // TODO + child_process.exec('open -b ' + bundleID + ' -a ' + appPath); } function buildProject(xcodeProject, scheme, args) { @@ -80,8 +85,7 @@ function buildProject(xcodeProject, scheme, args) { args.configuration, '-scheme', scheme, - '-destination', - 'macosx', + '-UseModernBuildSystem=NO', ]; logger.info( `Building ${chalk.dim( @@ -247,7 +251,7 @@ module.exports = { description: 'Path relative to project root where the Xcode project ' + '(.xcodeproj) lives.', - default: 'ios', + default: 'macos', }, { name: '--no-packager', diff --git a/scripts/packager.sh b/scripts/packager.sh index 1df530fe407a58..b86cd49489e7f9 100755 --- a/scripts/packager.sh +++ b/scripts/packager.sh @@ -18,10 +18,10 @@ source "${THIS_DIR}/.packager.env" source "${THIS_DIR}/node-binary.sh" # When running react-native tests, react-native doesn't live in node_modules but in the PROJECT_ROOT -if [ ! -d "$PROJECT_ROOT/node_modules/react-native" ]; +if [ ! -d "$PROJECT_ROOT/node_modules/react-native-macos" ]; then PROJECT_ROOT="$THIS_DIR/.." fi # Start packager from PROJECT_ROOT cd "$PROJECT_ROOT" || exit -"$NODE_BINARY" "$REACT_NATIVE_ROOT/cli.js" start "$@" +"$NODE_BINARY" "$REACT_NATIVE_ROOT/cli.js" start "$@" --use-react-native-macos From 185fa51851ceb4f47ee30459157b5eed53768a1d Mon Sep 17 00:00:00 2001 From: Tom Underhill Date: Sat, 11 Apr 2020 15:02:46 -0700 Subject: [PATCH 5/9] Add JSDoc --- local-cli/runMacOS/findXcodeProject.js | 13 ++++++---- local-cli/runMacOS/runMacOS.js | 35 +++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/local-cli/runMacOS/findXcodeProject.js b/local-cli/runMacOS/findXcodeProject.js index 8916af1483ff14..8f0e3162e3f776 100644 --- a/local-cli/runMacOS/findXcodeProject.js +++ b/local-cli/runMacOS/findXcodeProject.js @@ -1,13 +1,16 @@ /** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + * @format + * @ts-check */ +'use strict'; const path = require('path'); +/** + * @param {string[]} files + */ function findXcodeProject(files) { const sortedFiles = files.sort(); for (let i = sortedFiles.length - 1; i >= 0; i--) { diff --git a/local-cli/runMacOS/runMacOS.js b/local-cli/runMacOS/runMacOS.js index e4f657e7fea0f9..fc65391c44f62d 100644 --- a/local-cli/runMacOS/runMacOS.js +++ b/local-cli/runMacOS/runMacOS.js @@ -2,8 +2,8 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. * @format + * @ts-check */ -// @ts-check 'use strict'; const child_process = require('child_process'); @@ -17,6 +17,11 @@ const { getDefaultUserTerminal, } = require('@react-native-community/cli-tools'); +/** + * @param {string[]} _ + * @param {Object.} ctx + * @param {{configuration: string, scheme?: string, projectPath: string, packager: boolean, verbose: boolean, port: number, terminal: string | undefined}} args + */ function runMacOS(_, ctx, args) { if (!fs.existsSync(args.projectPath)) { throw new CLIError( @@ -47,6 +52,11 @@ function runMacOS(_, ctx, args) { return run(xcodeProject, scheme, args); } +/** + * @param {{name: string, isWorkspace: boolean}} xcodeProject + * @param {string} scheme + * @param {{configuration: string, scheme?: string, projectPath: string, packager: boolean, verbose: boolean, port: number, terminal: string | undefined}} args + */ async function run(xcodeProject, scheme, args) { const appName = await buildProject(xcodeProject, scheme, args); @@ -76,6 +86,11 @@ async function run(xcodeProject, scheme, args) { child_process.exec('open -b ' + bundleID + ' -a ' + appPath); } +/** + * @param {{name: string, isWorkspace: boolean}} xcodeProject + * @param {string} scheme + * @param {{configuration: string, scheme?: string, projectPath: string, packager: boolean, verbose: boolean, port: number, terminal: string | undefined}} args + */ function buildProject(xcodeProject, scheme, args) { return new Promise((resolve, reject) => { const xcodebuildArgs = [ @@ -149,6 +164,9 @@ function buildProject(xcodeProject, scheme, args) { }); } +/** + * @param {string} buildSettings + */ function getTargetBuildDir(buildSettings) { const settings = JSON.parse(buildSettings); @@ -163,6 +181,12 @@ function getTargetBuildDir(buildSettings) { return null; } +/** + * @param {{name: string, isWorkspace: boolean}} xcodeProject + * @param {string} configuration + * @param {string} appName + * @param {string} scheme + */ function getBuildPath(xcodeProject, configuration, appName, scheme) { const buildSettings = child_process.execFileSync( 'xcodebuild', @@ -188,6 +212,9 @@ function getBuildPath(xcodeProject, configuration, appName, scheme) { return `${targetBuildDir}/${appName}.app`; } +/** + * @param {string} buildOutput + */ function getProductName(buildOutput) { const productNameMatch = /export FULL_PRODUCT_NAME="?(.+).app"?$/m.exec( buildOutput, @@ -206,6 +233,12 @@ function xcprettyAvailable() { return true; } +/** + * @param {Object} args + * @param {boolean} args.packager + * @param {string|undefined} args.terminal + * @param {number} args.port + */ function getProcessOptions({packager, terminal, port}) { if (packager) { return { From a14fc67d9192f448b8eae5851a42a69218e52321 Mon Sep 17 00:00:00 2001 From: Tom Underhill Date: Sat, 11 Apr 2020 16:00:51 -0700 Subject: [PATCH 6/9] Fix script to only pass argument when installed --- scripts/packager.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/packager.sh b/scripts/packager.sh index b86cd49489e7f9..89e363de602af9 100755 --- a/scripts/packager.sh +++ b/scripts/packager.sh @@ -18,10 +18,13 @@ source "${THIS_DIR}/.packager.env" source "${THIS_DIR}/node-binary.sh" # When running react-native tests, react-native doesn't live in node_modules but in the PROJECT_ROOT +MODE_ARG= if [ ! -d "$PROJECT_ROOT/node_modules/react-native-macos" ]; then PROJECT_ROOT="$THIS_DIR/.." +else + EXTRA_ARGS=--use-react-native-macos fi # Start packager from PROJECT_ROOT cd "$PROJECT_ROOT" || exit -"$NODE_BINARY" "$REACT_NATIVE_ROOT/cli.js" start "$@" --use-react-native-macos +"$NODE_BINARY" "$REACT_NATIVE_ROOT/cli.js" start "$@" "$EXTRA_ARGS" From a657f5f2dc5943cf8a20a10564883dc26b622f1b Mon Sep 17 00:00:00 2001 From: Tom Underhill Date: Sat, 11 Apr 2020 16:05:06 -0700 Subject: [PATCH 7/9] Fixed var name --- scripts/packager.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/packager.sh b/scripts/packager.sh index 89e363de602af9..b688d53b5abcc8 100755 --- a/scripts/packager.sh +++ b/scripts/packager.sh @@ -18,7 +18,7 @@ source "${THIS_DIR}/.packager.env" source "${THIS_DIR}/node-binary.sh" # When running react-native tests, react-native doesn't live in node_modules but in the PROJECT_ROOT -MODE_ARG= +EXTRA_ARGS= if [ ! -d "$PROJECT_ROOT/node_modules/react-native-macos" ]; then PROJECT_ROOT="$THIS_DIR/.." From 3afa84d2d02cce8fefcaee2b25ae91a781cd905e Mon Sep 17 00:00:00 2001 From: Tom Underhill Date: Sat, 11 Apr 2020 16:18:00 -0700 Subject: [PATCH 8/9] Added run-macs CI step --- .ado/templates/react-native-macos-init.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.ado/templates/react-native-macos-init.yml b/.ado/templates/react-native-macos-init.yml index a880a34ac60942..73a00785bb1564 100644 --- a/.ado/templates/react-native-macos-init.yml +++ b/.ado/templates/react-native-macos-init.yml @@ -87,7 +87,7 @@ steps: - task: CmdLine@2 displayName: Init new project inputs: - script: react-native init testcli + script: npx react-native init testcli workingDirectory: $(Agent.BuildDirectory) - task: CmdLine@2 @@ -96,4 +96,8 @@ steps: script: npx react-native-macos-init --version latest --overwrite --prerelease workingDirectory: $(Agent.BuildDirectory)/testcli - # TODO: react-native run-macos and test when implemented \ No newline at end of file + - task: CmdLine@2 + displayName: Run macos + inputs: + script: npx react-native run-macos + workingDirectory: $(Agent.BuildDirectory)/testcli From 32674181f5dbd34066f6d2f9a8a3655bc3852ef2 Mon Sep 17 00:00:00 2001 From: Tom Underhill Date: Sat, 11 Apr 2020 16:42:23 -0700 Subject: [PATCH 9/9] Log success or failure --- local-cli/runMacOS/runMacOS.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/local-cli/runMacOS/runMacOS.js b/local-cli/runMacOS/runMacOS.js index fc65391c44f62d..eded6de85f7c87 100644 --- a/local-cli/runMacOS/runMacOS.js +++ b/local-cli/runMacOS/runMacOS.js @@ -83,7 +83,16 @@ async function run(xcodeProject, scheme, args) { `Launching app "${chalk.bold(bundleID)}" from "${chalk.bold(appPath)}"`, ); - child_process.exec('open -b ' + bundleID + ' -a ' + appPath); + child_process.exec( + 'open -b ' + bundleID + ' -a ' + appPath, + (error, stdout, stderr) => { + if (error) { + logger.error('Failed to launch the app', stderr); + } else { + logger.success('Successfully launched the app'); + } + }, + ); } /**