mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-10 21:07:48 +00:00
[fs-detectors] Add the writeFile function to DetectorFilesystem (#8536)
Adds a `writeFile` function to `DetectorFilesystem` that will be used to update the various file cache maps.
**Why is this needed?**
When detecting npm7+ monorepos, we identified a performance improvement where the service can inspect the `package-lock.json` file for workspaces, and reuse the package information for each workspace in framework-detection.
The pseudo code in `vercel/api` will look something like this
For a given lockfile
```json
{
...,
"packages": {
"": {
"name": "npm-workspaces",
"version": "1.0.0",
"license": "ISC",
"workspaces": {
"packages": [
"apps/*"
]
}
},
"apps/admin": {
"version": "0.1.0",
"dependencies": {
"next": "12.2.5",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"eslint": "8.23.0",
"eslint-config-next": "12.2.5"
}
},
...,
}
```
```ts
// for each projectPath we detect in package-lock.json
// switch the cwd of the fs to the project directory
const projectFs = fs.chdir(projectPath);
// gets the package info from the lockfile
const projectPackageInfo = lockFile.packages[projectPath];
// insert this content into fs cache
await projectFs.writeFile('package.json', projectPackageInfo)
// call detectFramework, which should now have a cached "package.json" file
const projectFramework = await detectFramework(projectFs);
```
### Related Issues
Related to https://linear.app/vercel/issue/HIT-57/monorepo-detection-api-prevent-rate-limits
### 📋 Checklist
<!--
Please keep your PR as a Draft until the checklist is complete
-->
#### Tests
- [x] The code changed/added as part of this PR has been covered with tests
- [x] All tests pass locally with `yarn test-unit`
#### Code Review
- [x] This PR has a concise title and thorough description useful to a reviewer
- [x] Issue from task tracker has a link to this PR
This commit is contained in:
@@ -173,6 +173,24 @@ describe('DetectorFilesystem', () => {
|
||||
expect(hasPathSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should be able to write files', async () => {
|
||||
const files = {};
|
||||
const fs = new VirtualFilesystem(files);
|
||||
const hasPathSpy = jest.spyOn(fs, '_hasPath');
|
||||
const isFileSpy = jest.spyOn(fs, '_isFile');
|
||||
const readFileSpy = jest.spyOn(fs, '_readFile');
|
||||
|
||||
await fs.writeFile('file.txt', 'Hello World');
|
||||
|
||||
expect(await fs.readFile('file.txt')).toEqual(Buffer.from('Hello World'));
|
||||
expect(await fs.hasPath('file.txt')).toBe(true);
|
||||
expect(await fs.isFile('file.txt')).toBe(true);
|
||||
// We expect that the fs returned values from it's caches instead of calling the underlying functions
|
||||
expect(hasPathSpy).not.toHaveBeenCalled();
|
||||
expect(isFileSpy).not.toHaveBeenCalled();
|
||||
expect(readFileSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should be able to change directories', async () => {
|
||||
const nextPackageJson = JSON.stringify({
|
||||
dependencies: {
|
||||
|
||||
Reference in New Issue
Block a user