feat: Implement platform-specific hosts file path retrieval
- Created a new `platform` package to handle OS-specific hosts file paths. - Added implementations for macOS, Linux, and Windows to retrieve the hosts file path. - Introduced tests for the `GetHostsFilePath` function to ensure correct behavior across platforms. feat: Add DNS resolver for IP lookups - Implemented a `resolver` package for performing DNS lookups. - Created a `DNSResolver` struct with a `LookupIP` method to handle A-record lookups and CNAME resolution. - Added comprehensive tests for various DNS scenarios, including CNAME chains and error handling. chore: Refactor project structure and update dependencies - Restructured the project to follow Go's standard package layout. - Updated `go.mod` to Go 1.20 and added `golang.org/x/net` dependency. - Removed old source files and ensured a clean build with all tests passing.
This commit is contained in:
@@ -0,0 +1,303 @@
|
||||
# Build script for dns-helper
|
||||
# Builds the executables using the go1.20 toolchain
|
||||
#
|
||||
# USAGE:
|
||||
# .\build.ps1 # Standard build for current platform (Windows amd64)
|
||||
# .\build.ps1 -Release # Build for all platforms (no debug symbols)
|
||||
# .\build.ps1 -Clean # Clean build (removes old files first)
|
||||
# .\build.ps1 -CrossCompile # Build for all platforms
|
||||
# .\build.ps1 -Package # Create release packages (ZIP / tar.gz)
|
||||
# .\build.ps1 -Release -Package # Full release: optimized build + packages
|
||||
#
|
||||
# OUTPUT:
|
||||
# - Default build: build\dns-helper.exe
|
||||
# - Cross-compiled: build\dns-helper-<os>-<arch>[.exe]
|
||||
# - Release packages: releases\dns-helper-<version>-<os>-<arch>.zip / .tar.gz
|
||||
|
||||
param(
|
||||
[string]$OutputDir = "build",
|
||||
[string]$OutputName = "dns-helper",
|
||||
[switch]$Release,
|
||||
[switch]$Clean,
|
||||
[switch]$CrossCompile,
|
||||
[switch]$Package
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# Go binary — use go1.20 toolchain
|
||||
$GoCmd = "go1.20"
|
||||
|
||||
# Get version information from git or use defaults
|
||||
$gitHash = "unknown"
|
||||
$gitTag = "dev"
|
||||
|
||||
$prevErrorActionPreference = $ErrorActionPreference
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
try {
|
||||
$gitHashResult = git rev-parse --short HEAD 2>&1
|
||||
if ($LASTEXITCODE -eq 0 -and $gitHashResult -and $gitHashResult -notmatch "fatal|error") {
|
||||
$gitHash = $gitHashResult.Trim()
|
||||
}
|
||||
|
||||
$gitTagResult = git describe --tags --always --dirty 2>&1
|
||||
if ($LASTEXITCODE -eq 0 -and $gitTagResult -and $gitTagResult -notmatch "fatal|error") {
|
||||
$gitTag = $gitTagResult.Trim()
|
||||
}
|
||||
} catch {
|
||||
# Git not available or not a git repository — use defaults
|
||||
}
|
||||
|
||||
$ErrorActionPreference = $prevErrorActionPreference
|
||||
|
||||
$buildTime = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
|
||||
|
||||
Write-Host "============================================" -ForegroundColor Cyan
|
||||
Write-Host " dns-helper Build" -ForegroundColor Cyan
|
||||
Write-Host "============================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host " Version: $gitTag" -ForegroundColor Gray
|
||||
Write-Host " Commit: $gitHash" -ForegroundColor Gray
|
||||
Write-Host " Time: $buildTime" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
# Clean output directory if requested
|
||||
if ($Clean) {
|
||||
Write-Host "Cleaning output directory..." -ForegroundColor Yellow
|
||||
if (Test-Path $OutputDir) {
|
||||
Remove-Item -Path $OutputDir -Recurse -Force
|
||||
}
|
||||
Write-Host "Cleaning Go caches..." -ForegroundColor Yellow
|
||||
& $GoCmd clean -cache -testcache 2>$null
|
||||
}
|
||||
|
||||
# Ensure output directory exists
|
||||
if (-not (Test-Path $OutputDir)) {
|
||||
New-Item -ItemType Directory -Path $OutputDir | Out-Null
|
||||
Write-Host "Created output directory: $OutputDir" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Build flags
|
||||
$ldflags = ""
|
||||
if ($Release) {
|
||||
$ldflags = "-s -w"
|
||||
Write-Host "Building RELEASE version (optimized, no debug symbols)..." -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "Building DEBUG version (with debug symbols)..." -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# Disable CGO for static binaries
|
||||
$env:CGO_ENABLED = "0"
|
||||
|
||||
$platforms = @(
|
||||
@{ GOOS = "windows"; GOARCH = "386"; Suffix = ".exe" },
|
||||
@{ GOOS = "windows"; GOARCH = "amd64"; Suffix = ".exe" },
|
||||
@{ GOOS = "linux"; GOARCH = "amd64"; Suffix = "" },
|
||||
@{ GOOS = "linux"; GOARCH = "arm64"; Suffix = "" },
|
||||
@{ GOOS = "darwin"; GOARCH = "amd64"; Suffix = "" },
|
||||
@{ GOOS = "darwin"; GOARCH = "arm64"; Suffix = "" }
|
||||
)
|
||||
|
||||
function Build-Binary {
|
||||
param(
|
||||
[string]$GOOS,
|
||||
[string]$GOARCH,
|
||||
[string]$OutputPath
|
||||
)
|
||||
|
||||
$env:GOOS = $GOOS
|
||||
$env:GOARCH = $GOARCH
|
||||
|
||||
if ($ldflags) {
|
||||
& $GoCmd build -ldflags $ldflags -o $OutputPath .
|
||||
} else {
|
||||
& $GoCmd build -o $OutputPath .
|
||||
}
|
||||
|
||||
return $LASTEXITCODE
|
||||
}
|
||||
|
||||
try {
|
||||
if ($CrossCompile -or $Release) {
|
||||
Write-Host "Cross-compiling for all platforms..." -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
foreach ($platform in $platforms) {
|
||||
$outputFile = "$OutputName-$($platform.GOOS)-$($platform.GOARCH)$($platform.Suffix)"
|
||||
$outputPath = Join-Path $OutputDir $outputFile
|
||||
|
||||
Write-Host " Building $outputFile..." -ForegroundColor Gray
|
||||
|
||||
$result = Build-Binary -GOOS $platform.GOOS -GOARCH $platform.GOARCH -OutputPath $outputPath
|
||||
|
||||
if ($result -eq 0) {
|
||||
$fileSizeMB = [math]::Round((Get-Item $outputPath).Length / 1MB, 2)
|
||||
Write-Host " [OK] $fileSizeMB MB" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " [FAILED]" -ForegroundColor Red
|
||||
exit $result
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Cross-compilation complete!" -ForegroundColor Green
|
||||
|
||||
} else {
|
||||
$outputPath = Join-Path $OutputDir "$OutputName.exe"
|
||||
|
||||
Write-Host "Compiling for Windows (amd64)..." -ForegroundColor Cyan
|
||||
|
||||
$result = Build-Binary -GOOS "windows" -GOARCH "amd64" -OutputPath $outputPath
|
||||
|
||||
if ($result -eq 0) {
|
||||
$fileSizeMB = [math]::Round((Get-Item $outputPath).Length / 1MB, 2)
|
||||
Write-Host "Build successful!" -ForegroundColor Green
|
||||
Write-Host " Output: $outputPath" -ForegroundColor Gray
|
||||
Write-Host " Size: $fileSizeMB MB" -ForegroundColor Gray
|
||||
} else {
|
||||
Write-Host "Build failed with exit code: $result" -ForegroundColor Red
|
||||
exit $result
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Build error: $_" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Build complete!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Usage:" -ForegroundColor Cyan
|
||||
Write-Host " .\$OutputDir\$OutputName.exe --help" -ForegroundColor White
|
||||
Write-Host " .\$OutputDir\$OutputName.exe add <hostname> <ip>" -ForegroundColor White
|
||||
|
||||
# Create release packages if requested
|
||||
if ($Package) {
|
||||
Write-Host ""
|
||||
Write-Host "============================================" -ForegroundColor Cyan
|
||||
Write-Host " Creating Release Packages" -ForegroundColor Cyan
|
||||
Write-Host "============================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
$releasesDir = "releases"
|
||||
if (-not (Test-Path $releasesDir)) {
|
||||
New-Item -ItemType Directory -Path $releasesDir | Out-Null
|
||||
Write-Host "Created releases directory: $releasesDir" -ForegroundColor Green
|
||||
}
|
||||
|
||||
foreach ($platform in $platforms) {
|
||||
$platformName = "$($platform.GOOS)-$($platform.GOARCH)"
|
||||
$packageName = "$OutputName-$gitTag-$platformName"
|
||||
$packageDir = Join-Path $releasesDir $packageName
|
||||
|
||||
$isWindowsPlatform = $platform.GOOS -eq "windows"
|
||||
if ($isWindowsPlatform) {
|
||||
$archivePath = "$packageDir.zip"
|
||||
$exeName = "$OutputName.exe"
|
||||
} else {
|
||||
$archivePath = "$packageDir.tar.gz"
|
||||
$exeName = $OutputName
|
||||
}
|
||||
|
||||
Write-Host "Creating package for $platformName..." -ForegroundColor Cyan
|
||||
|
||||
if (Test-Path $packageDir) {
|
||||
Remove-Item -Path $packageDir -Recurse -Force
|
||||
}
|
||||
if (Test-Path $archivePath) {
|
||||
try {
|
||||
Remove-Item -Path $archivePath -Force -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Host " Warning: Could not remove old package (file may be in use)" -ForegroundColor Yellow
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Path $packageDir | Out-Null
|
||||
|
||||
# Copy the binary
|
||||
$binaryFile = "$OutputName-$platformName$($platform.Suffix)"
|
||||
$binaryPath = Join-Path $OutputDir $binaryFile
|
||||
if (-not (Test-Path $binaryPath)) {
|
||||
Write-Host " Error: Binary not found at $binaryPath. Run build first." -ForegroundColor Red
|
||||
continue
|
||||
}
|
||||
Copy-Item -Path $binaryPath -Destination (Join-Path $packageDir $exeName)
|
||||
|
||||
# Copy README if present
|
||||
if (Test-Path "README.md") {
|
||||
Copy-Item -Path "README.md" -Destination (Join-Path $packageDir "README.md")
|
||||
}
|
||||
|
||||
# VERSION.txt
|
||||
@"
|
||||
dns-helper Version Information
|
||||
===============================
|
||||
|
||||
Version: $gitTag
|
||||
Git Commit: $gitHash
|
||||
Build Time: $buildTime
|
||||
Platform: $platformName
|
||||
|
||||
Run '$exeName --help' for usage information.
|
||||
"@ | Out-File -FilePath (Join-Path $packageDir "VERSION.txt") -Encoding UTF8
|
||||
|
||||
# CHECKSUMS.txt
|
||||
$exeHash = (Get-FileHash -Path (Join-Path $packageDir $exeName) -Algorithm SHA256).Hash
|
||||
@"
|
||||
dns-helper Release Checksums
|
||||
Version: $gitTag
|
||||
Build: $gitHash
|
||||
Platform: $platformName
|
||||
|
||||
SHA256 Checksums:
|
||||
-----------------
|
||||
$exeName
|
||||
$exeHash
|
||||
|
||||
To verify (PowerShell):
|
||||
`$hash = (Get-FileHash -Path $exeName -Algorithm SHA256).Hash
|
||||
if (`$hash -eq "$exeHash") { Write-Host "Verified!" -ForegroundColor Green }
|
||||
|
||||
To verify (Linux/macOS):
|
||||
echo "$exeHash $exeName" | sha256sum -c -
|
||||
"@ | Out-File -FilePath (Join-Path $packageDir "CHECKSUMS.txt") -Encoding UTF8
|
||||
|
||||
# Create archive
|
||||
try {
|
||||
if ($isWindowsPlatform) {
|
||||
Compress-Archive -Path "$packageDir\*" -DestinationPath $archivePath -CompressionLevel Optimal -Force
|
||||
} else {
|
||||
Push-Location $releasesDir
|
||||
try {
|
||||
tar -czf "$packageName.tar.gz" -C . $packageName 2>$null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host " Warning: tar not available, using ZIP format" -ForegroundColor Yellow
|
||||
$archivePath = "$packageDir.zip"
|
||||
Compress-Archive -Path "$packageDir\*" -DestinationPath $archivePath -CompressionLevel Optimal -Force
|
||||
}
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
}
|
||||
|
||||
$archiveSizeMB = [math]::Round((Get-Item $archivePath).Length / 1MB, 2)
|
||||
Remove-Item -Path $packageDir -Recurse -Force
|
||||
Write-Host " [OK] $archivePath ($archiveSizeMB MB)" -ForegroundColor Green
|
||||
|
||||
} catch {
|
||||
Write-Host " Error creating package: $_" -ForegroundColor Red
|
||||
if (Test-Path $packageDir) { Remove-Item -Path $packageDir -Recurse -Force }
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Release packaging complete!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Package contents:" -ForegroundColor Cyan
|
||||
Write-Host " - dns-helper executable" -ForegroundColor Gray
|
||||
Write-Host " - README.md (if present)" -ForegroundColor Gray
|
||||
Write-Host " - VERSION.txt" -ForegroundColor Gray
|
||||
Write-Host " - CHECKSUMS.txt (integrity verification)" -ForegroundColor Gray
|
||||
}
|
||||
Reference in New Issue
Block a user