blob: 406e1becfa1862f2615cac2d5ba3c8a9957d1b59 [file] [log] [blame]
import java.util.regex.Matcher
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
allConditionsMet = true
baseDirectory = project.model.pomFile.parent
/*
Checks if a given version number is at least as high as a given reference version.
*/
def checkVersionAtLeast(String current, String minimum) {
def currentSegments = current.tokenize('.')
def minimumSegments = minimum.tokenize('.')
def numSegments = Math.min(currentSegments.size(), minimumSegments.size())
for (int i = 0; i < numSegments; ++i) {
def currentSegment = currentSegments[i].toInteger()
def minimumSegment = minimumSegments[i].toInteger()
if (currentSegment < minimumSegment) {
println current.padRight(14) + " FAILED (required min " + minimum + " but got " + current + ")"
return false
} else if (currentSegment > minimumSegment) {
println current.padRight(14) + " OK"
return true
}
}
def curNotShorter = currentSegments.size() >= minimumSegments.size()
if (curNotShorter) {
println current.padRight(14) + " OK"
} else {
println current.padRight(14) + " (required min " + minimum + " but got " + current + ")"
}
curNotShorter
}
def checkVersionAtMost(String current, String maximum) {
def currentSegments = current.tokenize('.')
def maximumSegments = maximum.tokenize('.')
def numSegments = Math.min(currentSegments.size(), maximumSegments.size())
for (int i = 0; i < numSegments; ++i) {
def currentSegment = currentSegments[i].toInteger()
def maximumSegment = maximumSegments[i].toInteger()
if (currentSegment > maximumSegment) {
println current.padRight(14) + " FAILED (required max " + maximum + " but got " + current + ")"
return false
} else if (currentSegment < maximumSegment) {
println current.padRight(14) + " OK"
return true
}
}
def curNotShorter = currentSegments.size() >= maximumSegments.size()
if (curNotShorter) {
println current.padRight(14) + " OK"
} else {
println current.padRight(14) + " (required max " + maximum + " but got " + current + ")"
}
curNotShorter
}
def checkDotnet() {
print "Detecting Dotnet version: "
def output = new StringBuffer()
def errOutput = new StringBuffer()
try {
def proc = "dotnet --version".execute()
proc.waitForProcessOutput(output, errOutput)
} catch (IOException e) {
output = ""
errOutput.append(e)
}
Matcher matcher = extractVersion(output)
if (matcher.size() > 0) {
String curVersion = matcher[0][1]
def result = checkVersionAtLeast(curVersion, "4.5.2")
if (!result) {
allConditionsMet = false
}
} else {
println "missing"
println "--- output of version `dotnet --version` command ---"
println output
println errOutput
println "----------------------------------------------------"
allConditionsMet = false
}
}
def checkJavaVersion(String minVersion, String maxVersion) {
print "Detecting Java version: "
String curVersion = System.properties['java.version'].split("-")[0]
def result
if (minVersion != null) {
result = checkVersionAtLeast(curVersion, minVersion)
if (!result) {
allConditionsMet = false
return
}
}
if (maxVersion != null) {
result = checkVersionAtMost(curVersion, maxVersion)
if (!result) {
allConditionsMet = false
}
}
}
def checkMavenVersion(String minVersion, String maxVersion) {
print "Detecting Maven version: "
String curVersion = project.projectBuilderConfiguration.systemProperties['maven.version']
def result
if (minVersion != null) {
result = checkVersionAtLeast(curVersion, minVersion)
if (!result) {
allConditionsMet = false
return
}
}
if (maxVersion != null) {
result = checkVersionAtMost(curVersion, maxVersion)
if (!result) {
allConditionsMet = false
}
}
}
def checkGcc() {
print "Detecting Gcc version: "
// TODO: For windows, check that mingw32-make is on the PATH
def output = new StringBuffer()
def errOutput = new StringBuffer()
try {
def proc = "gcc --version".execute()
proc.waitForProcessOutput(output, errOutput)
} catch (IOException ignored) {
output = ""
errOutput.append(e)
}
Matcher matcher = extractVersion(output)
if (matcher.size() > 0) {
String curVersion = matcher[0][1]
def result = checkVersionAtLeast(curVersion, "1.0.0")
if (!result) {
allConditionsMet = false
}
} else {
println "missing"
println "--- output of version `gcc --version` command ---"
println output
println errOutput
println "-------------------------------------------------"
allConditionsMet = false
}
}
def checkGit() {
print "Detecting Git version: "
def output = new StringBuffer()
def errOutput = new StringBuffer()
try {
def proc = "git --version".execute()
proc.waitForProcessOutput(output, errOutput)
} catch (IOException ignored) {
output = ""
errOutput.append(e)
}
Matcher matcher = extractVersion(output)
if (matcher.size() > 0) {
String curVersion = matcher[0][1]
def result = checkVersionAtLeast(curVersion, "1.0.0")
if (!result) {
allConditionsMet = false
}
} else {
println "missing"
println "--- output of version `git --version` command ---"
println output
println errOutput
println "-------------------------------------------------"
allConditionsMet = false
}
}
// Remark: We're using venv, which was introduced with python 3.3,
// that's why this is the baseline for python.
def checkPython() {
String python = project.properties['python.exe.bin']
println "Using python executable: " + python.padRight(14) + " OK"
print "Detecting Python version: "
try {
def process = (python + " --version").execute()
def stdOut = new StringBuilder()
def stdErr = new StringBuilder()
process.waitForProcessOutput(stdOut, stdErr)
Matcher matcher = extractVersion(stdOut + stdErr)
if (matcher.size() > 0) {
String curVersion = matcher[0][1]
def result = checkVersionAtLeast(curVersion, "3.7.0")
if (!result) {
allConditionsMet = false
}
} else {
println "missing (Please install at least version 3.7.0)"
allConditionsMet = false
}
} catch (Exception ignored) {
println "missing"
println "--- output of version `${python} --version` command ---"
println output
println "----------------------------------------------------"
allConditionsMet = false
}
}
// On Ubuntu it seems that venv is generally available, but the 'ensurepip' command fails.
// In this case we need to install the python3-venv package. Unfortunately checking the
// venv is successful in this case, so we need this slightly odd test.
def checkPythonVenv() {
print "Detecting venv: "
try {
def python = project.properties['python.exe.bin']
def cmdArray = [python, "-Im", "ensurepip"]
def process = cmdArray.execute()
def stdOut = new StringBuilder()
def stdErr = new StringBuilder()
process.waitForProcessOutput(stdOut, stdErr)
if (stdErr.contains("No module named")) {
println "missing"
println "--- output of version `python -Im \"ensurepip\"` command ---"
println output
println "------------------------------------------------------------"
allConditionsMet = false
} else {
println " OK"
}
} catch (Exception e) {
println "missing"
println "--- failed with exception ---"
println e
e.printStackTrace()
println "----------------------------------------------------"
allConditionsMet = false
}
}
// When building the StreamPipes modules we need Docker.
// Not only should the docker executable be available, but also should the docker daemon be running.
def checkDocker() {
print "Detecting Docker version: "
def output = new StringBuilder()
def errOutput = new StringBuilder()
try {
def proc = "docker info".execute()
proc.waitForProcessOutput(output, errOutput)
} catch (IOException e) {
output = ""
errOutput.append(e)
}
// Check if Docker is installed at all
def matcher1 = output =~ /Server:/
if (matcher1.size() > 0) {
// If it is check if the daemon is running and if the version is ok
def matcher2 = output =~ /Server Version: (\d+\.\d+(\.\d+)?).*/
if (matcher2.size() > 0) {
String curVersion = matcher2[0][1]
def result = checkVersionAtLeast(curVersion, "1.0.0")
if (!result) {
allConditionsMet = false
}
} else {
println "Docker daemon probably not running"
allConditionsMet = false
}
} else {
println "missing"
println "--- output of version `docker info` command ---"
println output
println errOutput
println "-----------------------------------------------"
allConditionsMet = false
}
// TODO: Implement the actual check ...
}
def checkLibPcap(String minVersion, String os, String arch) {
print "Detecting LibPcap version: "
try {
// For some reason it doesn't work, if we pass this in from the outside.
if (os == "mac") {
// On my Intel Mac I found the libs in: "/usr/local/Cellar/libpcap/1.10.1/lib"
// On my M1 Mac I found the libs in: "/opt/homebrew/Cellar/libpcap/1.10.1/lib"
if (new File("/usr/local/Cellar/libpcap/1.10.1/lib").exists()) {
System.getProperties().setProperty("jna.library.path", "/usr/local/Cellar/libpcap/1.10.1/lib");
println("Found library: Be sure to run your application with '-Djna.library.path=/opt/homebrew/Cellar/libpcap/1.10.1/lib'")
} else if (new File("/usr/local/Cellar/libpcap/1.10.5/lib").exists()) {
System.getProperties().setProperty("jna.library.path", "/usr/local/Cellar/libpcap/1.10.5/lib");
println("Found library: Be sure to run your application with '-Djna.library.path=/opt/homebrew/Cellar/libpcap/1.10.5/lib'")
} else if (new File("/opt/homebrew/opt/libpcap/lib").exists()) {
System.getProperties().setProperty("jna.library.path", "/opt/homebrew/opt/libpcap/lib");
println("Found library: Be sure to run your application with '-Djna.library.path=/opt/homebrew/opt/libpcap/lib'")
}
}
output = org.pcap4j.core.Pcaps.libVersion()
Matcher matcher = extractVersion(output)
if (matcher.size() > 0) {
String version = matcher[0][1]
def result = checkVersionAtLeast(version, minVersion)
if (!result) {
allConditionsMet = false
}
} else {
println "unable to parse version from: " + output
allConditionsMet = false
}
} catch (Error e) {
output = ""
println "missing"
println "--- exception ---"
println e
e.printStackTrace()
println "-----------------"
allConditionsMet = false
}
}
def checkLibPcapHeaders() {
}
/**
* Version extraction function/macro. It looks for occurrence of x.y or x.y.z
* in passed input text (likely output from `program --version` command if found).
*
* @param input
* @return
*/
private static Matcher extractVersion(input) {
def matcher = input =~ /(\d+\.\d+(\.\d+)?).*/
matcher
}
/////////////////////////////////////////////////////
// Find out which OS and arch are bring used.
/////////////////////////////////////////////////////
println "Os name: ${System.getProperty("os.name")}"
println "Os arch: ${System.getProperty("os.arch")}"
println "Os version: ${System.getProperty("os.version")}"
def osString = project.properties['os.classifier']
def osMatcher = osString =~ /(.*)-(.*)/
if (osMatcher.size() == 0) {
throw new RuntimeException("Currently unsupported OS. Actual os string: $osString")
}
def os = osMatcher[0][1]
def arch = osMatcher[0][2]
println "Detected OS: $os"
println "Detected Arch: $arch"
/////////////////////////////////////////////////////
// Find out which profiles are enabled.
/////////////////////////////////////////////////////
def cEnabled = false
def dotnetEnabled = false
def goEnabled = false
// Java is always enabled ...
def javaEnabled = false
def pythonEnabled = false
def apacheReleaseEnabled = false
def activeProfiles = session.request.activeProfiles
for (def activeProfile : activeProfiles) {
if (activeProfile == "with-c") {
cEnabled = true
} else if (activeProfile == "with-dotnet") {
dotnetEnabled = true
} else if (activeProfile == "with-go") {
goEnabled = true
} else if (activeProfile == "with-java") {
javaEnabled = true
} else if (activeProfile == "with-python") {
pythonEnabled = true
} else if (activeProfile == "apache-release") {
apacheReleaseEnabled = true
}
}
println ""
// - Windows:
// - Check the length of the path of the base dir as we're having issues with the length of paths being too long.
if (os == "windows") {
File pomFile = project.model.pomFile
if (pomFile.absolutePath.length() > 100) {
println "On Windows we encounter problems with maximum path lengths. " +
"Please move the project to a place it has a shorter base path " +
"and run the build again."
allConditionsMet = false;
}
}
/////////////////////////////////////////////////////
// Do the actual checks depending on the enabled
// profiles.
/////////////////////////////////////////////////////
checkJavaVersion("21", null)
if (dotnetEnabled) {
checkDotnet()
}
if (javaEnabled) {
checkGit()
}
if (cEnabled) {
checkGcc()
}
if (goEnabled) {
checkLibPcapHeaders()
}
if (pythonEnabled) {
checkPython()
checkPythonVenv()
}
if (cEnabled) {
// CMake requires at least maven 3.6.0
checkMavenVersion("3.6.0", null)
}
if (apacheReleaseEnabled) {
// TODO: Check libpcap is installed
}
if (os == "mac") {
// The current system version from mac crashes so we assert for a version coming with brew
checkLibPcap("1.10.1", os, arch)
}
if (!allConditionsMet) {
throw new RuntimeException("Not all conditions met, see log for details.")
}
println ""
println "All known conditions met successfully."
println ""
// Things we could possibly check:
// - DNS Providers that return a default ip on unknown host-names
// - Availability and version of LibPCAP/NPCAP