portfolio-website/export_code.ps1

182 lines
4.5 KiB
PowerShell

param(
[string]$OutputFile = "code_export.txt"
)
$ErrorActionPreference = "Stop"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
if ([System.IO.Path]::IsPathRooted($OutputFile)) {
$OutputPath = $OutputFile
}
else {
$OutputPath = Join-Path $ScriptDir $OutputFile
}
$ExcludedDirectories = @("node_modules", "vendor", "dist", "build", "images")
$ExcludedFilePatterns = @(
"code_export*.txt",
"gitea-token*.txt",
"gitea-token*.txt.sig"
)
$ExcludedExtensions = @(
".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".svg", ".ico", ".webp",
".mp4", ".mov", ".avi", ".mkv", ".webm",
".mp3", ".wav", ".ogg", ".flac",
".pdf",
".zip", ".tar", ".gz", ".bz2", ".rar", ".7z",
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx",
".eot", ".ttf", ".woff", ".woff2"
)
function Get-RelativePath {
param(
[string]$BasePath,
[string]$FullPath
)
$baseUri = [System.Uri](([System.IO.Path]::GetFullPath($BasePath)).TrimEnd("\") + "\")
$fullUri = [System.Uri]([System.IO.Path]::GetFullPath($FullPath))
$relativeUri = $baseUri.MakeRelativeUri($fullUri)
return [System.Uri]::UnescapeDataString($relativeUri.ToString()).Replace("/", "\")
}
function Test-IsProbablyBinary {
param(
[string]$Path
)
try {
$stream = [System.IO.File]::OpenRead($Path)
try {
$buffer = New-Object byte[] 4096
$bytesRead = $stream.Read($buffer, 0, $buffer.Length)
}
finally {
$stream.Dispose()
}
}
catch {
return $true
}
if ($bytesRead -ge 2) {
if (
($buffer[0] -eq 0xFF -and $buffer[1] -eq 0xFE) -or
($buffer[0] -eq 0xFE -and $buffer[1] -eq 0xFF)
) {
return $false
}
}
if ($bytesRead -ge 3) {
if ($buffer[0] -eq 0xEF -and $buffer[1] -eq 0xBB -and $buffer[2] -eq 0xBF) {
return $false
}
}
if ($bytesRead -ge 4) {
if (
($buffer[0] -eq 0xFF -and $buffer[1] -eq 0xFE -and $buffer[2] -eq 0x00 -and $buffer[3] -eq 0x00) -or
($buffer[0] -eq 0x00 -and $buffer[1] -eq 0x00 -and $buffer[2] -eq 0xFE -and $buffer[3] -eq 0xFF)
) {
return $false
}
}
for ($index = 0; $index -lt $bytesRead; $index++) {
if ($buffer[$index] -eq 0) {
return $true
}
}
return $false
}
function Test-ShouldSkipFile {
param(
[System.IO.FileInfo]$File
)
$fullPath = [System.IO.Path]::GetFullPath($File.FullName)
if ($fullPath -eq [System.IO.Path]::GetFullPath($OutputPath)) {
return $true
}
$relativePath = Get-RelativePath -BasePath $ScriptDir -FullPath $File.FullName
if ($relativePath -eq "export_code.sh" -or $relativePath -eq "export_code.ps1") {
return $true
}
foreach ($pattern in $ExcludedFilePatterns) {
if ($File.Name -like $pattern) {
return $true
}
}
$segments = $relativePath -split "[\\/]+"
foreach ($segment in $segments) {
if ($segment.StartsWith(".")) {
return $true
}
if ($ExcludedDirectories -contains $segment) {
return $true
}
}
if ($ExcludedExtensions -contains $File.Extension.ToLowerInvariant()) {
return $true
}
return $false
}
if (Test-Path -LiteralPath $OutputPath) {
Remove-Item -LiteralPath $OutputPath -Force
}
$builder = New-Object System.Text.StringBuilder
$files = Get-ChildItem -LiteralPath $ScriptDir -File -Recurse | Sort-Object {
(Get-RelativePath -BasePath $ScriptDir -FullPath $_.FullName).Replace("\", "/")
}
foreach ($file in $files) {
if (Test-ShouldSkipFile -File $file) {
continue
}
if (Test-IsProbablyBinary -Path $file.FullName) {
continue
}
try {
$content = Get-Content -LiteralPath $file.FullName -Raw -ErrorAction Stop
}
catch {
continue
}
$relativePath = (Get-RelativePath -BasePath $ScriptDir -FullPath $file.FullName).Replace("\", "/")
[void]$builder.AppendLine(("`"./{0}`" : " -f $relativePath))
[void]$builder.AppendLine('"""')
[void]$builder.Append($content)
if (-not $content.EndsWith("`n")) {
[void]$builder.AppendLine()
}
[void]$builder.AppendLine('"""')
[void]$builder.AppendLine()
[void]$builder.AppendLine()
}
$utf8NoBom = New-Object System.Text.UTF8Encoding $false
[System.IO.File]::WriteAllText($OutputPath, $builder.ToString(), $utf8NoBom)
Write-Host ("Code export finished. Output saved to {0}" -f $OutputPath)