From 19caaba1d50df84463c7349e49ce5d58a0d100f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eloy=20Dur=C3=A1n?= Date: Mon, 27 Feb 2017 13:25:47 -0800 Subject: [PATCH] Fixes current CI failures and allows tree shaking of native dev support code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: * The dev support code moved into a `DevSupport` subspec, meaning that only if the subspec is specified in the user’s Podfile will the packager client, dev menu, etc be included. This is mainly done through checks for header availability. It also improves the weird situation where you had to specify the `RCTWebSocket` subspec if you wanted to be able to use the packager client during development. * I removed hardcoding the release version in the podspec on release, because the podspec still relies on `package.json` when evaluating, so there’s no real point in not also getting the version number from there. This should remove any requirement to perform maintenance of the OSS release script regarding the podspec. Closes https://github.com/facebook/react-native/pull/12602 Differential Revision: D4621021 Pulled By: ericvicenti fbshipit-source-id: 6c208371fc40ea607809a6ab05dd3714ed9980cf --- React.podspec | 21 ++++++++++++++++++--- React/Base/RCTBatchedBridge.m | 7 +++++-- React/Executors/RCTJSCExecutor.mm | 16 ++++++++++++---- React/Modules/RCTDevSettings.mm | 15 +++++++++++---- React/Profiler/RCTPerfMonitor.m | 15 ++++++++++++--- scripts/bump-oss-version.js | 12 +++--------- 6 files changed, 61 insertions(+), 25 deletions(-) diff --git a/React.podspec b/React.podspec index fb64f20b6..a00afd578 100644 --- a/React.podspec +++ b/React.podspec @@ -1,10 +1,19 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) +version = package['version'] + +source = { :git => 'https://github.com/facebook/react-native.git' } +if version == '1000.0.0' + # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in. + source[:commit] = `git rev-parse HEAD`.strip +else + source[:tag] = "v#{version}" +end Pod::Spec.new do |s| s.name = "React" - s.version = package["version"] + s.version = version s.summary = package["description"] s.description = <<-DESC React Native apps are built using the React JS @@ -22,7 +31,7 @@ Pod::Spec.new do |s| s.homepage = "http://facebook.github.io/react-native/" s.license = package["license"] s.author = "Facebook" - s.source = { :git => "https://github.com/facebook/react-native.git", :tag => "v#{s.version}" } + s.source = source s.default_subspec = "Core" s.requires_arc = true s.platform = :ios, "8.0" @@ -34,11 +43,17 @@ Pod::Spec.new do |s| ss.dependency "Yoga", "#{package["version"]}.React" ss.dependency "React/cxxreact" ss.source_files = "React/**/*.{c,h,m,mm,S}" - ss.exclude_files = "**/__tests__/*", "IntegrationTests/*", "React/**/RCTTVView.*", "ReactCommon/yoga/*", "React/Cxx*/*" + ss.exclude_files = "**/__tests__/*", "IntegrationTests/*", "React/DevSupport/*", "React/Modules/RCTDev{LoadingView,Menu}.*", "React/**/RCTTVView.*", "ReactCommon/yoga/*", "React/Cxx*/*" ss.framework = "JavaScriptCore" ss.libraries = "stdc++" end + s.subspec "DevSupport" do |ss| + ss.dependency "React/Core" + ss.dependency "React/RCTWebSocket" + ss.source_files = "React/DevSupport/*", "React/Modules/RCTDev{LoadingView,Menu}.*" + end + s.subspec "tvOS" do |ss| ss.dependency "React/Core" ss.source_files = "React/**/RCTTVView.{h, m}" diff --git a/React/Base/RCTBatchedBridge.m b/React/Base/RCTBatchedBridge.m index 21cde57c0..4c065d0d6 100644 --- a/React/Base/RCTBatchedBridge.m +++ b/React/Base/RCTBatchedBridge.m @@ -14,7 +14,6 @@ #import "RCTBridge.h" #import "RCTBridgeMethod.h" #import "RCTConvert.h" -#import "RCTDevLoadingView.h" #import "RCTDisplayLink.h" #import "RCTJSCExecutor.h" #import "RCTJavaScriptLoader.h" @@ -25,6 +24,10 @@ #import "RCTRedBox.h" #import "RCTUtils.h" +#if RCT_DEV && __has_include("RCTDevLoadingView.h") +#import "RCTDevLoadingView.h" +#endif + #define RCTAssertJSThread() \ RCTAssert(![NSStringFromClass([self->_javaScriptExecutor class]) isEqualToString:@"RCTJSCExecutor"] || \ [[[NSThread currentThread] name] isEqualToString:RCTJSCThreadName], \ @@ -116,7 +119,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithDelegate:(id)dele sourceCode = source; dispatch_group_leave(initModulesAndLoadSource); } onProgress:^(RCTLoadingProgress *progressData) { -#ifdef RCT_DEV +#if RCT_DEV && __has_include("RCTDevLoadingView.h") RCTDevLoadingView *loadingView = [weakSelf moduleForClass:[RCTDevLoadingView class]]; [loadingView updateProgress:progressData]; #endif diff --git a/React/Executors/RCTJSCExecutor.mm b/React/Executors/RCTJSCExecutor.mm index 2cd5e8e98..18a645a56 100644 --- a/React/Executors/RCTJSCExecutor.mm +++ b/React/Executors/RCTJSCExecutor.mm @@ -24,7 +24,6 @@ #import "RCTAssert.h" #import "RCTBridge+Private.h" #import "RCTDefines.h" -#import "RCTDevMenu.h" #import "RCTDevSettings.h" #import "RCTJSCErrorHandling.h" #import "RCTJSCProfiler.h" @@ -34,6 +33,10 @@ #import "RCTProfile.h" #import "RCTUtils.h" +#if (RCT_PROFILE || RCT_DEV) && __has_include("RCTDevMenu.h") +#import "RCTDevMenu.h" +#endif + NSString *const RCTJSCThreadName = @"com.facebook.react.JavaScript"; NSString *const RCTJavaScriptContextCreatedNotification = @"RCTJavaScriptContextCreatedNotification"; RCT_EXTERN NSString *const RCTFBJSContextClassKey = @"_RCTFBJSContextClassKey"; @@ -167,6 +170,7 @@ RCT_EXPORT_MODULE() #if RCT_DEV static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context) { +#if __has_include("RCTDevMenu.h") __weak RCTBridge *weakBridge = bridge; __weak RCTDevSettings *devSettings = bridge.devSettings; if (RCTJSCProfilerIsSupported()) { @@ -186,6 +190,7 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context) } }]]; } +#endif } #endif @@ -396,11 +401,13 @@ static NSThread *newJavaScriptThread(void) // Add toggles for JSC's sampling profiler, if the profiler is enabled if (JSC_JSSamplingProfilerEnabled(context.JSGlobalContextRef)) { - // Mark this thread as the main JS thread before starting profiling. - JSC_JSStartSamplingProfilingOnMainJSCThread(context.JSGlobalContextRef); + // Mark this thread as the main JS thread before starting profiling. + JSC_JSStartSamplingProfilingOnMainJSCThread(context.JSGlobalContextRef); - // Allow to toggle the sampling profiler through RN's dev menu __weak JSContext *weakContext = self->_context.context; + +#if __has_include("RCTDevMenu.h") + // Allow to toggle the sampling profiler through RN's dev menu [self->_bridge.devMenu addItem:[RCTDevMenuItem buttonItemWithTitle:@"Start / Stop JS Sampling Profiler" handler:^{ RCTJSCExecutor *strongSelf = weakSelf; if (!strongSelf.valid || !weakContext) { @@ -408,6 +415,7 @@ static NSThread *newJavaScriptThread(void) } [weakSelf.bridge.devSettings toggleJSCSamplingProfiler]; }]]; +#endif // Allow for the profiler to be poked from JS code as well // (see SamplingProfiler.js for an example of how it could be used with the JSCSamplingProfiler module). diff --git a/React/Modules/RCTDevSettings.mm b/React/Modules/RCTDevSettings.mm index baf17f0f9..b41733683 100644 --- a/React/Modules/RCTDevSettings.mm +++ b/React/Modules/RCTDevSettings.mm @@ -18,13 +18,9 @@ #import "JSCSamplingProfiler.h" #import "RCTBridge+Private.h" #import "RCTBridgeModule.h" -#import "RCTDevMenu.h" #import "RCTEventDispatcher.h" #import "RCTLog.h" -#import "RCTPackagerClient.h" #import "RCTProfile.h" -#import "RCTReloadPackagerMethod.h" -#import "RCTSamplingProfilerPackagerMethod.h" #import "RCTUtils.h" NSString *const kRCTDevSettingProfilingEnabled = @"profilingEnabled"; @@ -42,6 +38,11 @@ NSString *const kRCTDevSettingStartSamplingProfilerOnLaunch = @"startSamplingPro NSString *const kRCTDevSettingsUserDefaultsKey = @"RCTDevMenu"; #if RCT_DEV +#if __has_include("RCTPackagerClient.h") +#import "RCTPackagerClient.h" +#import "RCTReloadPackagerMethod.h" +#import "RCTSamplingProfilerPackagerMethod.h" +#endif @interface RCTDevSettingsUserDefaultsDataSource : NSObject @@ -459,6 +460,9 @@ RCT_EXPORT_METHOD(toggleElementInspector) - (NSURL *)packagerURL { +#if !__has_include("RCTWebSocketObserver.h") + return nil; +#else NSString *host = [_bridge.bundleURL host]; NSString *scheme = [_bridge.bundleURL scheme]; if (!host) { @@ -471,6 +475,7 @@ RCT_EXPORT_METHOD(toggleElementInspector) port = @8081; // Packager default port } return [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@:%@/message?role=ios-rn-rctdevmenu", scheme, host, port]]; +#endif } // TODO: Move non-UI logic into separate RCTDevSettings module @@ -483,6 +488,7 @@ RCT_EXPORT_METHOD(toggleElementInspector) return; } +#if __has_include("RCTPackagerClient.h") // The jsPackagerClient is a static map that holds different packager clients per the packagerURL // In case many instances of DevMenu are created, the latest instance that use the same URL as // previous instances will override given packager client's method handlers @@ -505,6 +511,7 @@ RCT_EXPORT_METHOD(toggleElementInspector) [packagerClient addHandler:[[RCTSamplingProfilerPackagerMethod alloc] initWithBridge:_bridge] forMethod:@"pokeSamplingProfiler"]; [packagerClient start]; +#endif } @end diff --git a/React/Profiler/RCTPerfMonitor.m b/React/Profiler/RCTPerfMonitor.m index d0a01a399..4d6b6e1cf 100644 --- a/React/Profiler/RCTPerfMonitor.m +++ b/React/Profiler/RCTPerfMonitor.m @@ -16,7 +16,6 @@ #import #import "RCTBridge.h" -#import "RCTDevMenu.h" #import "RCTDevSettings.h" #import "RCTFPSGraph.h" #import "RCTInvalidating.h" @@ -27,6 +26,10 @@ #import "RCTUIManager.h" #import "RCTBridge+Private.h" +#if __has_include("RCTDevMenu.h") +#import "RCTDevMenu.h" +#endif + static NSString *const RCTPerfMonitorCellIdentifier = @"RCTPerfMonitorCellIdentifier"; static CGFloat const RCTPerfMonitorBarHeight = 50; @@ -74,11 +77,11 @@ static vm_size_t RCTGetResidentMemorySize(void) return info.resident_size; } -@class RCTDevMenuItem; - @interface RCTPerfMonitor : NSObject +#if __has_include("RCTDevMenu.h") @property (nonatomic, strong, readonly) RCTDevMenuItem *devMenuItem; +#endif @property (nonatomic, strong, readonly) UIPanGestureRecognizer *gestureRecognizer; @property (nonatomic, strong, readonly) UIView *container; @property (nonatomic, strong, readonly) UILabel *memory; @@ -93,7 +96,9 @@ static vm_size_t RCTGetResidentMemorySize(void) @end @implementation RCTPerfMonitor { +#if __has_include("RCTDevMenu.h") RCTDevMenuItem *_devMenuItem; +#endif UIPanGestureRecognizer *_gestureRecognizer; UIView *_container; UILabel *_memory; @@ -142,7 +147,9 @@ RCT_EXPORT_MODULE() { _bridge = bridge; +#if __has_include("RCTDevMenu.h") [_bridge.devMenu addItem:self.devMenuItem]; +#endif } - (void)invalidate @@ -150,6 +157,7 @@ RCT_EXPORT_MODULE() [self hide]; } +#if __has_include("RCTDevMenu.h") - (RCTDevMenuItem *)devMenuItem { if (!_devMenuItem) { @@ -173,6 +181,7 @@ RCT_EXPORT_MODULE() return _devMenuItem; } +#endif - (UIPanGestureRecognizer *)gestureRecognizer { diff --git a/scripts/bump-oss-version.js b/scripts/bump-oss-version.js index 58e63216f..55d21285b 100755 --- a/scripts/bump-oss-version.js +++ b/scripts/bump-oss-version.js @@ -11,7 +11,7 @@ /** * This script bumps a new version for open source releases. - * It updates the version in podspec/json/gradle files and makes sure they are consistent between each other + * It updates the version in json/gradle files and makes sure they are consistent between each other * After changing the files it makes a commit and tags it. * All you have to do is push changes to remote and CI will make a new build. */ @@ -54,17 +54,11 @@ if (sed(`-i`, /^VERSION_NAME=.*/, `VERSION_NAME=${version}`, `ReactAndroid/gradl exit(1); } -// - change React.podspec -if (sed(`-i`, /s\.version\s*=.*/, `s.version = \"${version}\"`, `React.podspec`).code) { - echo(`Couldn't update version for React.podspec`); - exit(1); -} - // verify that files changed, we just do a git diff and check how many times version is added across files let numberOfChangedLinesWithNewVersion = exec(`git diff -U0 | grep '^[+]' | grep -c ${version} `, {silent: true}) .stdout.trim(); -if (+numberOfChangedLinesWithNewVersion !== 3) { - echo(`Failed to update all the files. React.podspec, package.json and gradle.properties must have versions in them`); +if (+numberOfChangedLinesWithNewVersion !== 2) { + echo(`Failed to update all the files. package.json and gradle.properties must have versions in them`); echo(`Fix the issue, revert and try again`); exec(`git diff`); exit(1);