Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .ado/templates/react-native-macos-init.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ steps:
script: npx react-native-macos-init --version latest --overwrite --prerelease
workingDirectory: $(Agent.BuildDirectory)/testcli

- task: CmdLine@2
displayName: Install pods
inputs:
script: pod install
workingDirectory: $(Agent.BuildDirectory)/testcli/macos

- task: CmdLine@2
displayName: Run macos
inputs:
Expand Down
2 changes: 2 additions & 0 deletions React/Modules/RCTUIManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
#endif // TODO(macOS ISS#2323203)
#import "RCTShadowView+Internal.h"
#import "RCTShadowView.h"
#if !TARGET_OS_OSX // TODO(macOS ISS#2323203)
#import "RCTSurfaceRootShadowView.h"
#import "RCTSurfaceRootView.h"
#endif // TODO(macOS ISS#2323203)
#import "RCTUIManagerObserverCoordinator.h"
#import "RCTUIManagerUtils.h"
#import "RCTUtils.h"
Expand Down
4 changes: 2 additions & 2 deletions React/React-Core.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ Pod::Spec.new do |s|
# TODO(macOS GH#214)
"**/MacOS/*"
s.osx.exclude_files = "Modules/RCTRedBoxExtraDataViewController.{h,m}",
"Modules/RCTStatusBarManager.*",
"UIUtils/*",
"Profiler/{RCTFPSGraph,RCTPerfMonitor}.*",
"Profiler/RCTProfileTrampoline-{arm,arm64,i386}.S",
"Base/{RCTPlatform,RCTKeyCommands}.*",
"Base/RCTKeyCommands.*",
"Base/RCTPlatform.m",
"Base/Surface/SurfaceHostingView/*",
"Base/Surface/RCTSurface{,Delegate,Root*}.*",
"Base/RCTTV*.*",
Expand Down
33 changes: 30 additions & 3 deletions local-cli/generator-common/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
// @ts-check

const fs = require('fs');
const chalk = require('chalk');
const path = require('path');
const copyAndReplace = require('@react-native-community/cli/build/tools/copyAndReplace').default;
const walk = require('@react-native-community/cli/build/tools/walk').default;
const prompt = require('@react-native-community/cli/build/tools/generator/promptSync').default();

/**
* @param {string} destPath
*/
function createDir(destPath) {
if (!fs.existsSync(destPath)) {
fs.mkdirSync(destPath);
fs.mkdirSync(destPath, { recursive: true });
}
}

/**
* @todo Move this upstream to @react-native-community/cli

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are we tracking this work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ll be touching the CLI package for the next iteration of this when I make auto-linking work and will make this change then.

*
* @param {string} templatePath
* @param {Record<string, string>} replacements
*/
function replaceInPath(templatePath, replacements) {
let result = templatePath;
Object.keys(replacements).forEach(key => {
result = result.replace(key, replacements[key]);
});
return result;
}

