summary refs log tree commit diff
path: root/pkgs/applications/networking/instant-messengers/signald/default.nix
blob: b15dbbb92bdb2b39955e59d97d1fe3950e509db7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
{ lib, stdenv, fetchurl, fetchFromGitLab, jdk17_headless, coreutils, gradle, git, perl
, makeWrapper, fetchpatch, substituteAll, jre_minimal
}:

# NOTE: when updating the package, please check if some of the hacks in `deps.installPhase`
# can be removed again!

let
  pname = "signald";
  version = "0.23.2";

  src = fetchFromGitLab {
    owner = pname;
    repo = pname;
    rev = version;
    sha256 = "sha256-EofgwZSDp2ZFhlKL2tHfzMr3EsidzuY4pkRZrV2+1bA=";
  };

  jre' = jre_minimal.override {
    jdk = jdk17_headless;
    # from https://gitlab.com/signald/signald/-/blob/0.23.0/build.gradle#L173
    modules = [
      "java.base"
      "java.management"
      "java.naming"
      "java.sql"
      "java.xml"
      "jdk.crypto.ec"
      "jdk.httpserver"

      # for java/beans/PropertyChangeEvent
      "java.desktop"
      # for sun/misc/Unsafe
      "jdk.unsupported"
    ];
  };

  # fake build to pre-download deps into fixed-output derivation
  deps = stdenv.mkDerivation {
    pname = "${pname}-deps";
    inherit src version;
    nativeBuildInputs = [ gradle perl ];
    patches = [ ./0001-Fetch-buildconfig-during-gradle-build-inside-Nix-FOD.patch ];
    buildPhase = ''
      export GRADLE_USER_HOME=$(mktemp -d)
      gradle --no-daemon build
    '';
    installPhase = ''
      find $GRADLE_USER_HOME/caches/modules-2 -type f -regex '.*\.\(jar\|pom\)' \
        | perl -pe 's#(.*/([^/]+)/([^/]+)/([^/]+)/[0-9a-f]{30,40}/([^/\s]+))$# ($x = $2) =~ tr|\.|/|; "install -Dm444 $1 \$out/$x/$3/$4/$5" #e' \
        | sh -x

      # WARNING: don't try this at home and wear safety-goggles while working with this!
      # We patch around in the dependency tree to resolve some spurious dependency resolution errors.
      # Whenever this package gets updated, please check if some of these hacks are obsolete!

      # Mimic existence of okio-3.2.0.jar. Originally known as okio-jvm-3.2.0 (and renamed),
      # but gradle doesn't detect such renames, only fetches the latter and then fails
      # in `signald.buildPhase` because it cannot find `okio-3.2.0.jar`.
      pushd $out/com/squareup/okio/okio/3.2.0 &>/dev/null
        cp -v ../../okio-jvm/3.2.0/okio-jvm-3.2.0.jar okio-3.2.0.jar
      popd &>/dev/null

      # For some reason gradle fetches 2.14.1 instead of 2.14.0 here even though 2.14.0 is required
      # according to `./gradlew -q dependencies`, so we pretend to have 2.14.0 available here.
      # According to the diff in https://github.com/FasterXML/jackson-dataformats-text/compare/jackson-dataformats-text-2.14.0...jackson-dataformats-text-2.14.1
      # the only relevant change is in the code itself (and in the tests/docs), so this seems
      # binary-compatible.
      cp -v \
        $out/com/fasterxml/jackson/dataformat/jackson-dataformat-toml/2.14.1/jackson-dataformat-toml-2.14.1.jar \
        $out/com/fasterxml/jackson/dataformat/jackson-dataformat-toml/2.14.0/jackson-dataformat-toml-2.14.0.jar
    '';
    # Don't move info to share/
    forceShare = [ "dummy" ];
    outputHashAlgo = "sha256";
    outputHashMode = "recursive";
    # Downloaded jars differ by platform
    outputHash = {
      x86_64-linux = "sha256-9DHykkvazVBN2kfw1Pbejizk/R18v5w8lRBHZ4aXL5Q=";
      aarch64-linux = "sha256-RgAiRbUojBc+9RN/HpAzzpTjkjZ6q+jebDsqvah5XBw=";
    }.${stdenv.system} or (throw "Unsupported platform");
  };

in stdenv.mkDerivation {
  inherit pname src version;

  patches = [
    (substituteAll {
      src = ./0002-buildconfig-local-deps-fixes.patch;
      inherit deps;
    })
  ];

  passthru = {
    # Mostly for debugging purposes.
    inherit deps;
  };

  buildPhase = ''
    runHook preBuild

    export GRADLE_USER_HOME=$(mktemp -d)

    gradle --offline --no-daemon distTar

    runHook postBuild
  '';

  installPhase = ''
    runHook preInstall

    mkdir -p $out
    tar xvf ./build/distributions/signald.tar --strip-components=1 --directory $out/
    wrapProgram $out/bin/signald \
      --prefix PATH : ${lib.makeBinPath [ coreutils ]} \
      --set JAVA_HOME "${jre'}"

    runHook postInstall
  '';

  nativeBuildInputs = [ git gradle makeWrapper ];

  doCheck = true;

  meta = with lib; {
    description = "Unofficial daemon for interacting with Signal";
    longDescription = ''
      Signald is a daemon that facilitates communication over Signal.  It is
      unofficial, unapproved, and not nearly as secure as the real Signal
      clients.
    '';
    homepage = "https://signald.org";
    sourceProvenance = with sourceTypes; [
      fromSource
      binaryBytecode  # deps
    ];
    license = licenses.gpl3Plus;
    maintainers = with maintainers; [ expipiplus1 ma27 ];
    platforms = [ "x86_64-linux" "aarch64-linux" ];
  };
}