facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.33k stars 24.23k forks source link

Error "no implicit conversion of String into Array" in Pod Install after migrating to RN > 0.74 (0.74.0 until 0.75.3) #46505

Open MasGaNo opened 3 days ago

MasGaNo commented 3 days ago

Description

I'm working on a very old application (RN 0.59.3) and we tried to keep it in shape by upgrading all dependencies, especially on RN version. So we might have many legacy configurations we bring from a version to another one, even if we are doing our best to clean as much as possible.

After migrating from RN 0.73.9 to any version > 0.74 including the latest 0.75.3 version, an error occurs during the pod installation:

cd ios && pod install

With the following error: no implicit conversion of String into Array

After some investigation, it appears that in the /node_modules/react-native/scripts/cocoapods/utils.rb file, the new method add_flag_to_map_with_inheritance was introduced and deals with an array of string settings value.

For some reason, on the method above, this method is called for OTHER_CPLUSPLUSFLAGS and OTHER_CFLAGS settings. If I tried to output these values, it appears they contain Array instead of string value such as: ["$(inherited)", "-DNDEBUG"]

And so obviously it fails, as the method tries to concat a string with an array

As a quick workaround, if I replace the following lines:

            unless map[field].include?(flag)
                map[field] = map[field] + flag
            end
            unless map[field].include?("$(inherited)")
                map[field] = "$(inherited) " + map[field]
            end

By:

            unless map[field].include?(flag)
                if map[field].instance_of? String
                    map[field] = map[field] + flag
                elsif map[field].instance_of? Array
                    map[field].push(flag)
                end
            end
            unless map[field].include?("$(inherited)")
                if map[field].instance_of? String
                    map[field] = "$(inherited) " + map[field]
                elsif map[field].instance_of? Array
                    map[field].unshift("$(inherited)")
                end
            end

in order to handle both Array and String, it works like a charm and I can complete the pod installation and even fully build my iOS App.

But I'm not sure it something you expect and I'm not able to find where the config.build_settings is filled from:

                self.add_flag_to_map_with_inheritance(config.build_settings, 'OTHER_CPLUSPLUSFLAGS', ndebug_flag);
                self.add_flag_to_map_with_inheritance(config.build_settings, 'OTHER_CFLAGS', ndebug_flag);

in order to understand why I'm getting an array of string instead of a string.

Any hints?

Steps to reproduce

  1. Using an old application < 0.74
  2. Bumping RN version to > 0.74
  3. cd ios && pod install

React Native Version

0.75.3

Affected Platforms

Runtime - iOS, Build - MacOS

Output of npx react-native info

System:
  OS: macOS 13.5.2
  CPU: (12) arm64 Apple M2 Pro
  Memory: 115.11 MB / 32.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.9.0
    path: ~/.nvm/versions/node/v20.9.0/bin/node
  Yarn:
    version: 1.22.19
    path: ~/.nvm/versions/node/v20.9.0/bin/yarn
  npm:
    version: 10.1.0
    path: ~/.nvm/versions/node/v20.9.0/bin/npm
  Watchman:
    version: 2024.01.22.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.0
      - iOS 17.0
      - macOS 14.0
      - tvOS 17.0
      - watchOS 10.0
  Android SDK:
    API Levels:
      - "33"
      - "34"
    Build Tools:
      - 30.0.3
      - 33.0.0
      - 33.0.1
      - 34.0.0
      - 35.0.0
    System Images:
      - android-33 | Google APIs ARM 64 v8a
      - android-33 | Google APIs Intel x86_64 Atom
      - android-34 | Google APIs ARM 64 v8a
      - android-34 | Google APIs Intel x86_64 Atom
    Android NDK: Not Found
IDEs:
  Android Studio: 2022.3 AI-223.8836.35.2231.10811636
  Xcode:
    version: 15.0/15A240d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.10
    path: /usr/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.74.5
    wanted: ^0.74.5
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

Stacktrace or Logs

[!] An error occurred while processing the post-install hook of the Podfile.

no implicit conversion of String into Array

/my-rn-project/node_modules/react-native/scripts/cocoapods/utils.rb:702:in `+'
/my-rn-project/node_modules/react-native/scripts/cocoapods/utils.rb:702:in `add_flag_to_map_with_inheritance'
/my-rn-project/node_modules/react-native/scripts/cocoapods/utils.rb:688:in `block (2 levels) in add_ndebug_flag_to_pods_in_release'
/my-rn-project/node_modules/react-native/scripts/cocoapods/utils.rb:683:in `each'
/my-rn-project/node_modules/react-native/scripts/cocoapods/utils.rb:683:in `block in add_ndebug_flag_to_pods_in_release'
/my-rn-project/node_modules/react-native/scripts/cocoapods/utils.rb:682:in `each'
/my-rn-project/node_modules/react-native/scripts/cocoapods/utils.rb:682:in `add_ndebug_flag_to_pods_in_release'
/my-rn-project/node_modules/react-native/scripts/react_native_pods.rb:304:in `react_native_post_install'
/my-rn-project/ios/Podfile:75:in `block (3 levels) in from_ruby'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-core-1.15.2/lib/cocoapods-core/podfile.rb:196:in `post_install!'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/installer.rb:1013:in `run_podfile_post_install_hook'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/installer.rb:1001:in `block in run_podfile_post_install_hooks'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/user_interface.rb:149:in `message'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/installer.rb:1000:in `run_podfile_post_install_hooks'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/installer.rb:337:in `block (2 levels) in create_and_save_projects'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/installer/xcode/pods_project_generator/pods_project_writer.rb:61:in `write!'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/installer.rb:336:in `block in create_and_save_projects'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/user_interface.rb:64:in `section'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/installer.rb:315:in `create_and_save_projects'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/installer.rb:307:in `generate_pods_project'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/installer.rb:183:in `integrate'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/installer.rb:170:in `install!'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/command/install.rb:52:in `run'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/claide-1.1.0/lib/claide/command.rb:334:in `run'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/lib/cocoapods/command.rb:52:in `run'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/gems/cocoapods-1.15.2/bin/pod:55:in `<top (required)>'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/bin/pod:25:in `load'
/opt/homebrew/Cellar/cocoapods/1.15.2/libexec/bin/pod:25:in `<main>'

Reproducer

No reproducer as it's not easy to reproduce, especially on recent project

Screenshots and Videos

No response

react-native-bot commented 3 days ago
:warning: Missing Reproducible Example
:information_source: We could not detect a reproducible example in your issue report. Please provide either:
  • If your bug is UI related: a Snack
  • If your bug is build/update related: use our Reproducer Template. A reproducer needs to be in a GitHub repository under your username.
react-native-bot commented 3 days ago
:warning: Missing Reproducible Example
:information_source: We could not detect a reproducible example in your issue report. Please provide either:
cipolleschi commented 3 days ago

@MasGaNo thanks for the issue. The build setting can definitely be either String or Array. I'm not sure if that's due to different versions of Xcode, version of cocoapods, or the method used to actually read the project.

Anyway, I'd like to ask you a couple of things:

  1. Could you try run bundle install and then install pods with bundle exec pod install? We use Ruby Bundler to ensure that all the cocoapods dependencies are aligned properly and that might fix your issue
  2. Could you create a PR with the fix for this? If we handle them more solidly (using array methods when we receive an array, and strings methods when we receive a string) that would be better for everyone!

Thank you so much.

MasGaNo commented 2 days ago

@cipolleschi Thank you for the quick feedback. Regarding the first point, I have some issue to run the bundle install command:

make: *** No rule to make target `/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/universal-darwin22/ruby/config.h', needed by `nkf.o'.  Stop.

I'm suspecting the fact I'm using the default Ruby 2.6 from MacOS/XCode and it may lead to some issues. I'm currently trying to replace it by a proper ruby and will let you know.

Regarding the fix itself, I just created the PR with the code snippet I put above and updated the test to support both Array and String value.

Thank you!