commitizen / cz-cli

The commitizen command line utility. #BlackLivesMatter
http://commitizen.github.io/cz-cli/
MIT License
16.89k stars 552 forks source link

Unable to execute commitizen from within nested directory inside the repository #742

Open castarco opened 4 years ago

castarco commented 4 years ago

In my setup, the git repository is placed in /home/user/Code/namespace/prj-name/, but all the CI/CD code is placed in /home/user/Code/namespace/prj-name/cx (in part, because it is not a JS project, and I want to "simplify" the directories/files structure at the root of the project).

Before that, I had everything in the project root, and it was running fine, but I'm in the middle of a refactoring process for the build system, hence the change.

Husky seems to adapt pretty well to this setup (I even checked the generated shell scripts inside .git/hooks, and it takes care of changing directory before running the hooks).

But... commitizen fails to do the same, and it insists on trying to load the modules from the "root" of the project, even if I set the $NODE_PATH environment variable to point the /home/user/Code/namespace/prj-name/cx directory (where $PWD points too, due to how Husky works).

Here you can see the error message, sadly it does not show the involved line numbers, and I couldn't follow the "jump" from dist/commitizen.js to dist/commitizen/adapter.js:

> @namespace/prj-name@0.0.1 git-cz /home/user/Code/namespace/prj-name/cx
> git-cz "--hook"

Could not resolve /home/user/Code/namespace/prj-name/node_modules/cz-conventional-changelog. Cannot find module '/home/user/Code/namespace/prj-name/node_modules/cz-conventional-changelog'
Require stack:
- /home/user/Code/namespace/prj-name/cx/node_modules/commitizen/dist/commitizen/adapter.js
- /home/user/Code/namespace/prj-name/cx/node_modules/commitizen/dist/commitizen.js
- /home/user/Code/namespace/prj-name/cx/node_modules/commitizen/dist/cli/git-cz.js
- /home/user/Code/namespace/prj-name/cx/node_modules/commitizen/bin/git-cz.js
- /home/user/Code/namespace/prj-name/cx/node_modules/commitizen/bin/git-cz

Here a simplified version of my package.json file (also in the cx directory):

{
  "name": "@namespace/prj-name",
  "version": "0.0.1",
  "description": "Project Name",
  "scripts": {
    "commitlint": "commitlint",
    "git-cz": "git-cz"
  },
  "dependencies": {
    "@commitlint/cli": "^8.3.5",
    "@commitlint/config-conventional": "^8.3.4",
    "commitizen": "^4.1.2",
    "cz-conventional-changelog": "^3.2.0",
    "husky": "^4.2.5"
  },
  "commitlint": {
    "extends": [
      "@commitlint/config-conventional"
    ],
    "rules": {
      "header-min-length": [2, "always", 8],
      "header-max-length": [2, "always", 72],
      "subject-min-length": [2, "always", 3],
      "subject-max-length": [2, "always", 50],
      "body-max-line-length": [2, "always", 80]
    }
  },
  "config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  },
  "husky": {
    "hooks": {
      "prepare-commit-msg": "exec < /dev/tty && npm run git-cz -- --hook || true",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  }
}

Is there any configuration option (or environment variable) I can use to tell commitizen how to behave?

Thanks for your attention.

castarco commented 4 years ago

I found the solution, I had to change the config entry in the package.json file (notice how I explicitly specify the cx directory):

{
  "config": {
    "commitizen": {
      "path": "cx/node_modules/cz-conventional-changelog"
    }
  }
}
castarco commented 4 years ago

Well, it seems I was too optimistic, there are still some "minor" problems:

(node:429371) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open '/home/user/Code/namespace/prj-name/cx/.git/COMMIT_EDITMSG'
    at openSync (fs.js:461:3)
    at commit (/home/user/Code/namespace/prj-name/cx/node_modules/commitizen/dist/git/commit.js:844:62)
    at dispatchGitCommit (/home/user/Code/namespace/prj-name/cx/node_modules/commitizen/dist/commitizen/commit.js:549:19)
    at /home/user/Code/namespace/prj-name/cx/node_modules/commitizen/dist/commitizen/commit.js:630:11
    at /home/user/Code/namespace/prj-name/cx/node_modules/cz-conventional-changelog/engine.js:217:9

The problem can be a little bit confusing, because the wizard works nicely... until the git editor is opened, and then you realize that the message is empty.

castarco commented 4 years ago

For now I'm applying a workaround, although it seems pretty nasty to me (basically I create a temporary symbolic link to the .git directory, and I also revert the change I made to the config.commitizen.path field):

{
  "config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  },
  "husky": {
    "hooks": {
      "prepare-commit-msg": "ln -fs ../.git ./.git && exec < /dev/tty && npm run git-cz -- --hook || true && unlink ./.git",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  }
}
jedwards1211 commented 4 years ago

even "path": "./node_modules/cz-conventional-changelog" doesn't work for me, cz still fails to resolve it even though it's installed in devDependencies argh. nevermind, I was missing an n in conventional 💩 😅