Skip to content

Commit d79dde0

Browse files
committed
graphhopper: init at 10.2
- Adds the graphhopper package.nix to nixpkgs -> This is an open source routing engine written in java and built with maven using the "double-invocation" pattern - see `doc/languages-frameworks/maven.md`. - Additionally, comes with a patch to it's pom.xml because it includes [frontend-maven-plugin](https://github.com/eirslett/frontend-maven-plugin), which tries to install node/npm during the build phase, which does not work. Hence, we fetch the single npm package required manually.
1 parent 9510aef commit d79dde0

File tree

4 files changed

+317
-0
lines changed

4 files changed

+317
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
{
2+
fetchFromGitHub,
3+
fetchurl,
4+
lib,
5+
stdenv,
6+
testers,
7+
8+
jre,
9+
makeWrapper,
10+
maven,
11+
...
12+
}:
13+
let
14+
version = builtins.fromTOML (builtins.readFile ./version.toml);
15+
16+
src = fetchFromGitHub {
17+
owner = "graphhopper";
18+
repo = "graphhopper";
19+
tag = version.patch;
20+
hash = version.hash.src;
21+
};
22+
23+
# Patch graphhopper to remove the npm download
24+
patches = [ ./remove-npm-dependency.patch ];
25+
26+
# Graphhopper also relies on a maps bundle downloaded from npm
27+
# By default it installs nodejs and npm during the build,
28+
# But we patch that out so we much fetch it ourselves
29+
mapsBundle = fetchurl {
30+
name = "@graphhopper/graphhopper-maps-bundle-${version.mapsBundle}";
31+
url = "https://registry.npmjs.org/@graphhopper/graphhopper-maps-bundle/-/graphhopper-maps-bundle-${version.mapsBundle}.tgz";
32+
hash = version.hash.mapsBundle;
33+
};
34+
35+
# We cannot use `buildMavenPackage` as we need to load in the
36+
# mapsBundle before doing anything
37+
mvnDeps = stdenv.mkDerivation {
38+
name = "graphhopper-dependencies";
39+
40+
inherit src patches;
41+
42+
buildInputs = [ maven ];
43+
44+
buildPhase = ''
45+
# Fetching deps with mvn dependency:go-offline does not quite catch everything, so we use this plugin instead
46+
mvn de.qaware.maven:go-offline-maven-plugin:resolve-dependencies \
47+
-Dmaven.repo.local=$out/.m2 \
48+
-Dmaven.wagon.rto=5000
49+
'';
50+
51+
installPhase = ''
52+
# keep only *.{pom,jar,sha1,nbm} and delete all ephemeral files with lastModified timestamps inside
53+
find $out -type f \( \
54+
-name \*.lastUpdated \
55+
-o -name resolver-status.properties \
56+
-o -name _remote.repositories \) \
57+
-delete
58+
'';
59+
60+
outputHashMode = "recursive";
61+
outputHash = version.hash.mvnDeps;
62+
};
63+
in
64+
stdenv.mkDerivation (finalAttrs: {
65+
pname = "graphhopper";
66+
67+
inherit src patches;
68+
69+
version = version.patch;
70+
71+
buildInputs = [
72+
makeWrapper
73+
maven
74+
];
75+
76+
configurePhase = ''
77+
runHook preConfigure
78+
79+
mkdir -p ./web-bundle/target/
80+
ln -s ${mapsBundle} ./web-bundle/target/graphhopper-graphhopper-maps-bundle-${version.mapsBundle}.tgz
81+
82+
runHook postConfigure
83+
'';
84+
85+
# Build and skip tests because downloading of
86+
# test deps seems to not work with the go-offline plugin
87+
buildPhase = ''
88+
runHook preBuild
89+
90+
mvn package --offline \
91+
-Dmaven.repo.local=${mvnDeps}/.m2 \
92+
-DskipTests
93+
94+
runHook postBuild
95+
'';
96+
97+
installPhase = ''
98+
runHook preInstall
99+
100+
mkdir -p $out/bin
101+
102+
ln -s ${mvnDeps}/.m2 $out/lib
103+
104+
# Grapphopper versions are seemingly compiled under the major release name,
105+
# not the patch name, which is the version we want for our package
106+
cp ./web/target/graphhopper-web-${version.major}-SNAPSHOT.jar $out/bin/graphhopper-web-${version.major}-SNAPSHOT.jar
107+
108+
makeWrapper ${jre}/bin/java $out/bin/graphhopper \
109+
--add-flags "-jar $out/bin/graphhopper-web-${version.major}-SNAPSHOT.jar" \
110+
--chdir $out
111+
112+
runHook postInstall
113+
'';
114+
115+
fixupPhase = ''
116+
runHook preFixup
117+
118+
# keep only *.{pom,jar,sha1,nbm} and delete all ephemeral files with lastModified timestamps inside
119+
find $out -type f \( \
120+
-name \*.lastUpdated \
121+
-o -name resolver-status.properties \
122+
-o -name _remote.repositories \) \
123+
-delete
124+
125+
runHook postFixup
126+
'';
127+
128+
meta = {
129+
description = "Fast and memory-efficient routing engine for OpenStreetMap";
130+
homepage = "https://www.graphhopper.com/";
131+
changelog = "https://github.com/graphhopper/graphhopper/releases/tag/${version.patch}";
132+
license = lib.licenses.asl20;
133+
maintainers = with lib.maintainers; [ baileylu ];
134+
teams = [ lib.teams.geospatial ];
135+
platforms = lib.platforms.all;
136+
mainProgram = "graphhopper";
137+
sourceProvenance = with lib.sourceTypes; [
138+
fromSource
139+
binaryBytecode
140+
];
141+
};
142+
143+
passthru = {
144+
updateScript = ./update.nu;
145+
tests.version = testers.testVersion {
146+
package = finalAttrs.finalPackage;
147+
# `graphhopper --version` does not work as the source does not specify `Implementation-Version`
148+
command = "graphhopper --help";
149+
version = "graphhopper-web-${version.major}-SNAPSHOT.jar";
150+
};
151+
};
152+
})
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
From ad687709cfca51603264ff565f296cfb5dceb15a Mon Sep 17 00:00:00 2001
2+
From: Luke Bailey <[email protected]>
3+
Date: Wed, 19 Mar 2025 22:25:44 +0000
4+
Subject: [PATCH] Swap out frontend maven plugin which downloads npm
5+
for fetching it through nix instead
6+
7+
---
8+
web-bundle/pom.xml | 31 -------------------------------
9+
1 file changed, 31 deletions(-)
10+
11+
diff --git a/web-bundle/pom.xml b/web-bundle/pom.xml
12+
index 9a4d83b62..1d995cbaf 100644
13+
--- a/web-bundle/pom.xml
14+
+++ b/web-bundle/pom.xml
15+
@@ -129,37 +129,6 @@
16+
17+
<build>
18+
<plugins>
19+
- <plugin>
20+
- <groupId>com.github.eirslett</groupId>
21+
- <artifactId>frontend-maven-plugin</artifactId>
22+
- <version>1.12.1</version>
23+
- <executions>
24+
- <execution>
25+
- <id>install node and npm</id>
26+
- <goals>
27+
- <goal>install-node-and-npm</goal>
28+
- </goals>
29+
- <configuration>
30+
- <nodeVersion>v20.14.0</nodeVersion>
31+
- <npmVersion>10.7.0</npmVersion>
32+
- </configuration>
33+
- </execution>
34+
- <execution>
35+
- <id>download graphhopper maps</id>
36+
- <phase>generate-resources</phase>
37+
- <goals>
38+
- <goal>npm</goal>
39+
- </goals>
40+
- <configuration>
41+
- <!--suppress UnresolvedMavenProperty (IntelliJ shows an error otherwise...)-->
42+
- <arguments>
43+
- pack --pack-destination=${basedir}/target
44+
- @graphhopper/graphhopper-maps-bundle@${graphhopper-maps.version}
45+
- </arguments>
46+
- </configuration>
47+
- </execution>
48+
- </executions>
49+
- </plugin>
50+
<plugin>
51+
<artifactId>maven-antrun-plugin</artifactId>
52+
<executions>
53+
--
54+
2.48.1
55+
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/usr/bin/env nix-shell
2+
#! nix-shell -i nu -p nushell nix-prefetch-github common-updater-scripts
3+
4+
use std/log
5+
6+
let version_info = "./pkgs/by-name/gr/graphhopper/version.toml"
7+
8+
let current_version = open $version_info
9+
10+
let latest_tag = list-git-tags --url=https://github.com/graphhopper/graphhopper
11+
| lines
12+
| sort --natural
13+
| where ($it =~ '^[\d.]+$')
14+
| last
15+
16+
if $current_version.patch == $latest_tag {
17+
log debug "Current graphhopper version matched latest version of graphhopper, no update is needed, exiting..."
18+
exit 0
19+
}
20+
21+
let major = $latest_tag
22+
| str replace -ar '(\d+)\.\d+' '$1.0'
23+
24+
log debug $"Fetching source for graphhopper patch ($latest_tag) on version ($major)"
25+
let source = nix-prefetch-github graphhopper graphhopper --rev $latest_tag
26+
| from json
27+
28+
log debug $"Reading maps bundle version for ($latest_tag)"
29+
let web_bundle_pom = http get $"https://api.github.com/repos/graphhopper/graphhopper/contents/web-bundle/pom.xml?ref=($latest_tag)"
30+
| $in.content
31+
| base64 --decode
32+
| into string
33+
| from xml
34+
35+
let maps_bundle_properties = $web_bundle_pom.content
36+
| where ($it.tag =~ "properties")
37+
| first
38+
39+
let maps_bundle_version = $maps_bundle_properties.content
40+
| where ($it.tag =~ "graphhopper-maps.version")
41+
| first
42+
| $in.content
43+
| first
44+
| $in.content
45+
46+
log debug $"Fetching maps bundle ($maps_bundle_version)"
47+
let maps_bundle_hash = nix-prefetch-url $"https://registry.npmjs.org/@graphhopper/graphhopper-maps-bundle/-/graphhopper-maps-bundle-($maps_bundle_version).tgz"
48+
| nix-hash --type sha256 --to-base64 $in
49+
| ["sha256-", $in]
50+
| str join
51+
52+
log debug $"Writing to ($version_info) without mvnDeps hash..."
53+
54+
{
55+
major: $major,
56+
patch: $latest_tag,
57+
mapsBundle: $maps_bundle_version,
58+
59+
hash: {
60+
src: $source.hash
61+
mapsBundle: $maps_bundle_hash
62+
mvnDeps: "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
63+
}
64+
}
65+
| to toml
66+
| save $version_info -f
67+
68+
log debug "Calculating mvnDeps hash..."
69+
let graphhopper_build_logs = nix-build -A graphhopper o+e>| cat
70+
71+
let mvn_hash_lines = $graphhopper_build_logs
72+
| lines
73+
| find "got:"
74+
75+
if ($mvn_hash_lines | length) == 0 {
76+
log error $"Could not find any maven hash in the graphhopper build logs - maybe a different error occurred: \n$($graphhopper_build_logs)"
77+
exit 1
78+
}
79+
80+
log debug $"Found relevant hash lines: ($mvn_hash_lines)"
81+
let mvn_hash = $mvn_hash_lines
82+
| first
83+
| ansi strip
84+
| str replace 'got:' ''
85+
| str trim
86+
87+
log debug $"Writing to ($version_info) with mvnDeps hash ($mvn_hash).."
88+
{
89+
major: $major,
90+
patch: $latest_tag,
91+
mapsBundle: $maps_bundle_version,
92+
93+
hash: {
94+
src: $source.hash
95+
mapsBundle: $maps_bundle_hash
96+
mvnDeps: $mvn_hash
97+
}
98+
}
99+
| to toml
100+
| save $version_info -f
101+
102+
log debug $"Successfully updated graphhopper package!"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
major = "10.0"
2+
patch = "10.2"
3+
mapsBundle = "0.0.0-4718098d1db1798841a4d12f1727e8e8f7eab202"
4+
5+
[hash]
6+
src = "sha256-E6G9JR1lrXhNJ4YgMM0n0RsQcMZQM2QldGc74f5FALo="
7+
mapsBundle = "sha256-jZTNJfmMWJQHpJ8um3yTBx/KtIfdr0EwKJ9kSFalWJQ="
8+
mvnDeps = "sha256-KidbIBnW//IiKPFy3plFWOED8gP/ZCg4buwMgzttaY8="

0 commit comments

Comments
 (0)