Skip to content

Commit 5251401

Browse files
Add Windows-safe CloudStack build helper
1 parent 8209e54 commit 5251401

2 files changed

Lines changed: 200 additions & 0 deletions

File tree

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
.github/workflows/*.lock.yml linguist-generated=true merge=ours
2+
*.sh text eol=lf

tools/cloudstack-build.ps1

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
#
19+
20+
<#
21+
.SYNOPSIS
22+
Runs a Windows-safe Apache CloudStack Maven build.
23+
24+
.DESCRIPTION
25+
Uses the local Codex Java/Maven toolchain when present, verifies that Java 17+
26+
is available, keeps Bash scripts on LF line endings, and promotes a server
27+
compile request to package so cloud-api test classes are produced for the
28+
cloud-server dependency graph.
29+
30+
.EXAMPLE
31+
powershell -NoProfile -ExecutionPolicy Bypass -File tools\cloudstack-build.ps1 -Modules server -Phase compile
32+
33+
.EXAMPLE
34+
powershell -NoProfile -ExecutionPolicy Bypass -File tools\cloudstack-build.ps1 -Modules server -Test VmwareCbtMigrationCutoverPolicyTest
35+
#>
36+
37+
[CmdletBinding()]
38+
param(
39+
[string[]] $Modules = @("server"),
40+
41+
[ValidateSet("validate", "compile", "test-compile", "test", "package", "verify", "install")]
42+
[string] $Phase = "package",
43+
44+
[string] $Test,
45+
46+
[switch] $RunTests,
47+
48+
[switch] $NoAutoPackage,
49+
50+
[string] $JavaHome = "$env:USERPROFILE\.codex\toolchains\jdk-17",
51+
52+
[string] $MavenHome = "$env:USERPROFILE\.codex\toolchains\apache-maven-3.9.9"
53+
)
54+
55+
$ErrorActionPreference = "Stop"
56+
57+
function Get-ExistingFile([string[]] $Candidates) {
58+
foreach ($candidate in $Candidates) {
59+
if (Test-Path -LiteralPath $candidate -PathType Leaf) {
60+
return $candidate
61+
}
62+
}
63+
return $null
64+
}
65+
66+
function Join-ModuleList([string[]] $ModuleValues) {
67+
$values = @()
68+
foreach ($moduleValue in $ModuleValues) {
69+
if ([string]::IsNullOrWhiteSpace($moduleValue)) {
70+
continue
71+
}
72+
$values += ($moduleValue -split "," | ForEach-Object { $_.Trim() } | Where-Object { $_ })
73+
}
74+
return ($values -join ",")
75+
}
76+
77+
function Convert-FileToLf([string] $Path) {
78+
if (-not (Test-Path -LiteralPath $Path)) {
79+
return
80+
}
81+
82+
$utf8NoBom = New-Object System.Text.UTF8Encoding $false
83+
$content = [System.IO.File]::ReadAllText($Path, $utf8NoBom)
84+
$normalized = $content.Replace("`r`n", "`n")
85+
if ($normalized -ne $content) {
86+
[System.IO.File]::WriteAllText($Path, $normalized, $utf8NoBom)
87+
Write-Host "Normalized LF line endings for $Path"
88+
}
89+
}
90+
91+
function Get-JavaMajorVersion([string] $JavaExecutable) {
92+
$processInfo = New-Object System.Diagnostics.ProcessStartInfo
93+
$processInfo.FileName = $JavaExecutable
94+
$processInfo.Arguments = "-version"
95+
$processInfo.RedirectStandardError = $true
96+
$processInfo.RedirectStandardOutput = $true
97+
$processInfo.UseShellExecute = $false
98+
99+
$process = [System.Diagnostics.Process]::Start($processInfo)
100+
$standardError = $process.StandardError.ReadToEnd()
101+
$standardOutput = $process.StandardOutput.ReadToEnd()
102+
$process.WaitForExit()
103+
104+
$combinedOutput = "$standardError`n$standardOutput"
105+
$versionLine = $combinedOutput -split "`r?`n" |
106+
Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
107+
Select-Object -First 1
108+
109+
if ($versionLine -notmatch 'version "([^"]+)"') {
110+
throw "Could not determine Java version from: $versionLine"
111+
}
112+
113+
$versionParts = $Matches[1].Split(".")
114+
if ($versionParts[0] -eq "1" -and $versionParts.Length -gt 1) {
115+
return [int] $versionParts[1]
116+
}
117+
return [int] $versionParts[0]
118+
}
119+
120+
function Add-PathPrefix([string] $PathValue) {
121+
if (-not [string]::IsNullOrWhiteSpace($PathValue)) {
122+
$env:Path = "$PathValue;$env:Path"
123+
}
124+
}
125+
126+
$moduleList = Join-ModuleList $Modules
127+
if ([string]::IsNullOrWhiteSpace($moduleList)) {
128+
throw "At least one Maven module must be provided."
129+
}
130+
131+
$requestedPhase = $Phase
132+
$serverModules = @("server", ":cloud-server", "cloud-server")
133+
if (-not $NoAutoPackage -and $Phase -eq "compile") {
134+
$selectedModules = $moduleList -split ","
135+
foreach ($serverModule in $serverModules) {
136+
if ($selectedModules -contains $serverModule) {
137+
$Phase = "package"
138+
Write-Host "Using Maven phase 'package' instead of 'compile' because cloud-server depends on cloud-api:tests."
139+
break
140+
}
141+
}
142+
}
143+
144+
if ($env:OS -eq "Windows_NT") {
145+
Convert-FileToLf (Join-Path (Get-Location) "engine\schema\templateConfig.sh")
146+
}
147+
148+
$javaExe = Get-ExistingFile @((Join-Path $JavaHome "bin\java.exe"))
149+
$mvnCmd = Get-ExistingFile @((Join-Path $MavenHome "bin\mvn.cmd"))
150+
151+
if ($javaExe -ne $null) {
152+
$env:JAVA_HOME = $JavaHome
153+
Add-PathPrefix (Join-Path $JavaHome "bin")
154+
} else {
155+
$javaCommand = Get-Command java -ErrorAction SilentlyContinue
156+
if ($javaCommand -eq $null) {
157+
throw "Java was not found. Install Java 17+ or pass -JavaHome."
158+
}
159+
$javaExe = $javaCommand.Source
160+
}
161+
162+
$javaMajorVersion = Get-JavaMajorVersion $javaExe
163+
if ($javaMajorVersion -lt 17) {
164+
throw "Java 17+ is required for this CloudStack build. Found Java major version $javaMajorVersion at $javaExe."
165+
}
166+
167+
if ($mvnCmd -ne $null) {
168+
$env:MAVEN_HOME = $MavenHome
169+
Add-PathPrefix (Join-Path $MavenHome "bin")
170+
} else {
171+
$mvnCommand = Get-Command mvn -ErrorAction SilentlyContinue
172+
if ($mvnCommand -eq $null) {
173+
throw "Maven was not found. Install Maven or pass -MavenHome."
174+
}
175+
$mvnCmd = $mvnCommand.Source
176+
}
177+
178+
$mavenArgs = @("-pl", $moduleList, "-am")
179+
180+
if ([string]::IsNullOrWhiteSpace($Test)) {
181+
if (-not $RunTests) {
182+
$mavenArgs += @("-DskipTests", "-DskipITs")
183+
}
184+
} else {
185+
$mavenArgs += @("-Dtest=$Test", "-DfailIfNoTests=false", "-DskipITs")
186+
}
187+
188+
$mavenArgs += @("-Dcheckstyle.skip=true", "-Dspotbugs.skip=true", $Phase)
189+
190+
Write-Host "JAVA_HOME=$env:JAVA_HOME"
191+
Write-Host "MAVEN_HOME=$env:MAVEN_HOME"
192+
Write-Host "Java executable: $javaExe"
193+
Write-Host "Java major version: $javaMajorVersion"
194+
Write-Host "Requested phase: $requestedPhase"
195+
Write-Host "Effective phase: $Phase"
196+
Write-Host "Running: mvn $($mavenArgs -join ' ')"
197+
198+
& $mvnCmd @mavenArgs
199+
exit $LASTEXITCODE

0 commit comments

Comments
 (0)