Skip to content

Commit

Permalink
Fix copy on write for nested paths
Browse files Browse the repository at this point in the history
  • Loading branch information
lettertwo committed Aug 16, 2023
1 parent a4bf601 commit 4caeed3
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
13 changes: 11 additions & 2 deletions packages/core/fs/src/OverlayFS.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@ export class OverlayFS implements FileSystem {
return false;
}

async _copyPathForWrite(filePath: FilePath): Promise<FilePath> {
filePath = await this._normalizePath(filePath);
let dirPath = path.dirname(filePath);
if (this.existsSync(dirPath) && !this.writable.existsSync(dirPath)) {
await this.writable.mkdirp(dirPath);
}
return filePath;
}

_normalizePath(filePath: FilePath): FilePath {
return path.resolve(this.cwd(), filePath);
}
Expand All @@ -134,14 +143,14 @@ export class OverlayFS implements FileSystem {
contents: string | Buffer,
options: ?FileOptions,
): Promise<void> {
filePath = this._normalizePath(filePath);
filePath = await this._copyPathForWrite(filePath);
await this.writable.writeFile(filePath, contents, options);
this.deleted.delete(filePath);
}

async copyFile(source: FilePath, destination: FilePath): Promise<void> {
source = this._normalizePath(source);
destination = this._normalizePath(destination);
destination = await this._copyPathForWrite(destination);

if (await this.writable.exists(source)) {
await this.writable.writeFile(
Expand Down
38 changes: 38 additions & 0 deletions packages/core/fs/test/OverlayFS.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,44 @@ describe('OverlayFS', () => {
assert.equal(underlayFS.readFileSync('foo', 'utf8'), 'foo');
});

it('copies on write with dir', async () => {
await fsFixture(underlayFS)`
foo/foo: foo
`;

assert.equal(fs.readFileSync('foo/foo', 'utf8'), 'foo');

await fs.writeFile('foo/bar', 'bar');

assert.equal(fs.readFileSync('foo/bar', 'utf8'), 'bar');
assert(!underlayFS.existsSync('foo/bar'));
});

it('copies on write when copying', async () => {
await fsFixture(underlayFS)`
foo: foo
`;

assert.equal(fs.readFileSync('foo', 'utf8'), 'foo');

await fs.copyFile('foo', 'bar');
assert.equal(fs.readFileSync('bar', 'utf8'), 'foo');
assert(!underlayFS.existsSync('bar'));
});

it('copies on write when copying with dir', async () => {
await fsFixture(underlayFS)`
foo/foo: foo
bar
`;

assert.equal(fs.readFileSync('foo/foo', 'utf8'), 'foo');

await fs.copyFile('foo/foo', 'bar/bar');
assert.equal(fs.readFileSync('bar/bar', 'utf8'), 'foo');
assert(!underlayFS.existsSync('bar/bar'));
});

it('writes to memory', async () => {
await fs.writeFile('foo', 'foo');

Expand Down

0 comments on commit 4caeed3

Please sign in to comment.