From 9492bc8f7aa8176d61918d6300d14e99c9f523f5 Mon Sep 17 00:00:00 2001 From: Thibault Gagnaux Date: Sun, 19 May 2024 19:38:14 +0200 Subject: [PATCH 1/3] buildMavenPackage: add overrideMavenAttrs function --- pkgs/by-name/ma/maven/package.nix | 32 +++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/pkgs/by-name/ma/maven/package.nix b/pkgs/by-name/ma/maven/package.nix index f7d88548f36b..543949398760 100644 --- a/pkgs/by-name/ma/maven/package.nix +++ b/pkgs/by-name/ma/maven/package.nix @@ -6,7 +6,6 @@ makeWrapper, stdenvNoCC, }: - stdenvNoCC.mkDerivation (finalAttrs: { pname = "maven"; version = "3.9.9"; @@ -34,14 +33,31 @@ stdenvNoCC.mkDerivation (finalAttrs: { runHook postInstall ''; - passthru = { - buildMaven = callPackage ./build-maven.nix { - maven = finalAttrs.finalPackage; + passthru = + let + makeOverridableMavenPackage = + mavenRecipe: mavenArgs: + let + drv = mavenRecipe mavenArgs; + overrideWith = + newArgs: mavenArgs // (if lib.isFunction newArgs then newArgs mavenArgs else newArgs); + in + drv + // { + overrideMavenAttrs = newArgs: makeOverridableMavenPackage mavenRecipe (overrideWith newArgs); + }; + in + { + buildMaven = callPackage ./build-maven.nix { + maven = finalAttrs.finalPackage; + }; + + buildMavenPackage = makeOverridableMavenPackage ( + callPackage ./build-maven-package.nix { + maven = finalAttrs.finalPackage; + } + ); }; - buildMavenPackage = callPackage ./build-maven-package.nix { - maven = finalAttrs.finalPackage; - }; - }; meta = { homepage = "https://maven.apache.org/"; From cbb3cec851be63f45a18b26e058288757739736a Mon Sep 17 00:00:00 2001 From: Thibault Gagnaux Date: Mon, 20 May 2024 16:14:03 +0200 Subject: [PATCH 2/3] doc/maven: document how to override maven attrs and offline build usage. --- doc/languages-frameworks/maven.section.md | 84 +++++++++++++++++++++++ doc/redirects.json | 6 ++ 2 files changed, 90 insertions(+) diff --git a/doc/languages-frameworks/maven.section.md b/doc/languages-frameworks/maven.section.md index d6c8357785e3..88fe4d0c9224 100644 --- a/doc/languages-frameworks/maven.section.md +++ b/doc/languages-frameworks/maven.section.md @@ -49,6 +49,90 @@ This package calls `maven.buildMavenPackage` to do its work. The primary differe After setting `maven.buildMavenPackage`, we then do standard Java `.jar` installation by saving the `.jar` to `$out/share/java` and then making a wrapper which allows executing that file; see [](#sec-language-java) for additional generic information about packaging Java applications. ::: +### Overriding Maven package attributes {#maven-overriding-package-attributes} + +``` +overrideMavenAttrs :: (AttrSet -> Derivation) | ((AttrSet -> Attrset) -> Derivation) -> Derivation +``` + +The output of `buildMavenPackage` has an `overrideMavenAttrs` attribute, which is a function that takes either +- any subset of the attributes that can be passed to `buildMavenPackage` + + or +- a function that takes the argument passed to the previous invocation of `buildMavenPackage` (conventionally called `old`) and returns an attribute set that can be passed to `buildMavenPackage` + +and returns a derivation that builds a Maven package based on the old and new arguments merged. + +This is similar to [](#sec-pkg-overrideAttrs), but notably does not allow accessing the final value of the argument to `buildMavenPackage`. + +:::{.example} +### `overrideMavenAttrs` Example + +Use `overrideMavenAttrs` to build `jd-cli` version 1.2.0 and disable some flaky test: + +```nix +jd-cli.overrideMavenAttrs (old: rec { + version = "1.2.0"; + src = fetchFromGitHub { + owner = old.src.owner; + repo = old.src.repo; + rev = "${old.pname}-${version}"; + # old source hash of 1.2.0 version + hash = "sha256-US7j6tQ6mh1libeHnQdFxPGoxHzbZHqehWSgCYynKx8="; + }; + + # tests can be disabled by prefixing it with `!` + # see Maven documentation for more details: + # https://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html#Multiple_Formats_in_One + mvnParameters = lib.escapeShellArgs [ + "-Dsurefire.failIfNoSpecifiedTests=false" + "-Dtest=!JavaDecompilerTest#basicTest,!JavaDecompilerTest#patternMatchingTest" + ]; + + # old mvnHash of 1.2.0 maven dependencies + mvnHash = "sha256-N9XC1pg6Y4sUiBWIQUf16QSXCuiAPpXEHGlgApviF4I="; +}); +``` +::: + +### Offline build {#maven-offline-build} + +By default, `buildMavenPackage` does the following: + +1. Run `mvn package -Dmaven.repo.local=$out/.m2 ${mvnParameters}` in the + `fetchedMavenDeps` [fixed-output derivation](https://nixos.org/manual/nix/stable/glossary.html#gloss-fixed-output-derivation). +2. Run `mvn package -o -nsu "-Dmaven.repo.local=$mvnDeps/.m2" + ${mvnParameters}` again in the main derivation. + +As a result, tests are run twice. +This also means that a failing test will trigger a new attempt to realise the fixed-output derivation, which in turn downloads all dependencies again. +For bigger Maven projects, this might lead to a long feedback cycle. + +Use `buildOffline = true` to change the behaviour of `buildMavenPackage to the following: +1. Run `mvn de.qaware.maven:go-offline-maven-plugin:1.2.8:resolve-dependencies + -Dmaven.repo.local=$out/.m2 ${mvnDepsParameters}` in the fixed-output derivation. +2. Run `mvn package -o -nsu "-Dmaven.repo.local=$mvnDeps/.m2" + ${mvnParameters}` in the main derivation. + +As a result, all dependencies are downloaded in step 1 and the tests are executed in step 2. +A failing test only triggers a rebuild of step 2 as it can reuse the dependencies of step 1 because they have not changed. + +::: {.warning} +Test dependencies are not downloaded in step 1 and are therefore missing in +step 2 which will most probably fail the build. The `go-offline` plugin cannot +handle these so-called [dynamic dependencies](https://github.com/qaware/go-offline-maven-plugin?tab=readme-ov-file#dynamic-dependencies). +In that case you must add these dynamic dependencies manually with: +```nix +maven.buildMavenPackage rec { + manualMvnArtifacts = [ + # add dynamic test dependencies here + "org.apache.maven.surefire:surefire-junit-platform:3.1.2" + "org.junit.platform:junit-platform-launcher:1.10.0" + ]; +}; +``` +::: + ### Stable Maven plugins {#stable-maven-plugins} Maven defines default versions for its core plugins, e.g. `maven-compiler-plugin`. If your project does not override these versions, an upgrade of Maven will change the version of the used plugins, and therefore the derivation and hash. diff --git a/doc/redirects.json b/doc/redirects.json index dd0e844fbbee..37fdc4307529 100644 --- a/doc/redirects.json +++ b/doc/redirects.json @@ -3192,6 +3192,12 @@ "maven-buildmavenpackage": [ "index.html#maven-buildmavenpackage" ], + "maven-overriding-package-attributes": [ + "index.html#maven-overriding-package-attributes" + ], + "maven-offline-build": [ + "index.html#maven-offline-build" + ], "stable-maven-plugins": [ "index.html#stable-maven-plugins" ], From 49a11892ea8315ed6c4fa36f23b2d744ff2d5c0f Mon Sep 17 00:00:00 2001 From: Thibault Gagnaux Date: Wed, 27 Nov 2024 09:51:21 +0100 Subject: [PATCH 3/3] maven: add tricktron to maintainer list --- pkgs/by-name/ma/maven/package.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/by-name/ma/maven/package.nix b/pkgs/by-name/ma/maven/package.nix index 543949398760..389c4c0d6284 100644 --- a/pkgs/by-name/ma/maven/package.nix +++ b/pkgs/by-name/ma/maven/package.nix @@ -70,7 +70,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { ''; license = lib.licenses.asl20; mainProgram = "mvn"; - maintainers = [ ] ++ lib.teams.java.members; + maintainers = with lib.maintainers; [ tricktron ] ++ lib.teams.java.members; inherit (jdk_headless.meta) platforms; }; })