generator icon indicating copy to clipboard operation
generator copied to clipboard

Yo doesn't check parent directories for `yo-rc.json`

Open juliankrieger opened this issue 3 years ago • 4 comments

Type of issue: Bug

My environment

  • OS version/details: MacOs 11.13
  • Node version: 14.16.1 (run node --version in your terminal)
  • npm version: 6.14.12 (run npm --version in your terminal)
  • Version of yo : 4.0.0 (run yo --version in your terminal)

Expected behavior

Yo correctly determines tmp (or whatever folder it was first run in) as the project root, and places files correctly even when run from a subdirectory. The subdirectory is not mistakenly marked as a new project root, the subdirectory does not mistakenly include a yo-rc.json itself.

Current behavior

  1. Instead of creating new files in tmp/files, the following file structure occurs
tmp
│   yo-rc.json    
└───files
│       │   <files here>
└───subdir
│   │   yo-rc.json
│   └───subfolder
│       │   <files here>

Steps to reproduce the behavior

  1. Set up simple project
  2. Create a "new" BaseGenerator, which all other generators extend from
  3. Write an initialise function as follows
_initialize() {
        const defaults: Config = {
          // Some defaults here
        }

        this.config.defaults(defaults)
    }
  1. In each Generator or Subgenerator, call _initialise in the initializing context. Generators create files either with this.destinationRoot or any configuration option in the config
  2. Setup Generator with npm link
  3. Create a directory, we'll call it tmp
  4. Run generator in tmp
  5. Observe it working as intended. Files are created in tmp/files. Config file yo-rc.json is created in tmp, marking project root
  6. Now, create a subdirectory, tmp/subdir
  7. Cd into subdir
  8. Run Generator again
  9. Observe wrong behaviour, as seen above

juliankrieger avatar Apr 28 '21 10:04 juliankrieger

This is the [email protected] behavior. While there are some use cases it may make sense, with workspaces it doesn't.

workspaces
│   yo-rc.json   (generator-workspaces)
└───packages
│   └───package1 (generator-node)
│       └   yo-rc.json
│   └───package2 (generator-node)
│       └   yo-rc.json

mshima avatar May 02 '21 04:05 mshima

@mshima Is there any way to get the intended behaviour? Otherwise, the whole deal with yo-rc.json doesn't seem to make sense to me, or the documentation about it is outdated

juliankrieger avatar May 03 '21 06:05 juliankrieger

Install and load 'find-up' package

Add at your constructor something like:

const rootPath = findUp.sync('.yo-rc.json', {
  cwd: this.destinationRoot()
});
if (rootPath) {
  this.destinationRoot(rootPath);
}

mshima avatar May 03 '21 21:05 mshima

I used the solution suggested by @mshima and found an incompleteness: the rootPath value at the end includes the '.yo-rc.json' filename. Consider removing it before passing rootPath to this.destinationRoot, or you will get an error on writing. Also keep in mind that since version 6.0.0 find-up uses ESM. The last CJS version of it is 5.0.0.

irvingmoar avatar Apr 29 '22 01:04 irvingmoar