-
-
Notifications
You must be signed in to change notification settings - Fork 101
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
feat: add --cache option to lint only changed files #1763
feat: add --cache option to lint only changed files #1763
Conversation
4d345a6
to
883240b
Compare
Wow, you have been busy! I was hoping to add a cache. I was thinking it would be a good idea to keep all cspell related files in the same directory:
|
In
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for adding this.
I think it will help a lot.
I think it is worth it to get this in with its current logic.
Note: the cache logic is not correct for a mono-repo style project (like this one) with nested cspell.json
files. In a future PR, it might be worth it to handle the case when a nested config file changes.
Oh, really, i did not get the idea that cspell supports nested configs. |
I'm looking forward to getting this in. I you would like, we can do it in two steps.
|
f59b7d2
to
a64657e
Compare
I've removed Could you review this again please? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for getting this done!
})); | ||
|
||
const mockReadFileInfo = jest.spyOn(fileHelper, 'readFileInfo'); | ||
jest.mock('../../fileHelper', () => ({ readFileInfo: jest.fn() })); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: It is also possible to use the spy
// jest.mock('../../fileHelper', () => ({ readFileInfo: jest.fn() }));
mockReadFileInfo.mockImplementation(jest.fn());
getConfigHash: jest.fn().mockReturnValue('TEST_CONFIG_HASH'), | ||
})); | ||
|
||
const mockCreateFileEntryCache = jest.spyOn(FileEntryCacheModule, 'create'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rule of thumb:
- Mock Module.
- Create Spy.
jest.mock('file-entry-cache');
const mockCreateFileEntryCache = jest.spyOn(FileEntryCacheModule, 'create');
mockCreateFileEntryCache.mockImplementation(
jest.fn().mockReturnValue({
getFileDescriptor: jest.fn(),
reconcile: jest.fn(),
})
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also worth reading:
mocked - Test helpers | ts-jest
|
||
beforeEach(() => { | ||
diskCache = new DiskCache('.foobar', false); | ||
fileEntryCache = mockCreateFileEntryCache.mock.results[0].value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fileEntryCache = mockCreateFileEntryCache.mock.results[0].value;
Accessing the mock like this is fragile because it depends upon Jest's implementation.
By flipping the spy logic and injecting a known cache entry, it will make things more reliable.
const fileEntryCache = {
getFileDescriptor: jest.fn(),
reconcile: jest.fn(),
};
beforeEach(() => {
diskCache = new DiskCache('.foobar', false);
mockCreateFileEntryCache.mockImplementation(jest.fn().mockReturnValue(fileEntryCache));
});
|
||
public async getCachedLintResults(filename: string, configInfo: ConfigInfo): Promise<FileResult | undefined> { | ||
const fileDescriptor = this.fileEntryCache.getFileDescriptor(filename); | ||
const meta = fileDescriptor.meta as CSpellCacheMeta; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Watch out for the cast. It removed the undefined
from the type.
meta
can be undefined, but it is not getting checked.
const meta = fileDescriptor.meta as CSpellCacheMeta | undefined;
or
type CSpellCacheMeta =
| (FileDescriptor['meta'] & {
result: CachedFileResult;
configHash: string;
})
| undefined;
return; | ||
} | ||
|
||
const meta = fileDescriptor.meta as CSpellCacheMeta; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above. meta
can be undefined.
jest.mock('./hash', () => ({ | ||
hash: jest.fn().mockReturnValue('TEST_HASH'), | ||
})); | ||
jest.mock('../../../package.json', () => ({ version: '0.0.0' })); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading the package.json
is also an option to ensure the version is correct.
// eslint-disable-next-line @typescript-eslint/no-var-requires
const packageVersion = require('../../../package.json').version;
// ...
expect(mockHash.mock.calls[0][0]).toContain(packageVersion);
Thank you very much! The suggestions I made can come in later PRs. |
Hi!
This PR adds three new cli options:
--cache
that enables caching lint results on disk--cache-location <path>
that sets cache file location--cache-strategy <metadata|content>
that sets cache strategy used by file-entry-cacheCache implementation is heavily inspired by ESLint https://github.com/eslint/eslint/blob/c981fb1994cd04914042ced1980aa86b68ba7be9/lib/cli-engine/lint-result-cache.js