Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple version checking #4914

Merged
merged 35 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2987693
init
tjzel Aug 10, 2023
4e0c7ed
androidele
tjzel Aug 10, 2023
d2ab1e9
invertio
tjzel Aug 10, 2023
f4e02fc
renamele
tjzel Aug 10, 2023
0a71101
hmmm... bugs...
tjzel Aug 10, 2023
4fbba50
init
tjzel Aug 10, 2023
9fc54c5
Merge branch 'main' into @tjzel/troubleshooting
tjzel Aug 10, 2023
4311419
remove future
tjzel Aug 10, 2023
80edeeb
sharebale pls
tjzel Aug 10, 2023
ba3861c
test trobule
tjzel Aug 11, 2023
99982f0
url validator lets goooo 🧨
tjzel Aug 11, 2023
3c551d6
fix urls
tjzel Aug 11, 2023
ba149e3
self-review
tjzel Aug 16, 2023
5a58f09
mergele to trobuleshooting
tjzel Aug 16, 2023
6f38b70
fix CI
tjzel Aug 16, 2023
65ca4aa
remove old checker
tjzel Aug 18, 2023
c5c4d67
mergele to trobuleshooting
tjzel Aug 23, 2023
4a107e0
actually...
tjzel Aug 24, 2023
4a86f30
Merge branch 'main' into @tjzel/version-checker
tjzel Aug 24, 2023
bf20b6a
cpp eats java
tjzel Aug 25, 2023
7413264
no more drafties
tjzel Aug 25, 2023
dd68a13
patch matching for js version
tjzel Aug 25, 2023
3fc88aa
Merge branch 'main' into @tjzel/version-checker
tjzel Aug 25, 2023
78d1bbd
mergele main
tjzel Aug 28, 2023
35ba611
huh
tjzel Aug 28, 2023
848916f
ok
tjzel Aug 28, 2023
6d174f7
review changes
tjzel Aug 30, 2023
bd5f532
version checker
tjzel Sep 7, 2023
cc6c399
mergele main
tjzel Sep 7, 2023
87afd30
review changes
tjzel Sep 14, 2023
12b6180
mergele main
tjzel Sep 26, 2023
2b5e2fa
trobuleshouting
tjzel Sep 26, 2023
cfe6749
remove whitespace
tjzel Sep 26, 2023
b8e5081
trobuleshouting
tjzel Sep 26, 2023
10dfb4b
final touches
tjzel Sep 26, 2023
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
7 changes: 5 additions & 2 deletions Common/cpp/ReanimatedRuntime/RNRuntimeDecorator.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "RNRuntimeDecorator.h"
#ifdef DEBUG
#include "ReanimatedVersion.h"
#endif // DEBUG

