child_process.exec/spawn вызывает обратный вызов/закрытие с помощью команды установки npm (через Gulp/Shipit)

  • Я использую Shipit для развертывания.
  • При развертывании Shipit извлекает текущий Git Sha в каталог tmp, затем я запускаю npm install, а затем gulp build, затем продолжаю развертывание.
  • Shipit использует Orchestrator для выполнения своих задач, как и Gulp.
  • У Shipit есть собственный интерфейс командной строки, поэтому я могу выполнить развертывание с помощью shipit development deploy.

Все вышеперечисленное работает. Что я пытаюсь сделать, так это создать задачу gulp deploy, которая будет инициализировать Shipit напрямую, вместо использования CLI. Выглядит примерно так:

gulp.task('shipit:deploy', function() {
  var deployToEnv = argv['deploy-to'] || false;
  var shipit;
  return inquirer.prompt([{
    type: 'list',
    name: 'deployToEnv',
    default: deployToEnv,
    message: 'Deploy to environment:',
    choices: envs
  }]).then(function(answers) {
    deployToEnv = answers.deployToEnv;
    shipit = new Shipit({environment: deployToEnv});
    shipit.initialize();
    shipit.start('deploy');
  });
});

Соответствующая конфигурация корабля:

  shipit.initConfig(config);
  shipit.blTask('build', function() {
    return shipit.local('npm install --silent', {
      cwd: shipit.config.workspace
    }).then(function() {
      return shipit.local('gulp build', {
        cwd: shipit.config.workspace
      });
    });
  });

  shipit.on('fetched', function() {
    shipit.start('build');
  });

Кажется, все работает с одной проблемой: на самом деле он не выполняет npm install!

Running "npm install --silent" on local. Running "gulp build" on local.

Итак, может показаться, что что-то в команде npm install преждевременно разрешает промис, но я не уверен, как и почему.

У меня была похожая проблема (просто с использованием shipit cli) с предупреждениями npm, когда я обнаружил, что использование --silent arg решило это.

В качестве теста я оставил код как есть, но заменил npm install --silent на sleep 10. Конечно же, он ждал 10 секунд, прежде чем выполнить gulp build. Так что, казалось бы, с командой npm install что-то особенное.

Любая помощь приветствуется!

Обновление №1:

shipit.local использует child_process.exec. Я попытался преобразовать это, чтобы использовать child_process.spawn, но получил тот же результат.

Обновление №2:

Если я изменю команду на sudo npm install, все будет работать как положено! Итак... что это значит и как избежать запуска с sudo?

Обновление №3:

Все еще не могу сделать это без sudo, но я попытался добавить флаг --verbose с такими результатами:

Без sudo:

@ npm info it worked if it ends with ok
@ npm verb cli [ '/Users/timkelty/.nvm/versions/node/v0.12.0/bin/node',
@ npm verb cli   '/Users/timkelty/.nvm/versions/node/v0.12.0/bin/npm',
@ npm verb cli   'install',
@ npm verb cli   '--verbose' ]
@ npm info using [email protected]
@ npm info using [email protected]
@ npm verb install where, deps [ '/Users/timkelty/tmp/edwards-garment-website', [] ]
@ npm verb install where, peers [ '/Users/timkelty/tmp/edwards-garment-website', [] ]
@ npm info preinstall [email protected]
@ npm info build /Users/timkelty/tmp/edwards-garment-website
@ npm verb linkStuff [ false, false, false, '/Users/timkelty/tmp' ]
@ npm info linkStuff [email protected]
@ npm verb linkBins [email protected]
@ npm verb linkMans [email protected]
@ npm verb rebuildBundles [email protected]
@ npm info install [email protected]
@ npm info postinstall [email protected]
@ npm verb exit [ 0, true ]
@ npm info ok
Running "gulp build" on local.
@ [15:14:32] Local gulp not found in ~/tmp/edwards-garment-website
@ [15:14:32] Try running: npm install gulp
'build' errored after 755 ms
Error: Command failed: /bin/sh -c gulp build

С sudo:

