Search code examples
javascriptyeomanyeoman-generator

How to setup a destination path for a custom yeoman generator files?


I'm building a custom yeoman generator, so when it's time to create files they're created one directory above my current location, or at .., so for example if I run:

yo koala

From /home/diegoaguilar/koala the files will be created at /home/diegoaguilar. How am I supposed to tell the path where the generator should copy files? I really thought that would be process.cwd() or simply where yeoman generator is being ran from.

This is the code I got for files generation:

  writing: {
    app: function () {
      this.fs.copyTpl(
        this.templatePath('_package.json'),
        this.destinationPath('package.json'),
        {appname: this.appname}
      );
      this.fs.copy(
        this.templatePath('_bower.json'),
        this.destinationPath('bower.json')
      );
    },

    projectfiles: function () {
      this.fs.copy(
        this.templatePath('editorconfig'),
        this.destinationPath('.editorconfig')
      );
      this.fs.copy(
        this.templatePath('jshintrc'),
        this.destinationPath('.jshintrc')
      );
    }
  },

Solution

  • First, I find it easier to use yeoman's this.template(), instead of using this.fs.copy()/this.fs.copyTpl() that are coming from the included instance of mem-fs-editor, but YMMV

    Regardless, you need to set the this.sourceRoot('rel/path/to/source/root') and this.destinationRoot('rel/path/to/dest/root') in the generator before you try to write to make sure you have set the correct template and destination contexts. See yeoman's getting started guide on interacting with the files system from more information. The this.destinationRoot() should be defined relative to the root directory of your current project (I explain this below), while the this.sourceRoot() should be defined relative to the root directory of your generator's files.

    You also have to consider that yeoman will try to figure out the root directory of whatever app you are currently in at the command line. It does this by navigating upwards (i.e. /home/diegoaguilar/koala -> /home/diegoaguilar/) until it finds a .yo-rc.json file. Yeoman then takes the directory of the nearest .yo-rc.json to where you ran the command as the intended root directory for your project.

    In your case you may want to delete/move/rename /home/diegoaguilar/.yo-rc.json if it exists. Then you can create the directory you want your project to live inside and run the generator there. This would look like

    /home/diegoaguilar/ $> mkdir koala
    /home/diegoaguilar/ $> cd koala
    /home/diegoaguilar/koala/ $> yo koala
    

    If you want or need to leave your /home/diegoaguilar/.yo-rc.json there, you should set the this.destinationRoot() in the generator relative to /home/diegoaguilar/, so to write into /home/diegoaguilar/koala/ you would use this.destinationRoot('koala').