Skip to content

Commit a7bb71f

Browse files
authored
(ref): extracted common functions from backup lib (#48)
1 parent fe94015 commit a7bb71f

File tree

3 files changed

+47
-35
lines changed

3 files changed

+47
-35
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1010
},
1111
"scripts": {
12-
"start": "NODE_ENV=dev tsc && node dist/app.js restore --ref 1bc41083-afd2-4b5e-8270-5e475844ba50 --dest ./dev/restore",
12+
"start": "NODE_ENV=dev tsc && node dist/app.js restore --ref 7203e58c-2e31-40f1-b6db-fd48cf98ca05 --dest ./dev/restore2",
1313
"build": "NODE_ENV=production tsc",
1414
"lint": "NODE_ENV=test eslint \"{src,libs,test}/**/*.ts\" --fix",
1515
"test": "echo \"WARN: no test specified\" && exit 0"

src/common/functions.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import figlet from 'figlet'
2+
import { MakeDirectoryOptions } from 'fs'
3+
import { pathExists } from 'fs-extra'
4+
import { chown, readdir, mkdir } from 'fs/promises'
25
import { userInfo } from 'os'
6+
import { join } from 'path/posix'
7+
import { log } from '../lib/logger.js'
38
import { PACKAGE_NAME } from './constants.js'
49
import { BackupRecord, Directory } from './types.js'
510

@@ -45,3 +50,37 @@ export function compareByDepth(dirA: Directory, dirB: Directory): number {
4550
if (dirA.depth > dirB.depth) return 1
4651
return 0
4752
}
53+
54+
// Create a directory with optional permissions modes
55+
export async function createDirectory(
56+
rootPath: string,
57+
directoryName: string,
58+
options: MakeDirectoryOptions = { mode: '0755' },
59+
ownership?: { uid: number; gid: number }
60+
): Promise<[string, Error]> {
61+
try {
62+
const fullPath = join(rootPath, directoryName)
63+
if (!await pathExists(fullPath)) {
64+
await mkdir(fullPath, { recursive: false, ...options })
65+
66+
// Append ownership information to directory
67+
if (ownership) await chown(fullPath, ownership.uid, ownership.gid)
68+
return [ fullPath, null ]
69+
} else {
70+
log(`Directory already exists ... skipping create.`)
71+
return [ fullPath, null ]
72+
}
73+
} catch (err) {
74+
if (!err.message.includes('EPERM')) {
75+
log(`ERROR creating directory: ${err}`)
76+
return [ null, err ]
77+
}
78+
}
79+
}
80+
81+
// Check whether a given directory is empty or not
82+
export async function isDirEmpty(path: string): Promise<boolean> {
83+
return readdir(path).then((files) => {
84+
return files.length === 0
85+
})
86+
}

src/lib/backup.ts

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { mkdir, lstat, readdir, chown } from 'fs/promises'
1+
import { lstat, readdir } from 'fs/promises'
22
import { join, sep } from 'path/posix'
3-
import { copy, pathExists } from 'fs-extra'
3+
import { copy } from 'fs-extra'
44
import { BackupRecord, BackupType, Directory, FileData, RecordTable } from '../common/types.js'
55
import { v4 as uuid } from 'uuid'
66
import {
@@ -10,10 +10,9 @@ import {
1010
IOException
1111
} from '../common/exceptions.js'
1212
import { DatabaseManager } from './database.js'
13-
import { log } from './logger.js'
1413
import { createHash } from 'crypto'
15-
import { createReadStream, MakeDirectoryOptions, ReadStream } from 'fs'
16-
import { compareByDepth } from '../common/functions.js'
14+
import { createReadStream, ReadStream } from 'fs'
15+
import { compareByDepth, createDirectory } from '../common/functions.js'
1716

1817
export class BackupManager {
1918
private static instance: BackupManager
@@ -32,32 +31,6 @@ export class BackupManager {
3231
return BackupManager.instance
3332
}
3433

35-
private async _createDirectory(
36-
rootPath: string,
37-
directoryName: string,
38-
options: MakeDirectoryOptions = { mode: '0755' },
39-
ownership?: { uid: number; gid: number }
40-
): Promise<[string, Error]> {
41-
try {
42-
const fullPath = join(rootPath, directoryName)
43-
if (!await pathExists(fullPath)) {
44-
await mkdir(fullPath, { recursive: false, ...options })
45-
46-
// Append ownership information to directory
47-
if (ownership) await chown(fullPath, ownership.uid, ownership.gid)
48-
return [ fullPath, null ]
49-
} else {
50-
log(`Directory already exists ... skipping create.`)
51-
return [ fullPath, null ]
52-
}
53-
} catch (err) {
54-
if (!err.message.includes('EPERM')) {
55-
log(`ERROR creating directory: ${err}`)
56-
return [ null, err ]
57-
}
58-
}
59-
}
60-
6134
public clearBuffers(): void {
6235
this.filesBuffer = []
6336
this.directoriesBuffer = []
@@ -296,7 +269,7 @@ export class BackupManager {
296269

297270
// Append the operation to the queue
298271
processQueue.push(
299-
this._createDirectory(
272+
createDirectory(
300273
destRoot,
301274
d.path.split(sourceRoot)[1],
302275
{ mode: d.mode || '0755' },
@@ -351,7 +324,7 @@ export class BackupManager {
351324
}
352325

353326
// Make the backup directory && Copy all changed files (maintaining path and timestamps)
354-
const [ _, createErr ] = await this._createDirectory(destination, generatedBackupName)
327+
const [ _, createErr ] = await createDirectory(destination, generatedBackupName)
355328
if (createErr) {
356329
throw new IOException(`Could not create the backup directory. Aborting... (${createErr.message})`)
357330
}
@@ -418,7 +391,7 @@ export class BackupManager {
418391
}
419392

420393
// Create the FULL backup
421-
const [ _, createErr ] = await this._createDirectory(destination, generatedBackupName)
394+
const [ _, createErr ] = await createDirectory(destination, generatedBackupName)
422395
if (createErr) {
423396
throw new IOException(`Could not create the backup directory. Aborting... (${createErr.message})`)
424397
}

0 commit comments

Comments
 (0)