Skip to content

Commit 0644c26

Browse files
authored
Remove fs-extra usage (#1107)
1 parent 65dd4c9 commit 0644c26

42 files changed

Lines changed: 241 additions & 244 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Remove fs-extra usage",
4+
"packageName": "beachball",
5+
"email": "elcraig@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
"dependencies": {
5252
"cosmiconfig": "^9.0.0",
5353
"execa": "^5.0.0",
54-
"fs-extra": "^11.1.1",
5554
"minimatch": "^3.0.4",
5655
"p-graph": "^1.1.2",
5756
"p-limit": "^3.0.2",
@@ -63,7 +62,6 @@
6362
},
6463
"devDependencies": {
6564
"@jest/globals": "^29.0.0",
66-
"@types/fs-extra": "^11.0.0",
6765
"@types/minimatch": "^5.0.0",
6866
"@types/node": "^14.0.0",
6967
"@types/prompts": "^2.4.2",
@@ -77,7 +75,6 @@
7775
"eslint": "^8.0.0",
7876
"eslint-config-prettier": "^10.1.8",
7977
"eslint-plugin-etc": "^2.0.3",
80-
"find-free-port": "^2.0.0",
8178
"get-port": "^5.0.0",
8279
"husky": "^8.0.0",
8380
"jest": "^29.0.0",

src/__e2e__/bump.test.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { describe, expect, it, afterEach, jest } from '@jest/globals';
2-
import fs from 'fs-extra';
32
import path from 'path';
43
import { generateChangeFiles, getChangeFiles } from '../__fixtures__/changeFiles';
54
import { readChangelogJson } from '../__fixtures__/changelog';
@@ -12,6 +11,7 @@ import type { Repository } from '../__fixtures__/repository';
1211
import type { PackageJson } from '../types/PackageInfo';
1312
import { getParsedOptions } from '../options/getOptions';
1413
import { defaultRemoteBranchName } from '../__fixtures__/gitDefaults';
14+
import { readJson } from '../object/readJson';
1515

1616
describe('version bumping', () => {
1717
let repositoryFactory: RepositoryFactory | undefined;
@@ -746,7 +746,7 @@ describe('version bumping', () => {
746746
expect(version).toBe('1.1.0');
747747

748748
const jsonPath = path.join(packagePath, 'package.json');
749-
expect((fs.readJSONSync(jsonPath) as PackageJson).version).toBe('1.0.0');
749+
expect(readJson<PackageJson>(jsonPath).version).toBe('1.0.0');
750750
}),
751751
},
752752
});
@@ -776,7 +776,8 @@ describe('version bumping', () => {
776776
expect(version).toBe('1.1.0');
777777

778778
const jsonPath = path.join(packagePath, 'package.json');
779-
expect(((await fs.readJSON(jsonPath)) as PackageJson).version).toBe('1.0.0');
779+
await new Promise(resolve => setTimeout(resolve, 0)); // simulate async work
780+
expect(readJson<PackageJson>(jsonPath).version).toBe('1.0.0');
780781
}),
781782
},
782783
});
@@ -830,7 +831,7 @@ describe('version bumping', () => {
830831
expect(version).toBe('1.1.0');
831832

832833
const jsonPath = path.join(packagePath, 'package.json');
833-
expect((fs.readJSONSync(jsonPath) as PackageJson).version).toBe('1.1.0');
834+
expect(readJson<PackageJson>(jsonPath).version).toBe('1.1.0');
834835
}),
835836
},
836837
});
@@ -860,7 +861,8 @@ describe('version bumping', () => {
860861
expect(version).toBe('1.1.0');
861862

862863
const jsonPath = path.join(packagePath, 'package.json');
863-
expect(((await fs.readJSON(jsonPath)) as PackageJson).version).toBe('1.1.0');
864+
await new Promise(resolve => setTimeout(resolve, 0)); // simulate async work
865+
expect(readJson<PackageJson>(jsonPath).version).toBe('1.1.0');
864866
}),
865867
},
866868
});