Running "sudo npm install --verbose" on local.
@ npm info it worked if it ends with ok
@ npm verb cli [ '/Users/timkelty/.nvm/versions/node/v0.12.0/bin/node',
@ npm verb cli   '/Users/timkelty/.nvm/versions/node/v0.12.0/bin/npm',
@ npm verb cli   'install',
@ npm verb cli   '--verbose' ]
@ npm info using [email protected]
@ npm info using [email protected]
@ npm verb install where, deps [ '/Users/timkelty/tmp/edwards-garment-website',
@ npm verb install   [ 'Select2',
@ npm verb install     'autoprefixer-core',
@ npm verb install     'babel',

... поэтому по какой-то причине при работе без sudo команда npm install, похоже, думает, что у нее нет никаких зависимостей для установки, поэтому она завершается без ошибок и переходит к моей следующей задаче.


person Tim Kelty    schedule 01.05.2015    source источник
comment
Можете ли вы использовать npm install без --silent и затем распечатать console.log(res.stdout); и console.log(res.stderr)?   -  person vanadium23    schedule 05.05.2015
comment
@vanadium23 в обратном вызове child_process.exec и stdout, и stderr являются пустыми строками: gist.github.com/4c0c905e2ab517806915   -  person Tim Kelty    schedule 05.05.2015
comment
просто чтобы убедиться, что это не ошибка разрешения, вы можете попробовать изменить разрешение на 755 и запустить скрипт?   -  person vanadium23    schedule 05.05.2015
comment
@ vanadium23 Конечно, но по какому пути? Я сделал chmod -R 755 в каталоге, из которого я запускаю команду npm install, тот же результат.   -  person Tim Kelty    schedule 05.05.2015
comment
У меня есть другая идея после хорошего сна. Можем ли мы сделать задачу echo "$(which npm) test" >> test.file вместо sleep 10. Зачем это нужно? Во-первых, мы знаем, может ли gulp создать файл, во-вторых, мы знаем, может ли gulp использовать npm и какой именно.   -  person vanadium23    schedule 06.05.2015
comment
@ vanadium23 содержимое test.file /Users/timkelty/.nvm/versions/node/v0.12.0/bin/npm test   -  person Tim Kelty    schedule 06.05.2015
comment
@vanadium23 см. обновление №2 о sudo   -  person Tim Kelty    schedule 08.05.2015


Ответы (2)


Я нашел решение!

Проблема заключалась в том, что я пытался установить devDependencies, но когда я запускал команду gulp deploy, NODE_ENV был настроен на рабочую среду, которая не устанавливает devDependencies.

Таким образом, изменение команды на NODE_ENV=development npm install, кажется, исправляет это!

person Tim Kelty    schedule 18.05.2015

После обновления #2 у меня появилось больше возможностей написать, почему эта комбинация не работает. Прежде всего, нам нужно выяснить, какой пользователь выполняет команды. Для этого нужно выполнить команду whoami и посмотреть результат (можно через ssh или шипит таск). Прямой вопрос заключается в том, какие привилегии не имеют пользователя для установки пакетов.

Возможное решение №1:

У пользователя нет прав на папку tmp. Мы можем проверить это через ls -ld /path/to/tmp, ожидаемый результат:

drwxrwxrwt 13 root root 280 May  8 19:42 /tmp

Вам необходимо убедиться, что все пользователи могут писать в директории tmp: drwxrwxrwx. Если нет, вы можете установить chmod -R 755.

Возможное решение №2:

Выполнение на npm разрешено только пользователю/группе-владельцу, а у нашего пользователя их нет. Мы можем проверить это через ls -lL $(which npm). Ожидаемый результат:

-rwxr-xr-x 1 root root 1881 Apr 19 07:12 /usr/../lib/node_modules/npm/bin/npm-cli.js

Если для файла нет разрешения x, выполните sudo chmod +x $(which npm).

ОБНОВЛЕНИЕ: после этого вопроса есть также может быть проблема не с вашей папкой tmp, а с папкой отладки для npm. Попробуйте найти его и проверьте разрешение.

Надеюсь, что это все варианты, которые мы можем встретить.

person vanadium23    schedule 08.05.2015
comment
права /tmp: lrwxr-xr-x 1 root wheel - person Tim Kelty; 11.05.2015
comment
@TimKelty это символическая ссылка, доступная для записи только для root/sudo, попробуйте ls -lLd /tmp - person vanadium23; 11.05.2015
comment
Чтобы избежать всей этой проблемы с разрешениями, я изменил местоположение tmp на ~/tmp/. Все еще есть проблема. Сейчас пробую решение №2. - person Tim Kelty; 11.05.2015
comment
Папка отладки: ls -lLd ~/.npm/debug drwxr-xr-x 14 timkelty staff 476 Mar 13 17:12 /Users/timkelty/.npm/debug - person Tim Kelty; 11.05.2015
comment
Что-нибудь еще, что я должен попробовать, @vanadium23? - person Tim Kelty; 12.05.2015
comment
@TimKelty, насколько я понимаю, если с sudo он устанавливается, то это определенно проблема с правами доступа к файлу. Думаю, мы не замечаем слона. :-( - person vanadium23; 12.05.2015
comment
см. обновление № 3 выше. Казалось бы, npm install не думает, что у него есть какие-либо установки для установки, если он не работает как sudo. В этом есть смысл? - person Tim Kelty; 18.05.2015
comment
Я, кажется, докопался до сути этого: все deps, которые должны быть установлены в этом случае, - это devDependencies. Я обнаружил, что если я переключу их только на dependencies, это сработает. - person Tim Kelty; 18.05.2015