Вызванный подгенератор Yeoman не запрашивает

Я хотел бы вызвать некоторые подгенераторы из моего основного генератора и заставить их использовать подсказку для получения собственной информации. Моя текущая реализация выполняет этап записи основного генератора одновременно с этапом запроса вызываемого подгенератора, но я хотел бы выполнить следующие шаги:

  1. Быстрый шаг основного генератора
  2. Быстрый шаг вызываемых подгенераторов
  3. Шаг записи основного генератора
  4. Шаг записи вызванных подгенераторов

Мой основной генератор выглядит так:

'use strict';
var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');

module.exports = yeoman.generators.Base.extend({
  initializing: function () {
    this.pkg = require('../package.json');
  },

  prompting: function () {
    var done = this.async();

    // Have Yeoman greet the user.
    this.log(yosay(
      'Welcome to the neat ' + chalk.red('DockerSetup') + ' generator!'
    ));

    // Check for usage of redis, postgres and mysql subgenerators
    this.prompt([
    {
      type: 'input',
      name: 'subApplications',
      message: 'Enter the names of the sub-apps comma seperated'
    }], function (props) {
      this.subApplications = props.subApplications.length ? props.subApplications.split(',') : [];


    // Run subgenerators

    this.subApplications.forEach(function(name) {
      this.composeWith('docker-setup:sub-application', { args: [name] });
    }.bind(this));

      done();
    }.bind(this));
  },

  writing: function () {
    this.fs.copyTpl(
      this.templatePath('_Readme.md'),
      this.destinationPath('Readme.md')
    );
  }
});

А это мой подгенератор

'use strict';
var yeoman = require('yeoman-generator');

module.exports = yeoman.generators.NamedBase.extend({
  initializing: function () {
    this.log('You called the DockerSetup subgenerator with the argument ' + this.name + '.');
  },

  prompting: function () {
    // Assume that the sub-apps are one level under this with same name

    this.prompt([
    {
      type: 'list',
      name: 'mainTech',
      message: 'Which is the main technology used?',
      choices: ['rails', 'yii', 'frontend']
    }, {
      type: 'checkbox',
      name: 'additionalTechnologies',
      message: 'Which technologies are used in this subapp?',
      choices: ['redis', 'postgres', 'mysql']
    }], function (props) {
      this.mainTech = props.mainTech;
      this.additionalTechnologies = props.additionalTechnologies;


      // This is done here, because if it's in the writing part it gets called before the prompt
      var path = this.destinationPath('fig.yml'),
          file = this.readFileAsString(path),
          content;

      switch(this.mainTech) {
        case 'rails':
          content = 'content';
        break;

        case 'yii':
        break;

        case 'frontend':
        break;
      }

      this.additionalTechnologies.forEach(function (tech) {
        content += ('    - ' + tech);
      });

      file += content;
      this.write(path, file);

      done();
    }.bind(this));
  }
});

person Daniel Schmidt    schedule 14.02.2015    source источник


Ответы (1)


Вы не должны вызывать функцию done() до тех пор, пока не закончите работу с подсказками в этом подгенераторе. Как бы то ни было, вы даете добро на продолжение выполнения сразу после отправки работы на подгенератор. Вместо этого вы должны вызывать done() только асинхронно (поскольку в большинстве случаев это вариант использования с async/done).

Для этого, я считаю, вы можете связать команду composeWith с .on как таковую:

this.subApplications.forEach(function(name) {
      this.composeWith('docker-setup:sub-application', { args: [name] })
          .on('end',function(){
                        done();
                    });
    }.bind(this));

(Событие 'end' генерируется в конце каждого процесса yo в соответствии с base. js строка 358)

person Tamas    schedule 14.02.2015
comment
Знаете ли вы, каков интерфейс возвращаемого значения? - person Daniel Schmidt; 16.02.2015
comment
Возвращаемое значение чего именно? - person Tamas; 17.02.2015
comment
К сожалению, я не знаю ни одного встроенного канала для возврата значений из подгенератора. Вызов emit, основанный на приведенной выше ссылке на источник, может принимать дополнительный параметр помимо «конца», но, похоже, он не используется. - person Tamas; 22.02.2015
comment
Большую часть времени архитектуру можно переработать, чтобы не нуждаться в возвращаемых значениях от подгенераторов. Я считаю, что подгенераторы следует рассматривать как независимые строительные блоки, которые также могут вызываться сами по себе, что делает этот вариант использования зависимости от вывода другого подгенератора немного необычным. - person Tamas; 22.02.2015
comment
Моя проблема не является возвращаемым значением, но я хотел бы создать одну базовую версию файла в основном генераторе, а затем добавить строки в вспомогательные генераторы. Если бы я мог, я бы хотел сначала выполнить все подсказки, а затем запустить генератор, по этой причине я хотел бы дождаться завершения шага подсказки подгенератора. - person Daniel Schmidt; 22.02.2015