UNPKG

@baseplate-dev/sync

Version:

Library for syncing Baseplate descriptions

83 lines 3.53 kB
import { promises as fs } from 'node:fs'; import path from 'node:path'; /** * Checks if a directory is empty, optionally ignoring specified files. * * @param dirPath - Path to the directory to check * @param options - Options including ignoreFiles array * @param options.ignoreFiles - Array of file names to ignore when determining if directory is empty * @returns Promise that resolves to true if directory is empty (or only contains ignored files), false otherwise * * @example * // Check if directory is empty, ignoring .gitkeep files * const isEmpty = await isDirectoryEmpty('/path/to/dir', { ignoreFiles: ['.gitkeep'] }); */ export async function isDirectoryEmpty(dirPath, options = {}) { try { const files = await fs.readdir(dirPath); const { ignoreFiles = [] } = options; // Filter out ignored files const nonIgnoredFiles = files.filter((file) => !ignoreFiles.includes(file)); return nonIgnoredFiles.length === 0; } catch { return false; } } /** * Removes empty ancestor directories starting from the parent directories of the given file paths. * * A directory is considered "empty" if it contains no files, or only contains files that are * specified in the ignoreFiles option. Directories that only contain ignored files will be * removed along with their ignored files. * * The function traverses up the directory tree from each file path's parent directory, * removing empty directories until it encounters: * - A directory that contains non-ignored files * - The specified stop directory * - The filesystem root * * @param filePaths - Array of file paths whose parent directories should be checked for removal * @param stopAt - Directory path to stop at (this directory will not be removed) * @param options - Options including ignoreFiles array * @param options.ignoreFiles - Array of file names to ignore when determining if directory is empty * * @example * // Remove empty directories after deleting files, ignoring .gitkeep files * await removeEmptyAncestorDirectories( * ['/project/src/components/Button.tsx'], * '/project', * { ignoreFiles: ['.gitkeep'] } * ); */ export async function removeEmptyAncestorDirectories(filePaths, stopAt, options = {}) { // Get unique parent directories from the file paths const uniqueParentDirs = [ ...new Set(filePaths.map((filePath) => path.dirname(filePath))), ]; // Sort by path length in descending order to process deeper directories first const sortedParentDirs = uniqueParentDirs.sort((a, b) => b.length - a.length); // Process each directory for (const dir of sortedParentDirs) { let currentDir = dir; // Continue until we hit the stop directory or root while (currentDir !== stopAt && currentDir !== path.parse(currentDir).root) { try { if (await isDirectoryEmpty(currentDir, options)) { // Directory is empty (or only contains ignored files), remove it await fs.rm(currentDir, { recursive: true, force: true }); currentDir = path.dirname(currentDir); } else { // Directory contains non-ignored files, stop here break; } } catch { break; // Stop on any error (e.g., permissions, non-existent directory) } } } } //# sourceMappingURL=directories.js.map