diff --git a/Libraries/Core/InitializeCore.js b/Libraries/Core/InitializeCore.js index bb100bb3bd4..009bef7146c 100644 --- a/Libraries/Core/InitializeCore.js +++ b/Libraries/Core/InitializeCore.js @@ -116,6 +116,23 @@ if (!global.__fbDisableExceptionsManager) { ErrorUtils.setGlobalHandler(handleError); } +const formatVersion = version => + `${version.major}.${version.minor}.${version.patch}` + + (version.prerelease !== null ? `-${version.prerelease}` : ''); + +const ReactNativeVersion = require('ReactNativeVersion'); +const nativeVersion = require('NativeModules').PlatformConstants.reactNativeVersion; +if (ReactNativeVersion.version.major !== nativeVersion.major || + ReactNativeVersion.version.minor !== nativeVersion.minor) { + throw new Error( + `React Native version mismatch.\n\nJavaScript version: ${formatVersion(ReactNativeVersion.version)}\n` + + `Native version: ${formatVersion(nativeVersion)}\n\n` + + 'Make sure that you have rebuilt the native code. If the problem persists ' + + 'try clearing the watchman and packager caches with `watchman watch-del-all ' + + '&& react-native start --reset-cache`.' + ); +} + // Set up collections const _shouldPolyfillCollection = require('_shouldPolyfillES6Collection'); if (_shouldPolyfillCollection('Map')) { diff --git a/Libraries/Core/ReactNativeVersion.js b/Libraries/Core/ReactNativeVersion.js new file mode 100644 index 00000000000..2f78126ef69 --- /dev/null +++ b/Libraries/Core/ReactNativeVersion.js @@ -0,0 +1,20 @@ +/** + * @generated by scripts/bump-oss-version.js + * + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @flow + * @providesModule ReactNativeVersion + */ + +exports.version = { + major: 0, + minor: 0, + patch: 0, + prerelease: null, +}; diff --git a/React/Base/RCTPlatform.m b/React/Base/RCTPlatform.m index 4593341066b..b9ece18b85b 100644 --- a/React/Base/RCTPlatform.m +++ b/React/Base/RCTPlatform.m @@ -12,6 +12,7 @@ #import #import "RCTUtils.h" +#import "RCTVersion.h" static NSString *interfaceIdiom(UIUserInterfaceIdiom idiom) { switch(idiom) { @@ -46,6 +47,7 @@ RCT_EXPORT_MODULE(PlatformConstants) @"systemName": [device systemName], @"interfaceIdiom": interfaceIdiom([device userInterfaceIdiom]), @"isTesting": @(RCTRunningInTestEnvironment()), + @"reactNativeVersion": REACT_NATIVE_VERSION, }; } diff --git a/React/Base/RCTVersion.h b/React/Base/RCTVersion.h new file mode 100644 index 00000000000..6aa3df5a538 --- /dev/null +++ b/React/Base/RCTVersion.h @@ -0,0 +1,17 @@ +/** + * @generated by scripts/bump-oss-version.js + * + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#define REACT_NATIVE_VERSION @{ \ + @"major": @(0), \ + @"minor": @(0), \ + @"patch": @(0), \ + @"prerelease": [NSNull null], \ +} diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index 603c16ca168..7e274727da8 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -203,6 +203,8 @@ 14F7A0F01BDA714B003C6C10 /* RCTFPSGraph.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F7A0EF1BDA714B003C6C10 /* RCTFPSGraph.m */; }; 191E3EBE1C29D9AF00C180A6 /* RCTRefreshControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 191E3EBD1C29D9AF00C180A6 /* RCTRefreshControlManager.m */; }; 191E3EC11C29DC3800C180A6 /* RCTRefreshControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 191E3EC01C29DC3800C180A6 /* RCTRefreshControl.m */; }; + 199B8A6F1F44DB16005DEF67 /* RCTVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 199B8A6E1F44DB16005DEF67 /* RCTVersion.h */; }; + 199B8A761F44DEDA005DEF67 /* RCTVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 199B8A6E1F44DB16005DEF67 /* RCTVersion.h */; }; 19F61BFA1E8495CD00571D81 /* bignum-dtoa.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E3A1E25C5A300323FB7 /* bignum-dtoa.h */; }; 19F61BFB1E8495CD00571D81 /* bignum.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E3C1E25C5A300323FB7 /* bignum.h */; }; 19F61BFC1E8495CD00571D81 /* cached-powers.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 139D7E3E1E25C5A300323FB7 /* cached-powers.h */; }; @@ -1921,6 +1923,7 @@ 191E3EBD1C29D9AF00C180A6 /* RCTRefreshControlManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRefreshControlManager.m; sourceTree = ""; }; 191E3EBF1C29DC3800C180A6 /* RCTRefreshControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRefreshControl.h; sourceTree = ""; }; 191E3EC01C29DC3800C180A6 /* RCTRefreshControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRefreshControl.m; sourceTree = ""; }; + 199B8A6E1F44DB16005DEF67 /* RCTVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTVersion.h; sourceTree = ""; }; 19DED2281E77E29200F089BB /* systemJSCWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = systemJSCWrapper.cpp; sourceTree = ""; }; 27B958731E57587D0096647A /* JSBigString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBigString.cpp; sourceTree = ""; }; 2D2A28131D9B038B00D4039D /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2750,6 +2753,7 @@ 1345A83B1B265A0E00583190 /* RCTURLRequestHandler.h */, 83CBBA4F1A601E3B00E9B192 /* RCTUtils.h */, 83CBBA501A601E3B00E9B192 /* RCTUtils.m */, + 199B8A6E1F44DB16005DEF67 /* RCTVersion.h */, ); path = Base; sourceTree = ""; @@ -2903,6 +2907,7 @@ 3D302F411DF828F800D6DDAE /* RCTModuleMethod.h in Headers */, 3D302F421DF828F800D6DDAE /* RCTMultipartDataTask.h in Headers */, 3D302F431DF828F800D6DDAE /* RCTMultipartStreamReader.h in Headers */, + 199B8A761F44DEDA005DEF67 /* RCTVersion.h in Headers */, 3D302F441DF828F800D6DDAE /* RCTNullability.h in Headers */, 3D302F451DF828F800D6DDAE /* RCTParserUtils.h in Headers */, 3D302F461DF828F800D6DDAE /* RCTPerformanceLogger.h in Headers */, @@ -3145,6 +3150,7 @@ 3D80DA191DF820620028D040 /* RCTImageLoader.h in Headers */, C654505E1F3BD9280090799B /* RCTManagedPointer.h in Headers */, 13134C941E296B2A00B9F3CB /* RCTObjcExecutor.h in Headers */, + 199B8A6F1F44DB16005DEF67 /* RCTVersion.h in Headers */, 3D80DA1A1DF820620028D040 /* RCTImageStoreManager.h in Headers */, 130443A11E3FEAA900D93A67 /* RCTFollyConvert.h in Headers */, 59FBEFB41E46D91C0095D885 /* RCTScrollContentViewManager.h in Headers */, diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java index 07666145e48..5431517f606 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java @@ -38,6 +38,7 @@ public class AndroidInfoModule extends BaseJavaModule { constants.put("Version", Build.VERSION.SDK_INT); constants.put("ServerHost", AndroidInfoHelpers.getServerHost()); constants.put("isTesting", "true".equals(System.getProperty(IS_TESTING))); + constants.put("reactNativeVersion", ReactNativeVersion.VERSION); return constants; } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/BUCK index 9d59eff8107..a967762f3a6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/BUCK @@ -4,6 +4,7 @@ android_library( name = "systeminfo", srcs = [ "AndroidInfoModule.java", + "ReactNativeVersion.java", ], exported_deps = [ ":systeminfo-moduleless", diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java new file mode 100644 index 00000000000..b6514ec58be --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java @@ -0,0 +1,24 @@ +/** + * @generated by scripts/bump-oss-version.js + * + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.modules.systeminfo; + +import com.facebook.react.common.MapBuilder; + +import java.util.Map; + +public class ReactNativeVersion { + public static final Map VERSION = MapBuilder.of( + "major", 0, + "minor", 0, + "patch", 0, + "prerelease", null); +} diff --git a/jest/setup.js b/jest/setup.js index 819b40c27df..26b710e93f4 100644 --- a/jest/setup.js +++ b/jest/setup.js @@ -34,7 +34,7 @@ jest jest.setMock('ErrorUtils', require('ErrorUtils')); jest - .mock('InitializeCore') + .mock('InitializeCore', () => {}) .mock('Image', () => mockComponent('Image')) .mock('Text', () => mockComponent('Text')) .mock('TextInput', () => mockComponent('TextInput')) diff --git a/scripts/bump-oss-version.js b/scripts/bump-oss-version.js index c1e3a38d3b1..b6c7d0daa9b 100755 --- a/scripts/bump-oss-version.js +++ b/scripts/bump-oss-version.js @@ -46,10 +46,39 @@ let versionMajor = branch.slice(0, branch.indexOf(`-stable`)); // e.g. 0.33.1 or 0.33.0-rc4 let version = argv._[0]; if (!version || version.indexOf(versionMajor) !== 0) { - echo(`You must pass a tag like ${versionMajor}.[X]-rc[Y] to bump a version`); + echo(`You must pass a tag like 0.${versionMajor}.[X]-rc[Y] to bump a version`); exit(1); } +// Generate version files to detect mismatches between JS and native. +let match = version.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/); +if (!match) { + echo(`You must pass a correctly formatted version; couldn't parse ${version}`); + exit(1); +} +let [, major, minor, patch, prerelease] = match; + +cat('scripts/versiontemplates/ReactNativeVersion.java.template') + .replace('${major}', major) + .replace('${minor}', minor) + .replace('${patch}', patch) + .replace('${prerelease}', prerelease !== undefined ? `"${prerelease}"` : 'null') + .to('ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java'); + +cat('scripts/versiontemplates/RCTVersion.h.template') + .replace('${major}', `@(${major})`) + .replace('${minor}', `@(${minor})`) + .replace('${patch}', `@(${patch})`) + .replace('${prerelease}', prerelease !== undefined ? `@"${prerelease}"` : '[NSNull null]') + .to('React/Base/RCTVersion.h'); + +cat('scripts/versiontemplates/ReactNativeVersion.js.template') + .replace('${major}', major) + .replace('${minor}', minor) + .replace('${patch}', patch) + .replace('${prerelease}', prerelease !== undefined ? `'${prerelease}'` : 'null') + .to('Libraries/Core/ReactNativeVersion.js'); + let packageJson = JSON.parse(cat(`package.json`)); packageJson.version = version; JSON.stringify(packageJson, null, 2).to(`package.json`); diff --git a/scripts/versiontemplates/RCTVersion.h.template b/scripts/versiontemplates/RCTVersion.h.template new file mode 100644 index 00000000000..52fd1c48050 --- /dev/null +++ b/scripts/versiontemplates/RCTVersion.h.template @@ -0,0 +1,17 @@ +/** + * @generated by scripts/bump-oss-version.js + * + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#define REACT_NATIVE_VERSION @{ \ + @"major": ${major}, \ + @"minor": ${minor}, \ + @"patch": ${patch}, \ + @"prerelease": ${prerelease}, \ +} diff --git a/scripts/versiontemplates/ReactNativeVersion.java.template b/scripts/versiontemplates/ReactNativeVersion.java.template new file mode 100644 index 00000000000..7ae1cecc8b1 --- /dev/null +++ b/scripts/versiontemplates/ReactNativeVersion.java.template @@ -0,0 +1,24 @@ +/** + * @generated by scripts/bump-oss-version.js + * + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.modules.systeminfo; + +import com.facebook.react.common.MapBuilder; + +import java.util.Map; + +public class ReactNativeVersion { + public static final Map VERSION = MapBuilder.of( + "major", ${major}, + "minor", ${minor}, + "patch", ${patch}, + "prerelease", ${prerelease}); +} diff --git a/scripts/versiontemplates/ReactNativeVersion.js.template b/scripts/versiontemplates/ReactNativeVersion.js.template new file mode 100644 index 00000000000..357625b8723 --- /dev/null +++ b/scripts/versiontemplates/ReactNativeVersion.js.template @@ -0,0 +1,20 @@ +/** + * @generated by scripts/bump-oss-version.js + * + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @flow + * @providesModule ReactNativeVersion + */ + +exports.version = { + major: ${major}, + minor: ${minor}, + patch: ${patch}, + prerelease: ${prerelease}, +};