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

If the user sets a custom node_modules location, always use it #4684

Conversation

mokagio
Copy link

@mokagio mokagio commented Jul 7, 2023

Summary

Users can provide a custom path for where the CocoaPods setup should look for the React Native node_modules.

The previous version used the user-defined REACT_NATIVE_NODE_MODULES_DIR as a fallback to read the React Native package.json but forgot to use it later on when looking for ReactCommon.

Test plan

Admittedly, the main issue this PR aims to solve occurs only in a contrived setup where node --print "require.resolve('react-native/package.json')" fails.

Such a setup can be reproduced by

  1. Creating a folder, e.g cocoapods-test in the same parent folder as this repository
  2. In the new folder, creating a Podfile with the following content:
# frozen_string_literal: true

RN_PATH = ENV.fetch('TEST_RN_PATH')
rn_utils_path = File.join(RN_PATH, 'scripts', 'react_native_pods.rb')

raise "Could not find React Native utils at #{rn_utils_path}" unless File.exist? rn_utils_path

require_relative rn_utils_path

install! 'cocoapods', integrate_targets: false

abstract_target 'Test' do
  platform :ios, '15.0'

  use_react_native! path: RN_PATH

  if ENV.fetch('TEST_MAIN', 'true') == 'true'
    git = 'https://github.com/software-mansion/react-native-reanimated'
    # Latest main at the time of writing
    commit = 'ce3a2820ae178de4ef265633a40c99783d3b9eac'

    puts '[TEST] Testing against RNReanimated main'
  else
    git = 'https://github.com/wordpress-mobile/react-native-reanimated'
    commit = '18a0922ed2fa269f76462838df155b2f975cc15e'

    puts '[TEST] Testing against RNReanimated PR'
  end

  pod 'RNReanimated', git: git, commit: commit
end

Before starting testing, we can set the path to React Native for the Podfile to use (different from the one that the library uses), e.g.:

export TEST_RN_PATH=../react-native-reanimated/node_modules/react-native

We can now test the following scenarios

1. main + no REACT_NATIVE_NODE_MODULES_DIR – Fails

Note: The rm -rfs and pod cache clean... commands make sure we test from a fresh setup.

rm -rf Pods \ 
  && rm -rf build \
  && pod cache clean RNReanimated \
  && TEST_MAIN=false \
  REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated/node_modules \
  pod install
node:internal/modules/cjs/loader:1078
  throw err;
  ^

Error: Cannot find module 'react-native/package.json'
Require stack:
- /Users/gio/Developer/oss/cocoapods-test/[eval]
    at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
    at Function.resolve (node:internal/modules/cjs/helpers:116:19)
    at [eval]:1:9
    at Script.runInThisContext (node:vm:129:12)
    at Object.runInThisContext (node:vm:307:38)
    at node:internal/process/execution:79:19
    at [eval]-wrapper:6:22
    at evalScript (node:internal/process/execution:78:60)
    at node:internal/main/eval_string:28:3 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/Users/gio/Developer/oss/cocoapods-test/[eval]' ]
}

Node.js v18.16.0
[!] Failed to load 'RNReanimated' podspec:
[!] Invalid `RNReanimated.podspec` file: no implicit conversion of nil into String.

 #  from /var/folders/dq/cdqxvx3s5ps75564rpmb_dc00000gn/T/d20230707-7863-i915iz/RNReanimated.podspec:5
 #  -------------------------------------------
 #  reanimated_package_json = JSON.parse(File.read(File.join(__dir__, "package.json")))
 >  config = find_config()
 #  assert_no_multiple_instances(config)
 #  -------------------------------------------

2. main + REACT_NATIVE_NODE_MODULES_DIR – Fails with different message

Notice the uses of $PWD, I run into issues when using a relative path. I haven't had a chance to investigate them yet. I think this PR consists in an improvement regardless.

rm -rf Pods \ 
  && rm -rf build \
  && pod cache clean RNReanimated \
  && TEST_MAIN=true \
  REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated/node_modules \
  pod install
node:internal/modules/cjs/loader:1078
  throw err;
  ^