src/__e2e__/change.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { describe, expect, it, afterEach, jest, beforeEach } from '@jest/globals';
2-
import fs from 'fs-extra';
32
import type prompts from 'prompts';
43
import { getChangeFiles } from '../__fixtures__/changeFiles';
54
import { initMockLogs } from '../__fixtures__/mockLogs';
@@ -13,6 +12,7 @@ import type { ChangeFileInfo, ChangeInfoMultiple } from '../types/ChangeInfo';
1312
import type { Repository } from '../__fixtures__/repository';
1413
import { getParsedOptions } from '../options/getOptions';
1514
import { getPackageInfos } from '../monorepo/getPackageInfos';
15+
import { readJson } from '../object/readJson';
1616

1717
// prompts writes to stdout (not console) in a way that can't really be mocked with spies,
1818
// so instead we inject a custom mock stdout stream, as well as stdin for entering answers
@@ -128,7 +128,7 @@ describe('change command', () => {
128128

129129
const changeFiles = getChangeFiles(options);
130130
expect(changeFiles).toHaveLength(1);
131-
expect(fs.readJSONSync(changeFiles[0])).toMatchObject({
131+
expect(readJson(changeFiles[0])).toMatchObject({
132132
comment: 'stage me please',
133133
packageName: 'foo',
134134
type: 'patch',
@@ -155,7 +155,7 @@ describe('change command', () => {
155155

156156
const changeFiles = getChangeFiles(options);
157157
expect(changeFiles).toHaveLength(1);
158-
expect(fs.readJSONSync(changeFiles[0])).toMatchObject({
158+
expect(readJson(changeFiles[0])).toMatchObject({
159159
comment: 'commit me please',
160160
packageName: 'foo',
161161
type: 'patch',
@@ -186,7 +186,7 @@ describe('change command', () => {
186186

187187
const changeFiles = getChangeFiles(options);
188188
expect(changeFiles).toHaveLength(1);
189-
expect(fs.readJSONSync(changeFiles[0])).toMatchObject({
189+
expect(readJson(changeFiles[0])).toMatchObject({
190190
comment: 'commit me please',
191191
packageName: 'foo',
192192
type: 'patch',
@@ -247,7 +247,7 @@ describe('change command', () => {
247247

248248
const changeFiles = getChangeFiles(options);
249249
expect(changeFiles).toHaveLength(2);
250-
const changeFileContents = changeFiles.map(changeFile => fs.readJSONSync(changeFile) as ChangeFileInfo);
250+
const changeFileContents = changeFiles.map(changeFile => readJson<ChangeFileInfo>(changeFile));
251251
expect(changeFileContents).toContainEqual(
252252
expect.objectContaining({ comment: 'custom', packageName: 'pkg-1', type: 'minor' })
253253
);
@@ -283,7 +283,7 @@ describe('change command', () => {
283283

284284
const changeFiles = getChangeFiles(options);
285285
expect(changeFiles).toHaveLength(1);
286-
const contents = fs.readJSONSync(changeFiles[0]) as ChangeInfoMultiple;
286+
const contents = readJson<ChangeInfoMultiple>(changeFiles[0]);
287287
expect(contents.changes).toEqual([
288288
expect.objectContaining({ comment: 'custom', packageName: 'pkg-1', type: 'minor' }),
289289
expect.objectContaining({ comment: 'commit 2', packageName: 'pkg-2', type: 'patch' }),
@@ -330,7 +330,7 @@ describe('change command', () => {
330330

331331
const changeFiles = getChangeFiles(options);
332332
expect(changeFiles).toHaveLength(1);
333-
const contents = fs.readJSONSync(changeFiles[0]) as ChangeInfoMultiple;
333+
const contents = readJson<ChangeInfoMultiple>(changeFiles[0]);
334334
expect(contents.changes).toEqual([
335335
expect.objectContaining({ packageName: 'pkg-1', type: 'patch', comment: 'commit 2' }),
336336
expect.objectContaining({ packageName: 'pkg-2', type: 'patch', comment: 'commit 2', custom: 'stuff' }),

src/__e2e__/publishE2E.test.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, expect, it, afterEach, jest } from '@jest/globals';
2-
import fs from 'fs-extra';
2+
import fs from 'fs';
33
import path from 'path';
44
import { addGitObserver, clearGitObservers } from 'workspace-tools';
55
import { generateChangeFiles } from '../__fixtures__/changeFiles';
@@ -15,6 +15,7 @@ import type { PackageJson } from '../types/PackageInfo';
1515
import { getParsedOptions } from '../options/getOptions';
1616
import { getPackageInfos } from '../monorepo/getPackageInfos';
1717
import { validate } from '../validation/validate';
18+
import { readJson } from '../object/readJson';
1819

1920
// Spawning actual npm to run commands against a fake registry is extremely slow, so mock it for
2021
// this test (packagePublish covers the more complete npm registry scenario).
@@ -172,7 +173,7 @@ describe('publish command (e2e)', () => {
172173
const anotherRepo = repositoryFactory!.cloneRepository();
173174
// inject a checkin
174175
const packageJsonFile = anotherRepo.pathTo('package.json');
175-
const contents = fs.readJSONSync(packageJsonFile, 'utf-8') as PackageJson;
176+
const contents = readJson<PackageJson>(packageJsonFile);
176177
delete contents.dependencies?.baz;
177178
anotherRepo.commitChange('package.json', JSON.stringify(contents, null, 2));
178179
anotherRepo.push();
@@ -374,7 +375,7 @@ describe('publish command (e2e)', () => {
374375
hooks: {
375376
prepublish: (packagePath: string) => {
376377
const packageJsonPath = path.join(packagePath, 'package.json');
377-
const packageJson = fs.readJSONSync(packageJsonPath) as ExtraPackageJson;
378+
const packageJson = readJson<ExtraPackageJson>(packageJsonPath);
378379
if (packageJson.onPublish) {
379380
Object.assign(packageJson, packageJson.onPublish);
380381
delete packageJson.onPublish;
@@ -400,7 +401,7 @@ describe('publish command (e2e)', () => {
400401

401402
// All git results should still have previous information
402403
expect(repo.getCurrentTags()).toEqual(['foo_v1.1.0']);
403-
const fooPackageJson = fs.readJSONSync(repo.pathTo('packages/foo/package.json')) as ExtraPackageJson;
404+
const fooPackageJson = readJson<ExtraPackageJson>(repo.pathTo('packages/foo/package.json'));
404405
expect(fooPackageJson.main).toBe('src/index.ts');
405406
expect(fooPackageJson.onPublish?.main).toBe('lib/index.js');
406407
});
@@ -416,7 +417,7 @@ describe('publish command (e2e)', () => {
416417
hooks: {
417418
postpublish: packagePath => {
418419
const packageJsonPath = path.join(packagePath, 'package.json');
419-
const packageJson = fs.readJSONSync(packageJsonPath) as ExtraPackageJson;
420+
const packageJson = readJson<ExtraPackageJson>(packageJsonPath);
420421
if (packageJson.afterPublish) {
421422
notified = packageJson.afterPublish.notify;
422423
}
@@ -429,7 +430,7 @@ describe('publish command (e2e)', () => {
429430

430431
await publish(options, packageInfos);
431432

432-
const fooPackageJson = fs.readJSONSync(repo.pathTo('packages/foo/package.json')) as ExtraPackageJson;
433+
const fooPackageJson = readJson<ExtraPackageJson>(repo.pathTo('packages/foo/package.json'));
433434
expect(fooPackageJson.main).toBe('src/index.ts');
434435
expect(notified).toBe(fooPackageJson.afterPublish?.notify);
435436
});
@@ -671,7 +672,7 @@ describe('publish command (e2e)', () => {
671672
await simulateWait(100);
672673
const packageName = path.basename(packagePath);
673674
const packageJsonPath = path.join(packagePath, 'package.json');
674-
const packageJson = fs.readJSONSync(packageJsonPath) as ExtraPackageJsonFixture;
675+
const packageJson = readJson<ExtraPackageJsonFixture>(packageJsonPath);
675676
if (packageJson.afterPublish) {
676677
afterPublishStrings.push({
677678
packageName,
@@ -693,7 +694,7 @@ describe('publish command (e2e)', () => {
693694
expect(maxConcurrency).toBe(concurrency);
694695

695696
for (const pkg of packagesToPublish) {
696-
const packageJson = fs.readJSONSync(repo.pathTo(`packages/${pkg}/package.json`)) as ExtraPackageJsonFixture;
697+
const packageJson = readJson<ExtraPackageJsonFixture>(repo.pathTo(`packages/${pkg}/package.json`));
697698
if (packageJson.afterPublish) {
698699
// Verify that all postpublish hooks were called
699700
expect(afterPublishStrings).toContainEqual({

src/__e2e__/publishGit.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { describe, expect, it, beforeEach, afterEach } from '@jest/globals';
2-
import fs from 'fs-extra';
32
import { defaultRemoteBranchName } from '../__fixtures__/gitDefaults';
43
import { generateChangeFiles, getChangeFiles } from '../__fixtures__/changeFiles';
54
import { initMockLogs } from '../__fixtures__/mockLogs';
@@ -12,6 +11,7 @@ import type { ChangeFileInfo } from '../types/ChangeInfo';
1211
import { getPackageInfos } from '../monorepo/getPackageInfos';
1312
import type { PackageJson } from '../types/PackageInfo';
1413
import { getParsedOptions } from '../options/getOptions';
14+
import { readJson } from '../object/readJson';
1515

1616
describe('publish command (git)', () => {
1717
let repositoryFactory: RepositoryFactory;
@@ -58,7 +58,7 @@ describe('publish command (git)', () => {
5858

5959
const newRepo = repositoryFactory.cloneRepository();
6060

61-
const packageJson = fs.readJSONSync(newRepo.pathTo('package.json')) as PackageJson;
61+
const packageJson = readJson<PackageJson>(newRepo.pathTo('package.json'));
6262

6363
expect(packageJson.version).toBe('1.1.0');
6464
});
@@ -88,7 +88,7 @@ describe('publish command (git)', () => {
8888
const newRepo = repositoryFactory.cloneRepository();
8989
const changeFiles = getChangeFiles({ ...options1, path: newRepo.rootPath });
9090
expect(changeFiles).toHaveLength(1);
91-
const changeFileContent = fs.readJSONSync(changeFiles[0]) as ChangeFileInfo;
91+
const changeFileContent = readJson<ChangeFileInfo>(changeFiles[0]);
9292
expect(changeFileContent.packageName).toBe('foo2');
9393
});
9494
});

src/__e2e__/syncE2E.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { describe, expect, it, afterEach, jest } from '@jest/globals';
2-
import fs from 'fs-extra';
32
import { defaultRemoteBranchName } from '../__fixtures__/gitDefaults';
43
import { initMockLogs } from '../__fixtures__/mockLogs';
54
import type { Repository } from '../__fixtures__/repository';
@@ -10,6 +9,7 @@ import type { packagePublish } from '../packageManager/packagePublish';
109
import type { RepoOptions } from '../types/BeachballOptions';
1110
import { initNpmMock } from '../__fixtures__/mockNpm';
1211
import { getParsedOptions } from '../options/getOptions';
12+
import { removeTempDir } from '../__fixtures__/tmpdir';
1313

1414
// Spawning actual npm to run commands against a fake registry is extremely slow, so mock it for
1515
// this test (packagePublish covers the more complete npm registry scenario).
@@ -59,7 +59,7 @@ describe('sync command (e2e)', () => {
5959
repositoryFactory.cleanUp();
6060
repositoryFactory = undefined;
6161
}
62-
tempDirs.forEach(dir => fs.removeSync(dir));
62+
tempDirs.forEach(dir => removeTempDir(dir));
6363
tempDirs.splice(0, tempDirs.length);
6464
});
6565

src/__fixtures__/changelog.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import fs from 'fs-extra';
1+
import fs from 'fs';
22
import path from 'path';
33
import type { ChangelogJson } from '../types/ChangeLog';
44
import { markerComment } from '../changelog/renderChangelog';
5+
import { readJson } from '../object/readJson';
56

67
/** Placeholder commit as replaced by cleanChangelogJson */
78
export const fakeCommit = '(sha1)';
@@ -38,7 +39,7 @@ export function readChangelogJson(packagePath: string, filename?: string, noClea
3839
return null;
3940
}
4041

41-
const changelog = fs.readJSONSync(changelogJsonFile, { encoding: 'utf-8' }) as ChangelogJson;
42+
const changelog = readJson<ChangelogJson>(changelogJsonFile);
4243
if (noClean) {
4344
return changelog;
4445
}

src/__fixtures__/createTestFileStructure.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import fs from 'fs-extra';
1+
import fs from 'fs';
22
import { tmpdir } from './tmpdir';
33
import path from 'path';
44

@@ -12,7 +12,7 @@ export function createTestFileStructure(files: Record<string, string | object>):
1212

1313
for (const [filename, content] of Object.entries(files)) {
1414
const filePath = path.join(testFolderPath, filename);
15-
fs.ensureDirSync(path.dirname(filePath));
15+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
1616
fs.writeFileSync(filePath, typeof content === 'string' ? content : JSON.stringify(content));
1717
}
1818

src/__fixtures__/mockNpm.test.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// dependency on actual npm CLI calls and a fake registry (which are very slow).
44

55
import { afterAll, afterEach, beforeAll, describe, expect, it, jest } from '@jest/globals';
6-
import fs from 'fs-extra';
6+
import fs from 'fs';
77
import { type NpmResult, npm } from '../packageManager/npm';
88
import type { PackageJson } from '../types/PackageInfo';
99
import {
@@ -14,8 +14,10 @@ import {
1414
_mockNpmShow,
1515
type MockNpmResult,
1616
} from './mockNpm';
17+
import * as readJsonModule from '../object/readJson';
1718

18-
jest.mock('fs-extra');
19+
jest.mock('fs');
20+
jest.mock('../object/readJson');
1921
jest.mock('../packageManager/npm');
2022

2123
describe('_makeRegistryData', () => {
@@ -193,10 +195,10 @@ describe('_mockNpmPublish', () => {
193195
let packageJson: PackageJson | undefined;
194196

195197
beforeAll(() => {
196-
(fs.readJsonSync as jest.MockedFunction<typeof fs.readJsonSync>).mockImplementation(() => {
198+
(readJsonModule.readJson as jest.MockedFunction<typeof readJsonModule.readJson>).mockImplementation((() => {
197199
if (!packageJson) throw new Error('packageJson not set');
198200
return packageJson;
199-
});
201+
}) as typeof readJsonModule.readJson);
200202
});
201203

202204
afterEach(() => {
@@ -289,10 +291,10 @@ describe('_mockNpmPack', () => {
289291
let writtenFiles: (fs.PathLike | number)[] = [];
290292

291293
beforeAll(() => {
292-
(fs.readJsonSync as jest.MockedFunction<typeof fs.readJsonSync>).mockImplementation(() => {
294+
(readJsonModule.readJson as jest.MockedFunction<typeof readJsonModule.readJson>).mockImplementation((() => {
293295
if (!packageJson) throw new Error('packageJson not set');
294296
return packageJson;
295-
});
297+
}) as typeof readJsonModule.readJson);
296298
(fs.writeFileSync as jest.MockedFunction<typeof fs.writeFileSync>).mockImplementation(filePath => {
297299
writtenFiles.push(String(filePath).replace(/\\/g, '/'));
298300
});
@@ -352,10 +354,10 @@ describe('mockNpm', () => {
352354
let packageJson: PackageJson | undefined;
353355

354356
beforeAll(() => {
355-
(fs.readJsonSync as jest.MockedFunction<typeof fs.readJsonSync>).mockImplementation(() => {
357+
(readJsonModule.readJson as jest.MockedFunction<typeof readJsonModule.readJson>).mockImplementation((() => {
356358
if (!packageJson) throw new Error('packageJson not set');
357359
return packageJson;
358-
});
360+
}) as typeof readJsonModule.readJson);
359361
});
360362

361363
afterEach(() => {

0 commit comments

Comments
 (0)