Sentry-cli: Supports NVM in sentry-cli.js when build from XCode (React Native) - node no such file or directory

Created on 31 Oct 2018  路  9Comments  路  Source: getsentry/sentry-cli

Dependencies

{
    "@babel/runtime": "^7.1.2",
    "add": "^2.0.6",
    "axios": "^0.18.0",
    "babel-plugin-transform-flow-strip-types": "^6.22.0",
    "lodash": "^4.17.10",
    "mobx": "^4.3.1",
    "mobx-react": "^5.1.0",
    "moment": "^2.22.2",
    "native-base": "^2.8.1",
    "numeral": "^2.0.6",
    "react": "16.6.0-alpha.8af6728",
    "react-native": "0.57.1",
    "react-native-contacts": "^2.2.4",
    "react-native-fast-image": "^5.0.11",
    "react-native-firebase": "^5.0.0",
    "react-native-image-crop-picker": "^0.21.2",
    "react-native-loading-spinner-overlay": "^0.5.2",
    "react-native-modal-datetime-picker": "^6.0.0",
    "react-native-sentry": "^0.39.1",
    "react-navigation": "^2.12.1",
    "schedule": "0.4.0"
}

Currently, the sentry wizard made following change to ProjectName.xcodeproj/project.pbxproj

- shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
+ shellScript = "export SENTRY_PROPERTIES=sentry.properties\nexport NODE_BINARY=node\n../node_modules/@sentry/cli/bin/sentry-cli react-native xcode ../node_modules/react-native/scripts/react-native-xcode.sh\n";

This breaks RN apps with RVM with following error
image

The reason is scripts/react-native-xcode.sh can leverage nvm node executable in their script but the sentry-cli script didn't

The fix was to copy the NVM handling part inside scripts/react-native-xcode.sh to build script to fix the above error.

react-native enhancement need more information

Most helpful comment

It appears that the "no such file or directory" error is coming from the sentry-cli script, as it is a javascript script, and also runs with node:

$ head ./node_modules/@sentry/cli/bin/sentry-cli 
#!/usr/bin/env node
/* eslint-disable no-console */

The error is actually coming from /usr/bin/env, hence why the error message starts with "env:", because "/usr/bin/env" is not finding "node".

To confirm this, I changed this line of the build phase script :

../node_modules/@sentry/cli/bin/sentry-cli react-native xcode ../node_modules/react-native/scripts/react-native-xcode.sh

To

../node_modules/@sentry/cli/bin/sentry-cli -h

Which should just print the help page of the command. I still see the error:

env: node: No such file or directory

So the problem is that the sentry-cli script cannot find our nvm's node.

Why?

This is because for each build phase script, XCode will create a wrapper shell script and run it _with a preset environment_.

To see the the wrapper script, go to XCode's report navigator after the build fails:

xcode-report-navigator-1

There are two notable things about this output. First, the PATH is missing the path to the nvm's node:

xcode-report-navigator-2

Second is this:

xcode-report-navigator-3

After setting up a bunch of variables via export ..., XCode runs the temporary script via sh -c:

/bin/sh -c /Users/..../Script-030D431E0DE5414187450AD2.sh

The shell that runs the script is ran in non-interactive mode, which typically means it won't read the "profile" files, including the call to initialize nvm.

I don't know if this is the best solution, but one way to fix this is to initialize nvm in the build phase itself and then use it to set the node version to use:

# this could be different for you
export NVM_DIR=$HOME/.nvm

if [ -n "$NVM_DIR" ] && [ -d "$NVM_DIR" ]; then
  echo "nvm detected"

  # This is the path to the nvm initializer when installed via homebrew. 
  # This might be different for you.
  source /usr/local/opt/nvm/nvm.sh

  # If the project root has an .nvmrc file, change to that node  
  # version first.
  if [ -f "../.nvmrc" ]; then
    NODE_VERSION=$(cat ../.nvmrc)
    echo "nvmrc found at project root, using node version: ${NODE_VERSION}"
    nvm use ${NODE_VERSION}
  fi
  export NODE_BINARY=$(nvm which node)
else
  export NODE_BINARY=node
fi

Be sure to include the snippet in both Sentry build phases that call out to ../node_modules/@sentry/cli/bin/sentry-cli.

Update: I was curious as to why this doesn't affect the react-native-xcode.sh script itself. It is because it has built-in support for nvm.

All 9 comments

Looks like this is still a temporary solution that works:
https://github.com/getsentry/react-native-sentry/issues/247

run this in your terminal - no edits required to project.pbxproj

n=$(which node);n=${n%/bin/node}; chmod -R 755 $n/bin/*; sudo cp -r $n/{bin,lib,share} /usr/local

https://docs.sentry.io/platforms/react-native/manual-setup/#using-node-with-nvm-or-notion
this works for me locally, but on travis-ci.com it does not work. (I use nvm on travis)
also the workaround https://github.com/getsentry/sentry-cli/issues/421#issuecomment-437699488 doesn't work for me on travis

@ManAnRuck what's the exact problem on CI you're running into?

It appears that the "no such file or directory" error is coming from the sentry-cli script, as it is a javascript script, and also runs with node:

$ head ./node_modules/@sentry/cli/bin/sentry-cli 
#!/usr/bin/env node
/* eslint-disable no-console */

The error is actually coming from /usr/bin/env, hence why the error message starts with "env:", because "/usr/bin/env" is not finding "node".

To confirm this, I changed this line of the build phase script :

../node_modules/@sentry/cli/bin/sentry-cli react-native xcode ../node_modules/react-native/scripts/react-native-xcode.sh

To

../node_modules/@sentry/cli/bin/sentry-cli -h

Which should just print the help page of the command. I still see the error:

env: node: No such file or directory

So the problem is that the sentry-cli script cannot find our nvm's node.

Why?

This is because for each build phase script, XCode will create a wrapper shell script and run it _with a preset environment_.

To see the the wrapper script, go to XCode's report navigator after the build fails:

xcode-report-navigator-1

There are two notable things about this output. First, the PATH is missing the path to the nvm's node:

xcode-report-navigator-2

Second is this:

xcode-report-navigator-3

After setting up a bunch of variables via export ..., XCode runs the temporary script via sh -c:

/bin/sh -c /Users/..../Script-030D431E0DE5414187450AD2.sh

The shell that runs the script is ran in non-interactive mode, which typically means it won't read the "profile" files, including the call to initialize nvm.

I don't know if this is the best solution, but one way to fix this is to initialize nvm in the build phase itself and then use it to set the node version to use:

# this could be different for you
export NVM_DIR=$HOME/.nvm

if [ -n "$NVM_DIR" ] && [ -d "$NVM_DIR" ]; then
  echo "nvm detected"

  # This is the path to the nvm initializer when installed via homebrew. 
  # This might be different for you.
  source /usr/local/opt/nvm/nvm.sh

  # If the project root has an .nvmrc file, change to that node  
  # version first.
  if [ -f "../.nvmrc" ]; then
    NODE_VERSION=$(cat ../.nvmrc)
    echo "nvmrc found at project root, using node version: ${NODE_VERSION}"
    nvm use ${NODE_VERSION}
  fi
  export NODE_BINARY=$(nvm which node)
else
  export NODE_BINARY=node
fi

Be sure to include the snippet in both Sentry build phases that call out to ../node_modules/@sentry/cli/bin/sentry-cli.

Update: I was curious as to why this doesn't affect the react-native-xcode.sh script itself. It is because it has built-in support for nvm.

@export-mike would you be open to a PR to add nvm support to the sentry build phases? It would probably require a similar approach to what the react native team did, and would need to be wrapped in a shell script.

Not really I don't think this is an issue for me anymore. @twelve17 this was 2 years ago

@export-mike This indeed is an old issue, but it is still reproducible. Are you sure it's not an issue for you because you've done the temporary workaround of copying node to /usr/local?

This is indeed still an issue

Was this page helpful?
0 / 5 - 0 ratings