summary refs log tree commit diff
path: root/flake.nix
blob: 8c7a4f8769561fa12c06f3dd0a0d40102fcb0b00 (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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# A nix flake that sets up a complete Synapse development environment. Dependencies
# for the SyTest (https://github.com/matrix-org/sytest) and Complement
# (https://github.com/matrix-org/complement) Matrix homeserver test suites are also
# installed automatically.
#
# You must have already installed nix (https://nixos.org) on your system to use this.
# nix can be installed on Linux or MacOS; NixOS is not required. Windows is not
# directly supported, but nix can be installed inside of WSL2 or even Docker
# containers. Please refer to https://nixos.org/download for details.
#
# You must also enable support for flakes in Nix. See the following for how to
# do so permanently: https://nixos.wiki/wiki/Flakes#Enable_flakes
#
# Usage:
#
# With nix installed, navigate to the directory containing this flake and run
# `nix develop --impure`. The `--impure` is necessary in order to store state
# locally from "services", such as PostgreSQL and Redis.
#
# You should now be dropped into a new shell with all programs and dependencies
# availabile to you!
#
# You can start up pre-configured, local PostgreSQL and Redis instances by
# running: `devenv up`. To stop them, use Ctrl-C.
#
# A PostgreSQL database called 'synapse' will be set up for you, along with
# a PostgreSQL user named 'synapse_user'.
# The 'host' can be found by running `echo $PGHOST` with the development
# shell activated. Use these values to configure your Synapse to connect
# to the local PostgreSQL database. You do not need to specify a password.
# https://matrix-org.github.io/synapse/latest/postgres
#
# All state (the venv, postgres and redis data and config) are stored in
# .devenv/state. Deleting a file from here and then re-entering the shell
# will recreate these files from scratch.
#
# You can exit the development shell by typing `exit`, or using Ctrl-D.
#
# If you would like this development environment to activate automatically
# upon entering this directory in your terminal, first install `direnv`
# (https://direnv.net/). Then run `echo 'use flake . --impure' >> .envrc` at
# the root of the Synapse repo. Finally, run `direnv allow .` to allow the
# contents of '.envrc' to run every time you enter this directory. VoilĂ !

{
  inputs = {
    # Use the master/unstable branch of nixpkgs. The latest stable, 22.11,
    # does not contain 'perl536Packages.NetAsyncHTTP', needed by Sytest.
    nixpkgs.url = "github:NixOS/nixpkgs/master";
    # Output a development shell for x86_64/aarch64 Linux/Darwin (MacOS).
    systems.url = "github:nix-systems/default";
    # A development environment manager built on Nix. See https://devenv.sh.
    devenv.url = "github:cachix/devenv/main";
    # Rust toolchains and rust-analyzer nightly.
    fenix = {
      url = "github:nix-community/fenix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, devenv, systems, ... } @ inputs:
    let
      forEachSystem = nixpkgs.lib.genAttrs (import systems);
    in {
      devShells = forEachSystem (system:
        let
          pkgs = nixpkgs.legacyPackages.${system};
        in {
          # Everything is configured via devenv - a nix module for creating declarative
          # developer environments. See https://devenv.sh/reference/options/ for a list
          # of all possible options.
          default = devenv.lib.mkShell {
            inherit inputs pkgs;
            modules = [
              {
                # Make use of the Starship command prompt when this development environment
                # is manually activated (via `nix develop --impure`).
                # See https://starship.rs/ for details on the prompt itself.
                starship.enable = true;

                # Configure packages to install.
                # Search for package names at https://search.nixos.org/packages?channel=unstable
                packages = with pkgs; [
                  # Native dependencies for running Synapse.
                  icu
                  libffi
                  libjpeg
                  libpqxx
                  libwebp
                  libxml2
                  libxslt
                  sqlite

                  # Native dependencies for unit tests (SyTest also requires OpenSSL).
                  openssl
                  xmlsec

                  # Native dependencies for running Complement.
                  olm

                  # For building the Synapse documentation website.
                  mdbook

                  # For releasing Synapse
                  debian-devscripts # (`dch` for manipulating the Debian changelog)
                  libnotify # (the release script uses `notify-send` to tell you when CI jobs are done)
                ];

                # Install Python and manage a virtualenv with Poetry.
                languages.python.enable = true;
                languages.python.poetry.enable = true;
                # Automatically activate the poetry virtualenv upon entering the shell.
                languages.python.poetry.activate.enable = true;
                # Install all extra Python dependencies; this is needed to run the unit
                # tests and utilitise all Synapse features.
                languages.python.poetry.install.arguments = ["--extras all"];
                # Install the 'matrix-synapse' package from the local checkout.
                languages.python.poetry.install.installRootPackage = true;

                # This is a work-around for NixOS systems. NixOS is special in
                # that you can have multiple versions of packages installed at
                # once, including your libc linker!
                #
                # Some binaries built for Linux expect those to be in a certain
                # filepath, but that is not the case on NixOS. In that case, we
                # force compiling those binaries locally instead.
                env.POETRY_INSTALLER_NO_BINARY = "ruff";

                # Install dependencies for the additional programming languages
                # involved with Synapse development.
                #
                # * Rust is used for developing and running Synapse.
                # * Golang is needed to run the Complement test suite.
                # * Perl is needed to run the SyTest test suite.
                languages.go.enable = true;
                languages.rust.enable = true;
                languages.rust.version = "stable";
                languages.perl.enable = true;

                # Postgres is needed to run Synapse with postgres support and
                # to run certain unit tests that require postgres.
                services.postgres.enable = true;

                # On the first invocation of `devenv up`, create a database for
                # Synapse to store data in.
                services.postgres.initdbArgs = ["--locale=C" "--encoding=UTF8"];
                services.postgres.initialDatabases = [
                  { name = "synapse"; }
                ];
                # Create a postgres user called 'synapse_user' which has ownership
                # over the 'synapse' database.
                services.postgres.initialScript = ''
                CREATE USER synapse_user;
                ALTER DATABASE synapse OWNER TO synapse_user;
                '';

                # Redis is needed in order to run Synapse in worker mode.
                services.redis.enable = true;

                # Define the perl modules we require to run SyTest.
                #
                # This list was compiled by cross-referencing https://metacpan.org/
                # with the modules defined in './cpanfile' and then finding the
                # corresponding nix packages on https://search.nixos.org/packages.
                #
                # This was done until `./install-deps.pl --dryrun` produced no output.
                env.PERL5LIB = "${with pkgs.perl536Packages; makePerlPath [
                  DBI
                  ClassMethodModifiers
                  CryptEd25519
                  DataDump
                  DBDPg
                  DigestHMAC
                  DigestSHA1
                  EmailAddressXS
                  EmailMIME
                  EmailSimple  # required by Email::Mime
                  EmailMessageID  # required by Email::Mime
                  EmailMIMEContentType  # required by Email::Mime
                  TextUnidecode  # required by Email::Mime
                  ModuleRuntime  # required by Email::Mime
                  EmailMIMEEncodings  # required by Email::Mime
                  FilePath
                  FileSlurper
                  Future
                  GetoptLong
                  HTTPMessage
                  IOAsync
                  IOAsyncSSL
                  IOSocketSSL
                  NetSSLeay
                  JSON
                  ListUtilsBy
                  ScalarListUtils
                  ModulePluggable
                  NetAsyncHTTP
                  MetricsAny  # required by Net::Async::HTTP
                  NetAsyncHTTPServer
                  StructDumb
                  URI
                  YAMLLibYAML
                ]}";
              }
            ];
          };
        });
    };
}