Error: Cannot find module 'react-native/package.json'
Require stack:
- /Users/gio/Developer/oss/cocoapods-test/[eval]
    at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
    at Function.resolve (node:internal/modules/cjs/helpers:116:19)
    at [eval]:1:9
    at Script.runInThisContext (node:vm:129:12)
    at Object.runInThisContext (node:vm:307:38)
    at node:internal/process/execution:79:19
    at [eval]-wrapper:6:22
    at evalScript (node:internal/process/execution:78:60)
    at node:internal/main/eval_string:28:3 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/Users/gio/Developer/oss/cocoapods-test/[eval]' ]
}

Node.js v18.16.0
[!] Failed to load 'RNReanimated' podspec:
[!] Invalid `RNReanimated.podspec` file: different prefix: "" and "/Users/gio/Developer/oss/cocoapods-test/Pods".

 #  from /var/folders/dq/cdqxvx3s5ps75564rpmb_dc00000gn/T/d20230707-8351-99vkw7/RNReanimated.podspec:5
 #  -------------------------------------------
 #  reanimated_package_json = JSON.parse(File.read(File.join(__dir__, "package.json")))
 >  config = find_config()
 #  assert_no_multiple_instances(config)
 #  -------------------------------------------

3. main + Invalid REACT_NATIVE_NODE_MODULES_DIR – Fails with different message

rm -rf Pods \ 
  && rm -rf build \
  && pod cache clean RNReanimated \
  && TEST_MAIN=true \
  REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated \
  pod install

This time, at least, the message points to using REACT_NATIVE_NODE_MODULES_DIR unlike the previous ones—even though because of the issues already highlighted, it won't work

node:internal/modules/cjs/loader:1078
  throw err;
  ^

Error: Cannot find module 'react-native/package.json'
Require stack:
- /Users/gio/Developer/oss/cocoapods-test/[eval]
    at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
    at Function.resolve (node:internal/modules/cjs/helpers:116:19)
    at [eval]:1:9
    at Script.runInThisContext (node:vm:129:12)
    at Object.runInThisContext (node:vm:307:38)
    at node:internal/process/execution:79:19
    at [eval]-wrapper:6:22
    at evalScript (node:internal/process/execution:78:60)
    at node:internal/main/eval_string:28:3 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/Users/gio/Developer/oss/cocoapods-test/[eval]' ]
}

Node.js v18.16.0
[!] Failed to load 'RNReanimated' podspec:
[!] Invalid `RNReanimated.podspec` file: [RNReanimated] Unable to recognize your `react-native` version! Please set environmental variable with `react-native` locations: `export REACT_NATIVE_NODE_MODULES_DIR="<path to react-native>" && pod install.

4. This PR + no REACT_NATIVE_NODE_MODULES_DIR – Fails (as expected) with better message

rm -rf Pods \ 
  && rm -rf build \
  && pod cache clean RNReanimated \
  && TEST_MAIN=false \
  pod install

Still fails, as expected when there are no available node_modules but at least it suggests using the REACT_NATIVE_NODE_MODULES_DIR environment variable.

node:internal/modules/cjs/loader:1078
  throw err;
  ^

Error: Cannot find module 'react-native/package.json'
Require stack:
- /Users/gio/Developer/oss/cocoapods-test/[eval]
    at Module._resolveFilename (node:internal/modules/cjs/loader:1075:15)
    at Function.resolve (node:internal/modules/cjs/helpers:116:19)
    at [eval]:1:9
    at Script.runInThisContext (node:vm:129:12)
    at Object.runInThisContext (node:vm:307:38)
    at node:internal/process/execution:79:19
    at [eval]-wrapper:6:22
    at evalScript (node:internal/process/execution:78:60)
    at node:internal/main/eval_string:28:3 {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/Users/gio/Developer/oss/cocoapods-test/[eval]' ]
}

Node.js v18.16.0
[RNReanimated] Looking for React Native configs at ./../react-native/package.json...
[!] Failed to load 'RNReanimated' podspec:
[!] Invalid `RNReanimated.podspec` file: [RNReanimated] Unable to recognize your `react-native` version! Please set environmental variable with `react-native` locations: `export REACT_NATIVE_NODE_MODULES_DIR="<path to react-native>" && pod install.

 #  from /var/folders/dq/cdqxvx3s5ps75564rpmb_dc00000gn/T/d20230707-10998-ar912d/RNReanimated.podspec:5
 #  -------------------------------------------
 #  reanimated_package_json = JSON.parse(File.read(File.join(__dir__, "package.json")))
 >  config = find_config()
 #  assert_no_multiple_instances(config)
 #  -------------------------------------------

