147 lines
4.0 KiB
PowerShell
147 lines
4.0 KiB
PowerShell
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$OutputDir,
|
|
|
|
[switch]$Force
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
function Get-FullPath([string]$Path) {
|
|
if ([System.IO.Path]::IsPathRooted($Path)) {
|
|
return [System.IO.Path]::GetFullPath($Path)
|
|
}
|
|
|
|
return [System.IO.Path]::GetFullPath((Join-Path (Get-Location) $Path))
|
|
}
|
|
|
|
function Is-SubPath([string]$Candidate, [string]$Parent) {
|
|
$candidateFull = [System.IO.Path]::GetFullPath($Candidate).TrimEnd('\', '/')
|
|
$parentFull = [System.IO.Path]::GetFullPath($Parent).TrimEnd('\', '/')
|
|
return $candidateFull.Equals($parentFull, [System.StringComparison]::OrdinalIgnoreCase) -or
|
|
$candidateFull.StartsWith($parentFull + [System.IO.Path]::DirectorySeparatorChar, [System.StringComparison]::OrdinalIgnoreCase)
|
|
}
|
|
|
|
function Should-ExcludeDirectory([string]$RelativePath) {
|
|
$segments = @($RelativePath -split '[\\/]' | Where-Object { $_ -ne "" })
|
|
if ($segments.Count -eq 0) {
|
|
return $false
|
|
}
|
|
|
|
$first = $segments[0].ToLowerInvariant()
|
|
if ($first -in @(
|
|
".git",
|
|
".vs",
|
|
".vscode",
|
|
".idea",
|
|
".agents",
|
|
".codex",
|
|
"build",
|
|
"dist",
|
|
"release_packages",
|
|
"docs",
|
|
"reports",
|
|
"config",
|
|
"logs"
|
|
)) {
|
|
return $true
|
|
}
|
|
|
|
return $first.StartsWith("cmake-build-")
|
|
}
|
|
|
|
function Should-ExcludeFile([string]$RelativePath) {
|
|
$fileName = [System.IO.Path]::GetFileName($RelativePath).ToLowerInvariant()
|
|
if ($fileName -in @(
|
|
"readme.dev.md"
|
|
)) {
|
|
return $true
|
|
}
|
|
|
|
foreach ($pattern in @(
|
|
"*.user",
|
|
"*.suo",
|
|
"*.vc.db",
|
|
"*.vc.opendb",
|
|
"*.autosave",
|
|
"*.broken.json",
|
|
"*.exe",
|
|
"*.dll",
|
|
"*.pdb",
|
|
"*.ilk",
|
|
"*.obj",
|
|
"*.o",
|
|
"*.a",
|
|
"*.lib"
|
|
)) {
|
|
if ($fileName -like $pattern) {
|
|
return $true
|
|
}
|
|
}
|
|
|
|
return $false
|
|
}
|
|
|
|
function Copy-PublicTree([string]$SourceDir, [string]$DestinationDir, [string]$RelativeDir) {
|
|
foreach ($item in Get-ChildItem -LiteralPath $SourceDir -Force) {
|
|
$relativePath = if ($RelativeDir) {
|
|
Join-Path $RelativeDir $item.Name
|
|
} else {
|
|
$item.Name
|
|
}
|
|
|
|
if ($item.PSIsContainer) {
|
|
if (Should-ExcludeDirectory $relativePath) {
|
|
continue
|
|
}
|
|
|
|
$targetDir = Join-Path $DestinationDir $item.Name
|
|
New-Item -ItemType Directory -Path $targetDir -Force | Out-Null
|
|
Copy-PublicTree -SourceDir $item.FullName -DestinationDir $targetDir -RelativeDir $relativePath
|
|
continue
|
|
}
|
|
|
|
if (Should-ExcludeFile $relativePath) {
|
|
continue
|
|
}
|
|
|
|
Copy-Item -LiteralPath $item.FullName -Destination (Join-Path $DestinationDir $item.Name) -Force
|
|
}
|
|
}
|
|
|
|
$repoRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot ".."))
|
|
$outputPath = Get-FullPath $OutputDir
|
|
|
|
if ([string]::IsNullOrWhiteSpace($OutputDir)) {
|
|
throw "OutputDir is required."
|
|
}
|
|
|
|
if (Is-SubPath -Candidate $outputPath -Parent $repoRoot) {
|
|
throw "OutputDir must be outside the repository to avoid recursive export: $outputPath"
|
|
}
|
|
|
|
if (Test-Path -LiteralPath $outputPath) {
|
|
$hasContent = (Get-ChildItem -LiteralPath $outputPath -Force | Select-Object -First 1) -ne $null
|
|
if ($hasContent -and -not $Force) {
|
|
throw "OutputDir already exists and is not empty. Pass -Force to replace it: $outputPath"
|
|
}
|
|
|
|
if ($Force) {
|
|
Remove-Item -LiteralPath $outputPath -Recurse -Force
|
|
}
|
|
}
|
|
|
|
New-Item -ItemType Directory -Path $outputPath -Force | Out-Null
|
|
Copy-PublicTree -SourceDir $repoRoot -DestinationDir $outputPath -RelativeDir ""
|
|
|
|
Write-Host "GitHub export prepared:"
|
|
Write-Host " $outputPath"
|
|
Write-Host ""
|
|
Write-Host "Next steps:"
|
|
Write-Host " cd $outputPath"
|
|
Write-Host " git init"
|
|
Write-Host " git remote add origin https://github.com/Ysm-04/DesktopPet.git"
|
|
Write-Host " git add ."
|
|
Write-Host " git commit -m `"Publish GitHub version`""
|
|
Write-Host " git push -u origin main"
|