diff --git a/stage/create-grpc-archive.ps1 b/stage/create-grpc-archive.ps1 new file mode 100644 index 0000000000000..009e1785ecc0f --- /dev/null +++ b/stage/create-grpc-archive.ps1 @@ -0,0 +1,554 @@ +<# +.SYNOPSIS +Copy all gRPC binaries and creates an archive. + +.DESCRIPTION +Copy all gRPC binaries and creates an archive. + +.PARAMETER Source +Source directory containing gRPC repository. + +.PARAMETER Destination +Specifies output directory for the archive file. + +.PARAMETER Version +Specifies version for the archive file. + +.PARAMETER Debug +(Optional) Enables script debug logging to console. Script debug logs are always included in log file. + +.PARAMETER Help +(Optional) Displays help information for script. + +.INPUTS +None. + +.OUTPUTS +None. + +.EXAMPLE +.\create-grpc-archive.ps1 -Source 'C:\work\projects\grpc' -Destination 'C:\work\projects\grpc\stage' -Version '12345' + +.LINK +#> + +param ( + [string]$Source = "c:\work\projects\grpc", + [string]$Destination = "c:\work\projects\grpc\stage", + [string]$Version = "", + [switch]$Debug = $false, + [switch]$Help = $false + ) + +# Constants + +$EXIT_SUCCESS = 0 +$EXIT_FAIL = 1 + +# Get current working directory + +$WORKING_DIR__ = Get-Location +$SCRIPT_DIR__ = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition +$TEMPDIR__ = New-Item -Type Directory -Path $env:TEMP -Name ([System.Guid]::NewGuid()) + +# Log formatting + +$logFileDateFormat = "dd-MMM-yyyy_HH_mm" +$logEntryDateFormat = "[ddd MM/dd/yyyy - HH:mm:ss.ff]" +$logFileDateStamp = Get-Date -format $logFileDateFormat +$scriptLog = "$WORKING_DIR__\create-grpc-archive.$logFileDateStamp.log" + +# Current date and time format + +$currentDateTimeFormat = "dd-MMM-yyyy HH:mm" +$currentDateTime = Get-Date -format $currentDateTimeFormat + +function IsValid($object) +{ + if ($object -eq $null) { + return $false + } + + if ($object -is [String] -and $object -eq [String]::Empty) { + return $false + } + + return $true +} + + +function Log +{ + param ( + [string]$Entry, + [bool]$Console, + [string]$Exception = "" + ) + + if ($Entry -eq "") + { + return + } + + # Get current time + + $currentTime = Get-Date -format $logEntryDateFormat + + if ($Console) + { + Write-Host "$currentTime $Entry" + } + + # Write to log file + + Add-content "$scriptLog" -value "$currentTime $Entry" -ErrorAction Stop + + # Write exception to log file + + if (IsValid($Exception)) + { + if($Console) + { + Write-Host "$Exception" + } + + Add-content "$scriptLog" -value "Exception: $Exception" -ErrorAction Stop + } +} + +function Error +{ + param ( + [string]$Entry, + [string]$Exception = "" + ) + + Log -Entry "ERR: $Entry" -Console $true -Exception $Exception +} + +function Info +{ + param ( + [string]$Entry + ) + + Log -Entry "INF: $Entry" -Console $true +} + +function Warn +{ + param ( + [string]$Entry + ) + + Log -Entry "WRN: $Entry" -Console $true +} + +function Debug +{ + param ( + [string]$Entry, + [bool]$Console = $Debug, + [string]$Name = "" + ) + + Log -Entry "DBG: ($Name) $Entry" -Console $Console +} + +function ExitWithError +{ + param ( + [string]$Message, + [int]$ExitCode = 1 + ) + + Error -Entry "-------------------------------------------------------------" + Error -Entry "An error occured during the execution of script. $Message." + Error -Entry "Abort execution and exit with code $ExitCode." + Error -Entry "-------------------------------------------------------------" + + exit $ExitCode +} + +# Global variables + +$DEST_DIR__='' +$SRC_DIR__='' +$TEMPDIR__='' +$ARCHIVE_VERSION__='' +$ARCHIVE_NAME__='grpc_1_51_1_stage_cpp17.zip' + +function IsDirectory +{ + param ( + [string]$Path + ) + + if(-Not(IsValid($Path))) + { + return $false; + } + + $result = Test-Path -LiteralPath $Path -PathType Container + if($result -eq $false) + { + return $false; + } + + return $true; +} + +function IsFile +{ + param ( + [string]$Path + ) + + if(-Not(IsValid($Path))) + { + return $false; + } + + $result = Test-Path -LiteralPath $Path -PathType leaf + if($result -eq $false) + { + return $false; + } + + return $true; +} + +function CreateDirectory +{ + param ( + [string]$Path + ) + + if(-Not(IsValid($Path))) + { + return $false; + } + + if(IsDirectory($Path)) + { + return $true; + } + + New-Item $Path -ItemType Directory -Force -ErrorAction Continue | Out-Null + + if(-Not(IsDirectory($Path))) + { + ExitWithError -Message "Unable to create directory $Path." + return $false; + } + + return $true; +} + +function CopyLibs +{ + param ( + [string]$Source, + [string]$Configuration, + [string]$Destination + ) + + Debug -Entry "entry" -Name $MyInvocation.MyCommand + + if(-Not(IsDirectory($Source))) + { + return $false; + } + + $files = Get-ChildItem -Path $Source -Recurse -Filter '*.lib' + foreach($file in $files) + { + $filename = $file.FullName + if($filename.Contains($Configuration)) + { + $result = CopyFile -Source $filename -Destination $Destination + } + } + + return $true; +} + +function CopyFile +{ + param ( + [string]$Source, + [string]$Destination + ) + + try + { + if(-Not(IsFile($Source))) + { + Error -Entry "Unable to find $Source. Not a valid file." + return $false + } + + Debug -Entry "Copying $Source to $Destination ..." -Name $MyInvocation.MyCommand + + if(IsDirectory($Destination)) + { + $onlyFilename = Split-Path -Path $Source -Leaf + $destFilename = "$Destination\$onlyFilename" + } + else + { + $destFilename = $Destination + } + + $error.clear() + Copy-Item -Path $Source -Destination $Destination -ErrorAction Continue + if ($error[0] -ne $null) + { + $errorMessage = $error[0] + Error -Entry "Failed to copy $Source to $Destination." -Exception $errorMessage + return $false + } + + if(-Not(IsFile($destFilename))) + { + Error -Entry "Failed to copy $Source to $Destination." + return $false + } + + return $true + } + catch + { + Error -Entry "Failed to copy file from $Source to $Destination directory." -Exception $_.Exception.Message + return $false + } +} + +function CopyBinaries +{ + Debug -Entry "entry" -Name $MyInvocation.MyCommand + + $expectedDir = @{'64' = 'x64'; '32' = 'win32'} + $configurations = @( 'Release', 'Debug') + $archs = @( '32', '64') + + foreach($config in $configurations) + { + foreach($arch in $archs) + { + Info -Entry "Copying binaries for $arch($config) ..." + + Debug -Entry '--------------------------' -Name $MyInvocation.MyCommand + Debug -Entry "Configuration: $config" -Name $MyInvocation.MyCommand + Debug -Entry "Architecture : $arch" -Name $MyInvocation.MyCommand + Debug -Entry '--------------------------' -Name $MyInvocation.MyCommand + + $destinationDir = $TEMPDIR__ + '\' + $expectedDir.$arch + '\' + $config +'\' + $result = CreateDirectory -Path $destinationDir + if($result -eq $false) + { + ExitWithError -Message "Failed to create $destinationDir directory." + } + + $destinationThirdPartyDir = $TEMPDIR__ + '\' + $expectedDir.$arch + '\' + $config +'\third_party\' + $result = CreateDirectory -Path $destinationThirdPartyDir + if($result -eq $false) + { + ExitWithError -Message "Failed to create $destinationThirdPartyDir directory." + } + + $sourceDir = $SRC_DIR__ + '\build_windows_' + $arch + '\' + $config + '\' + $result = CopyLibs -Source $sourceDir -Configuration $config -Destination $destinationDir + if($result -eq $false) + { + ExitWithError -Message "Failed to copy binaries from $sourceDir to $destinationDir." + } + + $sourceDir = $SRC_DIR__ + '\build_windows_' + $arch + '\third_party\' + $result = CopyLibs -Source $sourceDir -Configuration $config -Destination $destinationThirdPartyDir + if($result -eq $false) + { + ExitWithError -Message "Failed to copy binaries from $sourceDir to $destinationThirdPartyDir." + } + + Info -Entry "OK" + } + } +} + +function IsModuleInstalled +{ + param( + [string] $Name + ) + + Debug -Entry "entry" -Name $MyInvocation.MyCommand + + $module = Get-Module -Name $Name -ListAvailable | Select-Object -Last 1 + if ($null -ne $module) + { + Debug -Entry "Module '$Name' is installed." -Name $MyInvocation.MyCommand + return $true; + } + else + { + Debug -Entry "Module '$Name' is not installed." -Name $MyInvocation.MyCommand + return $false; + } +} + +function CreateArchive +{ + Debug -Entry "entry" -Name $MyInvocation.MyCommand + + $fullArchiveName = "$DEST_DIR__\$ARCHIVE_NAME__" + $fullArchiveNameWithVersion = "$DEST_DIR__\$ARCHIVE_NAME__.$ARCHIVE_VERSION__" + + Info -Entry "Create archive $fullArchiveNameWithVersion ..." + + # Remove destination file if exists + + if(IsFile($fullArchiveNameWithVersion)) + { + Remove-Item -Force -Path $fullArchiveNameWithVersion + } + + # Create archive with binaries + + $compress = @{ + Path = "$TEMPDIR__\*" + CompressionLevel = "Optimal" + DestinationPath = $fullArchiveName + } + Compress-Archive @compress -Force + + # Remove temporary directory + + Remove-Item -Recurse -Force $TEMPDIR__ + + # Check if archive exists + + if(-Not(IsFile($fullArchiveName))) + { + ExitWithError -Message "Failed to create archive $fullArchiveName." + } + + # Rename file to include the version + + Rename-Item -Path $fullArchiveName -NewName $fullArchiveNameWithVersion -Force + + if(-Not(IsFile($fullArchiveNameWithVersion))) + { + ExitWithError -Message "Failed to create archive $fullArchiveNameWithVersion." + } + + Info -Entry "$fullArchiveNameWithVersion created." +} + +function DisplayHelp +{ + Get-Help -Name $SCRIPT_DIR__\create-grpc-archive.ps1 -detailed +} + +function IsArchiveModuleInstalled +{ + Debug -Entry "entry" -Name $MyInvocation.MyCommand + + $moduleName = 'Microsoft.PowerShell.Archive' + $result = IsModuleInstalled -Name $moduleName + if($result -eq $false) + { + Error -Entry "Required module '$moduleName' is not installed. Please install module '$moduleName', command to install can be copied from 'https://www.powershellgallery.com/packages/Microsoft.PowerShell.Archive/'." + return $false; + } + + return $true; +} + +function CheckParametersConstraints +{ + $passed = $true + + if(IsValid($Source)) + { + if(-Not(IsDirectory($Source))) + { + Error -Entry "Parameter -$Source is not a valid directory." + $passed = $false + } + } + + if(IsValid($Destination)) + { + if(-Not(IsDirectory($Destination))) + { + Error -Entry "Parameter -$Destination is not a valid directory." + $passed = $false + } + } + + if(-Not(IsValid($Version))) + + { + Error -Entry "Parameter -$Version is empty." + $passed = $false + } + + return $passed +} + +function New-TemporaryDirectory +{ + $parentDir = [System.IO.Path]::GetTempPath() + do + { + $randomNameDir = [System.IO.Path]::GetRandomFileName() + $item = New-Item -Path $parentDir -Name $randomNameDir -ItemType "directory" -ErrorAction SilentlyContinue + } while (-not $item) + + return $item.FullName +} + +############################## +# MAIN +############################## + +function Main +{ + # Display help information + + if($Help -eq $true) + { + DisplayHelp + exit $EXIT_SUCCESS + } + + # Check input parameters + + $result = CheckParametersConstraints + if(-Not($result)) + { + exit $EXIT_FAIL + } + + # Check if archive module is installed + + $result = IsArchiveModuleInstalled + if(-Not($result)) + { + exit $EXIT_FAIL + } + + # Set Global variables to validated parameters + + $SRC_DIR__ = $Source + $DEST_DIR__ = $Destination + $ARCHIVE_VERSION__ = $Version + $TEMPDIR__ = New-TemporaryDirectory + + CopyBinaries + CreateArchive +} + +Main +