react-native: [iOS] FBReactNativeSpec pod checksum is not stable (RN 0.64.0)

Description

The SPEC CHECKSUM for FBReactNativeSpec in ios/Podfile.lock varies between development machines. This is caused by local paths in the output of pod ipc spec FBReactNativeSpec.podspec, such as output_files and prepare_command. This causes the Podfile.lock to constantly change when pod install is run on different developers’ machines.

React Native version: 0.64.0

This happens for a clean install of React Native 0.64.0. Previous versions are not affected (pod ipc spec does not include local paths).

System:
    OS: macOS 11.2.3
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Memory: 5.41 GB / 32.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.15.5 - /var/folders/tq/3s__skh57_300l201pdk9gjh0000gn/T/yarn--1616135350751-0.5787894354182639/node
    Yarn: 1.22.0 - /var/folders/tq/3s__skh57_300l201pdk9gjh0000gn/T/yarn--1616135350751-0.5787894354182639/yarn
    npm: 6.14.11 - ~/.nvm/versions/node/v14.15.5/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.10.1 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2
    Android SDK:
      API Levels: 28, 29
      Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.0
      System Images: android-21 | Google APIs ARM EABI v7a, android-21 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 4.1 AI-201.8743.12.41.7042882
    Xcode: 12.4/12D4e - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_252 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.1 => 17.0.1
    react-native: 0.64.0 => 0.64.0
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found
✨  Done in 4.48s.

Steps To Reproduce

  1. npx react-native init TestProject
  2. cd TestProject/ios && pod install

ios/Podfile.lock now has a checksum that matches pod ipc spec FBReactNativeSpec.podspec | openssl sha1 in node_modules/react-native/React/FBReactNativeSpec, and pod ipc spec FBReactNativeSpec.podspec contains local paths, such as:

{
  "script_phases": {
    "name": "Generate Specs",
    "input_files": [
      "/Users/thaapasa/rn/PodTestProject/node_modules/react-native/scripts/../Libraries"
    ],
    "output_files": [
      "$(DERIVED_FILE_DIR)/codegen-FBReactNativeSpec.log",
      "/Users/thaapasa/rn/PodTestProject/node_modules/react-native/scripts/../React/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h",
      "/Users/thaapasa/rn/PodTestProject/node_modules/react-native/scripts/../React/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm"
    ],
    "script": "set -o pipefail\n\nbash -l -c 'SRCS_DIR=/Users/thaapasa/rn/PodTestProject/node_modules/react-native/scripts/../Libraries CODEGEN_MODULES_OUTPUT_DIR=/Users/thaapasa/rn/PodTestProject/node_modules/react-native/scripts/../React/FBReactNativeSpec/FBReactNativeSpec CODEGEN_MODULES_LIBRARY_NAME=FBReactNativeSpec /Users/thaapasa/rn/PodTestProject/node_modules/react-native/scripts/generate-specs.sh' 2>&1 | tee \"${SCRIPT_OUTPUT_FILE_0}\"",
    "execution_position": "before_compile",
    "show_env_vars_in_log": true
  },
  "prepare_command": "mkdir -p /Users/thaapasa/rn/PodTestProject/node_modules/react-native/scripts/../React/FBReactNativeSpec/FBReactNativeSpec && touch /Users/thaapasa/rn/PodTestProject/node_modules/react-native/scripts/../React/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h /Users/thaapasa/rn/PodTestProject/node_modules/react-native/scripts/../React/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm"
}

Expected Results

pod ipc spec FBReactNativeSpec.podspec should give identical output on different developer machines; i.e. not containing absolute local paths.

Snack, code example, screenshot, or link to a repository:

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 51
  • Comments: 17

Commits related to this issue

Most upvoted comments

We are also still running into this issue with our team, and are constantly ping-ponging changes to our Podfile.lock with just this one line.

For reference, this is what I now run to fix this bug (and a bug with nvm) in yarn postinstall script:

#!/bin/bash

OS=`uname`

echo "Fixing RN 0.64.0 bugs:"
cd node_modules/react-native/scripts
echo "- unset PREFIX in find-node.sh"
if [ `cat find-node.sh | grep 'unset PREFIX' | wc -l` -lt 1 ]
then
  cp find-node.sh tmp
  head -n 1 tmp >find-node.sh
  echo "unset PREFIX" >>find-node.sh
  tail -n +2 tmp >>find-node.sh
  rm tmp
fi

if [ "$OS" = 'Darwin' ]
then
  # for MacOS; cannot install Pods on Win/Linux
  echo "- switch to relative paths in react_native_pods.rb "
  sed -i '' -e "s/File[.]join[(]__dir__, \"[.][.]\"[)]/\"..\/..\/node_modules\/react-native\"/" react_native_pods.rb
  sed -i '' -e "s/#{File[.]join[(]__dir__, \"generate-specs.sh\"[)]}/..\/..\/node_modules\/react-native\/scripts\/generate-specs.sh/" react_native_pods.rb
  sed -i '' -e "s/spec[.]prepare_command = \"#/spec.prepare_command = \"cd ..\/.. \&\& #/" react_native_pods.rb
fi

cd - >/dev/null

The culprit seems to be line 152 of node_modules/react-native/scripts/react_native_pods.rb:

  prefix = options[:path] ||= File.join(__dir__, "..")

and line 195 with another File.join(__dir__)

__dir__ here resolves to an absolute path that is part of the generated pod spec. Furthermore, prepare command shared the same prefix but runs in a different directory, so that command must also be adjusted.

If I change line 152 to

  prefix = options[:path] ||= "../../node_modules/react-native"

and line 195 to

    :script => "set -o pipefail\n\nbash -l -c '#{env_vars} CODEGEN_MODULES_LIBRARY_NAME=#{codegen_modules_library_name} ../../node_modules/react-native/scripts/generate-specs.sh' 2>&1 | tee \"${SCRIPT_OUTPUT_FILE_0}\"",

and line 200 to

  spec.prepare_command = "cd ../.. && #{mkdir_command} && touch #{generated_files.reduce() { |str, file| str + " " + file }}"

it seems to work.

Generated pod spec now looks like this, and should be stable.

{
  "name": "FBReactNativeSpec",
  "version": "0.64.0",
  "summary": "-",
  "homepage": "https://reactnative.dev/",
  "license": "MIT",
  "authors": "Facebook, Inc. and its affiliates",
  "platforms": {
    "ios": "10.0"
  },
  "compiler_flags": "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32 -Wno-nullability-completeness",
  "source": {
    "git": "https://github.com/facebook/react-native.git",
    "tag": "v0.64.0"
  },
  "source_files": "**/*.{c,h,m,mm,cpp}",
  "header_dir": "FBReactNativeSpec",
  "pod_target_xcconfig": {
    "USE_HEADERMAP": "YES",
    "CLANG_CXX_LANGUAGE_STANDARD": "c++14",
    "HEADER_SEARCH_PATHS": "\"$(PODS_TARGET_SRCROOT)/React/FBReactNativeSpec\" \"$(PODS_ROOT)/RCT-Folly\""
  },
  "dependencies": {
    "RCT-Folly": [
      "2020.01.13.00"
    ],
    "RCTRequired": [
      "0.64.0"
    ],
    "RCTTypeSafety": [
      "0.64.0"
    ],
    "React-Core": [
      "0.64.0"
    ],
    "React-jsi": [
      "0.64.0"
    ],
    "ReactCommon/turbomodule/core": [
      "0.64.0"
    ]
  },
  "script_phases": {
    "name": "Generate Specs",
    "input_files": [
      "../../node_modules/react-native/Libraries"
    ],
    "output_files": [
      "$(DERIVED_FILE_DIR)/codegen-FBReactNativeSpec.log",
      "../../node_modules/react-native/React/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h",
      "../../node_modules/react-native/React/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm"
    ],
    "script": "set -o pipefail\n\nbash -l -c 'SRCS_DIR=../../node_modules/react-native/Libraries CODEGEN_MODULES_OUTPUT_DIR=../../node_modules/react-native/React/FBReactNativeSpec/FBReactNativeSpec CODEGEN_MODULES_LIBRARY_NAME=FBReactNativeSpec ../../node_modules/react-native/scripts/generate-specs.sh' 2>&1 | tee \"${SCRIPT_OUTPUT_FILE_0}\"",
    "execution_position": "before_compile",
    "show_env_vars_in_log": true
  },
  "prepare_command": "cd ../.. && mkdir -p ../../node_modules/react-native/React/FBReactNativeSpec/FBReactNativeSpec && touch ../../node_modules/react-native/React/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h ../../node_modules/react-native/React/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm"
}

I have create patch-package for RN version 0.64.2 for doesn’t want to use sed and script

https://gist.github.com/zeemyself/69e2dce7cd88b0a1cb6dbcec54d1f265

Is this being fixed in 0.65?

Still running into this with 0.64.2. Why was this issue closed if it still persists?

[!] There were changes to the lockfile in deployment mode:
--
  | SPEC CHECKSUMS:
  | FBReactNativeSpec:
  | New Lockfile: 76cc58820784ccba47428a8eac3150f350075fe7
  | Old Lockfile: b2708f0fc27435e1bab6b324e66bd01c99c498b9

Is the only solution to patch over node_modules/react-native?

We are still facing this in 0.64.2 as others have stated. Can this issue be re-opened or should a new one be created?

I fixed the path to generate-specs.sh now as well (see updated comments here and the linked PR). @FreekVanDooren this should now create a stable podspec…

This is a duplicate: https://github.com/facebook/react-native/issues/31121 (sorry, did not find that one before)

@thaapasa is there a way to apply your fix on postinstall? I am unaware if npm offers a different way of doing this, so I’m thinking I could create a shell script to apply your change to the right line that would run post install. That or do it once, run pod install and hope that I never run into an issue because I forgot I did that.

Someone suggested using patch-package (https://www.npmjs.com/package/patch-package), but I think I’ll go with a custom postinstall script with some sort of sed spell or similar to fix that path.