Skip to content

Commit

Permalink
Recursively create directories and files (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulshryock committed Oct 1, 2023
1 parent c878694 commit 6f47de1
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 15 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Rewrite LocalFileSystem.copy with standard library.

### Deprecated

### Removed

- Uninstall fs-extra.

### Fixed

### Security
Expand Down
31 changes: 22 additions & 9 deletions src/FileSystem/LocalFileSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
FileOrDirectoryNotFound,
} from './FileSystemException.ts'
import { dirname, join, parse } from 'node:path'
import { copy } from 'fs-extra'
import { FileSystem } from './FileSystem.ts'
import { Stringable } from '../Stringable/Stringable.ts'

Expand All @@ -33,7 +32,7 @@ export class LocalFileSystem implements FileSystem {
* @since 0.1.1
*/
private ACTIONS = {
copy: { directory: copy, file: copyFile },
copy: { file: copyFile },
move: { directory: rename, file: rename },
}

Expand Down Expand Up @@ -154,12 +153,11 @@ export class LocalFileSystem implements FileSystem {

for (const item of await readdir(path)) {
const itemPath = join(path, item)
const stats = await stat(itemPath)

if ((await stat(itemPath)).isDirectory()) {
if (stats.isDirectory())
filePaths.push(...(await this.readDirectoryRecursive(itemPath)))
} else {
filePaths.push(itemPath)
}
else filePaths.push(itemPath)
}

return filePaths
Expand Down Expand Up @@ -203,10 +201,7 @@ export class LocalFileSystem implements FileSystem {
* @param {string} dest Destination path.
* @return {Promise<void>}
* @throws {import('./FileSystemException.ts').FileSystemException}
* @see https://github.com/nodejs/node/issues/44598
* @since 0.1.1
* @todo Remove fs-extra and use fs.promises.cp when it stabilizes.
* @todo Maybe handle symlinks.
*/
public async copy(src: string, dest: string): Promise<void> {
await this.copyOrMove('copy', src, dest)
Expand Down Expand Up @@ -291,9 +286,27 @@ export class LocalFileSystem implements FileSystem {
: dest

await mkdir(dirname(destination), { recursive: true })

if (action === 'copy') return this.copyDirectory(src, destination)

await this.ACTIONS[action].directory(src, destination)
}

/**
* Recursively creates directories and files to copy a directory.
*
* @param {string} src Directory to copy.
* @param {string} dest Destination path to copy the directory to.
* @return {Promise<void>}
* @since unreleased
*/
private async copyDirectory(src: string, dest: string): Promise<void> {
for (const item of await this.readDirectory(src))
if (await this.isFile(`${src}/${item}`))
await this.copy(`${src}/${item}`, `${dest}/${item}`)
else await this.copyDirectory(`${src}/${item}`, `${dest}/${item}`)
}

/**
* Checks if a file or directory exists.
*
Expand Down
12 changes: 6 additions & 6 deletions tests/FileSystem/LocalFileSystem.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,18 +474,18 @@ describe('LocalFileSystem', () => {
})

describe('when dest does not exist', () => {
beforeEach(() => mockFs({ path: { to: { file: '' } } }))
beforeEach(() => mockFs({ long: { path: { to: { file: '' } } } }))

it('should copy the directory to the new location', async () => {
const fs = new LocalFileSystem()

await fs.copy('path/to', 'new/path/to')
await fs.copy('long/path', 'new/long/path')

expect(await fs.exists('new/path/to')).toBe(true)
expect(await fs.isDirectory('new/path/to')).toBe(true)
expect(await fs.exists('new/long/path/to')).toBe(true)
expect(await fs.isDirectory('new/long/path/to')).toBe(true)

expect(await fs.exists('new/path/to')).toBe(true)
expect(await fs.isFile('new/path/to/file')).toBe(true)
expect(await fs.exists('new/long/path/to/file')).toBe(true)
expect(await fs.isFile('new/long/path/to/file')).toBe(true)
})
})
})
Expand Down

0 comments on commit 6f47de1

Please sign in to comment.