5. main + REACT_NATIVE_NODE_MODULES_DIR – Works

rm -rf Pods \ 
  && rm -rf build \
  && pod cache clean RNReanimated \
  && TEST_MAIN=false \
  REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated/node_modules \
  pod install

This one works, which is the desired behavior 😄

6. main + Invalid REACT_NATIVE_NODE_MODULES_DIR – Fails (as expected) with better message

rm -rf Pods \ 
  && rm -rf build \
  && pod cache clean RNReanimated \
  && TEST_MAIN=false \
  REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated \
  pod install

The failure is expected because the node_modules path is invalid. But in this version a user will know the path the install process used, which will be helpful in fixing the issue.

[RNReanimated] Looking for React Native configs at /Users/gio/Developer/oss/cocoapods-test/../react-native-reanimated/react-native/package.json...
[!] Failed to load 'RNReanimated' podspec:
[!] Invalid `RNReanimated.podspec` file: [RNReanimated] Unable to recognize your `react-native` version! Please set environmental variable with `react-native` locations: `export REACT_NATIVE_NODE_MODULES_DIR="<path to react-native>" && pod install.

 #  from /Users/gio/Developer/oss/react-native-reanimated/RNReanimated.podspec:5
 #  -------------------------------------------
 #  reanimated_package_json = JSON.parse(File.read(File.join(__dir__, "package.json")))
 >  config = find_config()
 #  assert_no_multiple_instances(config)
 #  -------------------------------------------

mokagio and others added 5 commits July 6, 2023 15:58
The previous version used the user-defined
`REACT_NATIVE_NODE_MODULES_DIR` as a fallback to read the React Native
`package.json` but forgot to use it later on when looking for
`ReactCommon`.
This way, if the env var is not set the returned value will be `nil`,
not a crash.
Comment on lines -20 to -25
react_native_node_modules_dir = File.join(File.dirname(`cd "#{Pod::Config.instance.installation_root.to_s}" && node --print "require.resolve('react-native/package.json')"`), '..')
react_native_json = try_to_parse_react_native_package_json(react_native_node_modules_dir)
# If the user set a custom location for where to look for React Native, use that
custom_react_native_node_modules_dir = ENV['REACT_NATIVE_NODE_MODULES_DIR']
if custom_react_native_node_modules_dir.nil?
react_native_node_modules_dir = File.join(File.dirname(`cd "#{Pod::Config.instance.installation_root.to_s}" && node --print "require.resolve('react-native/package.json')"`), '..')
else
unless File.exist? custom_react_native_node_modules_dir
raise "[RNReanimated] The given React Native lookup path #{custom_react_native_node_modules_dir} does not exist"
end

if react_native_json == nil
# user configuration, just in case
node_modules_dir = ENV["REACT_NATIVE_NODE_MODULES_DIR"]
Copy link
Author

Choose a reason for hiding this comment

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

My rational for using REACT_NATIVE_NODE_MODULES_DIR before trying to resolve the path ourselves is that if the users set a custom value, they likely expect it to be used.

lib_instances_in_reanimated_node_modules_array = Array.new
reanimated_instances = lib_instances_in_react_native_node_modules_array.length()
if react_native_info[:react_native_node_modules_dir] != react_native_info[:reanimated_node_modules_dir]
if react_native_info[:react_native_node_modules_dir] != react_native_info[:reanimated_node_modules_dir] && ENV['REACT_NATIVE_NODE_MODULES_DIR'].nil?
Copy link
Author

Choose a reason for hiding this comment

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

This is what resulted in the error

[!] Invalid `RNReanimated.podspec` file: different prefix: "" and "/Users/gio/Developer/oss/cocoapods-test/Pods".

which we got in the case of no available node_modules and a valid REACT_NATIVE_NODE_MODULES_DIR.

Basically, the setup had begun using one prefix but here it "forgot" about it.

@tjzel tjzel self-assigned this Jul 10, 2023
@tjzel
Copy link
Collaborator

tjzel commented Jul 10, 2023

Hi @mokagio. I'm testing your PR and can't help but notice there are some mistakes in the tests you provided, e.g. test1 is:

rm -rf Pods \ 
  && rm -rf build \
  && pod cache clean RNReanimated \
  && TEST_MAIN=false \
  REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated/node_modules \
  pod install

And I believe it should be:

rm -rf Pods \ 
  && rm -rf build \
  && pod cache clean RNReanimated \
  && TEST_MAIN=false \
-  REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated/node_modules \
-  pod install
+ && pod install

I could fix those for you but I'm not sure I will understand your intent in those tests. Would you be so kind to correct them?

@piaskowyk piaskowyk self-requested a review July 11, 2023 08:12
@mokagio
Copy link
Author

mokagio commented Jul 18, 2023

Hey @tjzel 👋 Thank you for taking a look at the PR and for double checking the steps I suggested.

The version provided in the PR description is intentional. Unless I'm mistaken, adding && after defining the REACT_NATIVE_NODE_MODULES_DIR variable would result in that value not being available to the pod command when it runs.

If it makes testing clearer, I can update the commands to explicitly set all the env before running.

Eg, the first test would go from

rm -rf Pods \ 
  && rm -rf build \
  && pod cache clean RNReanimated \
  && TEST_MAIN=false \
  REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated/node_modules \
  pod install

to

export TEST_MAIN=false \
  && export REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated/node_modules \
  && rm -rf Pods \
  && rm -rf build \
  && pod cache clean RNReanimated \
  && pod install \
  && unset TEST_MAIN \
  && unset REACT_NATIVE_NODE_MODULES_DIR

I provided those tests as one liners because it seemed to me like it would make for a clearer success/failure behavior. But we could also rewrite them as step-by-step one.

Keen to hear what you think. Thanks.

@tjzel
Copy link
Collaborator

tjzel commented Jul 18, 2023

Actually what I meant is when I pasted them into my terminal (iTerm2) they just wouldn't execute due to incorrect syntax (although now when I look into it it looks fine 🤔). I will try to run those tests tomorrow 😃

@tjzel
Copy link
Collaborator

tjzel commented Jul 19, 2023

@mokagio I'm sorry to say that but after some greater insight into those tests they have errors/typos in them. In the first test you are supposed to be checking main but you set TEST_MAIN to false. When I correct this test to make it true I'm getting different results depending on inclusion of REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated/node_modules \.

Without REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated/node_modules \:

[!] Failed to load 'RNReanimated' podspec:
[!] Invalid `RNReanimated.podspec` file: no implicit conversion of nil into String.

With:

[!] Failed to load 'RNReanimated' podspec:
[!] Invalid `RNReanimated.podspec` file: different prefix: "" and "/Users/user/reanimated/cocoapods-test/Pods".

Same for when I use export REACT_NATIVE_NODE_MODULES_DIR=...$PWD/../react-native-reanimated/node_modules \

Please double check your tests and their outcomes, some little details included, e.g.:

-  rm -rf Pods \ 
-    && rm -rf build \
-    && pod cache clean RNReanimated \
-    && TEST_MAIN=false \
-    REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated/node_modules \
-    pod install
+  rm -rf Pods \
+  && rm -rf build \
+  && pod cache clean RNReanimated \
+  && TEST_MAIN=false \
+  REACT_NATIVE_NODE_MODULES_DIR=$PWD/../react-native-reanimated/node_modules \
+  pod install

because in this case the trailing space after rm -rf Pods \ was causing a syntax error.

@tjzel tjzel added the Close when stale This issue is going to be closed when there is no activity for a while label Sep 26, 2023
@piaskowyk
Copy link
Member

Thank you for submitting this pull request! I value your time and dedication! 🙌 However, we have not fully comprehended every aspect of these changes, and since there has been little activity on this issue, I have made the decision to close it. If you wish to continue working on this pull request, we are still open to collaboration.

Have a grate day! 🤗

@piaskowyk piaskowyk closed this Oct 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Close when stale This issue is going to be closed when there is no activity for a while
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants