Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/fetchers.nix
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ rec {
}:
fetcher:
let
inherit (lib.attrsets) genAttrs intersectAttrs removeAttrs;
inherit (lib.trivial) const functionArgs setFunctionArgs;
inherit (lib.attrsets) intersectAttrs removeAttrs;
inherit (lib.trivial) functionArgs setFunctionArgs;

inherit (commonH hashTypes) hashSet;
fArgs = functionArgs fetcher;
Expand Down
31 changes: 27 additions & 4 deletions pkgs/by-name/ma/maven/build-maven-package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
stdenv,
jdk,
maven,
writers,
}:

{
Expand All @@ -28,6 +29,9 @@

let
mvnSkipTests = lib.optionalString (!doCheck) "-DskipTests";

writeProxySettings = writers.writePython3 "write-proxy-settings" { } ./maven-proxy.py;

fetchedMavenDeps = stdenv.mkDerivation (
{
name = "${pname}-${version}-maven-deps";
Expand All @@ -39,29 +43,48 @@ let

JAVA_HOME = mvnJdk;

impureEnvVars = lib.fetchers.proxyImpureEnvVars;

buildPhase =
''
runHook preBuild

MAVEN_EXTRA_ARGS=""

# handle proxy
if [[ -n "''${HTTP_PROXY-}" ]] || [[ -n "''${HTTPS_PROXY-}" ]] || [[ -n "''${NO_PROXY-}" ]];then
mvnSettingsFile="$(mktemp -d)/settings.xml"
${writeProxySettings} $mvnSettingsFile
MAVEN_EXTRA_ARGS="-s=$mvnSettingsFile"
fi

# handle cacert by populating a trust store on the fly
if [[ -n "''${NIX_SSL_CERT_FILE-}" ]] && [[ "''${NIX_SSL_CERT_FILE-}" != "/no-cert-file.crt" ]];then
keyStoreFile="$(mktemp -d)/keystore"
keyStorePwd="$(head -c10 /dev/random | base32)"
echo y | ${jdk}/bin/keytool -importcert -file "$NIX_SSL_CERT_FILE" -alias alias -keystore "$keyStoreFile" -storepass "$keyStorePwd"
MAVEN_EXTRA_ARGS="$MAVEN_EXTRA_ARGS -Djavax.net.ssl.trustStore=$keyStoreFile -Djavax.net.ssl.trustStorePassword=$keyStorePwd"
fi
''
+ lib.optionalString buildOffline ''
mvn de.qaware.maven:go-offline-maven-plugin:1.2.8:resolve-dependencies -Dmaven.repo.local=$out/.m2 ${mvnDepsParameters}
mvn $MAVEN_EXTRA_ARGS de.qaware.maven:go-offline-maven-plugin:1.2.8:resolve-dependencies -Dmaven.repo.local=$out/.m2 ${mvnDepsParameters}

for artifactId in ${builtins.toString manualMvnArtifacts}
do
echo "downloading manual $artifactId"
mvn dependency:get -Dartifact="$artifactId" -Dmaven.repo.local=$out/.m2
mvn $MAVEN_EXTRA_ARGS dependency:get -Dartifact="$artifactId" -Dmaven.repo.local=$out/.m2
done

for artifactId in ${builtins.toString manualMvnSources}
do
group=$(echo $artifactId | cut -d':' -f1)
artifact=$(echo $artifactId | cut -d':' -f2)
echo "downloading manual sources $artifactId"
mvn dependency:sources -DincludeGroupIds="$group" -DincludeArtifactIds="$artifact" -Dmaven.repo.local=$out/.m2
mvn $MAVEN_EXTRA_ARGS dependency:sources -DincludeGroupIds="$group" -DincludeArtifactIds="$artifact" -Dmaven.repo.local=$out/.m2
done
''
+ lib.optionalString (!buildOffline) ''
mvn package -Dmaven.repo.local=$out/.m2 ${mvnSkipTests} ${mvnParameters}
mvn $MAVEN_EXTRA_ARGS package -Dmaven.repo.local=$out/.m2 ${mvnSkipTests} ${mvnParameters}
''
+ ''
runHook postBuild
Expand Down
86 changes: 86 additions & 0 deletions pkgs/by-name/ma/maven/maven-proxy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
Maven doesn't honor HTTP[S]_PROXY and NO_PROXY env vars out of the box.
Instead, it expects the user to configure a settings.xml file.
We however impurely pass only these env vars in FODs.
This creates the XML file on demand, if one or more env vars is set.
"""

import os
import sys
from urllib.parse import urlparse


def parse_proxy_url(url):
if url is None:
return None
parsed = urlparse(url)

if parsed.hostname is None:
print(f"Failed to parse proxy URL {url}, ignoring", file=sys.stderr)
return None

return {
'protocol': parsed.scheme or 'http',
'host': parsed.hostname,
'port': parsed.port or (443 if parsed.scheme == 'https' else 80),
'username': parsed.username,
'password': parsed.password
}


def format_proxy_block(proxy, id_suffix, non_proxy_hosts):
auth = ""
if proxy.get("username"):
auth += f" <username>{proxy['username']}</username>\n"
if proxy.get("password"):
auth += f" <password>{proxy['password']}</password>\n"

np_hosts = ""
if non_proxy_hosts:
np_hosts = f" <nonProxyHosts>{non_proxy_hosts}</nonProxyHosts>\n"

return f""" <proxy>
<id>{id_suffix}-proxy</id>
<active>true</active>
<protocol>{proxy['protocol']}</protocol>
<host>{proxy['host']}</host>
<port>{proxy['port']}</port>
{auth}{np_hosts} </proxy>"""


def main(output_path):
http_proxy = parse_proxy_url(os.environ.get("HTTP_PROXY"))
https_proxy = parse_proxy_url(os.environ.get("HTTPS_PROXY"))
non_proxy_hosts = os.environ.get("NO_PROXY", "").replace(",", "|")

proxy_blocks = []

if http_proxy:
proxy_blocks.append(
format_proxy_block(http_proxy, "http", non_proxy_hosts)
)
if https_proxy and https_proxy != http_proxy:
proxy_blocks.append(
format_proxy_block(https_proxy, "https", non_proxy_hosts)
)

settings_xml = f"""<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<proxies>
{'\n'.join(proxy_blocks)}
</proxies>
</settings>
"""

with open(output_path, "w") as f:
f.write(settings_xml)

print(f"Generated Maven settings.xml at {output_path}")


if __name__ == "__main__":
output_file = sys.argv[1] if len(sys.argv) > 1 else "settings.xml"
main(output_file)