Problems with building "Tammy" package

Hi everyone,

I have been trying to learn more about how different projects are packaged in the Nixpkgs repository. In particular, I was looking into packaging a Matrix client called “Tammy”. Since it uses Gradle, I looked into the manual to see an example package. However, I have encountered an issue that left me stumped, in part because I do not know its workings well.

So far, I got this package file:

{
  androidenv,
  fetchFromGitLab,
  gradle_8,
  jdk17,
  makeWrapper,
  lib,
  stdenv,
  writeText,
}:

let
  androidComposition = androidenv.composeAndroidPackages {
    buildToolsVersions = [ "35.0.0" ];
    platformVersions = [ 35 ];
  };
  gradle = gradle_8.override { java = jdk17; };
in

stdenv.mkDerivation (finalAttrs: {
  pname = "tammy";
  version = "1.1.21";

  src = fetchFromGitLab {
    owner = "connect2x";
    repo = "tammy";
    tag = "v${finalAttrs.version}";
    hash = "sha256-TZF0KwDvfxIQaIyTVGa4Oh9tkBZkzO92zSvYbSzXC1o=";
  };

  nativeBuildInputs = [ androidComposition.androidsdk gradle makeWrapper ];
  gradleFlags = [ "-Dfile.encoding=utf-8" ];

  configurePhase = ''
    export ANDROID_USER_HOME=$tmpdir/.android
    mkdir -p $ANDROID_USER_HOME

    runHook preConfigure
    runHook postConfigure
  '';

  gradleInitScript = writeText "empty-init-script.gradle" "";
  mitmCache = gradle.fetchDeps {
    inherit (finalAttrs) pname;
    data = ./deps.json;
  };

})

Naturally, before building it, I first needed to generate the file with dependencies. Trying to run the command to do so, however, did not go successfully.

Initially, I did not have the configurePhase snippet, which produced the following error:

Error text:
FAILURE: Build failed with an exception.

* Where:
Build file '/tmp/nix-shell-2-3/tmp.kqknhuiojx/source/build.gradle.kts' line: 18

* What went wrong:
An exception occurred applying plugin request [id: 'com.android.application', version: '8.9.3']
> Failed to apply plugin 'com.android.internal.application'.
   > Failed to create service 'com.android.build.gradle.internal.services.AndroidLocationsBuildService_8bff33ad-a35c-4cd6-99b6-114de51369db'.
      > Could not create an instance of type com.android.build.gradle.internal.services.AndroidLocationsBuildService.
         > Could not create provider for value source AndroidLocationsBuildService.AndroidDirectoryCreator.

From what I understood, this was a matter of a writeable directory the project expects to have. That is when I added the configurePhase. After that, the error mentioned above indeed disappearaed, and the command reached the stage of downloading dependencies… until it hit a now different error:

New error text (somewhat lengthy):
Initialization script '/nix/store/wdw15x3256w3gv7jkjmaz211q3344xvc-init-deps.gradle' line: 5

* What went wrong:
Execution failed for task ':nixDownloadDeps'.
> Could not resolve all files for configuration ':DEVDebugAndroidTestCompileClasspath'.
   > The consumer was configured to find a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm'. However we cannot choose between the following variants of root project :
       - Configuration ':DEVDebugApiElements' variant android-app-symbol-for-data-binding declares a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-app-symbol-for-data-binding' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'DEVDebug' but the consumer didn't ask for it
               - Provides attribute 'version' with value 'DEV' but the consumer didn't ask for it
       - Configuration ':DEVDebugApiElements' variant android-base-module-metadata declares a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-base-module-metadata' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'DEVDebug' but the consumer didn't ask for it
               - Provides attribute 'version' with value 'DEV' but the consumer didn't ask for it
       - Configuration ':DEVDebugApiElements' variant android-classes-jar declares a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-classes-jar' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'DEVDebug' but the consumer didn't ask for it
               - Provides attribute 'version' with value 'DEV' but the consumer didn't ask for it
               - Provides its elements packaged as a jar but the consumer didn't ask for it
       - Configuration ':DEVDebugApiElements' variant android-feature-all-metadata declares a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-feature-all-metadata' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'DEVDebug' but the consumer didn't ask for it
               - Provides attribute 'version' with value 'DEV' but the consumer didn't ask for it
       - Configuration ':DEVDebugApiElements' variant android-feature-res-ap_ declares a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-feature-res-ap_' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'DEVDebug' but the consumer didn't ask for it
               - Provides attribute 'version' with value 'DEV' but the consumer didn't ask for it
       - Configuration ':DEVDebugApiElements' variant android-feature-signing-config-data declares a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-feature-signing-config-data' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'DEVDebug' but the consumer didn't ask for it
               - Provides attribute 'version' with value 'DEV' but the consumer didn't ask for it
       - Configuration ':DEVDebugApiElements' variant android-feature-signing-config-versions declares a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-feature-signing-config-versions' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'DEVDebug' but the consumer didn't ask for it
               - Provides attribute 'version' with value 'DEV' but the consumer didn't ask for it
       - Configuration ':DEVDebugApiElements' variant android-java-res declares a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-java-res' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'DEVDebug' but the consumer didn't ask for it
               - Provides attribute 'version' with value 'DEV' but the consumer didn't ask for it
       - Configuration ':DEVDebugApiElements' variant android-manifest-metadata declares a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-manifest-metadata' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'DEVDebug' but the consumer didn't ask for it
               - Provides attribute 'version' with value 'DEV' but the consumer didn't ask for it
       - Configuration ':DEVDebugApiElements' variant jar declares a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'jar' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'DEVDebug' but the consumer didn't ask for it
               - Provides attribute 'version' with value 'DEV' but the consumer didn't ask for it
               - Provides its elements packaged as a jar but the consumer didn't ask for it
       - Configuration ':DEVDebugApiElements' variant merged-test-only-native-libs declares a library for use during compile-time, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.9.3', attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'com.android.build.api.attributes.ProductFlavor:version' with value 'DEV', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'merged-test-only-native-libs' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'DEVDebug' but the consumer didn't ask for it
               - Provides attribute 'version' with value 'DEV' but the consumer didn't ask for it

I am not certain how to resolve this error; it might be something very simple that I overlooked due to inexperience, but between trying to configure more environment variables and using alternative tools, such as gradle2nix, I have not managed to overcome the problem. Does someone else have an idea what direction to take in order to resolve this issue?

I see this on the gitlab:

When running locally, you must set TAMMY_BUILD_FLAVOR to PROD (e.g. by prepending TAMMY_BUILD_FLAVOR=PROD to each command).

They might be using a custom environment setup, you might have to take that into consideration. Not a java programmer, but it looks like there is some sort of mismatch in production/developer build targets (DEVDebug everywhere).

I read that as talking about runtime, but OP’s error is happening at buildtime, right?

I read that as talking about runtime, but OP’s error is happening at buildtime, right?

Yes. Probably was irrelevant to bring up.

I gave it a go still, just in case I had previously incorrectly passed the variable. Unfortunately, the error persists, just without the “DEV” tag.

That said, yeah, this error isn’t occurring during the runtime, but rather, appears while running nix-build -A tammy.mitmCache.updateScript; looking at gradle-update-script, it builds the derivation’s source, runs some early phases, then runs the update script for it to fetch dependencies to generate the deps.json file.

When I tried to look at the file and the line which returns the error, I saw this: configurations.findAll{it.canBeResolved}.each{it.resolve()}, which makes sense in the context of the error, though I’m not sure why it’s this dependency specifically that results in an issue.