function copyAndReplaceWithChangedCallback(srcPath, destRoot, relativeDestPath, replacements, alwaysOverwrite) {
if (!replacements) {
replacements = {};
Expand All @@ -35,15 +54,23 @@ function copyAndReplaceWithChangedCallback(srcPath, destRoot, relativeDestPath,
);
}

/**
* @param {string} srcPath
* @param {string} destPath
* @param {string} relativeDestDir
* @param {Record<string, string>} replacements
* @param {boolean} alwaysOverwrite
*/
function copyAndReplaceAll(srcPath, destPath, relativeDestDir, replacements, alwaysOverwrite) {
walk(srcPath).forEach(absoluteSrcFilePath => {
const filename = path.relative(srcPath, absoluteSrcFilePath);
const relativeDestPath = path.join(relativeDestDir, filename);
const relativeDestPath = path.join(relativeDestDir, replaceInPath(filename, replacements));
copyAndReplaceWithChangedCallback(absoluteSrcFilePath, destPath, relativeDestPath, replacements, alwaysOverwrite);
});
}

function alwaysOverwriteContentChangedCallback( absoluteSrcFilePath,
function alwaysOverwriteContentChangedCallback(
absoluteSrcFilePath,
relativeDestPath,
contentChanged
) {
Expand Down
98 changes: 80 additions & 18 deletions local-cli/generator-macos/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// @ts-check

'use strict';

const chalk = require('chalk');
const path = require('path');
const childProcess = require('child_process');
Expand All @@ -10,7 +13,14 @@ const {
} = require('../generator-common');

const macOSDir = 'macos';
const oldProjectName = 'HelloWorld';

/**
* @param {string} srcRootPath
* @param {string} destPath
* @param {string} newProjectName
* @param {{ overwrite?: boolean }} options
*/
function copyProjectTemplateAndReplace(
srcRootPath,
destPath,
Expand All @@ -29,29 +39,23 @@ function copyProjectTemplateAndReplace(
throw new Error('Need a project name');
}

const projectNameMacOS = newProjectName + '-macOS';
const projectNameIOS = newProjectName;
const xcodeProjName = newProjectName + '.xcodeproj';
const schemeNameMacOS = newProjectName + '-macOS.xcscheme';
const schemeNameIOS = newProjectName + '.xcscheme';

createDir(path.join(destPath, macOSDir));
createDir(path.join(destPath, macOSDir, projectNameIOS));
createDir(path.join(destPath, macOSDir, projectNameMacOS));
createDir(path.join(destPath, macOSDir, xcodeProjName));
createDir(path.join(destPath, macOSDir, xcodeProjName, 'xcshareddata'));
createDir(path.join(destPath, macOSDir, xcodeProjName, 'xcshareddata/xcschemes'));
createDir(path.join(destPath, srcDirPath(newProjectName, 'iOS')));
createDir(path.join(destPath, srcDirPath(newProjectName, 'macOS')));
createDir(path.join(destPath, xcodeprojPath(newProjectName)));
createDir(path.join(destPath, schemesPath(newProjectName)));

const templateVars = {
'HelloWorld': newProjectName,
[oldProjectName]: newProjectName,
};

[
{ from: path.join(srcRootPath, 'macos/HelloWorld'), to: path.join(macOSDir, projectNameIOS) },
{ from: path.join(srcRootPath, 'macos/HelloWorld-macOS'), to: path.join(macOSDir, projectNameMacOS) },
{ from: path.join(srcRootPath, 'macos/HelloWorld.xcodeproj'), to: path.join(macOSDir, xcodeProjName) },
{ from: path.join(srcRootPath, 'macos/xcschemes/HelloWorld-macOS.xcscheme'), to: path.join(macOSDir, xcodeProjName, 'xcshareddata/xcschemes', schemeNameMacOS) },
{ from: path.join(srcRootPath, 'macos/xcschemes/HelloWorld.xcscheme'), to: path.join(macOSDir, xcodeProjName, 'xcshareddata/xcschemes', schemeNameIOS) },
{ from: path.join(srcRootPath, macOSDir, 'Podfile'), to: path.join(macOSDir, 'Podfile') },
{ from: path.join(srcRootPath, srcDirPath(oldProjectName, 'iOS')), to: srcDirPath(newProjectName, 'iOS') },
{ from: path.join(srcRootPath, srcDirPath(oldProjectName, 'macOS')), to: srcDirPath(newProjectName, 'macOS') },
{ from: path.join(srcRootPath, pbxprojPath(oldProjectName)), to: pbxprojPath(newProjectName) },
{ from: path.join(srcRootPath, schemePath(oldProjectName, 'iOS')), to: schemePath(newProjectName, 'iOS') },
{ from: path.join(srcRootPath, schemePath(oldProjectName, 'macOS')), to: schemePath(newProjectName, 'macOS') },
].forEach((mapping) => copyAndReplaceAll(mapping.from, destPath, mapping.to, templateVars, options.overwrite));

[
Expand All @@ -61,14 +65,70 @@ function copyProjectTemplateAndReplace(

console.log(`
${chalk.blue(`Run instructions for ${chalk.bold('macOS')}`)}:
β€’ cd macos && pod install && cd ..
β€’ npx react-native run-macos
${chalk.dim('- or -')}
β€’ Open ${macOSDir}/${xcodeProjName} in Xcode or run "xed -b ${macOSDir}"
β€’ Open ${xcworkspacePath(newProjectName)} in Xcode or run "xed -b ${macOSDir}"
β€’ yarn start:macos
β€’ Hit the Run button
`);
}

/**
* @param {string} basename
* @param {"iOS" | "macOS"} platform
*/
function projectName(basename, platform) {
return basename + '-' + platform;
}

/**
* @param {string} basename
* @param {"iOS" | "macOS"} platform
*/
function srcDirPath(basename, platform) {
return path.join(macOSDir, projectName(basename, platform));
}

/**
* @param {string} basename
*/
function xcodeprojPath(basename) {
return path.join(macOSDir, basename + '.xcodeproj');
}

/**
* @param {string} basename
*/
function xcworkspacePath(basename) {
return path.join(macOSDir, basename + '.xcworkspace');
}

/**
* @param {string} basename
*/
function pbxprojPath(basename) {
return path.join(xcodeprojPath(basename), 'project.pbxproj');
}

/**
* @param {string} basename
*/
function schemesPath(basename) {
return path.join(xcodeprojPath(basename), 'xcshareddata', 'xcschemes');
}

/**
* @param {string} basename
* @param {"iOS" | "macOS"} platform
*/
function schemePath(basename, platform) {
return path.join(schemesPath(basename), projectName(basename, platform) + '.xcscheme');
}

/**
* @param {{ verbose?: boolean }=} options
*/
function installDependencies(options) {
const cwd = process.cwd();

Expand All @@ -80,6 +140,8 @@ function installDependencies(options) {

// Install dependencies using correct package manager
const isYarn = fs.existsSync(path.join(cwd, 'yarn.lock'));

/** @type {{ stdio?: 'inherit' }} */
const execOptions = options && options.verbose ? { stdio: 'inherit' } : {};
childProcess.execSync(isYarn ? 'yarn' : 'npm i', execOptions);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
Expand Down Expand Up @@ -39,11 +29,6 @@
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>HelloWorld</string>
<string>$(PRODUCT_NAME)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"images" : [
{
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading