0

How can a postinstall script be restricted to run only on macOS?

I have a shell script inside my React native library and it needs to be started when the npm install has completed.

This works great with postinstall but the problem is that Windows can't execute the shell script.

"scripts": {
  "postinstall": "./iospatch.sh"
},

I need a way to limit that, to only run on macOS.

I tried with this library but it didn't work for my case https://www.npmjs.com/package/cross-os

RobC
  • 22,977
  • 20
  • 73
  • 80

1 Answers1

3

For cross-platform consider redefining your npm script as follows. This ensures that the shell script (.sh) is run only, via the postinstall npm script, when installing your package on macOS.

"scripts": {
  "postinstall": "node -e \"process.platform === 'darwin' && require('child_process').spawn('sh', ['./iospatch.sh'], { stdio: 'inherit'})\""
}

Explanation:

The node -e \"...\" part utilizes the Node.js command line option -e to evaluate the inline JavaScript as follows:

  • process.platform === 'darwin' utilizes the process.platform property to identify the operating system platform. If it equals darwin then it's macOS.

  • The last part on the right-hand side of the && operator;

    require('child_process').spawn('sh', ['./iospatch.sh'], { stdio: 'inherit'})
    

    is executed only if the expression on the left-hand side of the && operator is true, i.e. it only runs if the platform is macOS.

    That part of the code essentially utilizes the child_process.spawn() method to invoke your .sh file. The stdio option is set to inherit to configure the pipes for stdin, stdout, stderr in the child process.

    Also note the command passed to child_process.spawn() is sh and the argument is the file path to the shell script, i.e. ['./iospatch.sh']. We do this to avoid having to set file permissions on macOS so that it can execute iospatch.sh.

RobC
  • 22,977
  • 20
  • 73
  • 80
  • I would suggest that the "logic" from the postintall comamnd could be put into the postinstall script file itself. You could check in the iospatch.sh if the platform is macOS and if false, just exit. – psimms Sep 30 '21 at 13:02
  • @psimms - indeed, however that approach assumes the OS attempting to execute the `.sh` file can interpret a shell script - older Windows cannot for example. Hence for cross-platform support it's better to handle the check via Node.js. – RobC Sep 30 '21 at 13:08