Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File matching to determine generated tsconfig does not take relative directories into account #661

Closed
mcous opened this issue Apr 28, 2022 · 0 comments · Fixed by #677
Closed

Comments

@mcous
Copy link

mcous commented Apr 28, 2022

Overview

xo attempts to check if a given file that it's linting matches a tsconfig.json passed into parserOptions.project. If the file being checked does not match the tsconfig (according to minimatch), a temporary tsconfig will be created.

xo/lib/options-manager.js

Lines 178 to 181 in 352f20c

const hasMatch = options.tsConfig && !options.tsConfig.include && !options.tsConfig.files ? true : micromatch.contains(options.filePath, [
...(options.tsConfig && Array.isArray(options.tsConfig.include) ? options.tsConfig.include : []),
...(options.tsConfig && Array.isArray(options.tsConfig.files) ? options.tsConfig.files : []),
]);

However, options.filePath here is an absolute filepath, and the includes glob of a given tsconfig.json may be specified as a relative path from the config file itself. If the tsconfig in question is not in the current working directory, this check will erroneously fail.

I noticed this issue due to xojs/vscode-linter-xo#110. I thought I had given xo a good parserOptions.project path, but xo and the vscode-linter-xo started generating competing (and different!) temporary tsconfigs in the cache, eventually causing the editor extension to start choking on parser errors.

Reproduction

Project structure

- my-project/
    - package.json 
    - config/
        - tsconfig.lint.json
    - src/
        - some-file.ts

tsconfig.lint.json

{
  ...
  "include": ["../src/**/*"]
}

Behavior

/path/to/my-project/src/some-file.ts does not match the glob ../src/**/*, so a temporary tsconfig is created in node_modules/.cache/xo-linter, even though tsc would recognize the config as matching that file.

{
  "extends": "/path/to/my-project/config/tsconfig.lint.json",
  "files": ["/path/to/my-project/src/some-file.ts"],
  "include": [],
  "exclude": []
}

Proposal

Before passing options.filePath to micromatch, I think it should be made relative to options.tsConfigPath if it exists. If this is an acceptable solution, I'm happy open a PR!

micromatch.contains("/path/to/my-project/src/some-file.ts", ["src/**/*"])
> true
micromatch.contains("/path/to/my-project/src/some-file.ts", ["../src/**/*"])
> false
micromatch.contains("../src/some-file.ts", ["../src/**/*"])
> true

Workaround

This issue is pretty straightforward to workaround by placing the tsconfig given to parserOptions.project in the project root rather than a subdirectory, so that a glob like src/**/* will match an absolute path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant