keppel/lotion

Can't install Tendermint due to shell script

Closed this issue · 1 comments

Moved from tendermint/tendermint#2514.

A friend needed me to look at their code, but I couldn't run it because npm install fails because lotion uses tendermint as a dependency, and tendermint tries to run shell script commands that are not cross-platform friendly, instead of running node commands.

npm ERR! tendermint-node@2.0.5 preinstall: `rm -f ./bin/tendermint && touch ./bin/tendermint`

Instead of:

"scripts": {
  "preinstall": "rm -f ./bin/tendermint && touch ./bin/tendermint"
}

create a node script that uses fs to perform file system interactions and run it.

"scripts": {
  "preinstall": "node scripts/preinstall.js"
}

Something like:

const fs = require('fs');
const path = require('path');
const deleteFolderRecursive = function (folder) {
  if (fs.existsSync(folder)) {
    fs.readdirSync(folder).forEach(function (file) {
      let currentFile = path.join(folder, file);
      if (fs.lstatSync(currentFile).isDirectory()) {
        deleteFolderRecursive(currentFile);
      } else {
        fs.unlinkSync(currentfile);
      }
    });
    fs.rmdirSync(folder);
  }
};
deleteFolderRecursive('./bin/tendermint');
fs.mkdirSync('./bin/tendermint');

I didn't test that locally, but it should be pretty close to what you'd need.

Of course this could be much simpler:

const fs = require('fs-extra');
fs.removeSync('./bin/tendermint');
fs.mkdirSync('./bin/tendermint');

or even

"scripts": {
  "preinstall": "node -e \"let fs=require('fs-extra');let x='./bin/tendermint';fs.removeSync(x);fs.mkdirSync(x)\""
}

But that would require installing a 3rd party module prior to doing your install. Catch 22.

An alternative could be something like this:

let fs = require('fs');
let path = require('path');
let exec = require('child_process').execSync;
let dir = path.join('.', 'bin', 'tendermint');
if (fs.existsSync(dir)) {
  try {
    if (process.platform === 'win32') {
      exec('rd /s /q ' + dir);
    } else {
      exec('rm -f ' + dir);
    }
  } catch (err) {
    throw 'Error during preinstall of tendermint' + err;
  }
}
fs.mkdirSync(dir);

Duplicate of mappum/tendermint-node#2

(thanks Anton!)