Skip to content

Instantly share code, notes, and snippets.

@quantumJLBass
Created July 29, 2023 20:26
Show Gist options
  • Save quantumJLBass/ec12b80ed20c7eedeac22493e407c105 to your computer and use it in GitHub Desktop.
Save quantumJLBass/ec12b80ed20c7eedeac22493e407c105 to your computer and use it in GitHub Desktop.
Zip up a directory per a .gitignore file in PS1
function Get-ZipFiles {
param (
[string]$Path = (Get-Location),
[string]$GitIgnorePath = (Join-Path -Path (Get-Location) -ChildPath ".gitignore")
)
# Read .gitignore file
$gitIgnorePatterns = Get-Content -Path $GitIgnorePath | Where-Object {
$_ -notmatch '^\s*#' -and $_ -notmatch '^\s*$'
} | ForEach-Object {
# Convert gitignore patterns to regex patterns
$_.TrimEnd('/') -replace '\.', '\\.' -replace '\*', '.*' -replace '/', '\\'
}
#Write-Output $gitIgnorePatterns
# Get all files and directories
$items = Get-ChildItem -Path $Path -Recurse -Force
# Filter items based on .gitignore
$filteredItems = $items | Where-Object {
$itemPath = $_.FullName.Substring($Path.Length)
# Check against each gitignore pattern
$isIgnored = $gitIgnorePatterns | ForEach-Object {
$itemPath -match $_
} | Where-Object { $_ } | Select-Object -First 1
-not $isIgnored
}
# Print filtered items
$filteredItems | ForEach-Object {
$_.FullName
}
}
# Function to zip a directory
function ZipDir {
param(
[string]$Name,
[string]$srcDir = ".",
[string]$ignore,
[switch]$Force,
[switch]$DebugMode = $false
)
# Resolve the srcDir to an absolute path
$srcDir = (Resolve-Path $srcDir).Path
# If the Name parameter is null or empty, set it to the leaf of the srcDir
if ([string]::IsNullOrEmpty($Name)) {
$Name = Split-Path -Leaf $srcDir
}
# If the ignore parameter is null or empty, set it to the path of the .gitignore file in the srcDir
if ([string]::IsNullOrEmpty($ignore)) {
$ignore = Join-Path $srcDir ".gitignore"
}
# If the Name does not end with ".zip", append ".zip" to it
if ($Name -notlike "*.zip") {
$Name += ".zip"
}
# Join the srcDir and Name to get the zipPath
$zipPath = Join-Path $srcDir $Name
# If the zip file already exists and the Force flag is set, remove the zip file
if ((Test-Path $zipPath) -and $Force) {
Remove-Item -Path $zipPath -Force
}
# If the zip file still exists, throw an error
if (Test-Path $zipPath) {
throw "Zip file $zipPath already exists. Use -Force to overwrite."
}
# Create a temporary directory in the system's temporary path
$tempDir = Join-Path ([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName())
New-Item -ItemType Directory -Force -Path $tempDir | Out-Null
# Get files and directories not ignored by git
$notIgnoredItems = Get-ZipFiles -Path $srcDir -GitIgnorePath $ignore
# Copy the files to the temporary directory
$notIgnoredItems | ForEach-Object {
$relativePath = $_.Substring($srcDir.Length + 1)
$destination = Join-Path $tempDir $relativePath
if ($DebugMode) {
Write-Output "Copying: $destination"
}
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $destination) | Out-Null
Copy-Item -Path $_ -Destination $destination
}
# Compress the temporary directory into the zip file
Compress-Archive -Path (Join-Path $tempDir "*") -DestinationPath $zipPath
# Delete the temporary directory
Remove-Item -Recurse -Force -Path $tempDir
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment