summaryrefslogtreecommitdiffhomepage
path: root/gleam/flake.nix
blob: 5ffb74cbf56ff0e161a9d2029096bf7cab3f7ef6 (plain)
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
{
  description = "ocda-lib: the object-centric document abstraction as a Gleam library";
  inputs.nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.zst";
  outputs = { self, nixpkgs }:
    let
      system = "x86_64-linux"; # adjust for aarch64-linux / darwin
      pkgs = import nixpkgs { inherit system; };

      name = "ocda_lib";

      /* rebar3 with the port compiler already in it.
         esqlite builds a NIF, and its rebar3 configuration asks for the
         `pc` plugin, which rebar3 would otherwise fetch from Hex at build
         time: impossible in a sandbox, and the build fails with
         "missing_package pc". nixpkgs carries the plugin, so the answer is
         a rebar3 that has it before it starts.
      */
      rebar3-pc = pkgs.beamPackages.rebar3WithPlugins {
        plugins = [ pkgs.beamPackages.pc ];
      };

      /* The Hex dependencies, as manifest.toml pins them.
         .
         There is no Gleam builder in nixpkgs and `gleam build` fetches from
         Hex, so a sandboxed build cannot reach them. A fixed output
         derivation may, because its result is pinned by hash.
         .
         When a dependency changes, manifest.toml changes and this hash must
         change with it: build, take the hash nix reports, put it here.
      */
      deps = pkgs.stdenv.mkDerivation {
        pname = "${name}-deps";
        version = "0.1.0";
        src = ./.;
        nativeBuildInputs = [ pkgs.gleam pkgs.cacert ];
        buildPhase = ''
          export HOME=$TMPDIR
          gleam deps download
        '';
        installPhase = ''
          mkdir -p $out
          cp -r build/packages/* $out/
        '';
        dontFixup = true;
        outputHashMode = "recursive";
        outputHashAlgo = "sha256";
        outputHash = "sha256-nWU753YRsC28gsaGyy+A3aZaWf15ctULYiUlvsfyB1c=";
      };
    in {
      packages.${system} = {
        default = self.packages.${system}.${name};
        /* Shipped as an Erlang shipment rather than as an escript, because
           sqlite on the BEAM is a NIF: esqlite compiles its own sqlite into
           a shared object, and a NIF cannot be loaded from inside an
           escript archive, the runtime needing a real file on disk. The
           shipment keeps priv/ on disk, so it loads.
        */
        ${name} = pkgs.stdenv.mkDerivation {
          pname = "ocda-lib";
          version = "0.1.0";
          src = ./.;
          nativeBuildInputs = [
            pkgs.gleam
            pkgs.erlang
            rebar3-pc
            pkgs.makeWrapper
          ];
          buildPhase = ''
            runHook preBuild
            export HOME=$TMPDIR
            # the dependencies, in place of the fetch gleam would do
            mkdir -p build/packages
            cp -r ${deps}/* build/packages/
            chmod -R u+w build/packages
            gleam export erlang-shipment
            runHook postBuild
          '';
          installPhase = ''
            runHook preInstall
            mkdir -p $out/lib $out/bin
            cp -r build/erlang-shipment $out/lib/${name}
            makeWrapper $out/lib/${name}/entrypoint.sh $out/bin/ocda-lib \
              --add-flags run \
              --prefix PATH : ${pkgs.lib.makeBinPath [ pkgs.erlang pkgs.coreutils ]}
            # the reader under its own name, as the D flake installs it
            makeWrapper $out/lib/${name}/entrypoint.sh $out/bin/ocda-read \
              --add-flags "run read" \
              --prefix PATH : ${pkgs.lib.makeBinPath [ pkgs.erlang pkgs.coreutils ]}
            runHook postInstall
          '';
          meta = {
            description = "the abstraction as a Gleam library, with its reader, dump and agreement check";
            mainProgram = "ocda-lib";
          };
        };
      };
      devShells.${system}.default = pkgs.mkShell {
        packages = [ pkgs.gleam pkgs.erlang pkgs.rebar3 pkgs.sqlite ];
      };
    };
}