chore: initial hub repo structure
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Clean all node_modules directories in the repository with optional cache and lockfile cleanup.
|
||||
|
||||
.DESCRIPTION
|
||||
This script recursively finds and removes all 'node_modules' directories starting at the repo root.
|
||||
Optionally, it can also remove build caches and lockfiles, and run 'pnpm store prune'.
|
||||
|
||||
.PARAMETER IncludeCache
|
||||
Also remove common cache/build output directories (e.g., .next, .turbo, .vite, node_modules/.cache, dist, build, coverage, out, storybook-static).
|
||||
|
||||
.PARAMETER IncludeLock
|
||||
Also remove lock files (pnpm-lock.yaml, package-lock.json, yarn.lock) in the repo.
|
||||
|
||||
.PARAMETER PruneStore
|
||||
After deletion, try to run 'pnpm store prune' if pnpm is installed.
|
||||
|
||||
.PARAMETER Yes
|
||||
Proceed without interactive confirmation (non-interactive mode).
|
||||
|
||||
.PARAMETER DryRun
|
||||
Show what would be removed without deleting anything.
|
||||
|
||||
.EXAMPLE
|
||||
# Preview what will be removed
|
||||
./scripts/clean-node-modules.ps1 -DryRun
|
||||
|
||||
.EXAMPLE
|
||||
# Clean node_modules only, no prompt
|
||||
./scripts/clean-node-modules.ps1 -Yes
|
||||
|
||||
.EXAMPLE
|
||||
# Deep clean including caches and lockfiles, and prune pnpm store
|
||||
./scripts/clean-node-modules.ps1 -IncludeCache -IncludeLock -PruneStore -Yes
|
||||
#>
|
||||
|
||||
[CmdletBinding(SupportsShouldProcess=$true)]
|
||||
param(
|
||||
[switch] $IncludeCache,
|
||||
[switch] $IncludeLock,
|
||||
[switch] $PruneStore,
|
||||
[switch] $Yes,
|
||||
[switch] $DryRun
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function Write-Section($text) {
|
||||
Write-Host "`n==== $text ====\n" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
function Safe-RemoveDirectory {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string] $Path,
|
||||
[switch] $Preview
|
||||
)
|
||||
if (-not (Test-Path -LiteralPath $Path)) { return }
|
||||
if ($Preview) { Write-Host "[dir] $Path"; return }
|
||||
try {
|
||||
# Use cmd rmdir for better handling of read-only/long paths on Windows PowerShell 5.1
|
||||
& cmd.exe /c "rmdir /s /q \"$Path\"" | Out-Null
|
||||
} catch {
|
||||
try { Remove-Item -LiteralPath $Path -Recurse -Force -ErrorAction Stop } catch {
|
||||
Write-Warning "Failed to remove directory: $Path -> $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Safe-RemoveFile {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string] $Path,
|
||||
[switch] $Preview
|
||||
)
|
||||
if (-not (Test-Path -LiteralPath $Path)) { return }
|
||||
if ($Preview) { Write-Host "[file] $Path"; return }
|
||||
try { Remove-Item -LiteralPath $Path -Force -ErrorAction Stop } catch {
|
||||
Write-Warning "Failed to remove file: $Path -> $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
# Resolve repo root (this script lives in ./scripts)
|
||||
$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
|
||||
Set-Location -LiteralPath $RepoRoot
|
||||
|
||||
Write-Host "Repo root: $RepoRoot" -ForegroundColor DarkGray
|
||||
|
||||
# Accumulators
|
||||
$DirsToDelete = New-Object System.Collections.Generic.List[string]
|
||||
$FilesToDelete = New-Object System.Collections.Generic.List[string]
|
||||
|
||||
# 1) node_modules everywhere (including root)
|
||||
Write-Section 'Scanning node_modules directories'
|
||||
$nodeModulesDirs = Get-ChildItem -LiteralPath $RepoRoot -Directory -Recurse -Force -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Name -eq 'node_modules' }
|
||||
|
||||
# Ensure root node_modules is included if present
|
||||
$rootNM = Join-Path $RepoRoot 'node_modules'
|
||||
if (Test-Path -LiteralPath $rootNM) {
|
||||
$DirsToDelete.Add($rootNM)
|
||||
}
|
||||
foreach ($d in $nodeModulesDirs) {
|
||||
if (-not $DirsToDelete.Contains($d.FullName)) { $DirsToDelete.Add($d.FullName) }
|
||||
}
|
||||
Write-Host ("Found {0} node_modules directory(ies)" -f $DirsToDelete.Count)
|
||||
|
||||
# 2) Optional caches/output folders
|
||||
if ($IncludeCache) {
|
||||
Write-Section 'Scanning cache/output directories'
|
||||
$cacheNames = @(
|
||||
'.next', '.turbo', '.vite', '.parcel-cache', '.cache',
|
||||
'dist', 'build', 'coverage', 'out', 'storybook-static',
|
||||
'.wrangler'
|
||||
)
|
||||
# node_modules/.cache is common; include it via name match too
|
||||
$allDirs = Get-ChildItem -LiteralPath $RepoRoot -Directory -Recurse -Force -ErrorAction SilentlyContinue
|
||||
foreach ($dir in $allDirs) {
|
||||
if ($cacheNames -contains $dir.Name) {
|
||||
if (-not $DirsToDelete.Contains($dir.FullName)) { $DirsToDelete.Add($dir.FullName) }
|
||||
}
|
||||
}
|
||||
Write-Host ("Found {0} cache/output directory(ies)" -f ($DirsToDelete | Where-Object { Test-Path $_ }).Count)
|
||||
}
|
||||
|
||||
# 3) Optional lockfiles
|
||||
if ($IncludeLock) {
|
||||
Write-Section 'Scanning lock files'
|
||||
$lockGlobs = @('pnpm-lock.yaml', 'package-lock.json', 'yarn.lock')
|
||||
foreach ($glob in $lockGlobs) {
|
||||
$files = Get-ChildItem -LiteralPath $RepoRoot -Recurse -Force -File -Filter $glob -ErrorAction SilentlyContinue
|
||||
foreach ($f in $files) { if (-not $FilesToDelete.Contains($f.FullName)) { $FilesToDelete.Add($f.FullName) } }
|
||||
}
|
||||
Write-Host ("Found {0} lock file(s)" -f $FilesToDelete.Count)
|
||||
}
|
||||
|
||||
# 4) Summary
|
||||
Write-Section 'Summary'
|
||||
Write-Host ("Directories to delete: {0}" -f $DirsToDelete.Count)
|
||||
Write-Host ("Files to delete: {0}" -f $FilesToDelete.Count)
|
||||
|
||||
$preview = $DryRun -or (-not $Yes)
|
||||
if ($preview) {
|
||||
Write-Host "Preview mode (no deletions). Use -Yes to confirm, or pass -DryRun:$false to hide this list." -ForegroundColor Yellow
|
||||
foreach ($dir in $DirsToDelete) { Safe-RemoveDirectory -Path $dir -Preview }
|
||||
foreach ($fil in $FilesToDelete) { Safe-RemoveFile -Path $fil -Preview }
|
||||
if (-not $Yes) { Write-Host "\nRun again with -Yes to confirm deletion." -ForegroundColor Yellow }
|
||||
exit 0
|
||||
}
|
||||
|
||||
# 5) Deletion
|
||||
Write-Section 'Deleting directories'
|
||||
foreach ($dir in $DirsToDelete) { Safe-RemoveDirectory -Path $dir }
|
||||
|
||||
if ($FilesToDelete.Count -gt 0) {
|
||||
Write-Section 'Deleting files'
|
||||
foreach ($fil in $FilesToDelete) { Safe-RemoveFile -Path $fil }
|
||||
}
|
||||
|
||||
# 6) Optional pnpm store prune
|
||||
if ($PruneStore) {
|
||||
Write-Section 'Pruning pnpm store'
|
||||
$pnpm = Get-Command pnpm -ErrorAction SilentlyContinue
|
||||
if ($null -ne $pnpm) {
|
||||
try { & pnpm store prune } catch { Write-Warning "pnpm store prune failed: $($_.Exception.Message)" }
|
||||
} else {
|
||||
Write-Warning "pnpm not found on PATH; skipping 'pnpm store prune'."
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "\nDone." -ForegroundColor Green
|
||||
Reference in New Issue
Block a user