Files
ComfyUI_frontend/browser_tests/utils/backupUtils.ts
Glary-Bot 3e56bc925f lint: enable oxlint func-style rule and convert function expressions
Enables eslint/func-style in oxlint with declaration mode to enforce
function declarations over function expressions and arrow expressions
assigned to variables. Vendored litegraph is excluded via override.

Converts existing function expressions and variable-initialized arrow
functions to function declarations across src/, browser_tests/, apps/,
packages/, and scripts/. Adjusts a handful of let-reassignable callback
placeholders, narrowed variable patterns, and typed widget constructors
to keep type safety intact.

Pre-existing type-aware oxlint errors (no-console, no-floating-promises,
no-explicit-any) are unchanged from main.
2026-05-20 05:44:45 +00:00

95 lines
2.7 KiB
TypeScript

import fs from 'fs-extra'
import path from 'path'
type PathParts = readonly [string, ...string[]]
function getBackupPath(originalPath: string): string {
return `${originalPath}.bak`
}
function resolvePathIfExists(pathParts: PathParts): string | null {
const resolvedPath = path.resolve(...pathParts)
if (!fs.pathExistsSync(resolvedPath)) {
console.warn(`Path not found: ${resolvedPath}`)
return null
}
return resolvedPath
}
function createScaffoldingCopy(srcDir: string, destDir: string) {
// Get all items (files and directories) in the source directory
const items = fs.readdirSync(srcDir, { withFileTypes: true })
for (const item of items) {
const srcPath = path.join(srcDir, item.name)
const destPath = path.join(destDir, item.name)
if (item.isDirectory()) {
// Create the corresponding directory in the destination
fs.ensureDirSync(destPath)
// Recursively copy the directory structure
createScaffoldingCopy(srcPath, destPath)
}
}
}
export function backupPath(
pathParts: PathParts,
{ renameAndReplaceWithScaffolding = false } = {}
) {
const originalPath = resolvePathIfExists(pathParts)
if (!originalPath) return
const backupPath = getBackupPath(originalPath)
try {
if (renameAndReplaceWithScaffolding) {
// Rename the original path and create scaffolding in its place
fs.moveSync(originalPath, backupPath)
createScaffoldingCopy(backupPath, originalPath)
} else {
// Create a copy of the original path
fs.copySync(originalPath, backupPath)
}
} catch (error) {
console.error(`Failed to backup ${originalPath} from ${backupPath}`, error)
}
}
function removeWithRetry(targetPath: string, retries = 3, delayMs = 500) {
for (let attempt = 1; attempt <= retries; attempt++) {
try {
fs.removeSync(targetPath)
return
} catch (error: unknown) {
const code = (error as NodeJS.ErrnoException).code
if ((code === 'EPERM' || code === 'EBUSY') && attempt < retries) {
console.warn(
`Retry ${attempt}/${retries}: ${code} removing ${targetPath}`
)
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, delayMs)
continue
}
throw error
}
}
}
export function restorePath(pathParts: PathParts) {
const originalPath = resolvePathIfExists(pathParts)
if (!originalPath) return
const backupPath = getBackupPath(originalPath)
if (!fs.pathExistsSync(backupPath)) return
try {
removeWithRetry(originalPath)
fs.moveSync(backupPath, originalPath)
} catch (error) {
console.warn(
`Could not fully restore ${originalPath} from ${backupPath}:`,
(error as NodeJS.ErrnoException).message
)
}
}