commitlint icon indicating copy to clipboard operation
commitlint copied to clipboard

commitlint does not find plugin when a relative path is provided

Open avinashbot opened this issue 5 years ago • 7 comments

Expected Behavior

Currently, it seems that plugins can only be resolved if they're an npm package inside of the node_modules folder (node resolution logic). If I try to load a plugin using a relative path, I get this error:

Error: Failed to load plugin ./plugins/my-custom-plugin.js: Cannot find module 'commitlint-plugin-./plugins/my-custom-plugin.js'

Relative paths are supported for the extends and parserPreset keys, so making this work would align that behavior with plugins too.

Current Behavior

I would love to be able to write this and just have it work.

{
  plugins: ['./dir/my-custom-plugin.js'],
  ...
}

Affected packages

  • [ ] cli
  • [x] core
  • [ ] prompt
  • [ ] config-angular

Possible Solution

Looking at how the parserPreset key is being loaded, it seems like it's just a matter of using resolveFrom before requireing the plugin.

Context

I basically want to have a small custom rule in a single file, but it seems like a hassle to either handle two separate packages or set up lerna or something.

Your Environment

Executable Version
commitlint --version 8.2.0
git --version git version 2.23.0
node --version v12.10.0

avinashbot avatar Feb 04 '20 16:02 avinashbot

Yes, this should work if we expect plugins to be used.

marionebl avatar Feb 06 '20 02:02 marionebl

As a workaround you can try passing down an absolute path, e.g.:

// commitlint.config.js
{
  plugins: [require.resolve('./dir/my-custom-plugin.js')],
}

marionebl avatar Feb 06 '20 02:02 marionebl

The absolute path doesn't work either, for the same reason (it's assuming that it's a module name and prepending commitlint-plugin- to the path):

Error: Failed to load plugin /home/avinash/test/commitlint/custom-plugin.js: Cannot find module 'commitlint-plugin-/home/avinash/test/commitlint/custom-plugin.js'

avinashbot avatar Feb 06 '20 10:02 avinashbot

Ah thanks for pointing this out. I think this creates two bodies of work for us:

  1. resolve from the current config file for plugin paths starting with ./
  2. do not prefix for paths starting with ./ or /

marionebl avatar Feb 06 '20 12:02 marionebl

I think I have run into this issue as well, albeit in different use case. I am building a tool to provide "conventional release" services to projects across company and most of them are not based on NPM.

So what I am doing is building a docker image to be used in CI.

package.json:

{
  "name": "conventional-release",
  "version": "0.0.0",
  "license": "MIT",
  "dependencies": {
    "semantic-release": "^17.0.4",
    "@semantic-release/git": "^9.0.0",
    "@semantic-release/changelog": "^5.0.1",
    "@semantic-release/gitlab": "^6.0.3",
    "conventional-changelog-conventionalcommits": "^4.2.3",
    "@commitlint/config-conventional": "^8.3.4",
    "@commitlint/cli": "^8.3.5"
  }
}

Dockerfile:

FROM docker:git

ENV NODE_VERSION 12.15.0
ENV YARN_VERSION 1.19.2

RUN apk add --no-cache nodejs npm yarn

WORKDIR /opt
ENV PATH="/opt/node_modules/.bin:${PATH}"

COPY package.json .
COPY yarn.lock .
RUN yarn --prod && \
    yarn autoclean --init && \
    yarn autoclean --force && \
    rm package.json yarn.lock .yarnclean

Now running this results in

$ npx commitlint --from=$CI_MERGE_REQUEST_TARGET_BRANCH_SHA
 /opt/node_modules/@commitlint/cli/lib/cli.js:124
 	throw err;
 	^
 Error: Cannot find module "@commitlint/config-conventional" from "/builds/dotnet-demo"
     at resolveId (/opt/node_modules/@commitlint/resolve-extends/lib/index.js:97:15)
     at resolveConfig (/opt/node_modules/@commitlint/resolve-extends/lib/index.js:80:24)
     at /opt/node_modules/@commitlint/resolve-extends/lib/index.js:37:24
     at Array.reduce (<anonymous>)
     at loadExtends (/opt/node_modules/@commitlint/resolve-extends/lib/index.js:35:38)
     at resolveExtends (/opt/node_modules/@commitlint/resolve-extends/lib/index.js:22:20)
     at Object.<anonymous> (/opt/node_modules/@commitlint/load/lib/index.js:65:44) {
   code: 'MODULE_NOT_FOUND'
 }

Note that semantic release modules work as expected.

mrmartan avatar Apr 06 '20 13:04 mrmartan

Ah thanks for pointing this out. I think this creates two bodies of work for us:

  1. resolve from the current config file for plugin paths starting with ./
  2. do not prefix for paths starting with ./ or /

thats not fully true, we should support also windows absolute paths eg. C:\DEV\....

armano2 avatar Jan 11 '21 23:01 armano2

Currently there is a way to load local plugins by simply require'ing it

// commitlint.config.js
{
  plugins: [require('./dir/my-custom-plugin.js')],
}

armano2 avatar Jan 16 '21 22:01 armano2