chore: improved clean commands which work on windows and output pretty summary (#6685)

This commit is contained in:
Alessio Gravili
2024-06-09 01:21:11 -04:00
committed by GitHub
parent ac34380eb8
commit 1bd91b23ca
2 changed files with 163 additions and 5 deletions

View File

@@ -9,6 +9,7 @@
"build:app": "next build", "build:app": "next build",
"build:app:analyze": "cross-env ANALYZE=true next build", "build:app:analyze": "cross-env ANALYZE=true next build",
"build:core": "turbo build --filter \"!@payloadcms/plugin-*\"", "build:core": "turbo build --filter \"!@payloadcms/plugin-*\"",
"build:core:force": "pnpm clean:build && turbo build --filter \"!@payloadcms/plugin-*\" --no-cache --force",
"build:create-payload-app": "turbo build --filter create-payload-app", "build:create-payload-app": "turbo build --filter create-payload-app",
"build:db-mongodb": "turbo build --filter db-mongodb", "build:db-mongodb": "turbo build --filter db-mongodb",
"build:db-postgres": "turbo build --filter db-postgres", "build:db-postgres": "turbo build --filter db-postgres",
@@ -42,21 +43,21 @@
"build:translations": "turbo build --filter translations", "build:translations": "turbo build --filter translations",
"build:ui": "turbo build --filter ui", "build:ui": "turbo build --filter ui",
"clean": "turbo clean", "clean": "turbo clean",
"clean:all": "find . \\( -type d \\( -name node_modules -o -name dist -o -name .cache -o -name .next -o -name .turbo \\) -o -type f -name tsconfig.tsbuildinfo \\) -exec rm -rf {} +", "clean:all": "node ./scripts/delete-recursively.js '@node_modules' 'media' '**/dist' '**/.cache' '**/.next' '**/.turbo' '**/tsconfig.tsbuildinfo' '**/payload*.tgz'",
"clean:build": "find . \\( -type d \\( -name dist -o -name .cache -o -name .next -o -name .turbo \\) -o -type f -name tsconfig.tsbuildinfo \\) -not -path '*/node_modules/*' -exec rm -rf {} +", "clean:build": "node ./scripts/delete-recursively.js 'media' '**/dist' '**/.cache' '**/.next' '**/.turbo' '**/tsconfig.tsbuildinfo' '**/payload*.tgz'",
"clean:cache": "rimraf node_modules/.cache && rimraf packages/payload/node_modules/.cache && rimraf .next", "clean:cache": "node ./scripts/delete-recursively.js node_modules/.cache! packages/payload/node_modules/.cache! .next",
"dev": "cross-env NODE_OPTIONS=--no-deprecation node ./test/dev.js", "dev": "cross-env NODE_OPTIONS=--no-deprecation node ./test/dev.js",
"dev:generate-graphql-schema": "cross-env NODE_OPTIONS=--no-deprecation tsx ./test/generateGraphQLSchema.ts", "dev:generate-graphql-schema": "cross-env NODE_OPTIONS=--no-deprecation tsx ./test/generateGraphQLSchema.ts",
"dev:generate-types": "cross-env NODE_OPTIONS=--no-deprecation tsx ./test/generateTypes.ts", "dev:generate-types": "cross-env NODE_OPTIONS=--no-deprecation tsx ./test/generateTypes.ts",
"dev:postgres": "cross-env NODE_OPTIONS=--no-deprecation PAYLOAD_DATABASE=postgres node ./test/dev.js", "dev:postgres": "cross-env NODE_OPTIONS=--no-deprecation PAYLOAD_DATABASE=postgres node ./test/dev.js",
"devsafe": "rimraf .next && pnpm dev", "devsafe": "node ./scripts/delete-recursively.js '**/.next' && pnpm dev",
"docker:restart": "pnpm docker:stop --remove-orphans && pnpm docker:start", "docker:restart": "pnpm docker:stop --remove-orphans && pnpm docker:start",
"docker:start": "docker compose -f packages/plugin-cloud-storage/docker-compose.yml up -d", "docker:start": "docker compose -f packages/plugin-cloud-storage/docker-compose.yml up -d",
"docker:stop": "docker compose -f packages/plugin-cloud-storage/docker-compose.yml down", "docker:stop": "docker compose -f packages/plugin-cloud-storage/docker-compose.yml down",
"fix": "eslint \"packages/**/*.ts\" --fix", "fix": "eslint \"packages/**/*.ts\" --fix",
"lint": "eslint \"packages/**/*.ts\"", "lint": "eslint \"packages/**/*.ts\"",
"lint-staged": "lint-staged", "lint-staged": "lint-staged",
"obliterate-playwright-cache": "rm -rf ~/Library/Caches/ms-playwright && find /System/Volumes/Data/private/var/folders -type d -name 'playwright*' -exec rm -rf {} +", "obliterate-playwright-cache-macos": "rm -rf ~/Library/Caches/ms-playwright && find /System/Volumes/Data/private/var/folders -type d -name 'playwright*' -exec rm -rf {} +",
"prepare": "husky install", "prepare": "husky install",
"reinstall": "pnpm clean:all && pnpm install", "reinstall": "pnpm clean:all && pnpm install",
"release:alpha": "tsx ./scripts/release.ts --bump prerelease --tag alpha", "release:alpha": "tsx ./scripts/release.ts --bump prerelease --tag alpha",

View File

@@ -0,0 +1,157 @@
import { promises as fs, existsSync } from 'fs'
import path, { join } from 'path'
import glob from 'glob'
import process from 'process'
import chalk from 'chalk'
// Helper function to format size appropriately in KB or MB
function formatSize(sizeInBytes) {
const sizeInKB = sizeInBytes / 1024
if (sizeInKB < 1024) {
return `${sizeInKB.toFixed(2)} KB`
} else {
return `${(sizeInKB / 1024).toFixed(2)} MB`
}
}
// Function to calculate the size of a directory
async function calculateSize(targetPath) {
let totalSize = 0
const stats = await fs.lstat(targetPath)
if (stats.isDirectory()) {
const files = await fs.readdir(targetPath)
for (const file of files) {
const filePath = join(targetPath, file)
totalSize += await calculateSize(filePath)
}
} else {
totalSize = stats.size
}
return totalSize
}
// Function to delete a file or directory recursively
async function deleteRecursively(targetPath, fullDelete = false) {
try {
if (fullDelete && existsSync(targetPath)) {
const size = await calculateSize(targetPath)
await fs.rmdir(targetPath, { recursive: true }) // Use async version of rmdir
return size
}
const stats = await fs.lstat(targetPath)
let size = 0
if (stats.isDirectory()) {
const files = await fs.readdir(targetPath)
for (const file of files) {
const curPath = join(targetPath, file)
size += await deleteRecursively(curPath)
}
await fs.rmdir(targetPath)
} else {
size = stats.size
await fs.unlink(targetPath)
}
return size
} catch (error) {
console.error(chalk.red(`Error deleting ${targetPath}: ${error.message}`))
return 0 // Return 0 size if there's an error
}
}
// Function to clean directories based on provided patterns
async function cleanDirectories(patterns) {
const deletedCounts = {}
let totalSize = 0
for (let entry of patterns) {
const ignoreNodeModules = !entry.endsWith('!')
let pattern = ignoreNodeModules ? entry : entry.slice(0, -1)
let files = []
let fulleDelete = false
if (pattern === '@node_modules') {
pattern = '**/node_modules'
fulleDelete = true
files = await new Promise((resolve, reject) => {
glob(pattern, { nodir: false }, (err, files) => {
if (err) {
reject(err)
} else {
// Filter out node_modules within other node_modules
const topNodeModules = files.filter((file) => {
const parentDir = path.dirname(file)
return !parentDir.includes('node_modules')
})
resolve(topNodeModules)
}
})
})
} else {
const options = {
ignore: ignoreNodeModules ? '**/node_modules/**' : '',
nodir: false,
}
files = await new Promise((resolve, reject) => {
glob(pattern, options, (err, files) => {
if (err) {
reject(err)
} else {
resolve(files)
}
})
})
}
let count = 0
let patternSize = 0
for (const file of files) {
const fileSize = await deleteRecursively(file, fulleDelete)
count++
patternSize += fileSize
}
deletedCounts[pattern] = { count, size: patternSize }
totalSize += patternSize
}
// Determine the maximum lengths needed for even spacing
const maxPatternLength = Math.max(...Object.keys(deletedCounts).map((pattern) => pattern.length))
const maxCountLength = Math.max(
...Object.values(deletedCounts).map(
(item) => `${item.count} item${item.count !== 1 ? 's' : ''} deleted`.length,
),
)
const maxSizeLength = Math.max(
...Object.values(deletedCounts).map((item) => formatSize(item.size).length),
)
// Print details for each pattern with colors, formatted for alignment
console.log(chalk.blue('Summary of deleted items:'))
Object.keys(deletedCounts).forEach((pattern) => {
const itemCount =
`${deletedCounts[pattern].count} item${deletedCounts[pattern].count !== 1 ? 's' : ''} deleted`.padEnd(
maxCountLength,
)
console.log(
`${chalk.green(pattern.padEnd(maxPatternLength))} ${chalk.red(itemCount)} ${chalk.yellow(formatSize(deletedCounts[pattern].size).padStart(maxSizeLength))}`,
)
})
// Calculate total deleted items and size
console.log(
chalk.magenta(
`Total deleted items: ${Object.values(deletedCounts).reduce((acc, { count }) => acc + count, 0)}`,
),
)
console.log(chalk.cyan(`Total size of deleted items: ${formatSize(totalSize)}`))
}
// Get patterns from command-line arguments
const patterns = process.argv.slice(2)
if (patterns.length > 0) {
void cleanDirectories(patterns)
} else {
console.log(chalk.red('No patterns provided. Usage: node script.js [patterns]'))
}