namespace reanimated {

Expand Down Expand Up @@ -29,8 +31,9 @@ void RNRuntimeDecorator::decorate(
#endif // RCT_NEW_ARCH_ENABLED
rnRuntime.global().setProperty(rnRuntime, "_IS_FABRIC", isFabric);

auto version = getReanimatedVersionString(rnRuntime);
rnRuntime.global().setProperty(rnRuntime, "_REANIMATED_VERSION_CPP", version);
#ifdef DEBUG
checkJSVersion(rnRuntime);
#endif // DEBUG

rnRuntime.global().setProperty(
rnRuntime, "_REANIMATED_IS_REDUCED_MOTION", isReducedMotion);
Expand Down
56 changes: 54 additions & 2 deletions Common/cpp/Tools/ReanimatedVersion.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "ReanimatedVersion.h"
#include <regex>
#include <string>

#ifdef REANIMATED_VERSION
#define STRINGIZE(x) #x
Expand All @@ -10,8 +12,58 @@ using namespace facebook;

namespace reanimated {

jsi::String getReanimatedVersionString(jsi::Runtime &rt) {
return jsi::String::createFromUtf8(rt, REANIMATED_VERSION_STRING);
std::string getReanimatedCppVersion() {
return std::string(REANIMATED_VERSION_STRING);
}

// This function is pretty much a copy of
// `src/reanimated2/platform-specific/checkVersion.ts`.
bool matchVersion(std::string version1, std::string version2) {
tjzel marked this conversation as resolved.
Show resolved Hide resolved
std::regex pattern("^\\d+\\.\\d+\\.\\d+$");
if (std::regex_match(version1, pattern) &&
std::regex_match(version2, pattern)) {
auto major1 = std::regex_search(version1, std::regex("^\\d+"));
auto major2 = std::regex_search(version2, std::regex("^\\d+"));
tjzel marked this conversation as resolved.
Show resolved Hide resolved
if (major1 != major2) {
return false;
}
auto minor1 = std::regex_search(version1, std::regex("\\.\\d+\\."));
auto minor2 = std::regex_search(version2, std::regex("\\.\\d+\\."));
tjzel marked this conversation as resolved.
Show resolved Hide resolved
if (minor1 != minor2) {
return false;
}
return true;
} else {
return version1 == version2;
}
}

void checkJSVersion(jsi::Runtime &rnRuntime) {
auto cppVersion = getReanimatedCppVersion();

auto maybeJSVersion =
rnRuntime.global().getProperty(rnRuntime, "_REANIMATED_VERSION_JS");
if (maybeJSVersion.isUndefined()) {
throw std::runtime_error(
std::string(
"[Reanimated] (C++) Native side failed to resolve JavaScript code version\n") +
tjzel marked this conversation as resolved.
Show resolved Hide resolved
"See `https://docs.swmansion.com/react-native-reanimated/docs/guides/Troubleshooting#native-side-failed-to-resolve-javascript-code-version` for more details.");
}

auto jsVersion = maybeJSVersion.asString(rnRuntime).utf8(rnRuntime);

if (!matchVersion(cppVersion, jsVersion)) {
throw std::runtime_error(
std::string(
"[Reanimated] (C++) Mismatch between C++ code version and JavaScript code version (") +
tjzel marked this conversation as resolved.
Show resolved Hide resolved
cppVersion + " vs. " + jsVersion + " respectively).\n" +
"See `https://docs.swmansion.com/react-native-reanimated/docs/guides/Troubleshooting#c-mismatch-between-c-code-version-and-java-code-version` for more details.");
}

rnRuntime.global().setProperty(
rnRuntime,
"_REANIMATED_VERSION_CPP",
jsi::String::createFromUtf8(rnRuntime, cppVersion));
}

}; // namespace reanimated
10 changes: 8 additions & 2 deletions Common/cpp/Tools/ReanimatedVersion.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
#pragma once

#include <jsi/jsi.h>
#include <string>

using namespace facebook;

namespace reanimated {

jsi::String getReanimatedVersionString(jsi::Runtime &rt);
std::string getReanimatedCppVersion();

};
#ifdef DEBUG
tjzel marked this conversation as resolved.
Show resolved Hide resolved
bool matchVersion(std::string, std::string);
tjzel marked this conversation as resolved.
Show resolved Hide resolved
void checkJSVersion(jsi::Runtime &);
#endif // DEBUG

}; // namespace reanimated
2 changes: 1 addition & 1 deletion Example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ SPEC CHECKSUMS:
FlipperKit: 2efad7007d6745a3f95e4034d547be637f89d3f6
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: c3ad51f83e23bba4844c7cfa93062e1c7d57b47b
hermes-engine: 10fbd3f62405c41ea07e71973ea61e1878d07322
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
Expand Down
2 changes: 0 additions & 2 deletions RNReanimated.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ require_relative './scripts/reanimated_utils'

reanimated_package_json = JSON.parse(File.read(File.join(__dir__, "package.json")))
config = find_config()
assert_no_multiple_instances(config)
assert_latest_react_native_with_new_architecture(config, reanimated_package_json)

tjzel marked this conversation as resolved.
Show resolved Hide resolved
fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
is_release = ENV['PRODUCTION'] == '1'
using_hermes = ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == '1'
Expand Down
60 changes: 2 additions & 58 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,6 @@ def getPlaygroundAppName() { // only for the development
return playgroundAppName
}

def shouldAssertNoMultipleInstances() {
if (rootProject.hasProperty("disableMultipleInstancesCheck")) {
return rootProject.property("disableMultipleInstancesCheck") != "true"
} else {
return true
}
}

def getReanimatedVersion() {
def inputFile = file(projectDir.path + '/../package.json')
def json = new JsonSlurper().parseText(inputFile.text)
Expand Down Expand Up @@ -257,6 +249,7 @@ android {
versionCode 1
versionName "1.0"
buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", IS_NEW_ARCHITECTURE_ENABLED.toString())
buildConfigField("String", "REANIMATED_VERSION_JAVA", "\"${REANIMATED_VERSION}\"")
tomekzaw marked this conversation as resolved.
Show resolved Hide resolved
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared",
Expand Down Expand Up @@ -389,55 +382,6 @@ android {
}
}

abstract class NoMultipleInstancesAssertionTask extends DefaultTask {
@Inject abstract ObjectFactory getObjectFactory()

@Input abstract Property<File> getProjectDirFile()
@Input abstract Property<File> getRootDirFile()
@Input abstract Property<Boolean> getShouldCheck()

def findReanimatedInstancesForPath(String path) {
return objectFactory.fileTree().from(path)
.include("**/react-native-reanimated/package.json")
.exclude("**/.yarn/**")
.exclude({ Files.isSymbolicLink(it.getFile().toPath()) })
.findAll()
}

@TaskAction
def check() {
if (shouldCheck.get()) {
// Assert there are no multiple installations of Reanimated
Set<File> files

if (projectDirFile.get().parent.contains(rootDirFile.get().parent)) {
// standard app
files = findReanimatedInstancesForPath(rootDirFile.get().parent + "/node_modules")
} else {
// monorepo
files = findReanimatedInstancesForPath(rootDirFile.get().parent + "/node_modules")
files.addAll(
findReanimatedInstancesForPath(projectDirFile.get().parentFile.parent)
)
}

if (files.size() > 1) {
String parsedLocation = files.stream().map({
File file -> "- " + file.toString().replace("/package.json", "")
}).collect().join("\n")
String exceptionMessage = "\n[Reanimated] Multiple versions of Reanimated were detected in `build.gradle`. See `https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#multiple-versions-of-reanimated-were-detected-in-buildgradle` for more details.\n\nConflict between: \n" + parsedLocation + "\n"
throw new GradleException(exceptionMessage)
}
}
}
}

tasks.register('assertNoMultipleInstances', NoMultipleInstancesAssertionTask) {
shouldCheck = shouldAssertNoMultipleInstances()
rootDirFile = rootDir
projectDirFile = projectDir
}

def assertLatestReactNativeWithNewArchitecture = task assertLatestReactNativeWithNewArchitectureTask {
onlyIf { IS_NEW_ARCHITECTURE_ENABLED && REANIMATED_MAJOR_VERSION == 3 && REACT_NATIVE_MINOR_VERSION < 72 }
doFirst {
Expand All @@ -448,7 +392,7 @@ def assertLatestReactNativeWithNewArchitecture = task assertLatestReactNativeWit
}

tasks.preBuild {
dependsOn assertNoMultipleInstances, assertLatestReactNativeWithNewArchitecture
dependsOn assertLatestReactNativeWithNewArchitecture
}

task cleanCmakeCache() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public NativeProxy(ReactApplicationContext context) {
fabricUIManager);
prepareLayoutAnimations(LayoutAnimations);
installJSIBindings();
if(BuildConfig.DEBUG){
tjzel marked this conversation as resolved.
Show resolved Hide resolved
tjzel marked this conversation as resolved.
Show resolved Hide resolved
checkCppVersion();
}
}

private native HybridData initHybrid(
Expand Down
46 changes: 46 additions & 0 deletions android/src/main/cpp/NativeProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#include "PlatformDepMethodsHolder.h"
#include "RNRuntimeDecorator.h"
#include "ReanimatedRuntime.h"
#ifdef DEBUG
#include "ReanimatedVersion.h"
#endif // DEBUG
#include "WorkletRuntime.h"
#include "WorkletRuntimeCollector.h"

Expand Down Expand Up @@ -108,12 +111,55 @@ jni::local_ref<NativeProxy::jhybriddata> NativeProxy::initHybrid(
/**/);
}

#ifdef DEBUG
void NativeProxy::checkJavaVersion(jsi::Runtime &rnRuntime) {
std::string javaVersion;
try {
javaVersion =
getJniMethod<jstring()>("getReanimatedJavaVersion")(javaPart_.get())
->toStdString();
} catch (std::exception &) {
throw std::runtime_error(
std::string(
"[Reanimated] (C++) Native side failed to resolve Java code version.\n") +
"See `https://docs.swmansion.com/react-native-reanimated/docs/guides/Troubleshooting#native-side-failed-to-resolve-java-code-version` for more details.");
}
tjzel marked this conversation as resolved.
Show resolved Hide resolved

auto cppVersion = getReanimatedCppVersion();
if (cppVersion != javaVersion) {
throw std::runtime_error(
std::string(
"[Reanimated] (C++) Mismatch between C++ code version and Java code version ( ") +
cppVersion + " vs. " + javaVersion + " respectively).\n" +
"See `https://docs.swmansion.com/react-native-reanimated/docs/guides/Troubleshooting#c-mismatch-between-c-code-version-and-java-code-version` for more details.");
}
}

void NativeProxy::injectCppVersion() {
auto cppVersion = getReanimatedCppVersion();
try {
static const auto method =
getJniMethod<void(jni::local_ref<JString>)>("setCppVersion");
method(javaPart_.get(), make_jstring(cppVersion));
} catch (std::exception &) {
throw std::runtime_error(
std::string(
"[Reanimated] (C++) Native side failed to resolve Java code version (injection).\n") +
"See `https://docs.swmansion.com/react-native-reanimated/docs/guides/Troubleshooting#native-side-failed-to-resolve-java-code-version` for more details.");
}
}
#endif // DEBUG

void NativeProxy::installJSIBindings() {
jsi::Runtime &rnRuntime = *rnRuntime_;
WorkletRuntimeCollector::install(rnRuntime);
auto isReducedMotion = getIsReducedMotion();
RNRuntimeDecorator::decorate(
rnRuntime, nativeReanimatedModule_, isReducedMotion);
#ifdef DEBUG
checkJavaVersion(rnRuntime);
injectCppVersion();
#endif // DEBUG

registerEventHandler();
setupLayoutAnimations();
Expand Down
4 changes: 4 additions & 0 deletions android/src/main/cpp/NativeProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ class NativeProxy : public jni::HybridClass<NativeProxy> {
jsi::Runtime *rnRuntime_;
std::shared_ptr<NativeReanimatedModule> nativeReanimatedModule_;
jni::global_ref<LayoutAnimations::javaobject> layoutAnimations_;
#ifdef DEBUG
void checkJavaVersion(jsi::Runtime &);
void injectCppVersion();
#endif // DEBUG
#ifdef RCT_NEW_ARCH_ENABLED
std::shared_ptr<ReanimatedCommitHook> commitHook_;
#if REACT_NATIVE_MINOR_VERSION >= 73
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.facebook.soloader.SoLoader;
import com.swmansion.common.GestureHandlerStateManager;
import com.swmansion.reanimated.AndroidUIScheduler;
import com.swmansion.reanimated.BuildConfig;
import com.swmansion.reanimated.NativeProxy;
import com.swmansion.reanimated.NodesManager;
import com.swmansion.reanimated.ReanimatedModule;
Expand Down Expand Up @@ -44,6 +45,7 @@ public abstract class NativeProxyCommon {
private ReanimatedKeyboardEventListener reanimatedKeyboardEventListener;
private Long firstUptime = SystemClock.uptimeMillis();
private boolean slowAnimationsEnabled = false;
protected String cppVersion = null;

protected NativeProxyCommon(ReactApplicationContext context) {
mAndroidUIScheduler = new AndroidUIScheduler(context);
Expand Down Expand Up @@ -97,6 +99,35 @@ public void requestRender(AnimationFrameCallback callback) {
mNodesManager.postOnAnimation(callback);
}

@DoNotStrip
public String getReanimatedJavaVersion() {
return BuildConfig.REANIMATED_VERSION_JAVA;
}

@DoNotStrip
@SuppressWarnings("unused")
tjzel marked this conversation as resolved.
Show resolved Hide resolved
protected void setCppVersion(String version) {
cppVersion = version;
tjzel marked this conversation as resolved.
Show resolved Hide resolved
}

protected void checkCppVersion() {
if (cppVersion == null) {
throw new RuntimeException(
"[Reanimated] Native side failed to resolve C++ code version. "
+ "See https://docs.swmansion.com/react-native-reanimated/docs/guides/Troubleshooting#native-side-failed-to-resolve-c-code-version for more information.");
}
String javaVersion = getReanimatedJavaVersion();
if (!cppVersion.equals(javaVersion)) {
throw new RuntimeException(
"[Reanimated] (Java) Mismatch between Java code version and C++ code version ("
+ javaVersion
+ " vs. "
+ cppVersion
+ " respectively). See "
+ "https://docs.swmansion.com/react-native-reanimated/docs/guides/Troubleshooting#java-mismatch-between-java-code-version-and-c-code-version for more information.");
}
}

@DoNotStrip
public void updateProps(int viewTag, Map<String, Object> props) {
mNodesManager.updateProps(viewTag, props);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public NativeProxy(ReactApplicationContext context) {
messageQueueThread);
prepareLayoutAnimations(LayoutAnimations);
installJSIBindings();
if(BuildConfig.DEBUG){
tjzel marked this conversation as resolved.
Show resolved Hide resolved
checkCppVersion();
}
}

private native HybridData initHybrid(
Expand Down
Loading