summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
authorDmitry Kalinkin <dmitry.kalinkin@gmail.com>2021-04-08 22:42:26 -0400
committerDmitry Kalinkin <dmitry.kalinkin@gmail.com>2021-04-08 22:42:26 -0400
commit219590673ce4b8c01d595e64bff21d54a72191b7 (patch)
tree2b577ead908bf018df37b1241ba7a01d8659acdb /pkgs
parent625ce6c7f66c0b2ccae30f95cdd9e48feed8561c (diff)
parentc99b6f5343030d7e5e3feef8b6c596f7644310a0 (diff)
downloadnixpkgs-219590673ce4b8c01d595e64bff21d54a72191b7.tar
nixpkgs-219590673ce4b8c01d595e64bff21d54a72191b7.tar.gz
nixpkgs-219590673ce4b8c01d595e64bff21d54a72191b7.tar.bz2
nixpkgs-219590673ce4b8c01d595e64bff21d54a72191b7.tar.lz
nixpkgs-219590673ce4b8c01d595e64bff21d54a72191b7.tar.xz
nixpkgs-219590673ce4b8c01d595e64bff21d54a72191b7.tar.zst
nixpkgs-219590673ce4b8c01d595e64bff21d54a72191b7.zip
Merge branch 'staging-next' into staging
 Conflicts:
	pkgs/development/python-modules/panel/default.nix
	pkgs/os-specific/linux/kernel/generic.nix
	pkgs/servers/home-assistant/default.nix
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/applications/audio/kid3/default.nix66
-rw-r--r--pkgs/applications/editors/jetbrains/default.nix50
-rw-r--r--pkgs/applications/misc/blucontrol/wrapper.nix32
-rw-r--r--pkgs/applications/misc/free42/default.nix27
-rw-r--r--pkgs/applications/misc/metadata-cleaner/default.nix4
-rw-r--r--pkgs/applications/networking/browsers/chromium/upstream-info.json6
-rw-r--r--pkgs/applications/networking/browsers/palemoon/default.nix4
-rw-r--r--pkgs/applications/networking/cluster/fluxcd/default.nix8
-rw-r--r--pkgs/applications/networking/cluster/terragrunt/default.nix4
-rw-r--r--pkgs/applications/search/recoll/default.nix10
-rw-r--r--pkgs/applications/version-management/gitea/default.nix4
-rw-r--r--pkgs/applications/window-managers/dwl/default.nix21
-rw-r--r--pkgs/applications/window-managers/labwc/default.nix12
-rw-r--r--pkgs/applications/window-managers/sway/default.nix9
-rw-r--r--pkgs/applications/window-managers/sway/load-configuration-from-etc.patch38
-rw-r--r--pkgs/applications/window-managers/wayfire/applications.nix29
-rw-r--r--pkgs/development/compilers/dtc/default.nix9
-rw-r--r--pkgs/development/compilers/jetbrains-jdk/default.nix4
-rw-r--r--pkgs/development/compilers/llvm/12/clang/default.nix2
-rw-r--r--pkgs/development/compilers/llvm/12/compiler-rt.nix2
-rw-r--r--pkgs/development/compilers/llvm/12/default.nix4
-rw-r--r--pkgs/development/compilers/llvm/12/libc++/default.nix2
-rw-r--r--pkgs/development/compilers/llvm/12/libc++abi.nix2
-rw-r--r--pkgs/development/compilers/llvm/12/libunwind.nix2
-rw-r--r--pkgs/development/compilers/llvm/12/lld.nix2
-rw-r--r--pkgs/development/compilers/llvm/12/lldb.nix2
-rw-r--r--pkgs/development/compilers/llvm/12/llvm.nix4
-rw-r--r--pkgs/development/compilers/llvm/12/openmp.nix2
-rw-r--r--pkgs/development/libraries/grpc/default.nix9
-rw-r--r--pkgs/development/libraries/openzwave/default.nix51
-rw-r--r--pkgs/development/libraries/tracker/default.nix10
-rw-r--r--pkgs/development/libraries/v8/default.nix34
-rw-r--r--pkgs/development/libraries/v8/gcc_arm.patch31
-rw-r--r--pkgs/development/libraries/wlroots/0.12.nix57
-rw-r--r--pkgs/development/libraries/wlroots/default.nix10
-rw-r--r--pkgs/development/python-modules/aiodiscover/default.nix12
-rw-r--r--pkgs/development/python-modules/asyncio-nats-client/default.nix50
-rw-r--r--pkgs/development/python-modules/bokeh/default.nix5
-rw-r--r--pkgs/development/python-modules/grpcio-tools/default.nix4
-rw-r--r--pkgs/development/python-modules/homeassistant-pyozw/default.nix17
-rw-r--r--pkgs/development/python-modules/jupyterlab/default.nix6
-rw-r--r--pkgs/development/python-modules/nats-python/default.nix46
-rw-r--r--pkgs/development/python-modules/panel/default.nix30
-rw-r--r--pkgs/development/python-modules/panel/node/default.nix17
-rw-r--r--pkgs/development/python-modules/panel/node/node-env.nix567
-rw-r--r--pkgs/development/python-modules/panel/node/node-packages.nix572
-rw-r--r--pkgs/development/python-modules/panel/node/package.json27
-rw-r--r--pkgs/development/python-modules/smartypants/default.nix14
-rw-r--r--pkgs/development/python-modules/smartypants/hgtags17
-rw-r--r--pkgs/development/python-modules/ytmusicapi/default.nix4
-rw-r--r--pkgs/development/ruby-modules/bundix/default.nix2
-rw-r--r--pkgs/development/tools/analysis/radare2/default.nix17
-rw-r--r--pkgs/development/tools/analysis/rizin/cutter.nix2
-rw-r--r--pkgs/development/tools/analysis/rizin/default.nix2
-rw-r--r--pkgs/development/tools/build-managers/conan/default.nix33
-rw-r--r--pkgs/development/tools/rust/cargo-deny/default.nix6
-rw-r--r--pkgs/games/devilutionx/default.nix9
-rw-r--r--pkgs/misc/emulators/dolphin-emu/master.nix6
-rw-r--r--pkgs/misc/vim-plugins/generated.nix266
-rw-r--r--pkgs/misc/vim-plugins/vim-plugin-names1
-rw-r--r--pkgs/os-specific/darwin/macfuse/default.nix6
-rw-r--r--pkgs/os-specific/linux/kernel/generic.nix5
-rw-r--r--pkgs/os-specific/linux/kernel/linux-4.14.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-4.19.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-4.4.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-4.9.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-5.10.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-5.11.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-5.4.nix4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-testing.nix4
-rw-r--r--pkgs/servers/dns/doh-proxy-rust/cargo-lock.patch838
-rw-r--r--pkgs/servers/dns/doh-proxy-rust/default.nix27
-rw-r--r--pkgs/servers/home-assistant/component-packages.nix21
-rw-r--r--pkgs/servers/home-assistant/default.nix49
-rw-r--r--pkgs/servers/home-assistant/frontend.nix4
-rw-r--r--pkgs/servers/unifi/default.nix4
-rw-r--r--pkgs/servers/web-apps/discourse/action_mailer_ca_cert.patch12
-rw-r--r--pkgs/servers/web-apps/discourse/admin_create.patch48
-rw-r--r--pkgs/servers/web-apps/discourse/default.nix234
-rw-r--r--pkgs/servers/web-apps/discourse/disable_jhead.patch12
-rw-r--r--pkgs/servers/web-apps/discourse/mail_receiver/default.nix39
-rw-r--r--pkgs/servers/web-apps/discourse/nixos_defaults.patch13
-rw-r--r--pkgs/servers/web-apps/discourse/rubyEnv/Gemfile248
-rw-r--r--pkgs/servers/web-apps/discourse/rubyEnv/Gemfile.lock561
-rw-r--r--pkgs/servers/web-apps/discourse/rubyEnv/gemset.nix2272
-rw-r--r--pkgs/servers/web-apps/discourse/unicorn_logging_and_timeout.patch25
-rwxr-xr-xpkgs/servers/web-apps/discourse/update.py164
-rw-r--r--pkgs/tools/admin/awscli2/default.nix12
-rw-r--r--pkgs/tools/filesystems/sshfs-fuse/common.nix61
-rw-r--r--pkgs/tools/filesystems/sshfs-fuse/default.nix74
-rw-r--r--pkgs/tools/filesystems/sshfs-fuse/fix-fuse-darwin-h.patch14
-rw-r--r--pkgs/tools/networking/openssh/copyid.nix11
-rw-r--r--pkgs/top-level/aliases.nix2
-rw-r--r--pkgs/top-level/all-packages.nix61
-rw-r--r--pkgs/top-level/php-packages.nix8
-rw-r--r--pkgs/top-level/python-packages.nix8
96 files changed, 6671 insertions, 489 deletions
diff --git a/pkgs/applications/audio/kid3/default.nix b/pkgs/applications/audio/kid3/default.nix
index 99f7cec98af..abfc9e7fe1e 100644
--- a/pkgs/applications/audio/kid3/default.nix
+++ b/pkgs/applications/audio/kid3/default.nix
@@ -1,25 +1,67 @@
-{ lib, stdenv, fetchurl
-, pkg-config, cmake, python3, ffmpeg_3, phonon, automoc4
-, chromaprint, docbook_xml_dtd_45, docbook_xsl, libxslt
-, id3lib, taglib, mp4v2, flac, libogg, libvorbis
-, zlib, readline , qtbase, qttools, qtmultimedia, qtquickcontrols
+{ lib
+, stdenv
+, fetchurl
+, automoc4
+, chromaprint
+, cmake
+, docbook_xml_dtd_45
+, docbook_xsl
+, ffmpeg_3
+, flac
+, id3lib
+, libogg
+, libvorbis
+, libxslt
+, mp4v2
+, phonon
+, pkg-config
+, python3
+, qtbase
+, qtmultimedia
+, qtquickcontrols
+, qttools
+, readline
+, taglib
 , wrapQtAppsHook
+, zlib
 }:
 
 stdenv.mkDerivation rec {
   pname = "kid3";
-  version = "3.8.5";
+  version = "3.8.6";
 
   src = fetchurl {
     url = "mirror://sourceforge/project/kid3/kid3/${version}/${pname}-${version}.tar.gz";
-    sha256 = "sha256-DEZ5J1QendgXJ1gBZ3h0LwsVTLL1vPznJ7Nc+97jFB8=";
+    sha256 = "sha256-ce+MWCJzAnN+u+07f0dvn0jnbqiUlS2RbcM9nAj5bgg=";
   };
 
-  nativeBuildInputs = [ cmake pkg-config wrapQtAppsHook ];
-  buildInputs = [ python3 ffmpeg_3 phonon automoc4 chromaprint
-    docbook_xml_dtd_45 docbook_xsl libxslt id3lib taglib mp4v2 flac
-    libogg libvorbis zlib readline qtbase qttools qtmultimedia
-    qtquickcontrols ];
+  nativeBuildInputs = [
+    cmake
+    pkg-config
+    wrapQtAppsHook
+  ];
+  buildInputs = [
+    automoc4
+    chromaprint
+    docbook_xml_dtd_45
+    docbook_xsl
+    ffmpeg_3
+    flac
+    id3lib
+    libogg
+    libvorbis
+    libxslt
+    mp4v2
+    phonon
+    python3
+    qtbase
+    qtmultimedia
+    qtquickcontrols
+    qttools
+    readline
+    taglib
+    zlib
+  ];
 
   cmakeFlags = [ "-DWITH_APPS=Qt;CLI" ];
   NIX_LDFLAGS = "-lm -lpthread";
diff --git a/pkgs/applications/editors/jetbrains/default.nix b/pkgs/applications/editors/jetbrains/default.nix
index e7628715a21..fb653518530 100644
--- a/pkgs/applications/editors/jetbrains/default.nix
+++ b/pkgs/applications/editors/jetbrains/default.nix
@@ -57,7 +57,7 @@ let
           gdbLibPath=$out/clion-${version}/bin/gdb/linux/lib
           patchelf \
             --set-rpath "$gdbLibPath" \
-            bin/gdb/linux/lib/python3.*/lib-dynload/zlib.cpython-*m-x86_64-linux-gnu.so
+            bin/gdb/linux/lib/python3.*/lib-dynload/zlib.cpython-*-x86_64-linux-gnu.so
           patchelf --set-interpreter $interp \
             --set-rpath "${lib.makeLibraryPath [ stdenv.cc.cc.lib zlib ]}:$gdbLibPath" \
             bin/gdb/linux/bin/gdb
@@ -269,12 +269,12 @@ in
 
   clion = buildClion rec {
     name = "clion-${version}";
-    version = "2020.3.3"; /* updated by script */
+    version = "2021.1"; /* updated by script */
     description  = "C/C++ IDE. New. Intelligent. Cross-platform";
     license = lib.licenses.unfree;
     src = fetchurl {
       url = "https://download.jetbrains.com/cpp/CLion-${version}.tar.gz";
-      sha256 = "10s0jkxi892pg7d2slh7cvrd0ch2223qms3c9v1ax0n6ymfkcw14"; /* updated by script */
+      sha256 = "1qq2k14pf2qy93y1xchlv08vvx99zcml8bdcx3h6jnjz6d7gz0px"; /* updated by script */
     };
     wmClass = "jetbrains-clion";
     update-channel = "CLion RELEASE"; # channel's id as in http://www.jetbrains.com/updates/updates.xml
@@ -282,12 +282,12 @@ in
 
   datagrip = buildDataGrip rec {
     name = "datagrip-${version}";
-    version = "2020.3.2"; /* updated by script */
+    version = "2021.1"; /* updated by script */
     description = "Your Swiss Army Knife for Databases and SQL";
     license = lib.licenses.unfree;
     src = fetchurl {
       url = "https://download.jetbrains.com/datagrip/${name}.tar.gz";
-      sha256 = "1wjaavgslwpz4jniszswdy10rk3622i1w3awdwhgjlcc6mwkwz1f"; /* updated by script */
+      sha256 = "11am11lkrhgfianr1apkkl4mn8gcsf6p1vz47y7lz4rfm05ac4gj"; /* updated by script */
     };
     wmClass = "jetbrains-datagrip";
     update-channel = "DataGrip RELEASE";
@@ -295,12 +295,12 @@ in
 
   goland = buildGoland rec {
     name = "goland-${version}";
-    version = "2020.3.4"; /* updated by script */
+    version = "2021.1"; /* updated by script */
     description = "Up and Coming Go IDE";
     license = lib.licenses.unfree;
     src = fetchurl {
       url = "https://download.jetbrains.com/go/${name}.tar.gz";
-      sha256 = "148rs9w0fqr5xzhnq5bd473j4vnb69kf8yxxjmwdp25z2d7x47ip"; /* updated by script */
+      sha256 = "1hxid7k5b26hiwwdxbvhi1fzhlrvm1xsd5gb0vj0g5zw658y2lzz"; /* updated by script */
     };
     wmClass = "jetbrains-goland";
     update-channel = "GoLand RELEASE";
@@ -308,12 +308,12 @@ in
 
   idea-community = buildIdea rec {
     name = "idea-community-${version}";
-    version = "2020.3.3"; /* updated by script */
+    version = "2021.1"; /* updated by script */
     description = "Integrated Development Environment (IDE) by Jetbrains, community edition";
     license = lib.licenses.asl20;
     src = fetchurl {
       url = "https://download.jetbrains.com/idea/ideaIC-${version}.tar.gz";
-      sha256 = "1msfl8qq0aday4ssip73r0y096mrb89mr7z2j4mpqhkzgsmvpjk0"; /* updated by script */
+      sha256 = "1d7m39rzdgh2fyx50rpifqfsdmvfpi04hjp52pl76m35gyb5hsvs"; /* updated by script */
     };
     wmClass = "jetbrains-idea-ce";
     update-channel = "IntelliJ IDEA RELEASE";
@@ -321,12 +321,12 @@ in
 
   idea-ultimate = buildIdea rec {
     name = "idea-ultimate-${version}";
-    version = "2020.3.3"; /* updated by script */
+    version = "2021.1"; /* updated by script */
     description = "Integrated Development Environment (IDE) by Jetbrains, requires paid license";
     license = lib.licenses.unfree;
     src = fetchurl {
       url = "https://download.jetbrains.com/idea/ideaIU-${version}-no-jbr.tar.gz";
-      sha256 = "0szq8lqp1h7kci8kqd1bb3g16j3p5f4dfmbccbyrrwsram3hvjgi"; /* updated by script */
+      sha256 = "062kaph42xs5hc01sbmry4cm7nkyjks43qr5m7pbj5a2bgd7zzgx"; /* updated by script */
     };
     wmClass = "jetbrains-idea";
     update-channel = "IntelliJ IDEA RELEASE";
@@ -334,12 +334,12 @@ in
 
   mps = buildMps rec {
     name = "mps-${version}";
-    version = "2020.3.2"; /* updated by script */
+    version = "2020.3.3"; /* updated by script */
     description = "Create your own domain-specific language";
     license = lib.licenses.asl20;
     src = fetchurl {
       url = "https://download.jetbrains.com/mps/2020.3/MPS-${version}.tar.gz";
-      sha256 = "0vskzia48jq50bjdqw993gizvvd59f3qlszbsdp7xg5a3afbk7p3"; /* updated by script */
+      sha256 = "0sb50f7d4272dzx84njc326xvhbqn3xwrphvdq4zl3pk3wl8f4nz"; /* updated by script */
     };
     wmClass = "jetbrains-mps";
     update-channel = "MPS RELEASE";
@@ -347,12 +347,12 @@ in
 
   phpstorm = buildPhpStorm rec {
     name = "phpstorm-${version}";
-    version = "2020.3.3"; /* updated by script */
+    version = "2021.1"; /* updated by script */
     description = "Professional IDE for Web and PHP developers";
     license = lib.licenses.unfree;
     src = fetchurl {
       url = "https://download.jetbrains.com/webide/PhpStorm-${version}.tar.gz";
-      sha256 = "0arff0882xw1azbxpn1n3wbc5ncg8gmfim3jf6rq2dky8kp9ylkm"; /* updated by script */
+      sha256 = "052m7mqa1s548my0gda9y2mysi2ijq27c9b3bskrwqsf1pm5ry63"; /* updated by script */
     };
     wmClass = "jetbrains-phpstorm";
     update-channel = "PhpStorm RELEASE";
@@ -360,12 +360,12 @@ in
 
   pycharm-community = buildPycharm rec {
     name = "pycharm-community-${version}";
-    version = "2020.3.4"; /* updated by script */
+    version = "2021.1"; /* updated by script */
     description = "PyCharm Community Edition";
     license = lib.licenses.asl20;
     src = fetchurl {
       url = "https://download.jetbrains.com/python/${name}.tar.gz";
-      sha256 = "0xh0hb0v3ilgqjljh22c75hkllqgqbpppplni2dz2pv9rb3r5dv5"; /* updated by script */
+      sha256 = "1iiglh7s2zm37kj6hzlzxb1jnzh2p0j1f2zzhg3nqyrrakfbyq3h"; /* updated by script */
     };
     wmClass = "jetbrains-pycharm-ce";
     update-channel = "PyCharm RELEASE";
@@ -373,12 +373,12 @@ in
 
   pycharm-professional = buildPycharm rec {
     name = "pycharm-professional-${version}";
-    version = "2020.3.4"; /* updated by script */
+    version = "2021.1"; /* updated by script */
     description = "PyCharm Professional Edition";
     license = lib.licenses.unfree;
     src = fetchurl {
       url = "https://download.jetbrains.com/python/${name}.tar.gz";
-      sha256 = "18gkjc52qpghs721rkbsj03kaf6n8c8sxg57b2d82hjckjgm6q10"; /* updated by script */
+      sha256 = "1n3b4mdygzal7w88gwka5wh5jp09bh2zmm4n5rz9s7hr2srz71mz"; /* updated by script */
     };
     wmClass = "jetbrains-pycharm";
     update-channel = "PyCharm RELEASE";
@@ -386,12 +386,12 @@ in
 
   rider = buildRider rec {
     name = "rider-${version}";
-    version = "2020.3.4"; /* updated by script */
+    version = "2021.1"; /* updated by script */
     description = "A cross-platform .NET IDE based on the IntelliJ platform and ReSharper";
     license = lib.licenses.unfree;
     src = fetchurl {
       url = "https://download.jetbrains.com/rider/JetBrains.Rider-${version}.tar.gz";
-      sha256 = "1v99yqj83aw9j400z3v24n7xnyxzw5vm0b3rwd4yb8w3ajl59gq1"; /* updated by script */
+      sha256 = "089j52sig2ac21v6zl9mvb7x4sr9c428nn930b41y3qd6bg52xxx"; /* updated by script */
     };
     wmClass = "jetbrains-rider";
     update-channel = "Rider RELEASE";
@@ -399,12 +399,12 @@ in
 
   ruby-mine = buildRubyMine rec {
     name = "ruby-mine-${version}";
-    version = "2020.3.2"; /* updated by script */
+    version = "2021.1"; /* updated by script */
     description = "The Most Intelligent Ruby and Rails IDE";
     license = lib.licenses.unfree;
     src = fetchurl {
       url = "https://download.jetbrains.com/ruby/RubyMine-${version}.tar.gz";
-      sha256 = "17x3sz4jkz2px25gj813xqrrb2cm7mdl6m5a22zg086phym66g3c"; /* updated by script */
+      sha256 = "12mkb51x1w5wbx436pfnfzcad10qd53y43n0p4l2zg9yx985gm7v"; /* updated by script */
     };
     wmClass = "jetbrains-rubymine";
     update-channel = "RubyMine RELEASE";
@@ -412,12 +412,12 @@ in
 
   webstorm = buildWebStorm rec {
     name = "webstorm-${version}";
-    version = "2020.3.3"; /* updated by script */
+    version = "2021.1"; /* updated by script */
     description = "Professional IDE for Web and JavaScript development";
     license = lib.licenses.unfree;
     src = fetchurl {
       url = "https://download.jetbrains.com/webstorm/WebStorm-${version}.tar.gz";
-      sha256 = "0szq7qz5p1ksmqdy1rma5rfl0d9dy9qmhz8k5id4zdpyz2jsacfb"; /* updated by script */
+      sha256 = "15i521qj2b0y1viqr0xx815ckpq359j6nars4xxq8xvy7cg729yc"; /* updated by script */
     };
     wmClass = "jetbrains-webstorm";
     update-channel = "WebStorm RELEASE";
diff --git a/pkgs/applications/misc/blucontrol/wrapper.nix b/pkgs/applications/misc/blucontrol/wrapper.nix
new file mode 100644
index 00000000000..c0c76b4ef49
--- /dev/null
+++ b/pkgs/applications/misc/blucontrol/wrapper.nix
@@ -0,0 +1,32 @@
+{ stdenv, lib, makeWrapper, ghcWithPackages, packages ? (_:[]) }:
+let
+  blucontrolEnv = ghcWithPackages (self: [ self.blucontrol ] ++ packages self);
+in
+  stdenv.mkDerivation {
+    pname = "blucontrol-with-packages";
+    version = blucontrolEnv.version;
+
+    nativeBuildInputs = [ makeWrapper ];
+
+    buildCommand = ''
+      makeWrapper ${blucontrolEnv}/bin/blucontrol $out/bin/blucontrol \
+        --prefix PATH : ${lib.makeBinPath [ blucontrolEnv ]}
+    '';
+
+    # trivial derivation
+    preferLocalBuild = true;
+    allowSubstitues = false;
+
+    meta = with lib; {
+      description = "Configurable blue light filter";
+      longDescription = ''
+        This application is a blue light filter, with the main focus on configurability.
+        Configuration is done in Haskell in the style of xmonad.
+        Blucontrol makes use of monad transformers and allows monadic calculation of gamma values and recoloring. The user chooses, what will be captured in the monadic state.
+      '';
+      license = licenses.bsd3;
+      homepage = "https://github.com/jumper149/blucontrol";
+      platforms = platforms.unix;
+      maintainers = with maintainers; [ jumper149 ];
+    };
+  }
diff --git a/pkgs/applications/misc/free42/default.nix b/pkgs/applications/misc/free42/default.nix
index c48e151e8ae..51867a6acee 100644
--- a/pkgs/applications/misc/free42/default.nix
+++ b/pkgs/applications/misc/free42/default.nix
@@ -1,6 +1,8 @@
 { lib
 , stdenv
 , fetchFromGitHub
+, makeDesktopItem
+, copyDesktopItems
 , pkg-config
 , gtk3
 , alsaLib
@@ -17,7 +19,7 @@ stdenv.mkDerivation rec {
     sha256 = "sha256-Htk2NHgYVL622URx67BUtounAUopLTahaSqfAqd3+ZI=";
   };
 
-  nativeBuildInputs = [ pkg-config ];
+  nativeBuildInputs = [ copyDesktopItems pkg-config ];
   buildInputs = [ gtk3 alsaLib ];
 
   postPatch = ''
@@ -55,6 +57,29 @@ stdenv.mkDerivation rec {
     runHook postInstall
   '';
 
+  desktopItems = [
+    (makeDesktopItem {
+      name = "com.thomasokken.free42bin";
+      desktopName = "Free42Bin";
+      genericName = "Calculator";
+      exec = "free42bin";
+      type = "Application";
+      comment = meta.description;
+      categories = "Utility;Calculator;";
+      terminal = "false";
+    })
+    (makeDesktopItem {
+      name = "com.thomasokken.free42dec";
+      desktopName = "Free42Dec";
+      genericName = "Calculator";
+      exec = "free42dec";
+      type = "Application";
+      comment = meta.description;
+      categories = "Utility;Calculator;";
+      terminal = "false";
+    })
+  ];
+
   meta = with lib; {
     homepage = "https://github.com/thomasokken/free42";
     description = "A software clone of HP-42S Calculator";
diff --git a/pkgs/applications/misc/metadata-cleaner/default.nix b/pkgs/applications/misc/metadata-cleaner/default.nix
index de715bf315f..b1b77a53ea0 100644
--- a/pkgs/applications/misc/metadata-cleaner/default.nix
+++ b/pkgs/applications/misc/metadata-cleaner/default.nix
@@ -17,7 +17,7 @@
 
 python3.pkgs.buildPythonApplication rec {
   pname = "metadata-cleaner";
-  version = "1.0.3";
+  version = "1.0.4";
 
   format = "other";
 
@@ -25,7 +25,7 @@ python3.pkgs.buildPythonApplication rec {
     owner = "rmnvgr";
     repo = "metadata-cleaner";
     rev = "v${version}";
-    sha256 = "06dzfcnjb1xd8lk0r7bi4i784gfj8r7habbjbk2c4vn2847v71lf";
+    sha256 = "sha256-F/xh4dFX7W50kFzpWpGKyMUhxOlDO3WDXBzXVsDViY8=";
   };
 
   nativeBuildInputs = [
diff --git a/pkgs/applications/networking/browsers/chromium/upstream-info.json b/pkgs/applications/networking/browsers/chromium/upstream-info.json
index 7660f2f9e69..94c45120cc6 100644
--- a/pkgs/applications/networking/browsers/chromium/upstream-info.json
+++ b/pkgs/applications/networking/browsers/chromium/upstream-info.json
@@ -18,9 +18,9 @@
     }
   },
   "beta": {
-    "version": "90.0.4430.51",
-    "sha256": "1k87fw0pv0d2zlxm0il9b5p60gdz6l44jssmsns4zy2fmd9316wr",
-    "sha256bin64": "0q5yx7bc266azs3nl29ksz4yafvy2nmzn09ifcgr69fjkvsr1qh7",
+    "version": "90.0.4430.61",
+    "sha256": "01vssy3q64pv9rw4cdxv5rdg7yrxmhyc03a5r75fhxc95fj66iac",
+    "sha256bin64": "07l8dzyv0hav1gls3xw91q9ay2l8xxmsf7yagg940cya9ncl0lhi",
     "deps": {
       "gn": {
         "version": "2021-02-09",
diff --git a/pkgs/applications/networking/browsers/palemoon/default.nix b/pkgs/applications/networking/browsers/palemoon/default.nix
index cf5f13fa745..554167c3574 100644
--- a/pkgs/applications/networking/browsers/palemoon/default.nix
+++ b/pkgs/applications/networking/browsers/palemoon/default.nix
@@ -16,14 +16,14 @@ let
 
 in stdenv.mkDerivation rec {
   pname = "palemoon";
-  version = "29.1.0";
+  version = "29.1.1";
 
   src = fetchFromGitHub {
     githubBase = "repo.palemoon.org";
     owner = "MoonchildProductions";
     repo = "Pale-Moon";
     rev = "${version}_Release";
-    sha256 = "02blhk3v7gpnicd7s5l5fpqvdvj2279g3rq8xyhcd4sw6qnms8m6";
+    sha256 = "1ppdmj816zwccb0l0mgpq14ckdwg785wmqz41wran0nl63fg6i1x";
     fetchSubmodules = true;
   };
 
diff --git a/pkgs/applications/networking/cluster/fluxcd/default.nix b/pkgs/applications/networking/cluster/fluxcd/default.nix
index 1d8a8228af1..a0593aab989 100644
--- a/pkgs/applications/networking/cluster/fluxcd/default.nix
+++ b/pkgs/applications/networking/cluster/fluxcd/default.nix
@@ -1,11 +1,11 @@
 { lib, buildGoModule, fetchFromGitHub, fetchzip, installShellFiles }:
 
 let
-  version = "0.11.0";
+  version = "0.12.0";
 
   manifests = fetchzip {
     url = "https://github.com/fluxcd/flux2/releases/download/v${version}/manifests.tar.gz";
-    sha256 = "sha256-nqvFJriNMK3SvAsNzhE8MCzVNR8j/TjYU+f1PbuxkuI=";
+    sha256 = "sha256-8NgKr5uRVFBD1pARaD+vH9wPA5gUNltwMe0i0icED1c=";
     stripRoot = false;
   };
 in
@@ -19,10 +19,10 @@ buildGoModule rec {
     owner = "fluxcd";
     repo = "flux2";
     rev = "v${version}";
-    sha256 = "sha256-V4cZuRlC1Hu4gBG5/8ZNBKlSBFLgOtSJ3GbpjW5/8xM=";
+    sha256 = "sha256-idHMijca1lYQF4aW+RPyzRraLDNdVavMuj4TP6z90Oo=";
   };
 
-  vendorSha256 = "sha256-aVVvrOjCKxzFer5uZRSu1LCQKkGkPcBdKdebN5uHUUg=";
+  vendorSha256 = "sha256-VrDO8y6omRKf3mPRAnRMZsSMwQHxQxShUa9HZ3dfCgM=";
 
   nativeBuildInputs = [ installShellFiles ];
 
diff --git a/pkgs/applications/networking/cluster/terragrunt/default.nix b/pkgs/applications/networking/cluster/terragrunt/default.nix
index eb230062fee..b152fa33a87 100644
--- a/pkgs/applications/networking/cluster/terragrunt/default.nix
+++ b/pkgs/applications/networking/cluster/terragrunt/default.nix
@@ -2,13 +2,13 @@
 
 buildGoModule rec {
   pname = "terragrunt";
-  version = "0.28.18";
+  version = "0.28.19";
 
   src = fetchFromGitHub {
     owner = "gruntwork-io";
     repo = pname;
     rev = "v${version}";
-    sha256 = "sha256-W0HjGILezhuc1lXvGCHw23h8Sx1uw4YLLsOOBZYGvU8=";
+    sha256 = "sha256-REcVc4u7pDTDHvoI1Fw36Mioyg1D4U29Hq0ih8Bt95s=";
   };
 
   vendorSha256 = "sha256-kcRM76xfajtQist1aJTmaRludxRlfvHQ9ucB3LOgnBk=";
diff --git a/pkgs/applications/search/recoll/default.nix b/pkgs/applications/search/recoll/default.nix
index 48671582fba..a07340469fe 100644
--- a/pkgs/applications/search/recoll/default.nix
+++ b/pkgs/applications/search/recoll/default.nix
@@ -46,10 +46,12 @@ mkDerivation rec {
     ++ lib.optionals (!withGui) [ "--disable-qtgui" "--disable-x11mon" ]
     ++ (if stdenv.isLinux then [ "--with-inotify" ] else [ "--without-inotify" ]);
 
-  nativeBuildInputs = [ pkg-config ];
+  nativeBuildInputs = [
+    file pkg-config python3Packages.setuptools which
+  ];
 
-  buildInputs = with python3Packages; [
-    bison chmlib file python setuptools which xapian zlib
+  buildInputs = [
+    bison chmlib python3Packages.python xapian zlib
   ] ++ lib.optional withGui qtbase
     ++ lib.optional stdenv.isDarwin libiconv;
 
@@ -98,6 +100,6 @@ mkDerivation rec {
     homepage = "https://www.lesbonscomptes.com/recoll/";
     license = licenses.gpl2;
     platforms = platforms.unix;
-    maintainers = [ maintainers.jcumming ];
+    maintainers = with maintainers; [ jcumming kiyengar ];
   };
 }
diff --git a/pkgs/applications/version-management/gitea/default.nix b/pkgs/applications/version-management/gitea/default.nix
index 64c98768fdd..f1fdbad4cb7 100644
--- a/pkgs/applications/version-management/gitea/default.nix
+++ b/pkgs/applications/version-management/gitea/default.nix
@@ -16,12 +16,12 @@ with lib;
 
 buildGoPackage rec {
   pname = "gitea";
-  version = "1.13.6";
+  version = "1.13.7";
 
   # not fetching directly from the git repo, because that lacks several vendor files for the web UI
   src = fetchurl {
     url = "https://github.com/go-gitea/gitea/releases/download/v${version}/gitea-src-${version}.tar.gz";
-    sha256 = "1f0fsqcmmqygv0r796ddr2fjhh333i9nr0cqk9x2b2kbs1z264vf";
+    sha256 = "sha256-jJbX+kcXqd1v8aXNhmt24mq9mxOpTogCVm263rHVGHw=";
   };
 
   unpackPhase = ''
diff --git a/pkgs/applications/window-managers/dwl/default.nix b/pkgs/applications/window-managers/dwl/default.nix
index 52c0a6ae04d..d8f102ed767 100644
--- a/pkgs/applications/window-managers/dwl/default.nix
+++ b/pkgs/applications/window-managers/dwl/default.nix
@@ -12,8 +12,27 @@
 , patches ? [ ]
 , conf ? null
 , writeText
+, fetchpatch
 }:
 
+let
+  # Add two patches to fix compile errors with wlroots 0.13:
+  totalPatches = patches ++ [
+    # Fix the renamed constant WLR_KEY_PRESSED => WL_KEYBOARD_KEY_STATE_PRESSED
+    # https://github.com/djpohly/dwl/pull/66
+    (fetchpatch {
+      url = "https://github.com/djpohly/dwl/commit/a42613db9d9f6debfa4fb2363d75af9457d238ed.patch";
+      sha256 = "0h76hx1fhazi07gqg7sljh13f91v6bvjy7m9qqmimhvqgfwdcc0j";
+    })
+    # Use the new signature for wlr_backend_autocreate, which removes an argument:
+    # https://github.com/djpohly/dwl/pull/76
+    (fetchpatch {
+      url = "https://github.com/djpohly/dwl/commit/0ff13cf216056a36a261f4eed53c6a864989a9fb.patch";
+      sha256 = "18clpdb4il1vxf1b0cx0qrwild68s9dism8ab66zpmvxs5qag2dm";
+    })
+  ];
+in
+
 stdenv.mkDerivation rec {
   pname = "dwl";
   version = "0.2";
@@ -39,7 +58,7 @@ stdenv.mkDerivation rec {
   ];
 
   # Allow users to set their own list of patches
-  inherit patches;
+  patches = totalPatches;
 
   # Last line of config.mk enables XWayland
   prePatch = lib.optionalString enable-xwayland ''
diff --git a/pkgs/applications/window-managers/labwc/default.nix b/pkgs/applications/window-managers/labwc/default.nix
index 9d39bd537fd..c82eb76f6bf 100644
--- a/pkgs/applications/window-managers/labwc/default.nix
+++ b/pkgs/applications/window-managers/labwc/default.nix
@@ -8,7 +8,6 @@
 , glib
 , libinput
 , libxml2
-, pandoc
 , pango
 , wayland
 , wayland-protocols
@@ -16,20 +15,22 @@
 , libxcb
 , libxkbcommon
 , xwayland
+, libdrm
+, scdoc
 }:
 
 stdenv.mkDerivation rec {
   pname = "labwc";
-  version = "unstable-2021-02-06";
+  version = "unstable-2021-03-15";
 
   src = fetchFromGitHub {
     owner = "johanmalm";
     repo = pname;
-    rev = "4a8fcf5c6d0b730b1e2e17e544ce7d7d3c72cd13";
-    sha256 = "g1ba8dchUN393eis0VAu1bIjQfthDGLaSijSavz4lfU=";
+    rev = "fddeb74527e5b860d9c1a91a237d390041c758b6";
+    sha256 = "0rhniv5j4bypqxxj0nbpa3hclmn8znal9rldv0mrgbizn3wsbs54";
   };
 
-  nativeBuildInputs = [ pkg-config meson ninja pandoc ];
+  nativeBuildInputs = [ pkg-config meson ninja scdoc ];
   buildInputs = [
     cairo
     glib
@@ -42,6 +43,7 @@ stdenv.mkDerivation rec {
     libxcb
     libxkbcommon
     xwayland
+    libdrm
   ];
 
   mesonFlags = [ "-Dxwayland=enabled" ];
diff --git a/pkgs/applications/window-managers/sway/default.nix b/pkgs/applications/window-managers/sway/default.nix
index 1798c8235d0..d8a1679bbed 100644
--- a/pkgs/applications/window-managers/sway/default.nix
+++ b/pkgs/applications/window-managers/sway/default.nix
@@ -2,18 +2,18 @@
 , meson, ninja, pkg-config, wayland, scdoc
 , libxkbcommon, pcre, json_c, dbus, libevdev
 , pango, cairo, libinput, libcap, pam, gdk-pixbuf, librsvg
-, wlroots, wayland-protocols
+, wlroots, wayland-protocols, libdrm
 }:
 
 stdenv.mkDerivation rec {
   pname = "sway-unwrapped";
-  version = "1.5.1";
+  version = "1.6";
 
   src = fetchFromGitHub {
     owner = "swaywm";
     repo = "sway";
     rev = version;
-    sha256 = "1xsa3h8zhf29p0mi90baxpr76jkd9pd1gr97ky8cnjbcs4isj9j0";
+    sha256 = "0vnplva11yafhbijrk68wy7pw0psn9jm0caaymswq1s951xsn1c8";
   };
 
   patches = [
@@ -33,11 +33,12 @@ stdenv.mkDerivation rec {
   buildInputs = [
     wayland libxkbcommon pcre json_c dbus libevdev
     pango cairo libinput libcap pam gdk-pixbuf librsvg
-    wlroots wayland-protocols
+    wlroots wayland-protocols libdrm
   ];
 
   mesonFlags = [
     "-Ddefault-wallpaper=false"
+    "-Dsd-bus-provider=libsystemd"
   ];
 
   meta = with lib; {
diff --git a/pkgs/applications/window-managers/sway/load-configuration-from-etc.patch b/pkgs/applications/window-managers/sway/load-configuration-from-etc.patch
index 26a3d40d66c..46a170abc04 100644
--- a/pkgs/applications/window-managers/sway/load-configuration-from-etc.patch
+++ b/pkgs/applications/window-managers/sway/load-configuration-from-etc.patch
@@ -1,22 +1,26 @@
-From 26f9c65ef037892977a824f0d7d7111066856b53 Mon Sep 17 00:00:00 2001
-From: Michael Weiss <dev.primeos@gmail.com>
-Date: Sat, 27 Apr 2019 14:26:16 +0200
+From 92283df3acbffa5c1bb21f23cdd686113d905114 Mon Sep 17 00:00:00 2001
+From: Patrick Hilhorst <git@hilhorst.be>
+Date: Wed, 31 Mar 2021 21:14:13 +0200
 Subject: [PATCH] Load configs from /etc but fallback to /nix/store
 
 This change will load all configuration files from /etc, to make it easy
 to override them, but fallback to /nix/store/.../etc/sway/config to make
 Sway work out-of-the-box with the default configuration on non NixOS
 systems.
+
+Original patch by Michael Weiss, updated for Sway 1.6 by Patrick Hilhorst
+
+Co-authored-by: Michael Weiss <dev.primeos@gmail.com>
 ---
  meson.build   | 3 ++-
- sway/config.c | 1 +
- 2 files changed, 3 insertions(+), 1 deletion(-)
+ sway/config.c | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
 
 diff --git a/meson.build b/meson.build
-index 02b5d606..c03a9c0f 100644
+index b7a29660..8ae8ceb3 100644
 --- a/meson.build
 +++ b/meson.build
-@@ -129,7 +129,8 @@ if scdoc.found()
+@@ -164,7 +164,8 @@ if scdoc.found()
  	endforeach
  endif
  
@@ -25,18 +29,20 @@ index 02b5d606..c03a9c0f 100644
 +add_project_arguments('-DNIX_SYSCONFDIR="/@0@"'.format(join_paths(prefix, sysconfdir)), language : 'c')
  
  version = '"@0@"'.format(meson.project_version())
- if git.found()
+ git = find_program('git', native: true, required: false)
 diff --git a/sway/config.c b/sway/config.c
-index 4cd21bbc..dd855753 100644
+index 76b9ec08..fb5b51aa 100644
 --- a/sway/config.c
 +++ b/sway/config.c
-@@ -317,6 +317,7 @@ static char *get_config_path(void) {
- 		"$XDG_CONFIG_HOME/i3/config",
- 		SYSCONFDIR "/sway/config",
- 		SYSCONFDIR "/i3/config",
-+		NIX_SYSCONFDIR "/sway/config",
+@@ -374,7 +374,8 @@ static char *get_config_path(void) {
+ 		{ .prefix = home, .config_folder = ".i3"},
+ 		{ .prefix = config_home, .config_folder = "i3"},
+ 		{ .prefix = SYSCONFDIR, .config_folder = "sway"},
+-		{ .prefix = SYSCONFDIR, .config_folder = "i3"}
++		{ .prefix = SYSCONFDIR, .config_folder = "i3"},
++		{ .prefix = NIX_SYSCONFDIR, .config_folder = "sway"},
  	};
  
- 	char *config_home = getenv("XDG_CONFIG_HOME");
+ 	size_t num_config_paths = sizeof(config_paths)/sizeof(config_paths[0]);
 -- 
-2.19.2
+2.30.1
diff --git a/pkgs/applications/window-managers/wayfire/applications.nix b/pkgs/applications/window-managers/wayfire/applications.nix
index 6c22227c0c5..a77d3f8bf5d 100644
--- a/pkgs/applications/window-managers/wayfire/applications.nix
+++ b/pkgs/applications/window-managers/wayfire/applications.nix
@@ -1,23 +1,20 @@
-{ newScope, wayfirePlugins }:
+{ lib, newScope, wayfirePlugins }:
 
-let
-  self = with self; {
-    inherit wayfirePlugins;
+lib.makeExtensible (self: with self; {
+  inherit wayfirePlugins;
 
-    callPackage = newScope self;
+  callPackage = newScope self;
 
-    wayfire = callPackage ./. { };
+  wayfire = callPackage ./. { };
 
-    wcm = callPackage ./wcm.nix {
-      inherit (wayfirePlugins) wf-shell;
-    };
+  wcm = callPackage ./wcm.nix {
+    inherit (wayfirePlugins) wf-shell;
+  };
 
-    wrapWayfireApplication = callPackage ./wrapper.nix { };
+  wrapWayfireApplication = callPackage ./wrapper.nix { };
 
-    withPlugins = selector: self // {
-      wayfire = wrapWayfireApplication wayfire selector;
-      wcm = wrapWayfireApplication wcm selector;
-    };
+  withPlugins = selector: self // {
+    wayfire = wrapWayfireApplication wayfire selector;
+    wcm = wrapWayfireApplication wcm selector;
   };
-in
-self
+})
diff --git a/pkgs/development/compilers/dtc/default.nix b/pkgs/development/compilers/dtc/default.nix
index 245e5bf2f54..ac1acfe4b8f 100644
--- a/pkgs/development/compilers/dtc/default.nix
+++ b/pkgs/development/compilers/dtc/default.nix
@@ -1,9 +1,7 @@
 { stdenv, lib, fetchgit, flex, bison, pkg-config, which
-, pythonSupport ? false, python ? null, swig
+, pythonSupport ? false, python, swig, libyaml
 }:
 
-assert pythonSupport -> python != null;
-
 stdenv.mkDerivation rec {
   pname = "dtc";
   version = "1.6.0";
@@ -14,6 +12,7 @@ stdenv.mkDerivation rec {
     sha256 = "0li992wwd7kgy71bikanqky49y4hq3p3vx35p2hvyxy1k0wfy7i8";
   };
 
+  buildInputs = [ libyaml ];
   nativeBuildInputs = [ flex bison pkg-config which ] ++ lib.optionals pythonSupport [ python swig ];
 
   postPatch = ''
@@ -23,10 +22,12 @@ stdenv.mkDerivation rec {
   makeFlags = [ "PYTHON=python" ];
   installFlags = [ "INSTALL=install" "PREFIX=$(out)" "SETUP_PREFIX=$(out)" ];
 
+  doCheck = true;
+
   meta = with lib; {
     description = "Device Tree Compiler";
     homepage = "https://git.kernel.org/cgit/utils/dtc/dtc.git";
-    license = licenses.gpl2; # dtc itself is GPLv2, libfdt is dual GPL/BSD
+    license = licenses.gpl2Plus; # dtc itself is GPLv2, libfdt is dual GPL/BSD
     maintainers = [ maintainers.dezgeg ];
     platforms = platforms.unix;
   };
diff --git a/pkgs/development/compilers/jetbrains-jdk/default.nix b/pkgs/development/compilers/jetbrains-jdk/default.nix
index 3b5465ac9c3..c94df830095 100644
--- a/pkgs/development/compilers/jetbrains-jdk/default.nix
+++ b/pkgs/development/compilers/jetbrains-jdk/default.nix
@@ -2,12 +2,12 @@
 
 openjdk11.overrideAttrs (oldAttrs: rec {
   pname = "jetbrains-jdk";
-  version = "11.0.7-b64";
+  version = "11.0.10-b37";
   src = fetchFromGitHub {
     owner = "JetBrains";
     repo = "JetBrainsRuntime";
     rev = "jb${lib.replaceStrings ["."] ["_"] version}";
-    sha256 = "1gxqi6dkyriv9j29ppan638w1ns2g9m4q1sq7arf9kwqr05zim90";
+    sha256 = "0bcvwnwi29z000b1bk5dhfkd33xfp9899zc3idzifdwl7q42zi02";
   };
   patches = [];
   meta = with lib; {
diff --git a/pkgs/development/compilers/llvm/12/clang/default.nix b/pkgs/development/compilers/llvm/12/clang/default.nix
index d4d0ddf7954..d90d019e6d5 100644
--- a/pkgs/development/compilers/llvm/12/clang/default.nix
+++ b/pkgs/development/compilers/llvm/12/clang/default.nix
@@ -8,7 +8,7 @@ let
     pname = "clang";
     inherit version;
 
-    src = fetch "clang" "11ay72f81ffygil5ficq7mzplck4gffm77p0yj4ib3dgiqbb1qbw";
+    src = fetch "clang" "185r9rr254v75ja33nmm53j85lcnkj7bzsl18wvnd37jmz2nfxa5";
     inherit clang-tools-extra_src;
 
     unpackPhase = ''
diff --git a/pkgs/development/compilers/llvm/12/compiler-rt.nix b/pkgs/development/compilers/llvm/12/compiler-rt.nix
index 9721879d762..e6ac77b7d26 100644
--- a/pkgs/development/compilers/llvm/12/compiler-rt.nix
+++ b/pkgs/development/compilers/llvm/12/compiler-rt.nix
@@ -11,7 +11,7 @@ in
 stdenv.mkDerivation rec {
   pname = "compiler-rt";
   inherit version;
-  src = fetch pname "01dvir3858qkjmqhw2h6jjagq0la0kasnwzqbyv91yixnwx8369z";
+  src = fetch pname "1x0z875nbdpzhr4qb7linm6r9swvdf6dvwqy1s22pbn4wdcw0cvf";
 
   nativeBuildInputs = [ cmake python3 llvm ];
   buildInputs = lib.optional stdenv.hostPlatform.isDarwin libcxxabi;
diff --git a/pkgs/development/compilers/llvm/12/default.nix b/pkgs/development/compilers/llvm/12/default.nix
index 901e9c82eee..593db716ac6 100644
--- a/pkgs/development/compilers/llvm/12/default.nix
+++ b/pkgs/development/compilers/llvm/12/default.nix
@@ -8,7 +8,7 @@
 
 let
   release_version = "12.0.0";
-  candidate = "rc4"; # empty or "rcN"
+  candidate = "rc5"; # empty or "rcN"
   dash-candidate = lib.optionalString (candidate != "") "-${candidate}";
   version = "${release_version}${dash-candidate}"; # differentiating these (variables) is important for RCs
   targetConfig = stdenv.targetPlatform.config;
@@ -18,7 +18,7 @@ let
     inherit sha256;
   };
 
-  clang-tools-extra_src = fetch "clang-tools-extra" "1m1qga8m967bzqkxwx9xqkw1lkxi9dhlrn6km2k7g2yqyb6k14ag";
+  clang-tools-extra_src = fetch "clang-tools-extra" "1hga9k5m60ywmr7m69jf1v6vj1ra1n6ybv1abzlz94f5q22i1a02";
 
   tools = lib.makeExtensible (tools: let
     callPackage = newScope (tools // { inherit stdenv cmake libxml2 python3 isl release_version version fetch; });
diff --git a/pkgs/development/compilers/llvm/12/libc++/default.nix b/pkgs/development/compilers/llvm/12/libc++/default.nix
index e910d2c96b6..757651c0f4c 100644
--- a/pkgs/development/compilers/llvm/12/libc++/default.nix
+++ b/pkgs/development/compilers/llvm/12/libc++/default.nix
@@ -6,7 +6,7 @@ stdenv.mkDerivation {
   pname = "libc++";
   inherit version;
 
-  src = fetch "libcxx" "0ai91zls1738502c3b2frhawmjpi73rm3m677hh540wrjp3xv0ql";
+  src = fetch "libcxx" "01abh553dvjgk5cjzzp0ghmg00laqbr4ar4frdhyhpbwhhmwc880";
 
   postUnpack = ''
     unpackFile ${libcxxabi.src}
diff --git a/pkgs/development/compilers/llvm/12/libc++abi.nix b/pkgs/development/compilers/llvm/12/libc++abi.nix
index 70dd5af7277..e35480c7bf2 100644
--- a/pkgs/development/compilers/llvm/12/libc++abi.nix
+++ b/pkgs/development/compilers/llvm/12/libc++abi.nix
@@ -6,7 +6,7 @@ stdenv.mkDerivation {
   pname = "libc++abi";
   inherit version;
 
-  src = fetch "libcxxabi" "02qp6ndagq7n48p53z93d1rrx0v0v4rsahd4vkv5frid0vm4ah9h";
+  src = fetch "libcxxabi" "0mjj4f63ix4j1b72bgzpcki7mzf3qszrq7snqhiq0c5s73skkwx0";
 
   nativeBuildInputs = [ cmake python3 ];
   buildInputs = lib.optional (!stdenv.isDarwin && !stdenv.isFreeBSD && !stdenv.hostPlatform.isWasm) libunwind;
diff --git a/pkgs/development/compilers/llvm/12/libunwind.nix b/pkgs/development/compilers/llvm/12/libunwind.nix
index ddfcf508fd8..83e76c0c56c 100644
--- a/pkgs/development/compilers/llvm/12/libunwind.nix
+++ b/pkgs/development/compilers/llvm/12/libunwind.nix
@@ -6,7 +6,7 @@ stdenv.mkDerivation rec {
   pname = "libunwind";
   inherit version;
 
-  src = fetch pname "1a5db1lxw98a430b8mnaclc0w98y6cc8k587kgjhn0nghl40l40i";
+  src = fetch pname "0kaq75ygzv9dqfsx27pi5a0clipdjq6a9vghhb89d8k1rf20lslh";
 
   postUnpack = ''
     unpackFile ${libcxx.src}
diff --git a/pkgs/development/compilers/llvm/12/lld.nix b/pkgs/development/compilers/llvm/12/lld.nix
index 00e30e16b6b..a5e4ab834ec 100644
--- a/pkgs/development/compilers/llvm/12/lld.nix
+++ b/pkgs/development/compilers/llvm/12/lld.nix
@@ -11,7 +11,7 @@ stdenv.mkDerivation rec {
   pname = "lld";
   inherit version;
 
-  src = fetch pname "0r9pxhvinipirv9s5k8fnsnqd30zfniwqjkvw5sac3lq29rn2lp1";
+  src = fetch pname "044lv1d9am2xmbc3pvssxkkiyxyv72n2xkgk8z3p9k72h3ay00q3";
 
   nativeBuildInputs = [ cmake ];
   buildInputs = [ llvm libxml2 ];
diff --git a/pkgs/development/compilers/llvm/12/lldb.nix b/pkgs/development/compilers/llvm/12/lldb.nix
index f9f978c60b1..67de0c18741 100644
--- a/pkgs/development/compilers/llvm/12/lldb.nix
+++ b/pkgs/development/compilers/llvm/12/lldb.nix
@@ -25,7 +25,7 @@ stdenv.mkDerivation (rec {
   pname = "lldb";
   inherit version;
 
-  src = fetch pname "0943gan83mldizwbhksd07w4h90z4djjpv5f8v49caz8y9113svg";
+  src = fetch pname "0q4p4s5ws1zszs3i4da5w5fnxkpny0q3fr1s1sh7jp9wcwxbxiqq";
 
   patches = [ ./lldb-procfs.patch ];
 
diff --git a/pkgs/development/compilers/llvm/12/llvm.nix b/pkgs/development/compilers/llvm/12/llvm.nix
index f70c4379c1a..6e6127ba949 100644
--- a/pkgs/development/compilers/llvm/12/llvm.nix
+++ b/pkgs/development/compilers/llvm/12/llvm.nix
@@ -32,8 +32,8 @@ in stdenv.mkDerivation (rec {
   pname = "llvm";
   inherit version;
 
-  src = fetch pname "1jif65i165h41cfcsfvfjy5k1yrnikg61assj5vs0f25pv1vbyvf";
-  polly_src = fetch "polly" "0hk6j6rsal3zsp1f9fla71yzbwmzz9007m63x22hy7qfiwyplvf2";
+  src = fetch pname "088dyv7hppidl3rqfsjdibvn4d3a74896fg2sz4dwaxlg19way93";
+  polly_src = fetch "polly" "1qj7gkfr1yrsrz6j086l9p6d2kyyln15fmfiab4isn96g1dhsfb5";
 
   unpackPhase = ''
     unpackFile $src
diff --git a/pkgs/development/compilers/llvm/12/openmp.nix b/pkgs/development/compilers/llvm/12/openmp.nix
index fcb91574d17..1e4618e4a1b 100644
--- a/pkgs/development/compilers/llvm/12/openmp.nix
+++ b/pkgs/development/compilers/llvm/12/openmp.nix
@@ -11,7 +11,7 @@ stdenv.mkDerivation rec {
   pname = "openmp";
   inherit version;
 
-  src = fetch pname "07g2rsfhli3szv3chzy6y37p2176ywdb6w3k2fv9g2r416cpxjdz";
+  src = fetch pname "1d16r5whjb2n4n28rg8wn2g9krlc92q6nb0qmnnbzhqhx0rbkjfb";
 
   nativeBuildInputs = [ cmake perl ];
   buildInputs = [ llvm ];
diff --git a/pkgs/development/libraries/grpc/default.nix b/pkgs/development/libraries/grpc/default.nix
index 5cdd9886690..9dd5150f17d 100644
--- a/pkgs/development/libraries/grpc/default.nix
+++ b/pkgs/development/libraries/grpc/default.nix
@@ -1,15 +1,15 @@
 { lib, stdenv, fetchFromGitHub, fetchpatch, cmake, zlib, c-ares, pkg-config, re2, openssl, protobuf
-, gflags, abseil-cpp, libnsl
+, abseil-cpp, libnsl
 }:
 
 stdenv.mkDerivation rec {
-  version = "1.36.4"; # N.B: if you change this, change pythonPackages.grpcio-tools to a matching version too
+  version = "1.37.0"; # N.B: if you change this, change pythonPackages.grpcio-tools to a matching version too
   pname = "grpc";
   src = fetchFromGitHub {
     owner = "grpc";
     repo = "grpc";
     rev = "v${version}";
-    sha256 = "1zxvdg5vgjgkq5wmzwbxj2zydaj90ja074axs26yzd9x08j0bjxz";
+    sha256 = "0q3hcnq351j0qm0gsbaxbsnz1gd9w3bk4cazkvq4l2lfmmiw7z56";
     fetchSubmodules = true;
   };
   patches = [
@@ -22,7 +22,7 @@ stdenv.mkDerivation rec {
 
   nativeBuildInputs = [ cmake pkg-config ];
   propagatedBuildInputs = [ c-ares re2 zlib abseil-cpp ];
-  buildInputs = [ c-ares.cmake-config openssl protobuf gflags ]
+  buildInputs = [ c-ares.cmake-config openssl protobuf ]
     ++ lib.optionals stdenv.isLinux [ libnsl ];
 
   cmakeFlags =
@@ -31,7 +31,6 @@ stdenv.mkDerivation rec {
       "-DgRPC_RE2_PROVIDER=package"
       "-DgRPC_SSL_PROVIDER=package"
       "-DgRPC_PROTOBUF_PROVIDER=package"
-      "-DgRPC_GFLAGS_PROVIDER=package"
       "-DgRPC_ABSL_PROVIDER=package"
       "-DBUILD_SHARED_LIBS=ON"
       "-DCMAKE_SKIP_BUILD_RPATH=OFF"
diff --git a/pkgs/development/libraries/openzwave/default.nix b/pkgs/development/libraries/openzwave/default.nix
index 0a617561a89..723288ab4a9 100644
--- a/pkgs/development/libraries/openzwave/default.nix
+++ b/pkgs/development/libraries/openzwave/default.nix
@@ -1,23 +1,33 @@
-{ lib, stdenv, fetchFromGitHub
+{ lib, stdenv, fetchFromGitHub, fetchpatch
 , doxygen, fontconfig, graphviz-nox, libxml2, pkg-config, which
 , systemd }:
 
-let
-  version = "2019-12-08";
-
-in stdenv.mkDerivation {
+stdenv.mkDerivation rec {
   pname = "openzwave";
-  inherit version;
+  version = "1.6";
 
-  # Use fork by Home Assistant because this package is mainly used for python.pkgs.homeassistant-pyozw.
-  # See https://github.com/OpenZWave/open-zwave/compare/master...home-assistant:hass for the difference.
   src = fetchFromGitHub {
-    owner = "home-assistant";
+    owner = "OpenZWave";
     repo = "open-zwave";
-    rev = "2cd2137025c529835e4893a7b87c3d56605b2681";
-    sha256 = "04g8fb4f4ihakvvsmzcnncgfdd2ikmki7s22i9c6layzdwavbwf1";
+    rev = "v${version}";
+    sha256 = "0xgs4mmr0480c269wx9xkk67ikjzxkh8xcssrdx0f5xcl1lyd333";
   };
 
+  patches = [
+    (fetchpatch {
+      name = "fix-strncat-build-failure.patch";
+      url = "https://github.com/OpenZWave/open-zwave/commit/601e5fb16232a7984885e67fdddaf5b9c9dd8105.patch";
+      sha256 = "1n1k5arwk1dyc12xz6xl4n8yw28vghzhv27j65z1nca4zqsxgza1";
+    })
+    (fetchpatch {
+      name = "fix-text-uninitialized.patch";
+      url = "https://github.com/OpenZWave/open-zwave/commit/3b029a467e83bc7f0054e4dbba1e77e6eac7bc7f.patch";
+      sha256 = "183mrzjh1zx2b2wzkj4jisiw8br7g7bbs167afls4li0fm01d638";
+    })
+  ];
+
+  outputs = [ "out" "doc" ];
+
   nativeBuildInputs = [ doxygen fontconfig graphviz-nox libxml2 pkg-config which ];
 
   buildInputs = [ systemd ];
@@ -26,13 +36,9 @@ in stdenv.mkDerivation {
 
   enableParallelBuilding = true;
 
-  installPhase = ''
-    runHook preInstall
-
-    DESTDIR=$out PREFIX= pkgconfigdir=lib/pkgconfig make install $installFlags
-
-    runHook postInstall
-  '';
+  makeFlags = [
+    "PREFIX=${placeholder "out"}"
+  ];
 
   FONTCONFIG_FILE="${fontconfig.out}/etc/fonts/fonts.conf";
   FONTCONFIG_PATH="${fontconfig.out}/etc/fonts/";
@@ -42,15 +48,6 @@ in stdenv.mkDerivation {
       --replace /etc/openzwave $out/etc/openzwave
   '';
 
-  fixupPhase = ''
-    substituteInPlace $out/lib/pkgconfig/libopenzwave.pc \
-      --replace prefix= prefix=$out \
-      --replace dir=    dir=$out
-
-    substituteInPlace $out/bin/ozw_config \
-      --replace pcfile=${pkg-config} pcfile=$out
-  '';
-
   meta = with lib; {
     description = "C++ library to control Z-Wave Networks via a USB Z-Wave Controller";
     homepage = "http://www.openzwave.net/";
diff --git a/pkgs/development/libraries/tracker/default.nix b/pkgs/development/libraries/tracker/default.nix
index 1da2f34aa5b..fae10f2b1b4 100644
--- a/pkgs/development/libraries/tracker/default.nix
+++ b/pkgs/development/libraries/tracker/default.nix
@@ -27,7 +27,7 @@
 , substituteAll
 }:
 
-stdenv.mkDerivation rec {
+stdenv.mkDerivation (rec {
   pname = "tracker";
   version = "3.0.3";
 
@@ -82,7 +82,8 @@ stdenv.mkDerivation rec {
     "-Ddocs=true"
   ];
 
-  doCheck = true;
+  # https://gitlab.gnome.org/GNOME/tracker/-/issues/292#note_1075369
+  doCheck = !stdenv.isi686;
 
   postPatch = ''
     patchShebangs utils/g-ir-merge/g-ir-merge
@@ -133,3 +134,8 @@ stdenv.mkDerivation rec {
     platforms = platforms.linux;
   };
 }
+  // lib.optionalAttrs stdenv.isi686 {
+    # TMP: fatal error: libtracker-sparql/tracker-sparql-enum-types.h: No such file or directory
+    enableParallelBuilding = false;
+  }
+)
diff --git a/pkgs/development/libraries/v8/default.nix b/pkgs/development/libraries/v8/default.nix
index c79073f04e4..d513e01b7a3 100644
--- a/pkgs/development/libraries/v8/default.nix
+++ b/pkgs/development/libraries/v8/default.nix
@@ -11,23 +11,23 @@ let
   deps = {
     "base/trace_event/common" = fetchgit {
       url    = "${git_url}/chromium/src/base/trace_event/common.git";
-      rev    = "936ba8a963284a6b3737cf2f0474a7131073abee";
-      sha256 = "14nr22fqdpxma1kzjflj6a865vr3hfnnm2gs4vcixyq4kmfzfcy2";
+      rev    = "dab187b372fc17e51f5b9fad8201813d0aed5129";
+      sha256 = "0dmpj9hj4xv3xb0fl1kb9hm4bhpbs2s5csx3z8cgjd5vwvhdzig4";
     };
     build = fetchgit {
       url    = "${git_url}/chromium/src/build.git";
-      rev    = "325e95d6dae64f35b160b3dc7d73218cee5ec079";
-      sha256 = "0dddyxa76p2xpjhmxif05v63i5ar6h5v684fdl667sg84f5bhhxf";
+      rev    = "26e9d485d01d6e0eb9dadd21df767a63494c8fea";
+      sha256 = "1jjvsgj0cs97d26i3ba531ic1f9gqan8x7z4aya8yl8jx02l342q";
     };
     "third_party/googletest/src" = fetchgit {
       url    = "${git_url}/external/github.com/google/googletest.git";
-      rev    = "5ec7f0c4a113e2f18ac2c6cc7df51ad6afc24081";
-      sha256 = "0gmr10042c0xybxnn6g7ndj1na1mmd3l9w7449qlcv4s8gmfs7k6";
+      rev    = "e3f0319d89f4cbf32993de595d984183b1a9fc57";
+      sha256 = "18xz71l2xjrqsc0q317whgw4xi1i5db24zcj7v04f5g6r1hyf1a5";
     };
     "third_party/icu" = fetchgit {
       url    = "${git_url}/chromium/deps/icu.git";
-      rev    = "960f195aa87acaec46e6104ec93a596da7ae0843";
-      sha256 = "073kh6gpcairgjxf3hlhpqljc13gwl2aj8fz91fv220xibwqs834";
+      rev    = "f2223961702f00a8833874b0560d615a2cc42738";
+      sha256 = "0z5p53kbrjfkjn0i12dpk55cp8976j2zk7a4wk88423s2c5w87zl";
     };
     "third_party/jinja2" = fetchgit {
       url    = "${git_url}/chromium/src/third_party/jinja2.git";
@@ -39,29 +39,31 @@ let
       rev    = "8f45f5cfa0009d2a70589bcda0349b8cb2b72783";
       sha256 = "168ppjmicfdh4i1l0l25s86mdbrz9fgxmiq1rx33x79mph41scfz";
     };
+    "third_party/zlib" = fetchgit {
+      url    = "${git_url}/chromium/src/third_party/zlib.git";
+      rev    = "156be8c52f80cde343088b4a69a80579101b6e67";
+      sha256 = "0hxbkkzmlv714fjq2jlp5dd2jc339xyh6gkjx1sz3srwv33mlk92";
+    };
   };
 
 in
 
 stdenv.mkDerivation rec {
   pname = "v8";
-  version = "7.4.255";
+  version = "8.4.255";
 
   doCheck = true;
 
   patches = [
-    (fetchpatch {
-      url = "https://raw.githubusercontent.com/RPi-Distro/chromium-browser/master/debian/patches/revert-Xclang-instcombine-lower-dbg-declare.patch";
-      sha256 = "02hczcg43m36q8j1kv5j3hq9czj9niiil9w13w22vzv2f3c67dvn";
-    })
     ./darwin.patch
+    ./gcc_arm.patch  # Fix building zlib with gcc on aarch64, from https://gist.github.com/Adenilson/d973b6fd96c7709d33ddf08cf1dcb149
   ];
 
   src = fetchFromGitHub {
     owner = "v8";
     repo = "v8";
     rev = version;
-    sha256 = "14i0c71hmffzqnq9n73dh9dnabdxhbjhzkhqpk5yv9y90bwrzi2n";
+    sha256 = "07ymw4kqbz7kv311gpk5bs5q90wj73n2q7jkyfhqk4hvhs1q5bw7";
   };
 
   postUnpack = ''
@@ -97,9 +99,7 @@ stdenv.mkDerivation rec {
     ''v8_snapshot_toolchain="//build/toolchain/linux/unbundle:default"''
   ] ++ lib.optional stdenv.cc.isClang ''clang_base_path="${stdenv.cc}"'';
 
-  # with gcc8, -Wclass-memaccess became part of -Wall and causes logging limit
-  # to be exceeded
-  NIX_CFLAGS_COMPILE = lib.optionalString stdenv.cc.isGNU "-Wno-class-memaccess";
+  NIX_CFLAGS_COMPILE = "-O2";
 
   nativeBuildInputs = [ gn ninja pkg-config python ]
     ++ lib.optionals stdenv.isDarwin [ xcbuild darwin.DarwinTools ];
diff --git a/pkgs/development/libraries/v8/gcc_arm.patch b/pkgs/development/libraries/v8/gcc_arm.patch
new file mode 100644
index 00000000000..09579561fd8
--- /dev/null
+++ b/pkgs/development/libraries/v8/gcc_arm.patch
@@ -0,0 +1,31 @@
+diff --git a/third_party/zlib/contrib/optimizations/insert_string.h b/third_party/zlib/contrib/optimizations/insert_string.h
+index 1826601..d123305 100644
+--- a/third_party/zlib/contrib/optimizations/insert_string.h
++++ b/third_party/zlib/contrib/optimizations/insert_string.h
+@@ -26,15 +26,23 @@
+   #define _cpu_crc32_u32 _mm_crc32_u32
+ 
+ #elif defined(CRC32_ARMV8_CRC32)
+-  #if defined(__clang__)
++  #if defined(__GNUC__) || defined(__clang__)
+     #undef TARGET_CPU_WITH_CRC
+-    #define __crc32cw __builtin_arm_crc32cw
++    #if defined(__clang__)
++      #define __crc32cw __builtin_arm_crc32cw
++    #elif defined(__GNUC__)
++      #define __crc32cw __builtin_aarch64_crc32cw
++    #endif
+   #endif
+ 
+   #define _cpu_crc32_u32 __crc32cw
+ 
+   #if defined(__aarch64__)
+-    #define TARGET_CPU_WITH_CRC __attribute__((target("crc")))
++    #if defined(__clang__)
++      #define TARGET_CPU_WITH_CRC __attribute__((target("crc")))
++    #elif defined(__GNUC__)
++      #define TARGET_CPU_WITH_CRC __attribute__((target("+crc")))
++    #endif
+   #else  // !defined(__aarch64__)
+     #define TARGET_CPU_WITH_CRC __attribute__((target("armv8-a,crc")))
+   #endif  // defined(__aarch64__)
diff --git a/pkgs/development/libraries/wlroots/0.12.nix b/pkgs/development/libraries/wlroots/0.12.nix
new file mode 100644
index 00000000000..66d4fab2bf9
--- /dev/null
+++ b/pkgs/development/libraries/wlroots/0.12.nix
@@ -0,0 +1,57 @@
+{ lib, stdenv, fetchFromGitHub, meson, ninja, pkg-config, wayland
+, libGL, wayland-protocols, libinput, libxkbcommon, pixman
+, xcbutilwm, libX11, libcap, xcbutilimage, xcbutilerrors, mesa
+, libpng, ffmpeg
+}:
+
+# Fixed version derivation.
+# nixpkgs-update: no auto update
+stdenv.mkDerivation rec {
+  pname = "wlroots";
+  version = "0.12.0";
+
+  src = fetchFromGitHub {
+    owner = "swaywm";
+    repo = "wlroots";
+    rev = version;
+    sha256 = "01j38lmgs2c6fq68v8b75pkilia2wsgzgp46ivfbi9hhx47kgcfn";
+  };
+
+  # $out for the library and $examples for the example programs (in examples):
+  outputs = [ "out" "examples" ];
+
+  nativeBuildInputs = [ meson ninja pkg-config wayland ];
+
+  buildInputs = [
+    libGL wayland wayland-protocols libinput libxkbcommon pixman
+    xcbutilwm libX11 libcap xcbutilimage xcbutilerrors mesa
+    libpng ffmpeg
+  ];
+
+  mesonFlags = [ "-Dlogind-provider=systemd" "-Dlibseat=disabled" ];
+
+  postFixup = ''
+    # Install ALL example programs to $examples:
+    # screencopy dmabuf-capture input-inhibitor layer-shell idle-inhibit idle
+    # screenshot output-layout multi-pointer rotation tablet touch pointer
+    # simple
+    mkdir -p $examples/bin
+    cd ./examples
+    for binary in $(find . -executable -type f -printf '%P\n' | grep -vE '\.so'); do
+      cp "$binary" "$examples/bin/wlroots-$binary"
+    done
+  '';
+
+  meta = with lib; {
+    description = "A modular Wayland compositor library";
+    longDescription = ''
+      Pluggable, composable, unopinionated modules for building a Wayland
+      compositor; or about 50,000 lines of code you were going to write anyway.
+    '';
+    inherit (src.meta) homepage;
+    changelog = "https://github.com/swaywm/wlroots/releases/tag/${version}";
+    license     = licenses.mit;
+    platforms   = platforms.linux;
+    maintainers = with maintainers; [ primeos synthetica ];
+  };
+}
diff --git a/pkgs/development/libraries/wlroots/default.nix b/pkgs/development/libraries/wlroots/default.nix
index 50ccd3608d8..f2343e73c58 100644
--- a/pkgs/development/libraries/wlroots/default.nix
+++ b/pkgs/development/libraries/wlroots/default.nix
@@ -1,18 +1,18 @@
 { lib, stdenv, fetchFromGitHub, meson, ninja, pkg-config, wayland-scanner
 , libGL, wayland, wayland-protocols, libinput, libxkbcommon, pixman
 , xcbutilwm, libX11, libcap, xcbutilimage, xcbutilerrors, mesa
-, libpng, ffmpeg
+, libpng, ffmpeg, libuuid, xcbutilrenderutil, xwayland
 }:
 
 stdenv.mkDerivation rec {
   pname = "wlroots";
-  version = "0.12.0";
+  version = "0.13.0";
 
   src = fetchFromGitHub {
     owner = "swaywm";
     repo = "wlroots";
     rev = version;
-    sha256 = "01j38lmgs2c6fq68v8b75pkilia2wsgzgp46ivfbi9hhx47kgcfn";
+    sha256 = "01plhbnsp5yg18arz0v8fr0pr9l4w4pdzwkg9px486qdvb3s1vgy";
   };
 
   # $out for the library and $examples for the example programs (in examples):
@@ -23,7 +23,7 @@ stdenv.mkDerivation rec {
   buildInputs = [
     libGL wayland wayland-protocols libinput libxkbcommon pixman
     xcbutilwm libX11 libcap xcbutilimage xcbutilerrors mesa
-    libpng ffmpeg
+    libpng ffmpeg libuuid xcbutilrenderutil xwayland
   ];
 
   mesonFlags = [ "-Dlogind-provider=systemd" "-Dlibseat=disabled" ];
@@ -50,6 +50,6 @@ stdenv.mkDerivation rec {
     changelog = "https://github.com/swaywm/wlroots/releases/tag/${version}";
     license     = licenses.mit;
     platforms   = platforms.linux;
-    maintainers = with maintainers; [ primeos ];
+    maintainers = with maintainers; [ primeos synthetica ];
   };
 }
diff --git a/pkgs/development/python-modules/aiodiscover/default.nix b/pkgs/development/python-modules/aiodiscover/default.nix
index 923be510c45..e724d53bfe7 100644
--- a/pkgs/development/python-modules/aiodiscover/default.nix
+++ b/pkgs/development/python-modules/aiodiscover/default.nix
@@ -10,24 +10,16 @@
 
 buildPythonPackage rec {
   pname = "aiodiscover";
-  version = "1.3.2";
+  version = "1.3.3";
   disabled = pythonOlder "3.7";
 
   src = fetchFromGitHub {
     owner = "bdraco";
     repo = pname;
     rev = "v${version}";
-    sha256 = "0qg2wm6ddsfai788chylr5ynrvakwg91q3dszz7dxzbkfdcxixj3";
+    sha256 = "186agrjx818vn00d3pqlka5ir48rgpbfyn1cifkn9ylsxg9cz3ph";
   };
 
-  patches = [
-    (fetchpatch {
-      name = "remove-entry_point.patch";
-      url = "https://github.com/bdraco/aiodiscover/commit/4c497fb7d4c8685a78209c710e92e0bd17f46bb2.patch";
-      sha256 = "0py9alhg6qdncbn6a04mrnjhs4j19kg759dv69knpqzryikcfa63";
-    })
-  ];
-
   propagatedBuildInputs = [
     async-dns
     pyroute2
diff --git a/pkgs/development/python-modules/asyncio-nats-client/default.nix b/pkgs/development/python-modules/asyncio-nats-client/default.nix
new file mode 100644
index 00000000000..a7feac7312f
--- /dev/null
+++ b/pkgs/development/python-modules/asyncio-nats-client/default.nix
@@ -0,0 +1,50 @@
+{ lib
+, buildPythonPackage
+, ed25519
+, fetchFromGitHub
+, nats-server
+, pytestCheckHook
+, pythonOlder
+}:
+
+buildPythonPackage rec {
+  pname = "asyncio-nats-client";
+  version = "0.11.4";
+  disabled = pythonOlder "3.6";
+
+  src = fetchFromGitHub {
+    owner = "nats-io";
+    repo = "nats.py";
+    rev = "v${version}";
+    sha256 = "1aj57xi2rj1xswq8air13xdsll1ybpi0nmz5f6jq01azm0zy9xyd";
+  };
+
+  propagatedBuildInputs = [
+    ed25519
+  ];
+
+  checkInputs = [
+    nats-server
+    pytestCheckHook
+  ];
+
+  postPatch = ''
+    substituteInPlace setup.cfg \
+      --replace "--cov=nats --cov-report html" ""
+  '';
+
+  disabledTests = [
+    # RuntimeError: Event loop is closed
+    "test_subscribe_no_echo"
+    "test_reconnect_to_new_server_with_auth"
+  ];
+
+  pythonImportsCheck = [ "nats.aio" ];
+
+  meta = with lib; {
+    description = "Python client for NATS.io";
+    homepage = "https://github.com/nats-io/nats.py";
+    license = with licenses; [ asl20 ];
+    maintainers = with maintainers; [ fab ];
+  };
+}
diff --git a/pkgs/development/python-modules/bokeh/default.nix b/pkgs/development/python-modules/bokeh/default.nix
index 92dc2e80679..18fea103664 100644
--- a/pkgs/development/python-modules/bokeh/default.nix
+++ b/pkgs/development/python-modules/bokeh/default.nix
@@ -33,11 +33,12 @@
 
 buildPythonPackage rec {
   pname = "bokeh";
-  version = "2.2.3";  # update together with panel which is not straightforward
+  # update together with panel which is not straightforward
+  version = "2.3.0";
 
   src = fetchPypi {
     inherit pname version;
-    sha256 = "c4a3f97afe5f525019dd58ee8c4e3d43f53fe1b1ac264ccaae9b02c07b2abc17";
+    sha256 = "dd417708f90702190222b1068a645acae99e66d4b58d7a336d545aeaa04e9b40";
   };
 
   patches = [
diff --git a/pkgs/development/python-modules/grpcio-tools/default.nix b/pkgs/development/python-modules/grpcio-tools/default.nix
index d2d06450b92..2f4ee5de8d2 100644
--- a/pkgs/development/python-modules/grpcio-tools/default.nix
+++ b/pkgs/development/python-modules/grpcio-tools/default.nix
@@ -2,11 +2,11 @@
 
 buildPythonPackage rec {
   pname = "grpcio-tools";
-  version = "1.36.1";
+  version = "1.37.0";
 
   src = fetchPypi {
     inherit pname version;
-    sha256 = "80ef584f7b917f575e4b8f2ec59cd4a4d98c2046e801a735f3136b05742a36a6";
+    sha256 = "3ec510c1b6bfc32effc639acf9a055e72dab7a7b6757bf72f2132790d6a7cf1c";
   };
 
   outputs = [ "out" "dev" ];
diff --git a/pkgs/development/python-modules/homeassistant-pyozw/default.nix b/pkgs/development/python-modules/homeassistant-pyozw/default.nix
index a4ecb0d7ba3..271059e4851 100644
--- a/pkgs/development/python-modules/homeassistant-pyozw/default.nix
+++ b/pkgs/development/python-modules/homeassistant-pyozw/default.nix
@@ -1,6 +1,19 @@
-{ python_openzwave, fetchPypi }:
+{ python_openzwave, fetchPypi, openzwave, fetchFromGitHub }:
 
-python_openzwave.overridePythonAttrs (oldAttrs: rec {
+(python_openzwave.override {
+  openzwave = openzwave.overrideAttrs (oldAttrs: {
+    version = "unstable-2020-03-24";
+
+    src = fetchFromGitHub {
+      owner = "home-assistant";
+      repo = "open-zwave";
+      rev = "94267fa298c1882f0dc73c0fd08f1f755ba83e83";
+      sha256 = "0p2869fwidz1wcqzfm52cwm9ab96pmwkna3d4yvvh21nh09cvmwk";
+    };
+
+    patches = [ ];
+  });
+}).overridePythonAttrs (oldAttrs: rec {
   pname = "homeassistant_pyozw";
   version = "0.1.10";
 
diff --git a/pkgs/development/python-modules/jupyterlab/default.nix b/pkgs/development/python-modules/jupyterlab/default.nix
index f22b52b25b6..513cce507e3 100644
--- a/pkgs/development/python-modules/jupyterlab/default.nix
+++ b/pkgs/development/python-modules/jupyterlab/default.nix
@@ -18,7 +18,9 @@ buildPythonPackage rec {
     sha256 = "929c60d7fb4aa704084c02d8ededc209b8b378e0b3adab46158b7fa6acc24230";
   };
 
-  propagatedBuildInputs = [ jupyterlab_server notebook jupyter-packaging nbclassic ];
+  nativeBuildInputs = [ jupyter-packaging ];
+
+  propagatedBuildInputs = [ jupyterlab_server notebook nbclassic ];
 
   makeWrapperArgs = [
     "--set" "JUPYTERLAB_DIR" "$out/share/jupyter/lab"
@@ -27,6 +29,8 @@ buildPythonPackage rec {
   # Depends on npm
   doCheck = false;
 
+  pythonImportsCheck = [ "jupyterlab" ];
+
   meta = with lib; {
     description = "Jupyter lab environment notebook server extension.";
     license = with licenses; [ bsd3 ];
diff --git a/pkgs/development/python-modules/nats-python/default.nix b/pkgs/development/python-modules/nats-python/default.nix
new file mode 100644
index 00000000000..5bf5b2a6d21
--- /dev/null
+++ b/pkgs/development/python-modules/nats-python/default.nix
@@ -0,0 +1,46 @@
+{ lib
+, buildPythonPackage
+, fetchFromGitHub
+, fetchpatch
+, poetry-core
+, pythonOlder
+}:
+
+buildPythonPackage rec {
+  pname = "nats-python";
+  version = "0.8.0";
+  disabled = pythonOlder "3.6";
+  format = "pyproject";
+
+  src = fetchFromGitHub {
+    owner = "Gr1N";
+    repo = "nats-python";
+    rev = version;
+    sha256 = "1j7skyxldir3mphvnsyhjxmf3cimv4h7n5v58jl2gff4yd0hdw7g";
+  };
+
+  nativeBuildInputs = [
+    poetry-core
+  ];
+
+  patches = [
+    # Switch to poetry-core, https://github.com/Gr1N/nats-python/pull/19
+    (fetchpatch {
+      name = "use-poetry-core.patch";
+      url = "https://github.com/Gr1N/nats-python/commit/71b25b324212dccd7fc06ba3914491adba22e83f.patch";
+      sha256 = "1fip1qpzk2ka7qgkrdpdr6vnrnb1p8cwapa51xp0h26nm7yis1gl";
+    })
+  ];
+
+  # Tests require a running NATS server
+  doCheck = false;
+
+  pythonImportsCheck = [ "pynats" ];
+
+  meta = with lib; {
+    description = "Python client for NATS messaging system";
+    homepage = "https://github.com/Gr1N/nats-python";
+    license = with licenses; [ mit ];
+    maintainers = with maintainers; [ fab ];
+  };
+}
diff --git a/pkgs/development/python-modules/panel/default.nix b/pkgs/development/python-modules/panel/default.nix
index 5628b8cc19e..fa8dbddd04e 100644
--- a/pkgs/development/python-modules/panel/default.nix
+++ b/pkgs/development/python-modules/panel/default.nix
@@ -8,19 +8,39 @@
 , pyct
 , testpath
 , tqdm
+, callPackage
 }:
 
-buildPythonPackage rec {
+let
+  node = callPackage ./node {};
+in buildPythonPackage rec {
   pname = "panel";
   version = "0.11.1";
-  # Version 10 attempts to download models from the web during build-time
-  # https://github.com/holoviz/panel/issues/1819
 
+  # Don't forget to also update the node packages
+  # 1. retrieve the package.json file
+  # 2. nix shell nixpkgs#nodePackages.node2nix
+  # 3. node2nix
   src = fetchPypi {
     inherit pname version;
     sha256 = "ce531e5c0c8a8ae74d523762aeb1666650caebbe1867aba16129d29791e921f9";
   };
 
+  # Since 0.10.0 panel attempts to fetch from the web.
+  # We avoid this:
+  # - we use node2nix to fetch assets
+  # - we disable bundling (which also tries to fetch assets)
+  # Downside of disabling bundling is that in an airgapped environment
+  # one may miss assets.
+  # https://github.com/holoviz/panel/issues/1819
+  preBuild = ''
+    substituteInPlace setup.py --replace "bundle_resources()" ""
+    pushd panel
+    ln -s ${node.nodeDependencies}/lib/node_modules
+    export PATH="${node.nodeDependencies}/bin:$PATH"
+    popd
+  '';
+
   propagatedBuildInputs = [
     bokeh
     param
@@ -34,6 +54,10 @@ buildPythonPackage rec {
   # infinite recursion in test dependencies (hvplot)
   doCheck = false;
 
+  passthru = {
+    inherit node; # For convenience
+  };
+
   meta = with lib; {
     description = "A high level dashboarding library for python visualization libraries";
     homepage = "https://pyviz.org";
diff --git a/pkgs/development/python-modules/panel/node/default.nix b/pkgs/development/python-modules/panel/node/default.nix
new file mode 100644
index 00000000000..64326c6b216
--- /dev/null
+++ b/pkgs/development/python-modules/panel/node/default.nix
@@ -0,0 +1,17 @@
+# This file has been generated by node2nix 1.9.0. Do not edit!
+
+{pkgs ? import <nixpkgs> {
+    inherit system;
+  }, system ? builtins.currentSystem, nodejs ? pkgs."nodejs-12_x"}:
+
+let
+  nodeEnv = import ./node-env.nix {
+    inherit (pkgs) stdenv lib python2 runCommand writeTextFile;
+    inherit pkgs nodejs;
+    libtool = if pkgs.stdenv.isDarwin then pkgs.darwin.cctools else null;
+  };
+in
+import ./node-packages.nix {
+  inherit (pkgs) fetchurl nix-gitignore stdenv lib fetchgit;
+  inherit nodeEnv;
+}
diff --git a/pkgs/development/python-modules/panel/node/node-env.nix b/pkgs/development/python-modules/panel/node/node-env.nix
new file mode 100644
index 00000000000..c2b723195b7
--- /dev/null
+++ b/pkgs/development/python-modules/panel/node/node-env.nix
@@ -0,0 +1,567 @@
+# This file originates from node2nix
+
+{lib, stdenv, nodejs, python2, pkgs, libtool, runCommand, writeTextFile}:
+
+let
+  # Workaround to cope with utillinux in Nixpkgs 20.09 and util-linux in Nixpkgs master
+  utillinux = if pkgs ? utillinux then pkgs.utillinux else pkgs.util-linux;
+
+  python = if nodejs ? python then nodejs.python else python2;
+
+  # Create a tar wrapper that filters all the 'Ignoring unknown extended header keyword' noise
+  tarWrapper = runCommand "tarWrapper" {} ''
+    mkdir -p $out/bin
+
+    cat > $out/bin/tar <<EOF
+    #! ${stdenv.shell} -e
+    $(type -p tar) "\$@" --warning=no-unknown-keyword --delay-directory-restore
+    EOF
+
+    chmod +x $out/bin/tar
+  '';
+
+  # Function that generates a TGZ file from a NPM project
+  buildNodeSourceDist =
+    { name, version, src, ... }:
+
+    stdenv.mkDerivation {
+      name = "node-tarball-${name}-${version}";
+      inherit src;
+      buildInputs = [ nodejs ];
+      buildPhase = ''
+        export HOME=$TMPDIR
+        tgzFile=$(npm pack | tail -n 1) # Hooks to the pack command will add output (https://docs.npmjs.com/misc/scripts)
+      '';
+      installPhase = ''
+        mkdir -p $out/tarballs
+        mv $tgzFile $out/tarballs
+        mkdir -p $out/nix-support
+        echo "file source-dist $out/tarballs/$tgzFile" >> $out/nix-support/hydra-build-products
+      '';
+    };
+
+  includeDependencies = {dependencies}:
+    lib.optionalString (dependencies != [])
+      (lib.concatMapStrings (dependency:
+        ''
+          # Bundle the dependencies of the package
+          mkdir -p node_modules
+          cd node_modules
+
+          # Only include dependencies if they don't exist. They may also be bundled in the package.
+          if [ ! -e "${dependency.name}" ]
+          then
+              ${composePackage dependency}
+          fi
+
+          cd ..
+        ''
+      ) dependencies);
+
+  # Recursively composes the dependencies of a package
+  composePackage = { name, packageName, src, dependencies ? [], ... }@args:
+    builtins.addErrorContext "while evaluating node package '${packageName}'" ''
+      DIR=$(pwd)
+      cd $TMPDIR
+
+      unpackFile ${src}
+
+      # Make the base dir in which the target dependency resides first
+      mkdir -p "$(dirname "$DIR/${packageName}")"
+
+      if [ -f "${src}" ]
+      then
+          # Figure out what directory has been unpacked
+          packageDir="$(find . -maxdepth 1 -type d | tail -1)"
+
+          # Restore write permissions to make building work
+          find "$packageDir" -type d -exec chmod u+x {} \;
+          chmod -R u+w "$packageDir"
+
+          # Move the extracted tarball into the output folder
+          mv "$packageDir" "$DIR/${packageName}"
+      elif [ -d "${src}" ]
+      then
+          # Get a stripped name (without hash) of the source directory.
+          # On old nixpkgs it's already set internally.
+          if [ -z "$strippedName" ]
+          then
+              strippedName="$(stripHash ${src})"
+          fi
+
+          # Restore write permissions to make building work
+          chmod -R u+w "$strippedName"
+
+          # Move the extracted directory into the output folder
+          mv "$strippedName" "$DIR/${packageName}"
+      fi
+
+      # Unset the stripped name to not confuse the next unpack step
+      unset strippedName
+
+      # Include the dependencies of the package
+      cd "$DIR/${packageName}"
+      ${includeDependencies { inherit dependencies; }}
+      cd ..
+      ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
+    '';
+
+  pinpointDependencies = {dependencies, production}:
+    let
+      pinpointDependenciesFromPackageJSON = writeTextFile {
+        name = "pinpointDependencies.js";
+        text = ''
+          var fs = require('fs');
+          var path = require('path');
+
+          function resolveDependencyVersion(location, name) {
+              if(location == process.env['NIX_STORE']) {
+                  return null;
+              } else {
+                  var dependencyPackageJSON = path.join(location, "node_modules", name, "package.json");
+
+                  if(fs.existsSync(dependencyPackageJSON)) {
+                      var dependencyPackageObj = JSON.parse(fs.readFileSync(dependencyPackageJSON));
+
+                      if(dependencyPackageObj.name == name) {
+                          return dependencyPackageObj.version;
+                      }
+                  } else {
+                      return resolveDependencyVersion(path.resolve(location, ".."), name);
+                  }
+              }
+          }
+
+          function replaceDependencies(dependencies) {
+              if(typeof dependencies == "object" && dependencies !== null) {
+                  for(var dependency in dependencies) {
+                      var resolvedVersion = resolveDependencyVersion(process.cwd(), dependency);
+
+                      if(resolvedVersion === null) {
+                          process.stderr.write("WARNING: cannot pinpoint dependency: "+dependency+", context: "+process.cwd()+"\n");
+                      } else {
+                          dependencies[dependency] = resolvedVersion;
+                      }
+                  }
+              }
+          }
+
+          /* Read the package.json configuration */
+          var packageObj = JSON.parse(fs.readFileSync('./package.json'));
+
+          /* Pinpoint all dependencies */
+          replaceDependencies(packageObj.dependencies);
+          if(process.argv[2] == "development") {
+              replaceDependencies(packageObj.devDependencies);
+          }
+          replaceDependencies(packageObj.optionalDependencies);
+
+          /* Write the fixed package.json file */
+          fs.writeFileSync("package.json", JSON.stringify(packageObj, null, 2));
+        '';
+      };
+    in
+    ''
+      node ${pinpointDependenciesFromPackageJSON} ${if production then "production" else "development"}
+
+      ${lib.optionalString (dependencies != [])
+        ''
+          if [ -d node_modules ]
+          then
+              cd node_modules
+              ${lib.concatMapStrings (dependency: pinpointDependenciesOfPackage dependency) dependencies}
+              cd ..
+          fi
+        ''}
+    '';
+
+  # Recursively traverses all dependencies of a package and pinpoints all
+  # dependencies in the package.json file to the versions that are actually
+  # being used.
+
+  pinpointDependenciesOfPackage = { packageName, dependencies ? [], production ? true, ... }@args:
+    ''
+      if [ -d "${packageName}" ]
+      then
+          cd "${packageName}"
+          ${pinpointDependencies { inherit dependencies production; }}
+          cd ..
+          ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
+      fi
+    '';
+
+  # Extract the Node.js source code which is used to compile packages with
+  # native bindings
+  nodeSources = runCommand "node-sources" {} ''
+    tar --no-same-owner --no-same-permissions -xf ${nodejs.src}
+    mv node-* $out
+  '';
+
+  # Script that adds _integrity fields to all package.json files to prevent NPM from consulting the cache (that is empty)
+  addIntegrityFieldsScript = writeTextFile {
+    name = "addintegrityfields.js";
+    text = ''
+      var fs = require('fs');
+      var path = require('path');
+
+      function augmentDependencies(baseDir, dependencies) {
+          for(var dependencyName in dependencies) {
+              var dependency = dependencies[dependencyName];
+
+              // Open package.json and augment metadata fields
+              var packageJSONDir = path.join(baseDir, "node_modules", dependencyName);
+              var packageJSONPath = path.join(packageJSONDir, "package.json");
+
+              if(fs.existsSync(packageJSONPath)) { // Only augment packages that exist. Sometimes we may have production installs in which development dependencies can be ignored
+                  console.log("Adding metadata fields to: "+packageJSONPath);
+                  var packageObj = JSON.parse(fs.readFileSync(packageJSONPath));
+
+                  if(dependency.integrity) {
+                      packageObj["_integrity"] = dependency.integrity;
+                  } else {
+                      packageObj["_integrity"] = "sha1-000000000000000000000000000="; // When no _integrity string has been provided (e.g. by Git dependencies), add a dummy one. It does not seem to harm and it bypasses downloads.
+                  }
+
+                  if(dependency.resolved) {
+                      packageObj["_resolved"] = dependency.resolved; // Adopt the resolved property if one has been provided
+                  } else {
+                      packageObj["_resolved"] = dependency.version; // Set the resolved version to the version identifier. This prevents NPM from cloning Git repositories.
+                  }
+
+                  if(dependency.from !== undefined) { // Adopt from property if one has been provided
+                      packageObj["_from"] = dependency.from;
+                  }
+
+                  fs.writeFileSync(packageJSONPath, JSON.stringify(packageObj, null, 2));
+              }
+
+              // Augment transitive dependencies
+              if(dependency.dependencies !== undefined) {
+                  augmentDependencies(packageJSONDir, dependency.dependencies);
+              }
+          }
+      }
+
+      if(fs.existsSync("./package-lock.json")) {
+          var packageLock = JSON.parse(fs.readFileSync("./package-lock.json"));
+
+          if(![1, 2].includes(packageLock.lockfileVersion)) {
+             process.stderr.write("Sorry, I only understand lock file versions 1 and 2!\n");
+             process.exit(1);
+          }
+
+          if(packageLock.dependencies !== undefined) {
+              augmentDependencies(".", packageLock.dependencies);
+          }
+      }
+    '';
+  };
+
+  # Reconstructs a package-lock file from the node_modules/ folder structure and package.json files with dummy sha1 hashes
+  reconstructPackageLock = writeTextFile {
+    name = "addintegrityfields.js";
+    text = ''
+      var fs = require('fs');
+      var path = require('path');
+
+      var packageObj = JSON.parse(fs.readFileSync("package.json"));
+
+      var lockObj = {
+          name: packageObj.name,
+          version: packageObj.version,
+          lockfileVersion: 1,
+          requires: true,
+          dependencies: {}
+      };
+
+      function augmentPackageJSON(filePath, dependencies) {
+          var packageJSON = path.join(filePath, "package.json");
+          if(fs.existsSync(packageJSON)) {
+              var packageObj = JSON.parse(fs.readFileSync(packageJSON));
+              dependencies[packageObj.name] = {
+                  version: packageObj.version,
+                  integrity: "sha1-000000000000000000000000000=",
+                  dependencies: {}
+              };
+              processDependencies(path.join(filePath, "node_modules"), dependencies[packageObj.name].dependencies);
+          }
+      }
+
+      function processDependencies(dir, dependencies) {
+          if(fs.existsSync(dir)) {
+              var files = fs.readdirSync(dir);
+
+              files.forEach(function(entry) {
+                  var filePath = path.join(dir, entry);
+                  var stats = fs.statSync(filePath);
+
+                  if(stats.isDirectory()) {
+                      if(entry.substr(0, 1) == "@") {
+                          // When we encounter a namespace folder, augment all packages belonging to the scope
+                          var pkgFiles = fs.readdirSync(filePath);
+
+                          pkgFiles.forEach(function(entry) {
+                              if(stats.isDirectory()) {
+                                  var pkgFilePath = path.join(filePath, entry);
+                                  augmentPackageJSON(pkgFilePath, dependencies);
+                              }
+                          });
+                      } else {
+                          augmentPackageJSON(filePath, dependencies);
+                      }
+                  }
+              });
+          }
+      }
+
+      processDependencies("node_modules", lockObj.dependencies);
+
+      fs.writeFileSync("package-lock.json", JSON.stringify(lockObj, null, 2));
+    '';
+  };
+
+  prepareAndInvokeNPM = {packageName, bypassCache, reconstructLock, npmFlags, production}:
+    let
+      forceOfflineFlag = if bypassCache then "--offline" else "--registry http://www.example.com";
+    in
+    ''
+        # Pinpoint the versions of all dependencies to the ones that are actually being used
+        echo "pinpointing versions of dependencies..."
+        source $pinpointDependenciesScriptPath
+
+        # Patch the shebangs of the bundled modules to prevent them from
+        # calling executables outside the Nix store as much as possible
+        patchShebangs .
+
+        # Deploy the Node.js package by running npm install. Since the
+        # dependencies have been provided already by ourselves, it should not
+        # attempt to install them again, which is good, because we want to make
+        # it Nix's responsibility. If it needs to install any dependencies
+        # anyway (e.g. because the dependency parameters are
+        # incomplete/incorrect), it fails.
+        #
+        # The other responsibilities of NPM are kept -- version checks, build
+        # steps, postprocessing etc.
+
+        export HOME=$TMPDIR
+        cd "${packageName}"
+        runHook preRebuild
+
+        ${lib.optionalString bypassCache ''
+          ${lib.optionalString reconstructLock ''
+            if [ -f package-lock.json ]
+            then
+                echo "WARNING: Reconstruct lock option enabled, but a lock file already exists!"
+                echo "This will most likely result in version mismatches! We will remove the lock file and regenerate it!"
+                rm package-lock.json
+            else
+                echo "No package-lock.json file found, reconstructing..."
+            fi
+
+            node ${reconstructPackageLock}
+          ''}
+
+          node ${addIntegrityFieldsScript}
+        ''}
+
+        npm ${forceOfflineFlag} --nodedir=${nodeSources} ${npmFlags} ${lib.optionalString production "--production"} rebuild
+
+        if [ "''${dontNpmInstall-}" != "1" ]
+        then
+            # NPM tries to download packages even when they already exist if npm-shrinkwrap is used.
+            rm -f npm-shrinkwrap.json
+
+            npm ${forceOfflineFlag} --nodedir=${nodeSources} ${npmFlags} ${lib.optionalString production "--production"} install
+        fi
+    '';
+
+  # Builds and composes an NPM package including all its dependencies
+  buildNodePackage =
+    { name
+    , packageName
+    , version
+    , dependencies ? []
+    , buildInputs ? []
+    , production ? true
+    , npmFlags ? ""
+    , dontNpmInstall ? false
+    , bypassCache ? false
+    , reconstructLock ? false
+    , preRebuild ? ""
+    , dontStrip ? true
+    , unpackPhase ? "true"
+    , buildPhase ? "true"
+    , ... }@args:
+
+    let
+      extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" "dontStrip" "dontNpmInstall" "preRebuild" "unpackPhase" "buildPhase" ];
+    in
+    stdenv.mkDerivation ({
+      name = "node_${name}-${version}";
+      buildInputs = [ tarWrapper python nodejs ]
+        ++ lib.optional (stdenv.isLinux) utillinux
+        ++ lib.optional (stdenv.isDarwin) libtool
+        ++ buildInputs;
+
+      inherit nodejs;
+
+      inherit dontStrip; # Stripping may fail a build for some package deployments
+      inherit dontNpmInstall preRebuild unpackPhase buildPhase;
+
+      compositionScript = composePackage args;
+      pinpointDependenciesScript = pinpointDependenciesOfPackage args;
+
+      passAsFile = [ "compositionScript" "pinpointDependenciesScript" ];
+
+      installPhase = ''
+        # Create and enter a root node_modules/ folder
+        mkdir -p $out/lib/node_modules
+        cd $out/lib/node_modules
+
+        # Compose the package and all its dependencies
+        source $compositionScriptPath
+
+        ${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }}
+
+        # Create symlink to the deployed executable folder, if applicable
+        if [ -d "$out/lib/node_modules/.bin" ]
+        then
+            ln -s $out/lib/node_modules/.bin $out/bin
+        fi
+
+        # Create symlinks to the deployed manual page folders, if applicable
+        if [ -d "$out/lib/node_modules/${packageName}/man" ]
+        then
+            mkdir -p $out/share
+            for dir in "$out/lib/node_modules/${packageName}/man/"*
+            do
+                mkdir -p $out/share/man/$(basename "$dir")
+                for page in "$dir"/*
+                do
+                    ln -s $page $out/share/man/$(basename "$dir")
+                done
+            done
+        fi
+
+        # Run post install hook, if provided
+        runHook postInstall
+      '';
+    } // extraArgs);
+
+  # Builds a node environment (a node_modules folder and a set of binaries)
+  buildNodeDependencies =
+    { name
+    , packageName
+    , version
+    , src
+    , dependencies ? []
+    , buildInputs ? []
+    , production ? true
+    , npmFlags ? ""
+    , dontNpmInstall ? false
+    , bypassCache ? false
+    , reconstructLock ? false
+    , dontStrip ? true
+    , unpackPhase ? "true"
+    , buildPhase ? "true"
+    , ... }@args:
+
+    let
+      extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" ];
+    in
+      stdenv.mkDerivation ({
+        name = "node-dependencies-${name}-${version}";
+
+        buildInputs = [ tarWrapper python nodejs ]
+          ++ lib.optional (stdenv.isLinux) utillinux
+          ++ lib.optional (stdenv.isDarwin) libtool
+          ++ buildInputs;
+
+        inherit dontStrip; # Stripping may fail a build for some package deployments
+        inherit dontNpmInstall unpackPhase buildPhase;
+
+        includeScript = includeDependencies { inherit dependencies; };
+        pinpointDependenciesScript = pinpointDependenciesOfPackage args;
+
+        passAsFile = [ "includeScript" "pinpointDependenciesScript" ];
+
+        installPhase = ''
+          mkdir -p $out/${packageName}
+          cd $out/${packageName}
+
+          source $includeScriptPath
+
+          # Create fake package.json to make the npm commands work properly
+          cp ${src}/package.json .
+          chmod 644 package.json
+          ${lib.optionalString bypassCache ''
+            if [ -f ${src}/package-lock.json ]
+            then
+                cp ${src}/package-lock.json .
+            fi
+          ''}
+
+          # Go to the parent folder to make sure that all packages are pinpointed
+          cd ..
+          ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
+
+          ${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }}
+
+          # Expose the executables that were installed
+          cd ..
+          ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
+
+          mv ${packageName} lib
+          ln -s $out/lib/node_modules/.bin $out/bin
+        '';
+      } // extraArgs);
+
+  # Builds a development shell
+  buildNodeShell =
+    { name
+    , packageName
+    , version
+    , src
+    , dependencies ? []
+    , buildInputs ? []
+    , production ? true
+    , npmFlags ? ""
+    , dontNpmInstall ? false
+    , bypassCache ? false
+    , reconstructLock ? false
+    , dontStrip ? true
+    , unpackPhase ? "true"
+    , buildPhase ? "true"
+    , ... }@args:
+
+    let
+      nodeDependencies = buildNodeDependencies args;
+    in
+    stdenv.mkDerivation {
+      name = "node-shell-${name}-${version}";
+
+      buildInputs = [ python nodejs ] ++ lib.optional (stdenv.isLinux) utillinux ++ buildInputs;
+      buildCommand = ''
+        mkdir -p $out/bin
+        cat > $out/bin/shell <<EOF
+        #! ${stdenv.shell} -e
+        $shellHook
+        exec ${stdenv.shell}
+        EOF
+        chmod +x $out/bin/shell
+      '';
+
+      # Provide the dependencies in a development shell through the NODE_PATH environment variable
+      inherit nodeDependencies;
+      shellHook = lib.optionalString (dependencies != []) ''
+        export NODE_PATH=${nodeDependencies}/lib/node_modules
+        export PATH="${nodeDependencies}/bin:$PATH"
+      '';
+    };
+in
+{
+  buildNodeSourceDist = lib.makeOverridable buildNodeSourceDist;
+  buildNodePackage = lib.makeOverridable buildNodePackage;
+  buildNodeDependencies = lib.makeOverridable buildNodeDependencies;
+  buildNodeShell = lib.makeOverridable buildNodeShell;
+}
diff --git a/pkgs/development/python-modules/panel/node/node-packages.nix b/pkgs/development/python-modules/panel/node/node-packages.nix
new file mode 100644
index 00000000000..7b591b6e469
--- /dev/null
+++ b/pkgs/development/python-modules/panel/node/node-packages.nix
@@ -0,0 +1,572 @@
+# This file has been generated by node2nix 1.9.0. Do not edit!
+
+{nodeEnv, fetchurl, fetchgit, nix-gitignore, stdenv, lib, globalBuildInputs ? []}:
+
+let
+  sources = {
+    "@bokeh/bokehjs-2.3.0" = {
+      name = "_at_bokeh_slash_bokehjs";
+      packageName = "@bokeh/bokehjs";
+      version = "2.3.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/@bokeh/bokehjs/-/bokehjs-2.3.0.tgz";
+        sha512 = "geKBhYUVJ5IaY0UNk9k2P0yiYLCj+DOeNjdDneuTJ8K5R9fs0Rpp4iiaQKUGr1yUyQHGHLU8sk4CFZ+Bd5ZILg==";
+      };
+    };
+    "@bokeh/numbro-1.6.2" = {
+      name = "_at_bokeh_slash_numbro";
+      packageName = "@bokeh/numbro";
+      version = "1.6.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/@bokeh/numbro/-/numbro-1.6.2.tgz";
+        sha512 = "owIECPc3T3QXHCb2v5Ez+/uE9SIxI7N4nd9iFlWnfBrOelr0/omvFn09VisRn37AAFAY39sJiCVgECwryHWUPA==";
+      };
+    };
+    "@bokeh/slickgrid-2.4.2702" = {
+      name = "_at_bokeh_slash_slickgrid";
+      packageName = "@bokeh/slickgrid";
+      version = "2.4.2702";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/@bokeh/slickgrid/-/slickgrid-2.4.2702.tgz";
+        sha512 = "W9tm8Qdw5BrylbZbaVWaQMgLfW/klesnj6J3FnyWpo18hCCOFApccUD8iOnRv7bF6PHlgWk84mW3JT5RSzYKjA==";
+      };
+    };
+    "@luma.gl/constants-8.4.4" = {
+      name = "_at_luma.gl_slash_constants";
+      packageName = "@luma.gl/constants";
+      version = "8.4.4";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/@luma.gl/constants/-/constants-8.4.4.tgz";
+        sha512 = "4e58QW6UKXkxiIvWSLoAnTc4cT8nvb0PhLzu1h8KiCuaDT5Vq8csOymcNOy/jhpfcIhHlmT1KwowF5m/DcOlKg==";
+      };
+    };
+    "@types/debounce-1.2.0" = {
+      name = "_at_types_slash_debounce";
+      packageName = "@types/debounce";
+      version = "1.2.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.0.tgz";
+        sha512 = "bWG5wapaWgbss9E238T0R6bfo5Fh3OkeoSt245CM7JJwVwpw6MEBCbIxLq5z8KzsE3uJhzcIuQkyiZmzV3M/Dw==";
+      };
+    };
+    "@types/gl-matrix-2.4.5" = {
+      name = "_at_types_slash_gl-matrix";
+      packageName = "@types/gl-matrix";
+      version = "2.4.5";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/@types/gl-matrix/-/gl-matrix-2.4.5.tgz";
+        sha512 = "0L8Mq1+oaIW0oVzGUDbSW+HnTjCNb4CmoIQE5BkoHt/A7x20z0MJ1PnwfH3atty/vbWLGgvJwVu2Mz3SKFiEFw==";
+      };
+    };
+    "@types/jquery-3.5.5" = {
+      name = "_at_types_slash_jquery";
+      packageName = "@types/jquery";
+      version = "3.5.5";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.5.tgz";
+        sha512 = "6RXU9Xzpc6vxNrS6FPPapN1SxSHgQ336WC6Jj/N8q30OiaBZ00l1GBgeP7usjVZPivSkGUfL1z/WW6TX989M+w==";
+      };
+    };
+    "@types/sizzle-2.3.2" = {
+      name = "_at_types_slash_sizzle";
+      packageName = "@types/sizzle";
+      version = "2.3.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz";
+        sha512 = "7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==";
+      };
+    };
+    "@types/slickgrid-2.1.30" = {
+      name = "_at_types_slash_slickgrid";
+      packageName = "@types/slickgrid";
+      version = "2.1.30";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/@types/slickgrid/-/slickgrid-2.1.30.tgz";
+        sha512 = "9nTqNWD3BtEVK0CP+G+mBtvSrKTfQy3Dg5/al+GdTSVMHFm37UxsHJ1eURwPg7rYu6vc7xU95fGTCKMZbxsD5w==";
+      };
+    };
+    "choices.js-9.0.1" = {
+      name = "choices.js";
+      packageName = "choices.js";
+      version = "9.0.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/choices.js/-/choices.js-9.0.1.tgz";
+        sha512 = "JgpeDY0Tmg7tqY6jaW/druSklJSt7W68tXFJIw0GSGWmO37SDAL8o60eICNGbzIODjj02VNNtf5h6TgoHDtCsA==";
+      };
+    };
+    "d-1.0.1" = {
+      name = "d";
+      packageName = "d";
+      version = "1.0.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/d/-/d-1.0.1.tgz";
+        sha512 = "m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==";
+      };
+    };
+    "debounce-1.2.1" = {
+      name = "debounce";
+      packageName = "debounce";
+      version = "1.2.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz";
+        sha512 = "XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==";
+      };
+    };
+    "deepmerge-4.2.2" = {
+      name = "deepmerge";
+      packageName = "deepmerge";
+      version = "4.2.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz";
+        sha512 = "FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==";
+      };
+    };
+    "es5-ext-0.10.53" = {
+      name = "es5-ext";
+      packageName = "es5-ext";
+      version = "0.10.53";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz";
+        sha512 = "Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==";
+      };
+    };
+    "es6-iterator-2.0.3" = {
+      name = "es6-iterator";
+      packageName = "es6-iterator";
+      version = "2.0.3";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz";
+        sha1 = "a7de889141a05a94b0854403b2d0a0fbfa98f3b7";
+      };
+    };
+    "es6-map-0.1.5" = {
+      name = "es6-map";
+      packageName = "es6-map";
+      version = "0.1.5";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz";
+        sha1 = "9136e0503dcc06a301690f0bb14ff4e364e949f0";
+      };
+    };
+    "es6-promise-4.2.8" = {
+      name = "es6-promise";
+      packageName = "es6-promise";
+      version = "4.2.8";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz";
+        sha512 = "HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==";
+      };
+    };
+    "es6-set-0.1.5" = {
+      name = "es6-set";
+      packageName = "es6-set";
+      version = "0.1.5";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz";
+        sha1 = "d2b3ec5d4d800ced818db538d28974db0a73ccb1";
+      };
+    };
+    "es6-symbol-3.1.1" = {
+      name = "es6-symbol";
+      packageName = "es6-symbol";
+      version = "3.1.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz";
+        sha1 = "bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77";
+      };
+    };
+    "es6-symbol-3.1.3" = {
+      name = "es6-symbol";
+      packageName = "es6-symbol";
+      version = "3.1.3";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz";
+        sha512 = "NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==";
+      };
+    };
+    "es6-weak-map-2.0.3" = {
+      name = "es6-weak-map";
+      packageName = "es6-weak-map";
+      version = "2.0.3";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz";
+        sha512 = "p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==";
+      };
+    };
+    "event-emitter-0.3.5" = {
+      name = "event-emitter";
+      packageName = "event-emitter";
+      version = "0.3.5";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz";
+        sha1 = "df8c69eef1647923c7157b9ce83840610b02cc39";
+      };
+    };
+    "ext-1.4.0" = {
+      name = "ext";
+      packageName = "ext";
+      version = "1.4.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz";
+        sha512 = "Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==";
+      };
+    };
+    "fast-deep-equal-2.0.1" = {
+      name = "fast-deep-equal";
+      packageName = "fast-deep-equal";
+      version = "2.0.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz";
+        sha1 = "7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49";
+      };
+    };
+    "fast-json-patch-2.2.1" = {
+      name = "fast-json-patch";
+      packageName = "fast-json-patch";
+      version = "2.2.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-2.2.1.tgz";
+        sha512 = "4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig==";
+      };
+    };
+    "flatbush-3.3.0" = {
+      name = "flatbush";
+      packageName = "flatbush";
+      version = "3.3.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/flatbush/-/flatbush-3.3.0.tgz";
+        sha512 = "F3EzQvKpdmXUbFwWxLKBpytOFEGYQMCTBLuqZ4GEajFOEAvnOIBiyxW3OFSZXIOtpCS8teN6bFEpNZtnVXuDQA==";
+      };
+    };
+    "flatpickr-4.6.9" = {
+      name = "flatpickr";
+      packageName = "flatpickr";
+      version = "4.6.9";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.9.tgz";
+        sha512 = "F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw==";
+      };
+    };
+    "flatqueue-1.2.1" = {
+      name = "flatqueue";
+      packageName = "flatqueue";
+      version = "1.2.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/flatqueue/-/flatqueue-1.2.1.tgz";
+        sha512 = "X86TpWS1rGuY7m382HuA9vngLeDuWA9lJvhEG+GfgKMV5onSvx5a71cl7GMbXzhWtlN9dGfqOBrpfqeOtUfGYQ==";
+      };
+    };
+    "fuse.js-3.6.1" = {
+      name = "fuse.js";
+      packageName = "fuse.js";
+      version = "3.6.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/fuse.js/-/fuse.js-3.6.1.tgz";
+        sha512 = "hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw==";
+      };
+    };
+    "gl-matrix-3.3.0" = {
+      name = "gl-matrix";
+      packageName = "gl-matrix";
+      version = "3.3.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.3.0.tgz";
+        sha512 = "COb7LDz+SXaHtl/h4LeaFcNdJdAQSDeVqjiIihSXNrkWObZLhDI4hIkZC11Aeqp7bcE72clzB0BnDXr2SmslRA==";
+      };
+    };
+    "hammerjs-2.0.8" = {
+      name = "hammerjs";
+      packageName = "hammerjs";
+      version = "2.0.8";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz";
+        sha1 = "04ef77862cff2bb79d30f7692095930222bf60f1";
+      };
+    };
+    "htm-3.0.4" = {
+      name = "htm";
+      packageName = "htm";
+      version = "3.0.4";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/htm/-/htm-3.0.4.tgz";
+        sha512 = "VRdvxX3tmrXuT/Ovt59NMp/ORMFi4bceFMDjos1PV4E0mV+5votuID8R60egR9A4U8nLt238R/snlJGz3UYiTQ==";
+      };
+    };
+    "jquery-3.6.0" = {
+      name = "jquery";
+      packageName = "jquery";
+      version = "3.6.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz";
+        sha512 = "JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==";
+      };
+    };
+    "jquery-ui-1.12.1" = {
+      name = "jquery-ui";
+      packageName = "jquery-ui";
+      version = "1.12.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.12.1.tgz";
+        sha1 = "bcb4045c8dd0539c134bc1488cdd3e768a7a9e51";
+      };
+    };
+    "js-tokens-4.0.0" = {
+      name = "js-tokens";
+      packageName = "js-tokens";
+      version = "4.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz";
+        sha512 = "RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==";
+      };
+    };
+    "json-formatter-js-2.3.4" = {
+      name = "json-formatter-js";
+      packageName = "json-formatter-js";
+      version = "2.3.4";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/json-formatter-js/-/json-formatter-js-2.3.4.tgz";
+        sha512 = "gmAzYRtPRmYzeAT4T7+t3NhTF89JOAIioCVDddl9YDb3ls3kWcskirafw/MZGJaRhEU6fRimGJHl7CC7gaAI2Q==";
+      };
+    };
+    "loose-envify-1.4.0" = {
+      name = "loose-envify";
+      packageName = "loose-envify";
+      version = "1.4.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz";
+        sha512 = "lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==";
+      };
+    };
+    "mgrs-1.0.0" = {
+      name = "mgrs";
+      packageName = "mgrs";
+      version = "1.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/mgrs/-/mgrs-1.0.0.tgz";
+        sha1 = "fb91588e78c90025672395cb40b25f7cd6ad1829";
+      };
+    };
+    "next-tick-1.0.0" = {
+      name = "next-tick";
+      packageName = "next-tick";
+      version = "1.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz";
+        sha1 = "ca86d1fe8828169b0120208e3dc8424b9db8342c";
+      };
+    };
+    "nouislider-14.7.0" = {
+      name = "nouislider";
+      packageName = "nouislider";
+      version = "14.7.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/nouislider/-/nouislider-14.7.0.tgz";
+        sha512 = "4RtQ1+LHJKesDCNJrXkQcwXAWCrC2aggdLYMstS/G5fEWL+fXZbUA9pwVNHFghMGuFGRATlDLNInRaPeRKzpFQ==";
+      };
+    };
+    "preact-10.5.13" = {
+      name = "preact";
+      packageName = "preact";
+      version = "10.5.13";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/preact/-/preact-10.5.13.tgz";
+        sha512 = "q/vlKIGNwzTLu+jCcvywgGrt+H/1P/oIRSD6mV4ln3hmlC+Aa34C7yfPI4+5bzW8pONyVXYS7SvXosy2dKKtWQ==";
+      };
+    };
+    "proj4-2.7.2" = {
+      name = "proj4";
+      packageName = "proj4";
+      version = "2.7.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/proj4/-/proj4-2.7.2.tgz";
+        sha512 = "x/EboBmIq48a9FED0Z9zWCXkd8VIpXHLsyEXljGtsnzeztC41bFjPjJ0S//wBbNLDnDYRe0e6c3FSSiqMCebDA==";
+      };
+    };
+    "redux-4.0.5" = {
+      name = "redux";
+      packageName = "redux";
+      version = "4.0.5";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz";
+        sha512 = "VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==";
+      };
+    };
+    "sprintf-js-1.1.2" = {
+      name = "sprintf-js";
+      packageName = "sprintf-js";
+      version = "1.1.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz";
+        sha512 = "VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==";
+      };
+    };
+    "symbol-observable-1.2.0" = {
+      name = "symbol-observable";
+      packageName = "symbol-observable";
+      version = "1.2.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz";
+        sha512 = "e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==";
+      };
+    };
+    "timezone-1.0.23" = {
+      name = "timezone";
+      packageName = "timezone";
+      version = "1.0.23";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/timezone/-/timezone-1.0.23.tgz";
+        sha512 = "yhQgk6qmSLB+TF8HGmApZAVI5bfzR1CoKUGr+WMZWmx75ED1uDewAZA8QMGCQ70TEv4GmM8pDB9jrHuxdaQ1PA==";
+      };
+    };
+    "tslib-1.14.1" = {
+      name = "tslib";
+      packageName = "tslib";
+      version = "1.14.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz";
+        sha512 = "Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==";
+      };
+    };
+    "tslib-2.2.0" = {
+      name = "tslib";
+      packageName = "tslib";
+      version = "2.2.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz";
+        sha512 = "gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==";
+      };
+    };
+    "type-1.2.0" = {
+      name = "type";
+      packageName = "type";
+      version = "1.2.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/type/-/type-1.2.0.tgz";
+        sha512 = "+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==";
+      };
+    };
+    "type-2.5.0" = {
+      name = "type";
+      packageName = "type";
+      version = "2.5.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/type/-/type-2.5.0.tgz";
+        sha512 = "180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==";
+      };
+    };
+    "underscore.template-0.1.7" = {
+      name = "underscore.template";
+      packageName = "underscore.template";
+      version = "0.1.7";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/underscore.template/-/underscore.template-0.1.7.tgz";
+        sha1 = "3013e0ea181756306f1609e959cafbc722adb3e9";
+      };
+    };
+    "wkt-parser-1.2.4" = {
+      name = "wkt-parser";
+      packageName = "wkt-parser";
+      version = "1.2.4";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.2.4.tgz";
+        sha512 = "ZzKnc7ml/91fOPh5bANBL4vUlWPIYYv11waCtWTkl2TRN+LEmBg60Q1MA8gqV4hEp4MGfSj9JiHz91zw/gTDXg==";
+      };
+    };
+  };
+  args = {
+    name = "_at_holoviz_slash_panel";
+    packageName = "@holoviz/panel";
+    version = "0.11.1";
+    src = ./.;
+    dependencies = [
+      sources."@bokeh/bokehjs-2.3.0"
+      sources."@bokeh/numbro-1.6.2"
+      (sources."@bokeh/slickgrid-2.4.2702" // {
+        dependencies = [
+          sources."tslib-1.14.1"
+        ];
+      })
+      sources."@luma.gl/constants-8.4.4"
+      sources."@types/debounce-1.2.0"
+      sources."@types/gl-matrix-2.4.5"
+      sources."@types/jquery-3.5.5"
+      sources."@types/sizzle-2.3.2"
+      sources."@types/slickgrid-2.1.30"
+      sources."choices.js-9.0.1"
+      sources."d-1.0.1"
+      sources."debounce-1.2.1"
+      sources."deepmerge-4.2.2"
+      sources."es5-ext-0.10.53"
+      sources."es6-iterator-2.0.3"
+      sources."es6-map-0.1.5"
+      sources."es6-promise-4.2.8"
+      (sources."es6-set-0.1.5" // {
+        dependencies = [
+          sources."es6-symbol-3.1.1"
+        ];
+      })
+      sources."es6-symbol-3.1.3"
+      sources."es6-weak-map-2.0.3"
+      sources."event-emitter-0.3.5"
+      (sources."ext-1.4.0" // {
+        dependencies = [
+          sources."type-2.5.0"
+        ];
+      })
+      sources."fast-deep-equal-2.0.1"
+      sources."fast-json-patch-2.2.1"
+      sources."flatbush-3.3.0"
+      sources."flatpickr-4.6.9"
+      sources."flatqueue-1.2.1"
+      sources."fuse.js-3.6.1"
+      sources."gl-matrix-3.3.0"
+      sources."hammerjs-2.0.8"
+      sources."htm-3.0.4"
+      sources."jquery-3.6.0"
+      sources."jquery-ui-1.12.1"
+      sources."js-tokens-4.0.0"
+      sources."json-formatter-js-2.3.4"
+      sources."loose-envify-1.4.0"
+      sources."mgrs-1.0.0"
+      sources."next-tick-1.0.0"
+      sources."nouislider-14.7.0"
+      sources."preact-10.5.13"
+      sources."proj4-2.7.2"
+      sources."redux-4.0.5"
+      sources."sprintf-js-1.1.2"
+      sources."symbol-observable-1.2.0"
+      sources."timezone-1.0.23"
+      sources."tslib-2.2.0"
+      sources."type-1.2.0"
+      sources."underscore.template-0.1.7"
+      sources."wkt-parser-1.2.4"
+    ];
+    buildInputs = globalBuildInputs;
+    meta = {
+      description = "A high level dashboarding library for python visualization libraries.";
+      license = "BSD-3-Clause";
+    };
+    production = true;
+    bypassCache = true;
+    reconstructLock = true;
+  };
+in
+{
+  args = args;
+  sources = sources;
+  tarball = nodeEnv.buildNodeSourceDist args;
+  package = nodeEnv.buildNodePackage args;
+  shell = nodeEnv.buildNodeShell args;
+  nodeDependencies = nodeEnv.buildNodeDependencies (lib.overrideExisting args {
+    src = stdenv.mkDerivation {
+      name = args.name + "-package-json";
+      src = nix-gitignore.gitignoreSourcePure [
+        "*"
+        "!package.json"
+        "!package-lock.json"
+      ] args.src;
+      dontBuild = true;
+      installPhase = "mkdir -p $out; cp -r ./* $out;";
+    };
+  });
+}
diff --git a/pkgs/development/python-modules/panel/node/package.json b/pkgs/development/python-modules/panel/node/package.json
new file mode 100644
index 00000000000..f40e3773e23
--- /dev/null
+++ b/pkgs/development/python-modules/panel/node/package.json
@@ -0,0 +1,27 @@
+{
+  "name": "@holoviz/panel",
+  "version": "0.11.1",
+  "description": "A high level dashboarding library for python visualization libraries.",
+  "license": "BSD-3-Clause",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/holoviz/panel.git"
+  },
+  "dependencies": {
+    "@bokeh/bokehjs": "^2.3.0",
+    "@luma.gl/constants": "^8.0.3",
+    "@types/debounce": "^1.2.0",
+    "@types/gl-matrix": "^2.4.5",
+    "debounce": "^1.2.0",
+    "fast-json-patch": "^2.2.1",
+    "gl-matrix": "^3.1.0",
+    "htm": "^3.0.4",
+    "json-formatter-js": "^2.2.1",
+    "preact": "^10.5.12"
+  },
+  "devDependencies": {},
+  "files": [
+    "dist/**/*.{js,js.map,d.ts,json,css}"
+  ],
+  "main": "dist/panel.min.js"
+}
diff --git a/pkgs/development/python-modules/smartypants/default.nix b/pkgs/development/python-modules/smartypants/default.nix
index d1e11e30d61..ec41c8a32aa 100644
--- a/pkgs/development/python-modules/smartypants/default.nix
+++ b/pkgs/development/python-modules/smartypants/default.nix
@@ -1,6 +1,6 @@
 { lib
 , buildPythonPackage
-, fetchhg
+, fetchFromGitHub
 , isPyPy
 }:
 
@@ -9,15 +9,21 @@ buildPythonPackage rec {
   pname = "smartypants";
   disabled = isPyPy;
 
-  src = fetchhg {
-    url = "https://bitbucket.org/livibetter/smartypants.py";
+  src = fetchFromGitHub {
+    owner = "leohemsted";
+    repo = "smartypants.py";
     rev = "v${version}";
     sha256 = "1cmzz44d2hm6y8jj2xcq1wfr26760gi7iq92ha8xbhb1axzd7nq6";
+    # remove this file and the name on the next version update
+    extraPostFetch = ''
+      cp ${./hgtags} "$out"/.hgtags
+    '';
+    name = "hg-archive";
   };
 
   meta = with lib; {
     description = "Python with the SmartyPants";
-    homepage = "https://bitbucket.org/livibetter/smartypants.py";
+    homepage = "https://github.com/leohemsted/smartypants.py";
     license = licenses.bsd3;
     maintainers = with maintainers; [ ];
   };
diff --git a/pkgs/development/python-modules/smartypants/hgtags b/pkgs/development/python-modules/smartypants/hgtags
new file mode 100644
index 00000000000..522ca8d2c01
--- /dev/null
+++ b/pkgs/development/python-modules/smartypants/hgtags
@@ -0,0 +1,17 @@
+47e996532eff9d3bb2c7048aca37d5fd1028e706 v1.5_1.2
+4ff48eba1d3d37d708005e465cf701b63eb68fd3 v1.5_1.1
+6ba7f3a14ff77e4e9bf9918413b1710c33deae4d v1.5_1.3.1
+71006a014216defb21e4db6e03434d289564ea60 v1.5_1.6
+90950ff693122f80710974abc0f2be64d4105e84 v1.5_1.3
+a6ecae6541d64f5b12c7b788c65362b0c012278d v1.5_1.0
+eed4a8a16f116f98e8280dc79128845020bbe766 v1.5_1.5
+f9a62f541f19ead9be4c3be896b64d1caa0b524c v1.5_1.4
+fc0bee49a07daf05f034560cfef81a8a8d034d1f v1.5_1.7
+096ed5f806b6dbc473fae1848643cf45005b9bf1 v1.7.0
+aaeb8099a24ad7db3f36ebe71ef326d6377730aa v1.7.1
+fd8ccc937af7280db4e581b2eb1354245f4672ab v1.8.0
+7839b0eab3e9daf5b346edfa5c54f3cc46fc202a v1.8.1
+6140b78317beabb6e49cd91b35a779ccb0af7327 v1.8.2
+c3b1c83c5ddada685b421b8f82f7e92c794bf2f6 v1.8.3
+460c1add9b9f89831e1ab965f1e1c31325f6e72d v1.8.4
+78165f4976299c37d6e3dd5463adcd61f9cb2b75 v1.8.5
diff --git a/pkgs/development/python-modules/ytmusicapi/default.nix b/pkgs/development/python-modules/ytmusicapi/default.nix
index f84db4ff624..1f211cd2872 100644
--- a/pkgs/development/python-modules/ytmusicapi/default.nix
+++ b/pkgs/development/python-modules/ytmusicapi/default.nix
@@ -7,13 +7,13 @@
 
 buildPythonPackage rec {
   pname = "ytmusicapi";
-  version = "0.15.0";
+  version = "0.15.1";
 
   disabled = isPy27;
 
   src = fetchPypi {
     inherit pname version;
-    sha256 = "sha256-pVQqoMvuuFc/1QNG5z/AspGlgIGPi9aqjZ3/3eVNhis=";
+    sha256 = "sha256-W/eZubJ/SNLBya1S6wLUwTwZCUD+wCQ5FAuNcSpl+9Y=";
   };
 
   propagatedBuildInputs = [
diff --git a/pkgs/development/ruby-modules/bundix/default.nix b/pkgs/development/ruby-modules/bundix/default.nix
index 4eb06f76aba..17f5d6553f6 100644
--- a/pkgs/development/ruby-modules/bundix/default.nix
+++ b/pkgs/development/ruby-modules/bundix/default.nix
@@ -38,7 +38,7 @@ buildRubyGem rec {
     '';
     homepage = "https://github.com/manveru/bundix";
     license = "MIT";
-    maintainers = with lib.maintainers; [ manveru zimbatm ];
+    maintainers = with lib.maintainers; [ manveru marsam zimbatm ];
     platforms = lib.platforms.all;
   };
 }
diff --git a/pkgs/development/tools/analysis/radare2/default.nix b/pkgs/development/tools/analysis/radare2/default.nix
index f5ce1bbde76..1622c616860 100644
--- a/pkgs/development/tools/analysis/radare2/default.nix
+++ b/pkgs/development/tools/analysis/radare2/default.nix
@@ -13,23 +13,18 @@
 , file
 , libzip
 , xxHash
-, gtk2 ? null
-, vte ? null
-, gtkdialog ? null
-, python3 ? null
-, ruby ? null
-, lua ? null
+, gtk2
+, vte
+, gtkdialog
+, python3
+, ruby
+, lua
 , useX11 ? false
 , rubyBindings ? false
 , pythonBindings ? false
 , luaBindings ? false
 }:
 
-assert useX11 -> (gtk2 != null && vte != null && gtkdialog != null);
-assert rubyBindings -> ruby != null;
-assert pythonBindings -> python3 != null;
-
-
 let
   inherit (lib) optional;
 
diff --git a/pkgs/development/tools/analysis/rizin/cutter.nix b/pkgs/development/tools/analysis/rizin/cutter.nix
index 14d815f04b1..55795b9830c 100644
--- a/pkgs/development/tools/analysis/rizin/cutter.nix
+++ b/pkgs/development/tools/analysis/rizin/cutter.nix
@@ -35,8 +35,6 @@ mkDerivation rec {
     qtWrapperArgs+=(--prefix PYTHONPATH : "$PYTHONPATH")
   '';
 
-  enableParallelBuilding = true;
-
   meta = with lib; {
     description = "Free and Open Source Reverse Engineering Platform powered by rizin";
     homepage = src.meta.homepage;
diff --git a/pkgs/development/tools/analysis/rizin/default.nix b/pkgs/development/tools/analysis/rizin/default.nix
index bbcc432ea99..fdc8da7b5f8 100644
--- a/pkgs/development/tools/analysis/rizin/default.nix
+++ b/pkgs/development/tools/analysis/rizin/default.nix
@@ -40,8 +40,6 @@ stdenv.mkDerivation rec {
     "-Duse_sys_tree_sitter=true"
   ];
 
-  enableParallelBuilding = true;
-
   nativeBuildInputs = [ pkg-config meson ninja cmake ];
 
   buildInputs = [
diff --git a/pkgs/development/tools/build-managers/conan/default.nix b/pkgs/development/tools/build-managers/conan/default.nix
index da5e11cce2c..0ec9d3ea93e 100644
--- a/pkgs/development/tools/build-managers/conan/default.nix
+++ b/pkgs/development/tools/build-managers/conan/default.nix
@@ -1,4 +1,4 @@
-{ lib, stdenv, python3, fetchFromGitHub, git, pkg-config, fetchpatch }:
+{ lib, stdenv, python3, fetchFromGitHub, git, pkg-config }:
 
 # Note:
 # Conan has specific dependency demands; check
@@ -14,20 +14,6 @@
 
 let newPython = python3.override {
   packageOverrides = self: super: {
-    distro = super.distro.overridePythonAttrs (oldAttrs: rec {
-      version = "1.1.0";
-      src = oldAttrs.src.override {
-        inherit version;
-        sha256 = "1vn1db2akw98ybnpns92qi11v94hydwp130s8753k6ikby95883j";
-      };
-      patches = oldAttrs.patches or [] ++ [
-        # Don't raise import error on non-linux os. Remove after upgrading to distro≥1.2.0
-        (fetchpatch {
-          url = "https://github.com/nir0s/distro/commit/25aa3f8c5934346dc838387fc081ce81baddeb95.patch";
-          sha256 = "0m09ldf75gacazh2kr04cifgsqfxg670vk4ypl62zv7fp3nyd5dc";
-        })
-      ];
-    });
     node-semver = super.node-semver.overridePythonAttrs (oldAttrs: rec {
       version = "0.6.1";
       src = oldAttrs.src.override {
@@ -35,25 +21,25 @@ let newPython = python3.override {
         sha256 = "1dv6mjsm67l1razcgmq66riqmsb36wns17mnipqr610v0z0zf5j0";
       };
     });
-    pluginbase = super.pluginbase.overridePythonAttrs (oldAttrs: rec {
-      version = "0.7";
+    urllib3 = super.urllib3.overridePythonAttrs (oldAttrs: rec {
+      version = "1.25.11";
       src = oldAttrs.src.override {
         inherit version;
-        sha256 = "c0abe3218b86533cca287e7057a37481883c07acef7814b70583406938214cc8";
+        sha256 = "18hpzh1am1dqx81fypn57r2wk565fi4g14292qrc5jm1h9dalzld";
       };
     });
   };
 };
 
 in newPython.pkgs.buildPythonApplication rec {
-  version = "1.27.0";
+  version = "1.35.0";
   pname = "conan";
 
   src = fetchFromGitHub {
     owner = "conan-io";
     repo = "conan";
     rev = version;
-    sha256 = "0ncqs1p4g23fmzgdmwppgxr8w275h38hgjdzs456cgivz8xs9rjl";
+    sha256 = "19rgylkjxvv47vz5vgh46rw108xskpv7lmax8y2fnm2wd1j3bq9c";
   };
 
   propagatedBuildInputs = with newPython.pkgs; [
@@ -95,12 +81,7 @@ in newPython.pkgs.buildPythonApplication rec {
 
   postPatch = ''
     substituteInPlace conans/requirements.txt \
-      --replace "PyYAML>=3.11, <3.14.0" "PyYAML" \
-      --replace "deprecation>=2.0, <2.1" "deprecation" \
-      --replace "idna==2.6" "idna" \
-      --replace "cryptography>=1.3.4, <2.4.0" "cryptography" \
-      --replace "pyOpenSSL>=16.0.0, <19.0.0" "pyOpenSSL" \
-      --replace "six>=1.10.0,<=1.14.0" "six"
+      --replace "deprecation>=2.0, <2.1" "deprecation"
   '';
 
   meta = with lib; {
diff --git a/pkgs/development/tools/rust/cargo-deny/default.nix b/pkgs/development/tools/rust/cargo-deny/default.nix
index 1225d78d71e..73e3cfd3c4c 100644
--- a/pkgs/development/tools/rust/cargo-deny/default.nix
+++ b/pkgs/development/tools/rust/cargo-deny/default.nix
@@ -7,16 +7,16 @@
 
 rustPlatform.buildRustPackage rec {
   pname = "cargo-deny";
-  version = "0.8.9";
+  version = "0.9.0";
 
   src = fetchFromGitHub {
     owner = "EmbarkStudios";
     repo = pname;
     rev = version;
-    sha256 = "sha256-K8lNo2XmHzgbaVCMNvwDwr86hrXBPws9v3HD8ku+D6w=";
+    sha256 = "sha256-ZjXAZN93ij42WVYSOgvKAzFZ/cZ2RTFKT2sr44j7TVc=";
   };
 
-  cargoSha256 = "sha256-spTy9vzldzqu66904wRVwAeH1rNOQ3WeC6miJkRiAGg=";
+  cargoSha256 = "sha256-eQv9pFegHTjjjFURiD/yN/srtONAwAH3vwfrSY/LM/Q=";
 
   doCheck = false;
 
diff --git a/pkgs/games/devilutionx/default.nix b/pkgs/games/devilutionx/default.nix
index 0f89bdeabb4..5edadbd6a83 100644
--- a/pkgs/games/devilutionx/default.nix
+++ b/pkgs/games/devilutionx/default.nix
@@ -1,4 +1,5 @@
 { lib, stdenv, fetchFromGitHub, cmake, SDL2, SDL2_mixer, SDL2_ttf, libsodium, pkg-config }:
+
 stdenv.mkDerivation rec {
   pname = "devilutionx";
   version = "1.2.0";
@@ -7,9 +8,13 @@ stdenv.mkDerivation rec {
     owner = "diasurgical";
     repo = "devilutionX";
     rev = version;
-    sha256 = "03w3bgmzwsbycx3fzvn47fsmabl069gw77yn2fqg89wlgaw1yrr9";
+    sha256 = "034xkz0a7j2nba17mh44r0kamcblvykdwfsjvjwaz2mrcsmzkr9z";
   };
 
+  postPatch = ''
+    substituteInPlace Source/init.cpp --replace "/usr/share/diasurgical/devilutionx/" "${placeholder "out"}/share/diasurgical/devilutionx/"
+  '';
+
   NIX_CFLAGS_COMPILE = [
     "-I${SDL2_ttf}/include/SDL2"
     ''-DTTF_FONT_PATH="${placeholder "out"}/share/fonts/truetype/CharisSILB.ttf"''
@@ -17,6 +22,7 @@ stdenv.mkDerivation rec {
 
   cmakeFlags = [
     "-DBINARY_RELEASE=ON"
+    "-DVERSION_NUM=${version}"
   ];
 
   nativeBuildInputs = [ pkg-config cmake ];
@@ -31,6 +37,7 @@ stdenv.mkDerivation rec {
   '' else ''
     install -Dm755 -t $out/bin devilutionx
     install -Dt $out/share/fonts/truetype ../Packaging/resources/CharisSILB.ttf
+    install -Dt $out/share/diasurgical/devilutionx ../Packaging/resources/devilutionx.mpq
 
     # TODO: icons and .desktop (see Packages/{debian,fedora}/*)
   '') + ''
diff --git a/pkgs/misc/emulators/dolphin-emu/master.nix b/pkgs/misc/emulators/dolphin-emu/master.nix
index 8a4adfa314b..11627914560 100644
--- a/pkgs/misc/emulators/dolphin-emu/master.nix
+++ b/pkgs/misc/emulators/dolphin-emu/master.nix
@@ -21,13 +21,13 @@ let
   };
 in stdenv.mkDerivation rec {
   pname = "dolphin-emu";
-  version = "5.0-13603";
+  version = "5.0-14002";
 
   src = fetchFromGitHub {
     owner = "dolphin-emu";
     repo = "dolphin";
-    rev = "7250d6e4e091f4b5b4f2289c2c732349b69a2e8a";
-    sha256 = "0l4vvxmc79x0b5p8k4km7p380wv8wsbmxjnif08rj0p3brbavc1i";
+    rev = "53222560650e4a99eceafcd537d4e04d1c50b3a6";
+    sha256 = "1m71gk9hm011fpv5hmpladf7abkylmawgr60d0czkr276pzg04ky";
   };
 
   nativeBuildInputs = [ cmake pkg-config ]
diff --git a/pkgs/misc/vim-plugins/generated.nix b/pkgs/misc/vim-plugins/generated.nix
index caaeb85388a..20b72a0c7ff 100644
--- a/pkgs/misc/vim-plugins/generated.nix
+++ b/pkgs/misc/vim-plugins/generated.nix
@@ -65,12 +65,12 @@ let
 
   ale = buildVimPluginFrom2Nix {
     pname = "ale";
-    version = "2021-03-30";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "dense-analysis";
       repo = "ale";
-      rev = "06f57ca9733aab6e6b67015917fdfd4bf1c70c48";
-      sha256 = "0nsphdv6k5v0qa4p35g4j99pa68fwn7bll4jpvdqs74p82589dhd";
+      rev = "f0887d3e6178482255f11aa378124aef3699245f";
+      sha256 = "0kyfvpwfy4x7mnyb0v8cnjb9byjdj48czd3mzkd1yfpdmz4wgxsg";
     };
     meta.homepage = "https://github.com/dense-analysis/ale/";
   };
@@ -209,12 +209,12 @@ let
 
   auto-session = buildVimPluginFrom2Nix {
     pname = "auto-session";
-    version = "2021-04-06";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "rmagatti";
       repo = "auto-session";
-      rev = "52f7f0c686188ba132dd362fde64f45c30ef431a";
-      sha256 = "1512gd0z8wl8i6pc3gya9qg2pq9k5bfx9b7h2sgp8v356rjx21ks";
+      rev = "f6cfd92e96e9efb7e3e5249a4e45054fb7dc629b";
+      sha256 = "04771631jgm4f76vpmp5mwwf0nidvbw345ajk3nl5xd8lsq9zp3w";
     };
     meta.homepage = "https://github.com/rmagatti/auto-session/";
   };
@@ -257,12 +257,12 @@ let
 
   barbar-nvim = buildVimPluginFrom2Nix {
     pname = "barbar-nvim";
-    version = "2021-04-02";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "romgrk";
       repo = "barbar.nvim";
-      rev = "9c80bfbce9f9b2bdbb42ad9cebfeba6a3dd9a9a8";
-      sha256 = "10dln43kjafj7vaf7s2yvxvc1vaga7rygnl4819275ardjpgddgs";
+      rev = "c5c67f450921dec675b42c7f6f960169411dc7fc";
+      sha256 = "17gpmyqqskzmfvqilgdmcp5rb2ddgb8hvjz7ihfyaawp8sy11lv0";
     };
     meta.homepage = "https://github.com/romgrk/barbar.nvim/";
   };
@@ -389,12 +389,12 @@ let
 
   chadtree = buildVimPluginFrom2Nix {
     pname = "chadtree";
-    version = "2021-04-06";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "ms-jpq";
       repo = "chadtree";
-      rev = "cd20e2323045c7dda2d42af64fa86a7325752a55";
-      sha256 = "1jhxdfvvdvbar9gdzsjvxs8brckww454f2agf2ariwndakcinqqn";
+      rev = "012e3f21bf60858308db77f68ef3ee83a333587c";
+      sha256 = "1q6f0z0mnwg43ri4dzpdzx8n88hr1j32hp3x06zsmfq47rlf4iij";
     };
     meta.homepage = "https://github.com/ms-jpq/chadtree/";
   };
@@ -485,12 +485,12 @@ let
 
   coc-explorer = buildVimPluginFrom2Nix {
     pname = "coc-explorer";
-    version = "2021-04-01";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "weirongxu";
       repo = "coc-explorer";
-      rev = "259d681b368dd0ea11e3b62bbb537c4eece2ef6a";
-      sha256 = "1vzfx5ajjd4fq3n9ixj80l7gwq6wmiib899ww27sc5v4fkm5ykf6";
+      rev = "adb0ef3bbefee3747ce7ac96551789ea882832fb";
+      sha256 = "0kcag0sv94fjcvqfsjx6q1bdq5qvnji5iz2rg3pry49ar1igxmj8";
     };
     meta.homepage = "https://github.com/weirongxu/coc-explorer/";
   };
@@ -654,12 +654,12 @@ let
 
   completion-nvim = buildVimPluginFrom2Nix {
     pname = "completion-nvim";
-    version = "2021-01-15";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "nvim-lua";
       repo = "completion-nvim";
-      rev = "fc9b2fd2d47bea6a8954de1b1b19f2330545b354";
-      sha256 = "0dip8z6cfhjbz5lvf6f75382lg7d819djrpygbc12lf1s4i66i3z";
+      rev = "8bca7aca91c947031a8f14b038459e35e1755d90";
+      sha256 = "02zqc75p9ggrz6fyiwvzpnzipfd1s5xfr7fli2yypb4kp72mrbaf";
     };
     meta.homepage = "https://github.com/nvim-lua/completion-nvim/";
   };
@@ -810,12 +810,12 @@ let
 
   ctrlp-py-matcher = buildVimPluginFrom2Nix {
     pname = "ctrlp-py-matcher";
-    version = "2017-11-01";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "FelikZ";
       repo = "ctrlp-py-matcher";
-      rev = "cf63fd546f1e80dd4db3db96afbeaad301d21f13";
-      sha256 = "0hs829x3vxv12y78hz5g4a5qpw05xf42dk0hxxk3ind77mnl1ir1";
+      rev = "24969b88702bca79a6bfd85256450936968cf55d";
+      sha256 = "0fc2i14gsg6srjvmibz1d5dzzg9bry35pl5xs43l80xnhpkdndm8";
     };
     meta.homepage = "https://github.com/FelikZ/ctrlp-py-matcher/";
   };
@@ -894,12 +894,12 @@ let
 
   defx-nvim = buildVimPluginFrom2Nix {
     pname = "defx-nvim";
-    version = "2021-03-24";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "Shougo";
       repo = "defx.nvim";
-      rev = "e5a757e2dc2f3409f5ccc4e4df384df93b0ef09d";
-      sha256 = "1qfwpwb7r94hnjidggn1fwcshikac8j0ckf1qb0fppfx1akyf78q";
+      rev = "981804894051a6006b9337978a4f939a46b0c254";
+      sha256 = "05a9cv86qazfgpm4nhw6x9pvpj646i7n9jsbk6qn9jmrq7rm0whp";
     };
     meta.homepage = "https://github.com/Shougo/defx.nvim/";
   };
@@ -1136,12 +1136,12 @@ let
 
   deoplete-tabnine = buildVimPluginFrom2Nix {
     pname = "deoplete-tabnine";
-    version = "2021-02-28";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "tbodt";
       repo = "deoplete-tabnine";
-      rev = "6997d621f6bd10351041be8e9dfbc6874009bf1b";
-      sha256 = "17xxxk75w852qj89b1283pff1rsv6qd3siy14sxrz4455x4j1sj5";
+      rev = "181dc9e615e39fa95a722ec21b5604ef3b40c6f3";
+      sha256 = "0xc6kwgfvzfi1apgq6g0zl5wlvwxv51ipnpycrzq93sz618hg78j";
     };
     meta.homepage = "https://github.com/tbodt/deoplete-tabnine/";
   };
@@ -1256,12 +1256,12 @@ let
 
   dracula-vim = buildVimPluginFrom2Nix {
     pname = "dracula-vim";
-    version = "2021-03-18";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "dracula";
       repo = "vim";
-      rev = "ab37ffc5aeb1693002f30254b3b9992965f45d5d";
-      sha256 = "0affiaa2ng43r3rj2yzxs50fiilsk5vqkgjah2zqa159lb2058ra";
+      rev = "d82b9198d4dda1ac4a96756570f56125a1f86cb1";
+      sha256 = "1zj6ifair5gm1nn4nh886y6m8snlhiskiwxlfd1cm7j3xafwqapx";
     };
     meta.homepage = "https://github.com/dracula/vim/";
   };
@@ -1647,8 +1647,8 @@ let
     src = fetchFromGitHub {
       owner = "lewis6991";
       repo = "gitsigns.nvim";
-      rev = "f66a368efa3cf605673492fd7afde80117aa2103";
-      sha256 = "1lyjdnizif33g3bfrrmrxwgvavyvn260h08c49ai4il5vpgs8ap4";
+      rev = "5be4faafe18dc808878e127d69b9cd1883b03bee";
+      sha256 = "0k0z9bgrcidk8m1lckh3kkz0i6w6whrlc22v4vf8yfkqa8g7vai1";
     };
     meta.homepage = "https://github.com/lewis6991/gitsigns.nvim/";
   };
@@ -2028,12 +2028,12 @@ let
 
   jellybeans-nvim = buildVimPluginFrom2Nix {
     pname = "jellybeans-nvim";
-    version = "2021-04-05";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "metalelf0";
       repo = "jellybeans-nvim";
-      rev = "736aa1024741871aa5902ae5a7d5fb21192b4fa1";
-      sha256 = "13k3hf2y979xk3j4q4pwwhrxv0mw320ri4nyg3q39j3fprkryxs7";
+      rev = "cef41133874073b35bf7e8061d97a5214623770d";
+      sha256 = "1hd21h48mwsixbx4iw8r86pmml2z79wpc0p0wb8d50jjxlyphgv4";
     };
     meta.homepage = "https://github.com/metalelf0/jellybeans-nvim/";
   };
@@ -2076,12 +2076,12 @@ let
 
   julia-vim = buildVimPluginFrom2Nix {
     pname = "julia-vim";
-    version = "2021-04-06";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "JuliaEditorSupport";
       repo = "julia-vim";
-      rev = "21ab5e899db6ad963b30102e14fb13be8eeb454c";
-      sha256 = "1m3jgj47pq21ra3znccpgkln42h03799fc845zrrsv186fhqmrjr";
+      rev = "d589986c9dbb95ef08a1f5a01197fd43687e7031";
+      sha256 = "04hrc9wgdk0rjzx23dhnvjyybkpa7m8lf4p7cqmg5sdhlahqicjr";
     };
     meta.homepage = "https://github.com/JuliaEditorSupport/julia-vim/";
   };
@@ -2232,12 +2232,12 @@ let
 
   lh-vim-lib = buildVimPluginFrom2Nix {
     pname = "lh-vim-lib";
-    version = "2021-03-20";
+    version = "2021-04-06";
     src = fetchFromGitHub {
       owner = "LucHermitte";
       repo = "lh-vim-lib";
-      rev = "4b59e0470c4b9b359a4f6229c420686d6d8ea65f";
-      sha256 = "0fbzkmargimal2xyjsyrc6kmw6gdl61hcf17arqp9wv3yn18k637";
+      rev = "6cb8f4cbe54b735dfa6dbb708cc9eaddead251d2";
+      sha256 = "0qggqhj2ikq2ki9g93qgwpl2w5nhssafmwc8a2xkwi4qm4k2shqh";
     };
     meta.homepage = "https://github.com/LucHermitte/lh-vim-lib/";
   };
@@ -2352,12 +2352,12 @@ let
 
   lualine-nvim = buildVimPluginFrom2Nix {
     pname = "lualine-nvim";
-    version = "2021-03-31";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "hoob3rt";
       repo = "lualine.nvim";
-      rev = "7f1d7ba3fbd098d2afd0ee445e5889aca0ffe968";
-      sha256 = "0qbv46byksmbnw068q57v5w4ss3bayxm433kidxdabs80msikhhz";
+      rev = "2b32fb090fa09d68e8e5a222646979fa1d54f899";
+      sha256 = "0vkskwgi8vw06j9nv97ndwli3xrvgd4sl046yk3xf3x3ph890wpj";
     };
     meta.homepage = "https://github.com/hoob3rt/lualine.nvim/";
   };
@@ -2436,12 +2436,12 @@ let
 
   mkdx = buildVimPluginFrom2Nix {
     pname = "mkdx";
-    version = "2021-01-28";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "SidOfc";
       repo = "mkdx";
-      rev = "602a78430aee47881f8c57f73ba96fdded9a3ace";
-      sha256 = "1j4icyp3p20rlb8apyp7ixwxv59q2pdzjg7krh1mc6spr6m779jv";
+      rev = "186cf8cf96777ebdc4976c2de08e7b62a248d2da";
+      sha256 = "01clzfnk86acpm24kfz3xwsy4xcqbx8ar4n0i1i6vvn8hq602mbv";
     };
     meta.homepage = "https://github.com/SidOfc/mkdx/";
   };
@@ -2736,12 +2736,12 @@ let
 
   neogit = buildVimPluginFrom2Nix {
     pname = "neogit";
-    version = "2021-04-06";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "TimUntersberger";
       repo = "neogit";
-      rev = "ac8d7e1942a947eb335d77c3e611a526a4e24d4e";
-      sha256 = "1jnyybcj9g26wrwq6i7yq7bpncywfqm957dy4lq0s531yv6m3yly";
+      rev = "fa941274218fb16464072805a17ba80e7c6f2648";
+      sha256 = "12f4f22wdsaa7ac0yzzqzsrrm2vrh0y7jmfir6ngkc9j3l52mg9d";
     };
     meta.homepage = "https://github.com/TimUntersberger/neogit/";
   };
@@ -2988,12 +2988,12 @@ let
 
   nvcode-color-schemes-vim = buildVimPluginFrom2Nix {
     pname = "nvcode-color-schemes-vim";
-    version = "2021-04-05";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "ChristianChiarulli";
       repo = "nvcode-color-schemes.vim";
-      rev = "29d4a787ad847c267ba836c82e71bfc0a8346c47";
-      sha256 = "0id5abls81yy9n8zvailrqljq5gd70x2wg3vbajrman8phpy7m9z";
+      rev = "383aed3efefb81168a607012006fb4bdcf918956";
+      sha256 = "1mbzcb9iqjia6mwfkznm8bh3c5mvsfnz2ysrvhhr3143nh71m2np";
     };
     meta.homepage = "https://github.com/ChristianChiarulli/nvcode-color-schemes.vim/";
   };
@@ -3012,12 +3012,12 @@ let
 
   nvim-autopairs = buildVimPluginFrom2Nix {
     pname = "nvim-autopairs";
-    version = "2021-03-24";
+    version = "2021-04-06";
     src = fetchFromGitHub {
       owner = "windwp";
       repo = "nvim-autopairs";
-      rev = "b8272f539017ffb6de6a05247e7c333b3721279b";
-      sha256 = "11ng14pb14l0hsv27r24wwkjkw2l77kvd114pij3k5dl8b9zdgv2";
+      rev = "cae76770d1f69b927616313fe1676528adb6d62a";
+      sha256 = "1kh38zfa4x69m0j94f1wzzw4nqxwd89s50inik32zj5948j6licb";
     };
     meta.homepage = "https://github.com/windwp/nvim-autopairs/";
   };
@@ -3036,12 +3036,12 @@ let
 
   nvim-bufferline-lua = buildVimPluginFrom2Nix {
     pname = "nvim-bufferline-lua";
-    version = "2021-04-02";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "akinsho";
       repo = "nvim-bufferline.lua";
-      rev = "2043d254017002c4862afefbacd5d1bd7fe94e55";
-      sha256 = "062kg1vq3b09b009n75kijfs9hlfmlj1yfsnd517imm9n5xhvfmr";
+      rev = "224f2627c471f319626fc7c1ab85f9d7d91bb98a";
+      sha256 = "0yxby3p82pjkz8n0vnavbhw0qlva8mfq3nqff4bf1sg9iw0jpfkm";
     };
     meta.homepage = "https://github.com/akinsho/nvim-bufferline.lua/";
   };
@@ -3072,12 +3072,12 @@ let
 
   nvim-compe = buildVimPluginFrom2Nix {
     pname = "nvim-compe";
-    version = "2021-04-05";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "hrsh7th";
       repo = "nvim-compe";
-      rev = "9fc416854685a8e05836b70d477d9bbbddefcd3b";
-      sha256 = "1irasadwqdijqixbbbysd50qh1rfhfkhfljz2438hiv3ayvj4aad";
+      rev = "e2f1caba42f5b1af07ef9d729ae75d74855ac5d4";
+      sha256 = "0xk8hm3m8aywky7p2jm36a9sf495pa52lixmp14c7qj2s0wrki1c";
     };
     meta.homepage = "https://github.com/hrsh7th/nvim-compe/";
   };
@@ -3096,12 +3096,12 @@ let
 
   nvim-dap = buildVimPluginFrom2Nix {
     pname = "nvim-dap";
-    version = "2021-03-24";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "mfussenegger";
       repo = "nvim-dap";
-      rev = "cd0afafc788f9d4d9df5fef5d348841906b295d6";
-      sha256 = "1zh35qjxmkf37khagn8722byzjq2pns20cbmc821hfqdkj6q3pc8";
+      rev = "06e201849605dabf5dd28f972d2b7c507a8aff1f";
+      sha256 = "19mk9r2h491gqf0q9jv3yrlznfxwfz2q4h7jqq6yai740nx5yhzj";
     };
     meta.homepage = "https://github.com/mfussenegger/nvim-dap/";
   };
@@ -3276,24 +3276,24 @@ let
 
   nvim-tree-lua = buildVimPluginFrom2Nix {
     pname = "nvim-tree-lua";
-    version = "2021-04-05";
+    version = "2021-04-06";
     src = fetchFromGitHub {
       owner = "kyazdani42";
       repo = "nvim-tree.lua";
-      rev = "3350e4e97e51be10de9aca0617b665c9259d3089";
-      sha256 = "1vp6nsyhnwhnqkpgqll4b2x4pcxc8wsc7xy0nq2i1a5qjrpbb4ss";
+      rev = "bbb8d6070f2a35ae85d1790fa3f8fff56c06d4ec";
+      sha256 = "0xsvbpq8sygl6d8nkw4vaj20bdnrx1x97sjr8y4p76kmqqrch09s";
     };
     meta.homepage = "https://github.com/kyazdani42/nvim-tree.lua/";
   };
 
   nvim-treesitter = buildVimPluginFrom2Nix {
     pname = "nvim-treesitter";
-    version = "2021-04-06";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "nvim-treesitter";
       repo = "nvim-treesitter";
-      rev = "11e1db3ec29abb5711556085766cb6912814c6dc";
-      sha256 = "0fsmbf8hnhcxxp8m738lmm75wg2ijxj8z0755aj0mcs8s735pjxz";
+      rev = "1f00ecdfa36ef5e43a4feaf189e8c2c003118c00";
+      sha256 = "1fidjwl7w1msg38b470cahjblcy7lgg885wbmswl380kf9c8118l";
     };
     meta.homepage = "https://github.com/nvim-treesitter/nvim-treesitter/";
   };
@@ -3336,36 +3336,36 @@ let
 
   nvim-ts-rainbow = buildVimPluginFrom2Nix {
     pname = "nvim-ts-rainbow";
-    version = "2021-04-05";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "p00f";
       repo = "nvim-ts-rainbow";
-      rev = "d463320156e7e3d85a98aca1f5292422fd3b5b12";
-      sha256 = "08sc8vd0arwyw3zpbnkmdp884fksw73yqzbw5fwddr3wn47sdckc";
+      rev = "97798465743459cb5f7d82e54c693bebc84e73f8";
+      sha256 = "0wibgcrpxb5hqbjig1sgisnxik0f8wv7ap4l2xv5mhwm8yz6x4gn";
     };
     meta.homepage = "https://github.com/p00f/nvim-ts-rainbow/";
   };
 
   nvim-web-devicons = buildVimPluginFrom2Nix {
     pname = "nvim-web-devicons";
-    version = "2021-04-05";
+    version = "2021-04-06";
     src = fetchFromGitHub {
       owner = "kyazdani42";
       repo = "nvim-web-devicons";
-      rev = "95c6d6bc3a9b969578d555b98a7be8619c65908e";
-      sha256 = "15rw8qr52gi169x9cgs68dkm1f4blgqdrdmcqb7frqn8qjzaib9s";
+      rev = "ecc0ec031ec4330c7c4eaf3ed2efdf1abbaff834";
+      sha256 = "1m4bhwb1vg75lizdj8dkai9zcrxgky2g1gm6ivzj7i1y7p1k1ccv";
     };
     meta.homepage = "https://github.com/kyazdani42/nvim-web-devicons/";
   };
 
   nvim-whichkey-setup-lua = buildVimPluginFrom2Nix {
     pname = "nvim-whichkey-setup-lua";
-    version = "2021-03-26";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "AckslD";
       repo = "nvim-whichkey-setup.lua";
-      rev = "59aa0a4287adf6c2c9faabf912cdc005230e7c98";
-      sha256 = "093yjj28ak1ifbkn1s69wx8ldinj4v2bpf82fhqziw6d58ghwang";
+      rev = "7299ebd2bcfb412630a18356a653def7e72f162d";
+      sha256 = "1kxg7ss95cijf9i8nbsp3jkpmx9x3c4qp52d0ckwcdbyvskkal9y";
     };
     meta.homepage = "https://github.com/AckslD/nvim-whichkey-setup.lua/";
   };
@@ -3484,8 +3484,8 @@ let
     src = fetchFromGitHub {
       owner = "wbthomason";
       repo = "packer.nvim";
-      rev = "b495895dffca9aabfead066a860b87ab3a67cf7e";
-      sha256 = "08anlafdhmxc66yi4h13fkvqpkq1chazmyy8c18nx41af4b0p9bn";
+      rev = "fdf1851c6121dee98294791c72aebff92b99b733";
+      sha256 = "1ylwr70z7jlga260ydah03ngh47kf8jh7zgpl9iclih01nz6xwci";
     };
     meta.homepage = "https://github.com/wbthomason/packer.nvim/";
   };
@@ -3576,12 +3576,12 @@ let
 
   plenary-nvim = buildVimPluginFrom2Nix {
     pname = "plenary-nvim";
-    version = "2021-04-06";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "nvim-lua";
       repo = "plenary.nvim";
-      rev = "720c304dc41da563857610e737ff281c250681ac";
-      sha256 = "0gcd88v2jykdgp7mqf10n9ydpg8gfb7258mxysjaf67313idh626";
+      rev = "d0d291f87bed757f6be05c8bf753cb0e9602a478";
+      sha256 = "0xjz85yzcvxd0dynygxdb1b9jkzmy1m52s4rc5w67jidqc7hs8ii";
     };
     meta.homepage = "https://github.com/nvim-lua/plenary.nvim/";
   };
@@ -3793,12 +3793,12 @@ let
 
   registers-nvim = buildVimPluginFrom2Nix {
     pname = "registers-nvim";
-    version = "2021-03-31";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "tversteeg";
       repo = "registers.nvim";
-      rev = "b8f6283724d3ccacf2c7add61f3fcb9c02e7d61d";
-      sha256 = "1b1amy9k6j2ilcm79pp30gcqqjhbd2zfwxm5vbcra29p9s4f14y2";
+      rev = "105200aea2edd8c7ba995a76789a03e7dab83a85";
+      sha256 = "0vvr1mdrnybgrbvs7r5yrzwab35viz488gyibzdjl3b5wisxqwxh";
     };
     meta.homepage = "https://github.com/tversteeg/registers.nvim/";
   };
@@ -3877,12 +3877,12 @@ let
 
   rust-tools-nvim = buildVimPluginFrom2Nix {
     pname = "rust-tools-nvim";
-    version = "2021-04-06";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "simrat39";
       repo = "rust-tools.nvim";
-      rev = "42a9fb0441630ea640b7d3e967d6ad5c7f41b520";
-      sha256 = "0mcjcxhq2ri1galva5xjx4f0z98jyskmwypxc77gizisl2fjplnz";
+      rev = "ea210456f8eac176822c8777619d2f05797dc708";
+      sha256 = "14ygid112wwpgf429j1i65k72a1bn3pd6b7c1vpvyvvzdyfwnhiw";
     };
     meta.homepage = "https://github.com/simrat39/rust-tools.nvim/";
   };
@@ -4081,12 +4081,12 @@ let
 
   SpaceCamp = buildVimPluginFrom2Nix {
     pname = "SpaceCamp";
-    version = "2021-03-16";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "jaredgorski";
       repo = "SpaceCamp";
-      rev = "ce034929763903937396cf6b2c9912eb209e6b39";
-      sha256 = "07a1441gccilbhnk99lz66nvaiv14vdn34ink3jjd27d2mkf3skb";
+      rev = "376af5c2204de61726ea86b596acb2dab9795e1f";
+      sha256 = "0h3wxkswd5z9y46d6272sr210i73j5pwf5faw7qhr1plilfgx4gb";
     };
     meta.homepage = "https://github.com/jaredgorski/SpaceCamp/";
   };
@@ -4394,12 +4394,12 @@ let
 
   telescope-fzy-native-nvim = buildVimPluginFrom2Nix {
     pname = "telescope-fzy-native-nvim";
-    version = "2020-12-31";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "nvim-telescope";
       repo = "telescope-fzy-native.nvim";
-      rev = "654dffd924b29fb9a9252dcbd63528b1498ac9fb";
-      sha256 = "01x9z3n03qharjw778cxb16gw1dsxzmsxph4xsbfy1avf21c6x9g";
+      rev = "7b3d2528102f858036627a68821ccf5fc1d78ce4";
+      sha256 = "1mb47ixnpgd7ygrq1cldp9anc6gxqly4amj0l1pgh8cllj63393v";
       fetchSubmodules = true;
     };
     meta.homepage = "https://github.com/nvim-telescope/telescope-fzy-native.nvim/";
@@ -4407,12 +4407,12 @@ let
 
   telescope-nvim = buildVimPluginFrom2Nix {
     pname = "telescope-nvim";
-    version = "2021-04-04";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "nvim-telescope";
       repo = "telescope.nvim";
-      rev = "d0cf646f65746415294f570ec643ffd0101ca3ab";
-      sha256 = "02l65jxd50x4jc7mv1d9bsqasa7m0vkil0b36jamhvp1syzkwhkj";
+      rev = "64e59060b1750d0c86761693b6847c3db07afcd2";
+      sha256 = "0racv0zqklfn3dh7jvkw8hx9rh85mkrljixjh528h12qfv53arw7";
     };
     meta.homepage = "https://github.com/nvim-telescope/telescope.nvim/";
   };
@@ -5212,12 +5212,12 @@ let
 
   vim-clap = buildVimPluginFrom2Nix {
     pname = "vim-clap";
-    version = "2021-04-03";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "liuchengxu";
       repo = "vim-clap";
-      rev = "97a2649ecb75cbad4081a9f575b2bb7f17582a3c";
-      sha256 = "0jn8iyhw80xasnp7b09yqjxa46jkcrfmy2r8b7ynxan9a37b206i";
+      rev = "ee7e6a5782ec7033f361311f8f61f23146822e62";
+      sha256 = "0gr2sh6fbc8qfz0xlv5rhkg8jxh81wb2lb141m0hyc0fk1n2pya7";
     };
     meta.homepage = "https://github.com/liuchengxu/vim-clap/";
   };
@@ -5920,12 +5920,12 @@ let
 
   vim-fugitive = buildVimPluginFrom2Nix {
     pname = "vim-fugitive";
-    version = "2021-04-04";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "tpope";
       repo = "vim-fugitive";
-      rev = "f29c9e50795cdfcc2b31b1e76ab6bd202e476298";
-      sha256 = "0wn3c4jads0201433kc8f9mnlg1phhgamr218yz1q70waj60ns2n";
+      rev = "8ede0aaf57e1dbb5416ddbe30d0bfdde762e90bf";
+      sha256 = "1aa7cqkp2pkpn175y67gfjbd0p3jxca42n7iysykzi9hcgkshqm2";
     };
     meta.homepage = "https://github.com/tpope/vim-fugitive/";
   };
@@ -6714,12 +6714,12 @@ let
 
   vim-lsp-cxx-highlight = buildVimPluginFrom2Nix {
     pname = "vim-lsp-cxx-highlight";
-    version = "2021-03-14";
+    version = "2021-04-06";
     src = fetchFromGitHub {
       owner = "jackguo380";
       repo = "vim-lsp-cxx-highlight";
-      rev = "00818f0d8b7c87d3a1ecd81cc4ff1ab782355c2b";
-      sha256 = "1pjricwcqsbw466anwcndhj97g6qbblk95jaa8yg3a2fs8gdz8iz";
+      rev = "130fd4189e0328630be7ad4aa7e1d98a0a503170";
+      sha256 = "1nsac8f2c0lj42a77wxcv3k6i8sbpm5ghip6nx7yz0dj7zd4xm10";
     };
     meta.homepage = "https://github.com/jackguo380/vim-lsp-cxx-highlight/";
   };
@@ -7049,6 +7049,18 @@ let
     meta.homepage = "https://github.com/rakr/vim-one/";
   };
 
+  vim-opencl = buildVimPluginFrom2Nix {
+    pname = "vim-opencl";
+    version = "2018-06-13";
+    src = fetchFromGitHub {
+      owner = "petRUShka";
+      repo = "vim-opencl";
+      rev = "7668b018fe9461c6b51e0b736ed84aa84d6bafce";
+      sha256 = "0z8qasymkkaa272bjxmkp4sgd8qr4ypcqxlyzxgh5imp3gmrc6n1";
+    };
+    meta.homepage = "https://github.com/petRUShka/vim-opencl/";
+  };
+
   vim-operator-replace = buildVimPluginFrom2Nix {
     pname = "vim-operator-replace";
     version = "2015-02-24";
@@ -7531,24 +7543,24 @@ let
 
   vim-rhubarb = buildVimPluginFrom2Nix {
     pname = "vim-rhubarb";
-    version = "2021-04-03";
+    version = "2021-04-05";
     src = fetchFromGitHub {
       owner = "tpope";
       repo = "vim-rhubarb";
-      rev = "71d5c3598e0d14af3fbaf2530c061c306db5a962";
-      sha256 = "03izgmaa150159lp43hsn17yqx0w8r8wa04cf1rnk1zw00zr2073";
+      rev = "1c36bf8668e329b51f8baf752c4ffe42f8d524ab";
+      sha256 = "1ad0ypfv7bsla964q8jd1mds62vr2rfd5309bq7dybbi8z3bz6fp";
     };
     meta.homepage = "https://github.com/tpope/vim-rhubarb/";
   };
 
   vim-rooter = buildVimPluginFrom2Nix {
     pname = "vim-rooter";
-    version = "2021-03-11";
+    version = "2021-04-08";
     src = fetchFromGitHub {
       owner = "airblade";
       repo = "vim-rooter";
-      rev = "544e701066c69bbeb45297d0285c2719e125440b";
-      sha256 = "0mj5zvfsi4n8qi8cq0h99j1zb11xmrpkm31ll4q1bm5mf57kbmxa";
+      rev = "e122cb925b2d0e4f44f289fbdffd6a6ebb837a11";
+      sha256 = "0hc3k5338az962b2slia6lc5dkby79iqf1mvpxh57j9jp3gn9b3s";
     };
     meta.homepage = "https://github.com/airblade/vim-rooter/";
   };
@@ -7963,12 +7975,12 @@ let
 
   vim-swap = buildVimPluginFrom2Nix {
     pname = "vim-swap";
-    version = "2021-03-18";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "machakann";
       repo = "vim-swap";
-      rev = "f363ea636f4e18b4a3382ff352d3cf2e2ac5840e";
-      sha256 = "1pa5crmamama4v3yzcjfbizvpx03wb67zbjx1mn5rz6dcar903f6";
+      rev = "e75fb91c4940447758902f8cab95d13f8be84d0e";
+      sha256 = "0z8mlcjhp1r2v9hs69h6kpk7yfyi7c2y7ck096y5y0hbcwrarn6n";
     };
     meta.homepage = "https://github.com/machakann/vim-swap/";
   };
@@ -8624,12 +8636,12 @@ let
 
   vimspector = buildVimPluginFrom2Nix {
     pname = "vimspector";
-    version = "2021-03-30";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "puremourning";
       repo = "vimspector";
-      rev = "caeb6610ed9f209490fbfacacc99e720847e6130";
-      sha256 = "014xvr14kxk0js4qwdzv0ljzrz6dji9qrkjyjpr1qfx6r8kz2j1z";
+      rev = "7d83419a4f813aee826eee994b8e419b6ff102b0";
+      sha256 = "05xlpf3rm54kb6vxkm4gngbxabd58736najdawjxf8y7b6ajv39z";
       fetchSubmodules = true;
     };
     meta.homepage = "https://github.com/puremourning/vimspector/";
@@ -8637,12 +8649,12 @@ let
 
   vimtex = buildVimPluginFrom2Nix {
     pname = "vimtex";
-    version = "2021-04-06";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "lervag";
       repo = "vimtex";
-      rev = "b31d4e3ed3942c98fcb928ca65bf9e9427608439";
-      sha256 = "0vl0a71in04pi3v9h61piny6qrd91z8anmzv724dznqkc4ydp9hx";
+      rev = "83b8e2998c6f0554b7eb4a04cfe783b8eab86c88";
+      sha256 = "08k9in6xg0vbihwgcyy2c3gfsc91iz3lw2r3awg0zwgd41699qby";
     };
     meta.homepage = "https://github.com/lervag/vimtex/";
   };
@@ -8879,12 +8891,12 @@ let
 
   zig-vim = buildVimPluginFrom2Nix {
     pname = "zig-vim";
-    version = "2021-03-16";
+    version = "2021-04-07";
     src = fetchFromGitHub {
       owner = "ziglang";
       repo = "zig.vim";
-      rev = "33b62b688ef4f0b3810c4d3d1b3901f572488691";
-      sha256 = "0dsc1h8ih5jgfni5szm8dby368naxh3igndm80yrciy2glcj1ayn";
+      rev = "fc32adfada0fac7a2f6088672e177d410c9e3ae1";
+      sha256 = "051l2dig6861xzl6zg41d6a776jhms7v6a86cap1ipd2rxkqh5yh";
     };
     meta.homepage = "https://github.com/ziglang/zig.vim/";
   };
diff --git a/pkgs/misc/vim-plugins/vim-plugin-names b/pkgs/misc/vim-plugins/vim-plugin-names
index 0eb035485d3..82b6543b418 100644
--- a/pkgs/misc/vim-plugins/vim-plugin-names
+++ b/pkgs/misc/vim-plugins/vim-plugin-names
@@ -465,6 +465,7 @@ pearofducks/ansible-vim
 peitalin/vim-jsx-typescript
 peterbjorgensen/sved
 peterhoeg/vim-qml
+petRUShka/vim-opencl
 phaazon/hop.nvim
 phanviet/vim-monokai-pro
 plasticboy/vim-markdown
diff --git a/pkgs/os-specific/darwin/macfuse/default.nix b/pkgs/os-specific/darwin/macfuse/default.nix
index 7e1b4ed7763..4fd92a15562 100644
--- a/pkgs/os-specific/darwin/macfuse/default.nix
+++ b/pkgs/os-specific/darwin/macfuse/default.nix
@@ -56,4 +56,10 @@ stdenv.mkDerivation rec {
       lgpl2Plus # libfuse
     ];
   };
+
+  passthru.warning = ''
+    macFUSE is required for this package to work on macOS. To install macFUSE,
+    use the installer from the <link xlink:href="https://osxfuse.github.io/">
+    project website</link>.
+  '';
 }
diff --git a/pkgs/os-specific/linux/kernel/generic.nix b/pkgs/os-specific/linux/kernel/generic.nix
index 1c289d86002..68a1fcdb0e6 100644
--- a/pkgs/os-specific/linux/kernel/generic.nix
+++ b/pkgs/os-specific/linux/kernel/generic.nix
@@ -54,7 +54,7 @@
 , autoModules ? stdenv.hostPlatform.linux-kernel.autoModules
 , preferBuiltin ? stdenv.hostPlatform.linux-kernel.preferBuiltin or false
 , kernelArch ? stdenv.hostPlatform.linuxArch
-
+, kernelTests ? []
 , ...
 }:
 
@@ -175,11 +175,12 @@ let
 
   passthru = {
     features = kernelFeatures;
-    inherit commonStructuredConfig isZen isHardened isLibre;
+    inherit commonStructuredConfig isZen isHardened isLibre modDirVersion;
     isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true;
     kernelOlder = lib.versionOlder version;
     kernelAtLeast = lib.versionAtLeast version;
     passthru = kernel.passthru // (removeAttrs passthru [ "passthru" ]);
+    tests = kernelTests;
   };
 
 in lib.extendDerivation true passthru kernel
diff --git a/pkgs/os-specific/linux/kernel/linux-4.14.nix b/pkgs/os-specific/linux/kernel/linux-4.14.nix
index 729cf3a6019..fc647d10959 100644
--- a/pkgs/os-specific/linux/kernel/linux-4.14.nix
+++ b/pkgs/os-specific/linux/kernel/linux-4.14.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
 with lib;
 
@@ -15,4 +15,6 @@ buildLinux (args // rec {
     url = "mirror://kernel/linux/kernel/v4.x/linux-${version}.tar.xz";
     sha256 = "0nw1jf6x5a990n69aw2da4s4lc1c7mnwiwcda40bl2rkmd24s1qm";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_4_14 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-4.19.nix b/pkgs/os-specific/linux/kernel/linux-4.19.nix
index dbd0f9e7f58..b0e5a865724 100644
--- a/pkgs/os-specific/linux/kernel/linux-4.19.nix
+++ b/pkgs/os-specific/linux/kernel/linux-4.19.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
 with lib;
 
@@ -15,4 +15,6 @@ buildLinux (args // rec {
     url = "mirror://kernel/linux/kernel/v4.x/linux-${version}.tar.xz";
     sha256 = "0z5pgal8775rf7pvpxq47dnghr42al2k9py0s9jl3js2wamgdyix";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_4_19 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-4.4.nix b/pkgs/os-specific/linux/kernel/linux-4.4.nix
index d90489922a4..3a5f86db3a1 100644
--- a/pkgs/os-specific/linux/kernel/linux-4.4.nix
+++ b/pkgs/os-specific/linux/kernel/linux-4.4.nix
@@ -1,4 +1,4 @@
-{ buildPackages, fetchurl, perl, buildLinux, ... } @ args:
+{ buildPackages, fetchurl, perl, buildLinux, nixosTests, ... } @ args:
 
 buildLinux (args // rec {
   version = "4.4.264";
@@ -8,4 +8,6 @@ buildLinux (args // rec {
     url = "mirror://kernel/linux/kernel/v4.x/linux-${version}.tar.xz";
     sha256 = "1b0d735qnk0bcqn9gdsjqxhk8pkb3597ya9f34lv1vjfaqkkxk7l";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_4_4 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-4.9.nix b/pkgs/os-specific/linux/kernel/linux-4.9.nix
index e0caeb138da..798a16d7a30 100644
--- a/pkgs/os-specific/linux/kernel/linux-4.9.nix
+++ b/pkgs/os-specific/linux/kernel/linux-4.9.nix
@@ -1,4 +1,4 @@
-{ buildPackages, fetchurl, perl, buildLinux, ... } @ args:
+{ buildPackages, fetchurl, perl, buildLinux, nixosTests, ... } @ args:
 
 buildLinux (args // rec {
   version = "4.9.264";
@@ -8,4 +8,6 @@ buildLinux (args // rec {
     url = "mirror://kernel/linux/kernel/v4.x/linux-${version}.tar.xz";
     sha256 = "1df2dv26c9z6zsdlqzbcc60f2pszh0hx1n94v65jswlb72a2mipc";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_4_9 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-5.10.nix b/pkgs/os-specific/linux/kernel/linux-5.10.nix
index 911cb326dd7..f35b0e432be 100644
--- a/pkgs/os-specific/linux/kernel/linux-5.10.nix
+++ b/pkgs/os-specific/linux/kernel/linux-5.10.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
 with lib;
 
@@ -15,4 +15,6 @@ buildLinux (args // rec {
     url = "mirror://kernel/linux/kernel/v5.x/linux-${version}.tar.xz";
     sha256 = "1nb95ll66kxiz702gs903n3gy5ialz8cin58l19rqaai55kck7fr";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_5_10 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-5.11.nix b/pkgs/os-specific/linux/kernel/linux-5.11.nix
index 16d0e5c1d4c..1c8540d8934 100644
--- a/pkgs/os-specific/linux/kernel/linux-5.11.nix
+++ b/pkgs/os-specific/linux/kernel/linux-5.11.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
 with lib;
 
@@ -15,4 +15,6 @@ buildLinux (args // rec {
     url = "mirror://kernel/linux/kernel/v5.x/linux-${version}.tar.xz";
     sha256 = "1fc3yl4srzla3cbihgnry0pqmgcc17zv0zlkk9zpx99371hpay0a";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_5_11 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-5.4.nix b/pkgs/os-specific/linux/kernel/linux-5.4.nix
index ac867e78768..e9d72200eda 100644
--- a/pkgs/os-specific/linux/kernel/linux-5.4.nix
+++ b/pkgs/os-specific/linux/kernel/linux-5.4.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
 with lib;
 
@@ -15,4 +15,6 @@ buildLinux (args // rec {
     url = "mirror://kernel/linux/kernel/v5.x/linux-${version}.tar.xz";
     sha256 = "1vmpc6yrr2zm4m3naflwik5111jr8hy0mnyddwk31l0p4xbg8smc";
   };
+
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_5_4 ];
 } // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/linux-testing.nix b/pkgs/os-specific/linux/kernel/linux-testing.nix
index eec306f2892..f0d41869346 100644
--- a/pkgs/os-specific/linux/kernel/linux-testing.nix
+++ b/pkgs/os-specific/linux/kernel/linux-testing.nix
@@ -1,4 +1,4 @@
-{ lib, buildPackages, fetchurl, perl, buildLinux, modDirVersionArg ? null, ... } @ args:
+{ lib, buildPackages, fetchurl, perl, buildLinux, nixosTests, modDirVersionArg ? null, ... } @ args:
 
 with lib;
 
@@ -14,6 +14,8 @@ buildLinux (args // rec {
     sha256 = "0w0zk2byimdbcvn8myqaq0ab6lyd43493fnkv9a1407dimpxb03d";
   };
 
+  kernelTests = args.kernelTests or [ nixosTests.kernel-generic.linux_testing ];
+
   # Should the testing kernels ever be built on Hydra?
   extraMeta.hydraPlatforms = [];
 
diff --git a/pkgs/servers/dns/doh-proxy-rust/cargo-lock.patch b/pkgs/servers/dns/doh-proxy-rust/cargo-lock.patch
new file mode 100644
index 00000000000..8eeb0702bf7
--- /dev/null
+++ b/pkgs/servers/dns/doh-proxy-rust/cargo-lock.patch
@@ -0,0 +1,838 @@
+diff --git a/Cargo.lock b/Cargo.lock
+new file mode 100644
+index 0000000..0dd9527
+--- /dev/null
++++ b/Cargo.lock
+@@ -0,0 +1,832 @@
++# This file is automatically @generated by Cargo.
++# It is not intended for manual editing.
++[[package]]
++name = "ansi_term"
++version = "0.11.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
++dependencies = [
++ "winapi",
++]
++
++[[package]]
++name = "anyhow"
++version = "1.0.40"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
++
++[[package]]
++name = "atty"
++version = "0.2.14"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
++dependencies = [
++ "hermit-abi",
++ "libc",
++ "winapi",
++]
++
++[[package]]
++name = "autocfg"
++version = "1.0.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
++
++[[package]]
++name = "base64"
++version = "0.13.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
++
++[[package]]
++name = "bitflags"
++version = "1.2.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
++
++[[package]]
++name = "bumpalo"
++version = "3.6.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
++
++[[package]]
++name = "byteorder"
++version = "1.4.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
++
++[[package]]
++name = "bytes"
++version = "1.0.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
++
++[[package]]
++name = "cc"
++version = "1.0.67"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
++
++[[package]]
++name = "cfg-if"
++version = "1.0.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
++
++[[package]]
++name = "clap"
++version = "2.33.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
++dependencies = [
++ "ansi_term",
++ "atty",
++ "bitflags",
++ "strsim",
++ "textwrap",
++ "unicode-width",
++ "vec_map",
++]
++
++[[package]]
++name = "doh-proxy"
++version = "0.3.8"
++dependencies = [
++ "clap",
++ "jemallocator",
++ "libdoh",
++]
++
++[[package]]
++name = "fnv"
++version = "1.0.7"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
++
++[[package]]
++name = "fs_extra"
++version = "1.2.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
++
++[[package]]
++name = "futures"
++version = "0.3.13"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1"
++dependencies = [
++ "futures-channel",
++ "futures-core",
++ "futures-executor",
++ "futures-io",
++ "futures-sink",
++ "futures-task",
++ "futures-util",
++]
++
++[[package]]
++name = "futures-channel"
++version = "0.3.13"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939"
++dependencies = [
++ "futures-core",
++ "futures-sink",
++]
++
++[[package]]
++name = "futures-core"
++version = "0.3.13"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94"
++
++[[package]]
++name = "futures-executor"
++version = "0.3.13"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1"
++dependencies = [
++ "futures-core",
++ "futures-task",
++ "futures-util",
++]
++
++[[package]]
++name = "futures-io"
++version = "0.3.13"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59"
++
++[[package]]
++name = "futures-macro"
++version = "0.3.13"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7"
++dependencies = [
++ "proc-macro-hack",
++ "proc-macro2",
++ "quote",
++ "syn",
++]
++
++[[package]]
++name = "futures-sink"
++version = "0.3.13"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3"
++
++[[package]]
++name = "futures-task"
++version = "0.3.13"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80"
++
++[[package]]
++name = "futures-util"
++version = "0.3.13"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1"
++dependencies = [
++ "futures-channel",
++ "futures-core",
++ "futures-io",
++ "futures-macro",
++ "futures-sink",
++ "futures-task",
++ "memchr",
++ "pin-project-lite",
++ "pin-utils",
++ "proc-macro-hack",
++ "proc-macro-nested",
++ "slab",
++]
++
++[[package]]
++name = "h2"
++version = "0.3.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "fc018e188373e2777d0ef2467ebff62a08e66c3f5857b23c8fbec3018210dc00"
++dependencies = [
++ "bytes",
++ "fnv",
++ "futures-core",
++ "futures-sink",
++ "futures-util",
++ "http",
++ "indexmap",
++ "slab",
++ "tokio",
++ "tokio-util",
++ "tracing",
++]
++
++[[package]]
++name = "hashbrown"
++version = "0.9.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
++
++[[package]]
++name = "hermit-abi"
++version = "0.1.18"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
++dependencies = [
++ "libc",
++]
++
++[[package]]
++name = "http"
++version = "0.2.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747"
++dependencies = [
++ "bytes",
++ "fnv",
++ "itoa",
++]
++
++[[package]]
++name = "http-body"
++version = "0.4.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "5dfb77c123b4e2f72a2069aeae0b4b4949cc7e966df277813fc16347e7549737"
++dependencies = [
++ "bytes",
++ "http",
++ "pin-project-lite",
++]
++
++[[package]]
++name = "httparse"
++version = "1.3.5"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691"
++
++[[package]]
++name = "httpdate"
++version = "0.3.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
++
++[[package]]
++name = "hyper"
++version = "0.14.5"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "8bf09f61b52cfcf4c00de50df88ae423d6c02354e385a86341133b5338630ad1"
++dependencies = [
++ "bytes",
++ "futures-channel",
++ "futures-core",
++ "futures-util",
++ "h2",
++ "http",
++ "http-body",
++ "httparse",
++ "httpdate",
++ "itoa",
++ "pin-project",
++ "tokio",
++ "tower-service",
++ "tracing",
++ "want",
++]
++
++[[package]]
++name = "indexmap"
++version = "1.6.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
++dependencies = [
++ "autocfg",
++ "hashbrown",
++]
++
++[[package]]
++name = "instant"
++version = "0.1.9"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
++dependencies = [
++ "cfg-if",
++]
++
++[[package]]
++name = "itoa"
++version = "0.4.7"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
++
++[[package]]
++name = "jemalloc-sys"
++version = "0.3.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "0d3b9f3f5c9b31aa0f5ed3260385ac205db665baa41d49bb8338008ae94ede45"
++dependencies = [
++ "cc",
++ "fs_extra",
++ "libc",
++]
++
++[[package]]
++name = "jemallocator"
++version = "0.3.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "43ae63fcfc45e99ab3d1b29a46782ad679e98436c3169d15a167a1108a724b69"
++dependencies = [
++ "jemalloc-sys",
++ "libc",
++]
++
++[[package]]
++name = "js-sys"
++version = "0.3.50"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c"
++dependencies = [
++ "wasm-bindgen",
++]
++
++[[package]]
++name = "lazy_static"
++version = "1.4.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
++
++[[package]]
++name = "libc"
++version = "0.2.92"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "56d855069fafbb9b344c0f962150cd2c1187975cb1c22c1522c240d8c4986714"
++
++[[package]]
++name = "libdoh"
++version = "0.3.8"
++dependencies = [
++ "anyhow",
++ "base64",
++ "byteorder",
++ "futures",
++ "hyper",
++ "tokio",
++ "tokio-rustls",
++]
++
++[[package]]
++name = "lock_api"
++version = "0.4.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
++dependencies = [
++ "scopeguard",
++]
++
++[[package]]
++name = "log"
++version = "0.4.14"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
++dependencies = [
++ "cfg-if",
++]
++
++[[package]]
++name = "memchr"
++version = "2.3.4"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
++
++[[package]]
++name = "mio"
++version = "0.7.11"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956"
++dependencies = [
++ "libc",
++ "log",
++ "miow",
++ "ntapi",
++ "winapi",
++]
++
++[[package]]
++name = "miow"
++version = "0.3.7"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
++dependencies = [
++ "winapi",
++]
++
++[[package]]
++name = "ntapi"
++version = "0.3.6"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
++dependencies = [
++ "winapi",
++]
++
++[[package]]
++name = "num_cpus"
++version = "1.13.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
++dependencies = [
++ "hermit-abi",
++ "libc",
++]
++
++[[package]]
++name = "once_cell"
++version = "1.7.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
++
++[[package]]
++name = "parking_lot"
++version = "0.11.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
++dependencies = [
++ "instant",
++ "lock_api",
++ "parking_lot_core",
++]
++
++[[package]]
++name = "parking_lot_core"
++version = "0.8.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
++dependencies = [
++ "cfg-if",
++ "instant",
++ "libc",
++ "redox_syscall",
++ "smallvec",
++ "winapi",
++]
++
++[[package]]
++name = "pin-project"
++version = "1.0.6"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "bc174859768806e91ae575187ada95c91a29e96a98dc5d2cd9a1fed039501ba6"
++dependencies = [
++ "pin-project-internal",
++]
++
++[[package]]
++name = "pin-project-internal"
++version = "1.0.6"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "a490329918e856ed1b083f244e3bfe2d8c4f336407e4ea9e1a9f479ff09049e5"
++dependencies = [
++ "proc-macro2",
++ "quote",
++ "syn",
++]
++
++[[package]]
++name = "pin-project-lite"
++version = "0.2.6"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
++
++[[package]]
++name = "pin-utils"
++version = "0.1.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
++
++[[package]]
++name = "proc-macro-hack"
++version = "0.5.19"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
++
++[[package]]
++name = "proc-macro-nested"
++version = "0.1.7"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
++
++[[package]]
++name = "proc-macro2"
++version = "1.0.26"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
++dependencies = [
++ "unicode-xid",
++]
++
++[[package]]
++name = "quote"
++version = "1.0.9"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
++dependencies = [
++ "proc-macro2",
++]
++
++[[package]]
++name = "redox_syscall"
++version = "0.2.5"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
++dependencies = [
++ "bitflags",
++]
++
++[[package]]
++name = "ring"
++version = "0.16.20"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
++dependencies = [
++ "cc",
++ "libc",
++ "once_cell",
++ "spin",
++ "untrusted",
++ "web-sys",
++ "winapi",
++]
++
++[[package]]
++name = "rustls"
++version = "0.19.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "064fd21ff87c6e87ed4506e68beb42459caa4a0e2eb144932e6776768556980b"
++dependencies = [
++ "base64",
++ "log",
++ "ring",
++ "sct",
++ "webpki",
++]
++
++[[package]]
++name = "scopeguard"
++version = "1.1.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
++
++[[package]]
++name = "sct"
++version = "0.6.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
++dependencies = [
++ "ring",
++ "untrusted",
++]
++
++[[package]]
++name = "slab"
++version = "0.4.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
++
++[[package]]
++name = "smallvec"
++version = "1.6.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
++
++[[package]]
++name = "spin"
++version = "0.5.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
++
++[[package]]
++name = "strsim"
++version = "0.8.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
++
++[[package]]
++name = "syn"
++version = "1.0.68"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "3ce15dd3ed8aa2f8eeac4716d6ef5ab58b6b9256db41d7e1a0224c2788e8fd87"
++dependencies = [
++ "proc-macro2",
++ "quote",
++ "unicode-xid",
++]
++
++[[package]]
++name = "textwrap"
++version = "0.11.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
++dependencies = [
++ "unicode-width",
++]
++
++[[package]]
++name = "tokio"
++version = "1.4.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "134af885d758d645f0f0505c9a8b3f9bf8a348fd822e112ab5248138348f1722"
++dependencies = [
++ "autocfg",
++ "bytes",
++ "libc",
++ "memchr",
++ "mio",
++ "num_cpus",
++ "parking_lot",
++ "pin-project-lite",
++]
++
++[[package]]
++name = "tokio-rustls"
++version = "0.22.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
++dependencies = [
++ "rustls",
++ "tokio",
++ "webpki",
++]
++
++[[package]]
++name = "tokio-util"
++version = "0.6.5"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "5143d049e85af7fbc36f5454d990e62c2df705b3589f123b71f441b6b59f443f"
++dependencies = [
++ "bytes",
++ "futures-core",
++ "futures-sink",
++ "log",
++ "pin-project-lite",
++ "tokio",
++]
++
++[[package]]
++name = "tower-service"
++version = "0.3.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
++
++[[package]]
++name = "tracing"
++version = "0.1.25"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
++dependencies = [
++ "cfg-if",
++ "pin-project-lite",
++ "tracing-core",
++]
++
++[[package]]
++name = "tracing-core"
++version = "0.1.17"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f"
++dependencies = [
++ "lazy_static",
++]
++
++[[package]]
++name = "try-lock"
++version = "0.2.3"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
++
++[[package]]
++name = "unicode-width"
++version = "0.1.8"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
++
++[[package]]
++name = "unicode-xid"
++version = "0.2.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
++
++[[package]]
++name = "untrusted"
++version = "0.7.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
++
++[[package]]
++name = "vec_map"
++version = "0.8.2"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
++
++[[package]]
++name = "want"
++version = "0.3.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
++dependencies = [
++ "log",
++ "try-lock",
++]
++
++[[package]]
++name = "wasm-bindgen"
++version = "0.2.73"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9"
++dependencies = [
++ "cfg-if",
++ "wasm-bindgen-macro",
++]
++
++[[package]]
++name = "wasm-bindgen-backend"
++version = "0.2.73"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae"
++dependencies = [
++ "bumpalo",
++ "lazy_static",
++ "log",
++ "proc-macro2",
++ "quote",
++ "syn",
++ "wasm-bindgen-shared",
++]
++
++[[package]]
++name = "wasm-bindgen-macro"
++version = "0.2.73"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f"
++dependencies = [
++ "quote",
++ "wasm-bindgen-macro-support",
++]
++
++[[package]]
++name = "wasm-bindgen-macro-support"
++version = "0.2.73"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c"
++dependencies = [
++ "proc-macro2",
++ "quote",
++ "syn",
++ "wasm-bindgen-backend",
++ "wasm-bindgen-shared",
++]
++
++[[package]]
++name = "wasm-bindgen-shared"
++version = "0.2.73"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489"
++
++[[package]]
++name = "web-sys"
++version = "0.3.50"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be"
++dependencies = [
++ "js-sys",
++ "wasm-bindgen",
++]
++
++[[package]]
++name = "webpki"
++version = "0.21.4"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
++dependencies = [
++ "ring",
++ "untrusted",
++]
++
++[[package]]
++name = "winapi"
++version = "0.3.9"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
++dependencies = [
++ "winapi-i686-pc-windows-gnu",
++ "winapi-x86_64-pc-windows-gnu",
++]
++
++[[package]]
++name = "winapi-i686-pc-windows-gnu"
++version = "0.4.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
++
++[[package]]
++name = "winapi-x86_64-pc-windows-gnu"
++version = "0.4.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/pkgs/servers/dns/doh-proxy-rust/default.nix b/pkgs/servers/dns/doh-proxy-rust/default.nix
new file mode 100644
index 00000000000..76f1397611a
--- /dev/null
+++ b/pkgs/servers/dns/doh-proxy-rust/default.nix
@@ -0,0 +1,27 @@
+{ lib, stdenv, rustPlatform, fetchFromGitHub, Security, libiconv }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "doh-proxy-rust";
+  version = "0.3.8";
+
+  src = fetchFromGitHub {
+    owner = "jedisct1";
+    repo = "doh-server";
+    rev = version;
+    sha256 = "0jksdrji06ykk5cj6i8ydcjhagjwb2xz5bjs6qsw044p8a2hsq53";
+  };
+
+  cargoSha256 = "1wilm7bzr8h9yjwzw97ihavaylkv6nrk8f0vmm7kia69vqdrz9in";
+  cargoPatches = [ ./cargo-lock.patch ];
+
+  buildInputs = lib.optionals stdenv.isDarwin [ Security libiconv ];
+
+  doCheck = false; # no test suite, skip useless compile step
+
+  meta = with lib; {
+    homepage = "https://github.com/jedisct1/doh-server";
+    description = "Fast, mature, secure DoH server proxy written in Rust";
+    license = with licenses; [ mit ];
+    maintainers = with maintainers; [ stephank ];
+  };
+}
diff --git a/pkgs/servers/home-assistant/component-packages.nix b/pkgs/servers/home-assistant/component-packages.nix
index 91f995d6cca..7d5c6f29e02 100644
--- a/pkgs/servers/home-assistant/component-packages.nix
+++ b/pkgs/servers/home-assistant/component-packages.nix
@@ -2,7 +2,7 @@
 # Do not edit!
 
 {
-  version = "2021.3.4";
+  version = "2021.4.0";
   components = {
     "abode" = ps: with ps; [ abodepy ];
     "accuweather" = ps: with ps; [ accuweather ];
@@ -31,6 +31,7 @@
     "ambient_station" = ps: with ps; [ aioambient ];
     "amcrest" = ps: with ps; [ amcrest ha-ffmpeg ];
     "ampio" = ps: with ps; [ ]; # missing inputs: asmog
+    "analytics" = ps: with ps; [ aiohttp-cors ];
     "android_ip_webcam" = ps: with ps; [ ]; # missing inputs: pydroid-ipcam
     "androidtv" = ps: with ps; [ adb-shell androidtv pure-python-adb ];
     "anel_pwrctrl" = ps: with ps; [ ]; # missing inputs: anel_pwrctrl-homeassistant
@@ -57,7 +58,7 @@
     "atag" = ps: with ps; [ ]; # missing inputs: pyatag
     "aten_pe" = ps: with ps; [ atenpdu ];
     "atome" = ps: with ps; [ ]; # missing inputs: pyatome
-    "august" = ps: with ps; [ ]; # missing inputs: py-august
+    "august" = ps: with ps; [ yalexs ];
     "aurora" = ps: with ps; [ auroranoaa ];
     "aurora_abb_powerone" = ps: with ps; [ ]; # missing inputs: aurorapy
     "auth" = ps: with ps; [ aiohttp-cors ];
@@ -154,7 +155,7 @@
     "deconz" = ps: with ps; [ pydeconz ];
     "decora" = ps: with ps; [ bluepy ]; # missing inputs: decora
     "decora_wifi" = ps: with ps; [ ]; # missing inputs: decora_wifi
-    "default_config" = ps: with ps; [ pynacl aiohttp-cors async-upnp-client defusedxml distro emoji hass-nabucasa netdisco pillow scapy sqlalchemy zeroconf ];
+    "default_config" = ps: with ps; [ pynacl aiodiscover aiohttp-cors async-upnp-client defusedxml distro emoji hass-nabucasa netdisco pillow scapy sqlalchemy zeroconf ];
     "delijn" = ps: with ps; [ ]; # missing inputs: pydelijn
     "deluge" = ps: with ps; [ deluge-client ];
     "demo" = ps: with ps; [ aiohttp-cors ];
@@ -167,7 +168,7 @@
     "device_tracker" = ps: with ps; [ ];
     "devolo_home_control" = ps: with ps; [ aiohttp-cors devolo-home-control-api zeroconf ];
     "dexcom" = ps: with ps; [ pydexcom ];
-    "dhcp" = ps: with ps; [ scapy ];
+    "dhcp" = ps: with ps; [ aiodiscover scapy ];
     "dht" = ps: with ps; [ ]; # missing inputs: Adafruit-DHT
     "dialogflow" = ps: with ps; [ aiohttp-cors ];
     "digital_ocean" = ps: with ps; [ digital-ocean ];
@@ -277,7 +278,7 @@
     "foscam" = ps: with ps; [ ]; # missing inputs: libpyfoscam
     "foursquare" = ps: with ps; [ aiohttp-cors ];
     "free_mobile" = ps: with ps; [ ]; # missing inputs: freesms
-    "freebox" = ps: with ps; [ aiohttp-cors freebox-api netdisco zeroconf ];
+    "freebox" = ps: with ps; [ freebox-api ];
     "freedns" = ps: with ps; [ ];
     "fritz" = ps: with ps; [ fritzconnection ];
     "fritzbox" = ps: with ps; [ pyfritzhome ];
@@ -326,7 +327,6 @@
     "gree" = ps: with ps; [ ]; # missing inputs: greeclimate
     "greeneye_monitor" = ps: with ps; [ ]; # missing inputs: greeneye_monitor
     "greenwave" = ps: with ps; [ ]; # missing inputs: greenwavereality
-    "griddy" = ps: with ps; [ ]; # missing inputs: griddypower
     "group" = ps: with ps; [ ];
     "growatt_server" = ps: with ps; [ ]; # missing inputs: growattServer
     "gstreamer" = ps: with ps; [ ]; # missing inputs: gstreamer-player
@@ -352,6 +352,7 @@
     "hive" = ps: with ps; [ ]; # missing inputs: pyhiveapi
     "hlk_sw16" = ps: with ps; [ ]; # missing inputs: hlk-sw16
     "home_connect" = ps: with ps; [ aiohttp-cors ]; # missing inputs: homeconnect
+    "home_plus_control" = ps: with ps; [ aiohttp-cors homepluscontrol ];
     "homeassistant" = ps: with ps; [ ];
     "homekit" = ps: with ps; [ HAP-python pyqrcode pyturbojpeg aiohttp-cors base36 fnvhash ha-ffmpeg zeroconf ];
     "homekit_controller" = ps: with ps; [ aiohomekit aiohttp-cors zeroconf ];
@@ -448,7 +449,7 @@
     "linux_battery" = ps: with ps; [ batinfo ];
     "lirc" = ps: with ps; [ ]; # missing inputs: python-lirc
     "litejet" = ps: with ps; [ ]; # missing inputs: pylitejet
-    "litterrobot" = ps: with ps; [ ]; # missing inputs: pylitterbot
+    "litterrobot" = ps: with ps; [ pylitterbot ];
     "llamalab_automate" = ps: with ps; [ ];
     "local_file" = ps: with ps; [ ];
     "local_ip" = ps: with ps; [ ];
@@ -715,6 +716,7 @@
     "scene" = ps: with ps; [ ];
     "schluter" = ps: with ps; [ ]; # missing inputs: py-schluter
     "scrape" = ps: with ps; [ beautifulsoup4 jsonpath xmltodict ];
+    "screenlogic" = ps: with ps; [ screenlogicpy ];
     "script" = ps: with ps; [ ];
     "scsgate" = ps: with ps; [ ]; # missing inputs: scsgate
     "search" = ps: with ps; [ aiohttp-cors ];
@@ -864,6 +866,7 @@
     "tplink" = ps: with ps; [ pyhs100 ];
     "tplink_lte" = ps: with ps; [ ]; # missing inputs: tp-connected
     "traccar" = ps: with ps; [ aiohttp-cors stringcase ]; # missing inputs: pytraccar
+    "trace" = ps: with ps; [ ];
     "trackr" = ps: with ps; [ ]; # missing inputs: pytrackr
     "tradfri" = ps: with ps; [ ]; # missing inputs: pytradfri[async]
     "trafikverket_train" = ps: with ps; [ pytrafikverket ];
@@ -906,7 +909,7 @@
     "velux" = ps: with ps; [ pyvlx ];
     "venstar" = ps: with ps; [ venstarcolortouch ];
     "vera" = ps: with ps; [ pyvera ];
-    "verisure" = ps: with ps; [ jsonpath vsure ];
+    "verisure" = ps: with ps; [ vsure ];
     "versasense" = ps: with ps; [ ]; # missing inputs: pyversasense
     "version" = ps: with ps; [ pyhaversion ];
     "vesync" = ps: with ps; [ pyvesync ];
@@ -974,7 +977,7 @@
     "zeroconf" = ps: with ps; [ aiohttp-cors zeroconf ];
     "zerproc" = ps: with ps; [ pyzerproc ];
     "zestimate" = ps: with ps; [ xmltodict ];
-    "zha" = ps: with ps; [ bellows pyserial-asyncio pyserial zha-quirks zigpy-cc zigpy-deconz zigpy-xbee zigpy-zigate zigpy-znp zigpy ];
+    "zha" = ps: with ps; [ aiohttp-cors bellows pyserial-asyncio pyserial zeroconf zha-quirks zigpy-cc zigpy-deconz zigpy-xbee zigpy-zigate zigpy-znp zigpy ];
     "zhong_hong" = ps: with ps; [ ]; # missing inputs: zhong_hong_hvac
     "ziggo_mediabox_xl" = ps: with ps; [ ]; # missing inputs: ziggo-mediabox-xl
     "zodiac" = ps: with ps; [ ];
diff --git a/pkgs/servers/home-assistant/default.nix b/pkgs/servers/home-assistant/default.nix
index e192c3c4d63..400e0da3970 100644
--- a/pkgs/servers/home-assistant/default.nix
+++ b/pkgs/servers/home-assistant/default.nix
@@ -1,7 +1,6 @@
 { stdenv
 , lib
 , fetchFromGitHub
-, fetchpatch
 , python3
 , nixosTests
 
@@ -51,6 +50,21 @@ let
     (mkOverride "pykmtronic" "0.0.3"
       "sha256-8bxn27DU1XUQUxQFJklEge29DHx1DMu7pJG4hVE1jDU=")
 
+    # Pinned due to API changes in pylilterbot>=2021.3.0
+    (self: super: {
+      pylitterbot = super.pylitterbot.overridePythonAttrs (oldAttrs: rec {
+        version = "2021.2.8";
+        src = fetchFromGitHub {
+          owner = "natekspencer";
+          repo = "pylitterbot";
+          rev = version;
+          sha256 = "142lhijm51v11cd0lhcfdnjdd143jxi2hjsrqdq0rrbbnmj6mymp";
+        };
+        # had no tests before 2021.3.0
+        doCheck = false;
+      });
+    })
+
     # Pinned due to bug in ring-doorbell 0.7.0
     # https://github.com/tchellomello/python-ring-doorbell/issues/240
     (mkOverride "ring-doorbell" "0.6.2"
@@ -89,7 +103,7 @@ let
   extraBuildInputs = extraPackages py.pkgs;
 
   # Don't forget to run parse-requirements.py after updating
-  hassVersion = "2021.3.4";
+  hassVersion = "2021.4.0";
 
 in with py.pkgs; buildPythonApplication rec {
   pname = "homeassistant";
@@ -108,32 +122,22 @@ in with py.pkgs; buildPythonApplication rec {
     owner = "home-assistant";
     repo = "core";
     rev = version;
-    sha256 = "110pvin39lr40zd3lhb8zvh2wafl0k0dy3nbmc483yafy31xa4kw";
+    sha256 = "1gkbkyxqsw3isdyskzi0ib07fgqvirnr20jkhrz86vl0k9ix8hwf";
   };
 
   # leave this in, so users don't have to constantly update their downstream patch handling
   patches = [
-    (fetchpatch {
-      # Fix I-frame interval in stream test video
-      # https://github.com/home-assistant/core/pull/47638
-      url = "https://github.com/home-assistant/core/commit/d9bf63103fde44ddd38fb6b9a510d82609802b36.patch";
-      sha256 = "1y34cmw9zqb2lxyzm0q7vxlm05wwz76mhysgnh1jn39484fn9f9m";
-    })
   ];
 
   postPatch = ''
     substituteInPlace setup.py \
-      --replace "aiohttp==3.7.4" "aiohttp>=3.7.3" \
-      --replace "attrs==19.3.0" "attrs>=19.3.0" \
-      --replace "awesomeversion==21.2.3" "awesomeversion>=21.2.3" \
-      --replace "bcrypt==3.1.7" "bcrypt>=3.1.7" \
+      --replace "awesomeversion==21.2.3" "awesomeversion" \
+      --replace "bcrypt==3.1.7" "bcrypt" \
       --replace "cryptography==3.3.2" "cryptography" \
-      --replace "httpx==0.16.1" "httpx>=0.16.1" \
-      --replace "jinja2>=2.11.3" "jinja2>=2.11.2" \
       --replace "pip>=8.0.3,<20.3" "pip" \
-      --replace "pytz>=2021.1" "pytz>=2020.5" \
+      --replace "pytz>=2021.1" "pytz" \
       --replace "pyyaml==5.4.1" "pyyaml" \
-      --replace "ruamel.yaml==0.15.100" "ruamel.yaml>=0.15.100"
+      --replace "ruamel.yaml==0.15.100" "ruamel.yaml"
     substituteInPlace tests/test_config.py --replace '"/usr"' '"/build/media"'
   '';
 
@@ -187,6 +191,7 @@ in with py.pkgs; buildPythonApplication rec {
   componentTests = [
     "accuweather"
     "airly"
+    "analytics"
     "alert"
     "api"
     "auth"
@@ -239,6 +244,7 @@ in with py.pkgs; buildPythonApplication rec {
     "hddtemp"
     "history"
     "history_stats"
+    "home_plus_control"
     "homekit"
     "homekit_controller"
     "homeassistant"
@@ -261,6 +267,7 @@ in with py.pkgs; buildPythonApplication rec {
     "ipp"
     "kmtronic"
     "light"
+    "litterrobot"
     "local_file"
     "local_ip"
     "lock"
@@ -306,6 +313,7 @@ in with py.pkgs; buildPythonApplication rec {
     "rss_feed_template"
     "safe_mode"
     "scene"
+    "screenlogic"
     "script"
     "search"
     "shell_command"
@@ -336,6 +344,7 @@ in with py.pkgs; buildPythonApplication rec {
     "time_date"
     "timer"
     "tod"
+    "trace"
     "tts"
     "universal"
     "updater"
@@ -365,6 +374,8 @@ in with py.pkgs; buildPythonApplication rec {
     "--dist loadfile"
     # tests are located in tests/
     "tests"
+    # screenlogic/test_config_flow.py: Tries to send out UDP broadcasts
+    "--deselect tests/components/screenlogic/test_config_flow.py::test_form_cannot_connect"
     # dynamically add packages required for component tests
   ] ++ map (component: "tests/components/" + component) componentTests;
 
@@ -387,9 +398,13 @@ in with py.pkgs; buildPythonApplication rec {
     # generic/test_camera.py: AssertionError: 500 == 200
     "test_fetching_without_verify_ssl"
     "test_fetching_url_with_verify_ssl"
+    # util/test_package.py: AssertionError on package.is_installed('homeassistant>=999.999.999')
+    "test_check_package_version_does_not_match"
   ];
 
   preCheck = ''
+    export HOME="$TEMPDIR"
+
     # the tests require the existance of a media dir
     mkdir /build/media
 
diff --git a/pkgs/servers/home-assistant/frontend.nix b/pkgs/servers/home-assistant/frontend.nix
index e62ee9b42b6..72a1ea13e0d 100644
--- a/pkgs/servers/home-assistant/frontend.nix
+++ b/pkgs/servers/home-assistant/frontend.nix
@@ -4,11 +4,11 @@ buildPythonPackage rec {
   # the frontend version corresponding to a specific home-assistant version can be found here
   # https://github.com/home-assistant/home-assistant/blob/master/homeassistant/components/frontend/manifest.json
   pname = "home-assistant-frontend";
-  version = "20210302.6";
+  version = "20210407.1";
 
   src = fetchPypi {
     inherit pname version;
-    sha256 = "sha256-h3jCqfAPg+z6vsdLm5Pdr+7PCEWW58GCG9viIz3Mi64=";
+    sha256 = "sha256-7kgL6Ixlc1OZ+3sUAuvJd7vgY6FBgPFEKi6xhq7fiBc=";
   };
 
   # there is nothing to strip in this package
diff --git a/pkgs/servers/unifi/default.nix b/pkgs/servers/unifi/default.nix
index 0bc3c3413bb..aeaa4409aa7 100644
--- a/pkgs/servers/unifi/default.nix
+++ b/pkgs/servers/unifi/default.nix
@@ -52,7 +52,7 @@ in rec {
   };
 
   unifi6 = generic {
-    version = "6.0.45";
-    sha256 = "1mph22x2p26q76gh6s714xwsvc03cciy4gx00jv4vhcm28p6nlxy";
+    version = "6.1.71";
+    sha256 = "1lvsq0xpfgwpbzs25khy7bnrhv8i1jgzi8ij75bsh65hfa3rplc2";
   };
 }
diff --git a/pkgs/servers/web-apps/discourse/action_mailer_ca_cert.patch b/pkgs/servers/web-apps/discourse/action_mailer_ca_cert.patch
new file mode 100644
index 00000000000..83c44a466fa
--- /dev/null
+++ b/pkgs/servers/web-apps/discourse/action_mailer_ca_cert.patch
@@ -0,0 +1,12 @@
+diff --git a/config/environments/production.rb b/config/environments/production.rb
+index 75c3a69512..7fc374cd9d 100644
+--- a/config/environments/production.rb
++++ b/config/environments/production.rb
+@@ -32,6 +32,7 @@ Discourse::Application.configure do
+       user_name: GlobalSetting.smtp_user_name,
+       password: GlobalSetting.smtp_password,
+       authentication: GlobalSetting.smtp_authentication,
++      ca_file: "/etc/ssl/certs/ca-certificates.crt",
+       enable_starttls_auto: GlobalSetting.smtp_enable_start_tls
+     }
+ 
diff --git a/pkgs/servers/web-apps/discourse/admin_create.patch b/pkgs/servers/web-apps/discourse/admin_create.patch
new file mode 100644
index 00000000000..651e8ce81dc
--- /dev/null
+++ b/pkgs/servers/web-apps/discourse/admin_create.patch
@@ -0,0 +1,48 @@
+diff --git a/lib/tasks/admin.rake b/lib/tasks/admin.rake
+index 80c403616d..cba01202ac 100644
+--- a/lib/tasks/admin.rake
++++ b/lib/tasks/admin.rake
+@@ -107,3 +107,43 @@ task "admin:create" => :environment do
+   end
+ 
+ end
++
++desc "Creates a forum administrator noninteractively"
++task "admin:create_noninteractively" => :environment do
++  email = ENV["ADMIN_EMAIL"]
++  existing_user = User.find_by_email(email)
++
++  # check if user account already exixts
++  if existing_user
++    admin = existing_user
++  else
++    # create new user
++    admin = User.new
++  end
++
++  admin.email = email
++  admin.name = ENV["ADMIN_NAME"]
++  admin.username = ENV["ADMIN_USERNAME"]
++
++  password = ENV["ADMIN_PASSWORD"]
++  unless admin.confirm_password?(password)
++    admin.password = password
++    puts "Admin password set!"
++  end
++
++  admin.active = true
++
++  # save/update user account
++  saved = admin.save
++  raise admin.errors.full_messages.join("\n") unless saved
++
++  puts "Account created successfully with username #{admin.username}" unless existing_user
++
++  # grant admin privileges
++  admin.grant_admin!
++  if admin.trust_level < 1
++    admin.change_trust_level!(1)
++  end
++  admin.email_tokens.update_all confirmed: true
++  admin.activate
++end
diff --git a/pkgs/servers/web-apps/discourse/default.nix b/pkgs/servers/web-apps/discourse/default.nix
new file mode 100644
index 00000000000..900d6921092
--- /dev/null
+++ b/pkgs/servers/web-apps/discourse/default.nix
@@ -0,0 +1,234 @@
+{ stdenv, makeWrapper, runCommandNoCC, lib, nixosTests
+, fetchFromGitHub, bundlerEnv, ruby, replace, gzip, gnutar, git
+, util-linux, gawk, imagemagick, optipng, pngquant, libjpeg, jpegoptim
+, gifsicle, libpsl, redis, postgresql, which, brotli, procps
+, nodePackages, v8
+}:
+
+let
+  version = "2.6.3";
+
+  src = fetchFromGitHub {
+    owner = "discourse";
+    repo = "discourse";
+    rev = "v${version}";
+    sha256 = "sha256-lAIhVxvmjxEiru1KNxbFV+eDMLUGza/Dma3WU0ex0xs=";
+  };
+
+  runtimeDeps = [
+    # For backups, themes and assets
+    rubyEnv.wrappedRuby
+    gzip
+    gnutar
+    git
+    brotli
+
+    # Misc required system utils
+    which
+    procps       # For ps and kill
+    util-linux   # For renice
+    gawk
+
+    # Image optimization
+    imagemagick
+    optipng
+    pngquant
+    libjpeg
+    jpegoptim
+    gifsicle
+    nodePackages.svgo
+  ];
+
+  runtimeEnv = {
+    HOME = "/run/discourse/home";
+    RAILS_ENV = "production";
+    UNICORN_LISTENER = "/run/discourse/sockets/unicorn.sock";
+  };
+
+  rake = runCommandNoCC "discourse-rake" {
+    nativeBuildInputs = [ makeWrapper ];
+  } ''
+    mkdir -p $out/bin
+    makeWrapper ${rubyEnv}/bin/rake $out/bin/discourse-rake \
+        ${lib.concatStrings (lib.mapAttrsToList (name: value: "--set ${name} '${value}' ") runtimeEnv)} \
+        --prefix PATH : ${lib.makeBinPath runtimeDeps} \
+        --set RAKEOPT '-f ${discourse}/share/discourse/Rakefile' \
+        --run 'cd ${discourse}/share/discourse'
+  '';
+
+  rubyEnv = bundlerEnv {
+    name = "discourse-ruby-env-${version}";
+    inherit version ruby;
+    gemdir = ./rubyEnv;
+    gemset =
+      let
+        gems = import ./rubyEnv/gemset.nix;
+      in
+        gems // {
+          mini_racer = gems.mini_racer // {
+            buildInputs = [ v8 ];
+            dontBuild = false;
+            # The Ruby extension makefile generator assumes the source
+            # is C, when it's actually C++ ¯\_(ツ)_/¯
+            postPatch = ''
+              substituteInPlace ext/mini_racer_extension/extconf.rb \
+                --replace '" -std=c++0x"' \
+                          '" -x c++ -std=c++0x"'
+            '';
+          };
+          mini_suffix = gems.mini_suffix // {
+            propagatedBuildInputs = [ libpsl ];
+            dontBuild = false;
+            # Use our libpsl instead of the vendored one, which isn't
+            # available for aarch64
+            postPatch = ''
+              cp $(readlink -f ${libpsl}/lib/libpsl.so) vendor/libpsl.so
+            '';
+          };
+        };
+
+    groups = [
+      "default" "assets" "development" "test"
+    ];
+  };
+
+  assets = stdenv.mkDerivation {
+    pname = "discourse-assets";
+    inherit version src;
+
+    nativeBuildInputs = [
+      rubyEnv.wrappedRuby
+      postgresql
+      redis
+      which
+      brotli
+      procps
+      nodePackages.uglify-js
+    ];
+
+    # We have to set up an environment that is close enough to
+    # production ready or the assets:precompile task refuses to
+    # run. This means that Redis and PostgreSQL has to be running and
+    # database migrations performed.
+    preBuild = ''
+      redis-server >/dev/null &
+
+      initdb -A trust $NIX_BUILD_TOP/postgres >/dev/null
+      postgres -D $NIX_BUILD_TOP/postgres -k $NIX_BUILD_TOP >/dev/null &
+      export PGHOST=$NIX_BUILD_TOP
+
+      echo "Waiting for Redis and PostgreSQL to be ready.."
+      while ! redis-cli --scan >/dev/null || ! psql -l >/dev/null; do
+        sleep 0.1
+      done
+
+      psql -d postgres -tAc 'CREATE USER "discourse"'
+      psql -d postgres -tAc 'CREATE DATABASE "discourse" OWNER "discourse"'
+      psql 'discourse' -tAc "CREATE EXTENSION IF NOT EXISTS pg_trgm"
+      psql 'discourse' -tAc "CREATE EXTENSION IF NOT EXISTS hstore"
+
+      # Create a temporary home dir to stop bundler from complaining
+      mkdir $NIX_BUILD_TOP/tmp_home
+      export HOME=$NIX_BUILD_TOP/tmp_home
+
+      export RAILS_ENV=production
+
+      bundle exec rake db:migrate >/dev/null
+      rm -r tmp/*
+    '';
+
+    buildPhase = ''
+      runHook preBuild
+
+      bundle exec rake assets:precompile
+
+      runHook postBuild
+    '';
+
+    installPhase = ''
+      runHook preInstall
+
+      mv public/assets $out
+
+      runHook postInstall
+    '';
+  };
+
+  discourse = stdenv.mkDerivation {
+    pname = "discourse";
+    inherit version src;
+
+    buildInputs = [
+      rubyEnv rubyEnv.wrappedRuby rubyEnv.bundler
+    ];
+
+    patches = [
+      # Load a separate NixOS site settings file
+      ./nixos_defaults.patch
+
+      # Add a noninteractive admin creation task
+      ./admin_create.patch
+
+      # Disable jhead, which is currently marked as vulnerable
+      ./disable_jhead.patch
+
+      # Add the path to the CA cert bundle to make TLS work
+      ./action_mailer_ca_cert.patch
+
+      # Log Unicorn messages to the journal and make request timeout
+      # configurable
+      ./unicorn_logging_and_timeout.patch
+    ];
+
+    postPatch = ''
+      # Always require lib-files and application.rb through their store
+      # path, not their relative state directory path. This gets rid of
+      # warnings and means we don't have to link back to lib from the
+      # state directory.
+      find config -type f -execdir sed -Ei "s,(\.\./)+(lib|app)/,$out/share/discourse/\2/," {} \;
+
+      ${replace}/bin/replace-literal -f -r -e 'File.rename(temp_destination, destination)' "FileUtils.mv(temp_destination, destination)" .
+    '';
+
+    buildPhase = ''
+      runHook preBuild
+
+      mv config config.dist
+      mv public public.dist
+      mv plugins plugins.dist
+
+      runHook postBuild
+    '';
+
+    installPhase = ''
+      runHook preInstall
+
+      mkdir -p $out/share
+      cp -r . $out/share/discourse
+      rm -r $out/share/discourse/log
+      ln -sf /var/log/discourse $out/share/discourse/log
+      ln -sf /run/discourse/tmp $out/share/discourse/tmp
+      ln -sf /run/discourse/config $out/share/discourse/config
+      ln -sf /run/discourse/assets/javascripts/plugins $out/share/discourse/app/assets/javascripts/plugins
+      ln -sf /run/discourse/public $out/share/discourse/public
+      ln -sf /run/discourse/plugins $out/share/discourse/plugins
+      ln -sf ${assets} $out/share/discourse/public.dist/assets
+
+      runHook postInstall
+    '';
+
+    meta = with lib; {
+      homepage = "https://www.discourse.org/";
+      platforms = platforms.linux;
+      maintainers = with maintainers; [ talyz ];
+      license = licenses.gpl2Plus;
+      description = "Discourse is an open source discussion platform";
+    };
+
+    passthru = {
+      inherit rubyEnv runtimeEnv runtimeDeps rake;
+      ruby = rubyEnv.wrappedRuby;
+      tests = nixosTests.discourse;
+    };
+  };
+in discourse
diff --git a/pkgs/servers/web-apps/discourse/disable_jhead.patch b/pkgs/servers/web-apps/discourse/disable_jhead.patch
new file mode 100644
index 00000000000..709a1959d63
--- /dev/null
+++ b/pkgs/servers/web-apps/discourse/disable_jhead.patch
@@ -0,0 +1,12 @@
+diff --git a/lib/file_helper.rb b/lib/file_helper.rb
+index 162de9a40b..9ac8807e9d 100644
+--- a/lib/file_helper.rb
++++ b/lib/file_helper.rb
+@@ -124,6 +124,7 @@ class FileHelper
+         jpegoptim: { strip: strip_image_metadata ? "all" : "none" },
+         jpegtran: false,
+         jpegrecompress: false,
++        jhead: false,
+       )
+     end
+   end
diff --git a/pkgs/servers/web-apps/discourse/mail_receiver/default.nix b/pkgs/servers/web-apps/discourse/mail_receiver/default.nix
new file mode 100644
index 00000000000..c1a3a2df106
--- /dev/null
+++ b/pkgs/servers/web-apps/discourse/mail_receiver/default.nix
@@ -0,0 +1,39 @@
+{ stdenv, lib, fetchFromGitHub, ruby, makeWrapper, replace }:
+
+stdenv.mkDerivation rec {
+  pname = "discourse-mail-receiver";
+  version = "4.0.7";
+
+  src = fetchFromGitHub {
+    owner = "discourse";
+    repo = "mail-receiver";
+    rev = "v${version}";
+    sha256 = "0grifm5qyqazq63va3w26xjqnxwmfixhx0fx0zy7kd39378wwa6i";
+  };
+
+  nativeBuildInputs = [ replace ];
+  buildInputs = [ ruby makeWrapper ];
+
+  dontBuild = true;
+
+  installPhase = ''
+    mkdir -p $out/bin
+
+    replace-literal -f -r -e /etc/postfix /run/discourse-mail-receiver .
+
+    cp -r receive-mail discourse-smtp-fast-rejection $out/bin/
+    cp -r lib $out/
+
+    wrapProgram $out/bin/receive-mail --set RUBYLIB $out/lib
+    wrapProgram $out/bin/discourse-smtp-fast-rejection --set RUBYLIB $out/lib
+  '';
+
+  meta = with lib; {
+    homepage = "https://www.discourse.org/";
+    platforms = platforms.linux;
+    maintainers = with maintainers; [ talyz ];
+    license = licenses.mit;
+    description = "A helper program which receives incoming mail for Discourse";
+  };
+
+}
diff --git a/pkgs/servers/web-apps/discourse/nixos_defaults.patch b/pkgs/servers/web-apps/discourse/nixos_defaults.patch
new file mode 100644
index 00000000000..3efca97e62c
--- /dev/null
+++ b/pkgs/servers/web-apps/discourse/nixos_defaults.patch
@@ -0,0 +1,13 @@
+diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb
+index 89a5e923fc..b60754f50a 100644
+--- a/app/models/site_setting.rb
++++ b/app/models/site_setting.rb
+@@ -26,6 +26,8 @@ class SiteSetting < ActiveRecord::Base
+     end
+   end
+ 
++  load_settings(File.join(Rails.root, 'config', 'nixos_site_settings.json'))
++
+   setup_deprecated_methods
+   client_settings << :available_locales
+ 
diff --git a/pkgs/servers/web-apps/discourse/rubyEnv/Gemfile b/pkgs/servers/web-apps/discourse/rubyEnv/Gemfile
new file mode 100644
index 00000000000..cb86d7e4bac
--- /dev/null
+++ b/pkgs/servers/web-apps/discourse/rubyEnv/Gemfile
@@ -0,0 +1,248 @@
+# frozen_string_literal: true
+
+source 'https://rubygems.org'
+# if there is a super emergency and rubygems is playing up, try
+#source 'http://production.cf.rubygems.org'
+
+gem 'bootsnap', require: false, platform: :mri
+
+def rails_master?
+  ENV["RAILS_MASTER"] == '1'
+end
+
+if rails_master?
+  gem 'arel', git: 'https://github.com/rails/arel.git'
+  gem 'rails', git: 'https://github.com/rails/rails.git'
+else
+  # NOTE: Until rubygems gives us optional dependencies we are stuck with this needing to be explicit
+  # this allows us to include the bits of rails we use without pieces we do not.
+  #
+  # To issue a rails update bump the version number here
+  gem 'actionmailer', '6.0.3.3'
+  gem 'actionpack', '6.0.3.3'
+  gem 'actionview', '6.0.3.3'
+  gem 'activemodel', '6.0.3.3'
+  gem 'activerecord', '6.0.3.3'
+  gem 'activesupport', '6.0.3.3'
+  gem 'railties', '6.0.3.3'
+  gem 'sprockets-rails'
+end
+
+gem 'json'
+
+# TODO: At the moment Discourse does not work with Sprockets 4, we would need to correct internals
+# This is a desired upgrade we should get to.
+gem 'sprockets', '3.7.2'
+
+# this will eventually be added to rails,
+# allows us to precompile all our templates in the unicorn master
+gem 'actionview_precompiler', require: false
+
+gem 'seed-fu'
+
+gem 'mail', require: false
+gem 'mini_mime'
+gem 'mini_suffix'
+
+gem 'redis'
+
+# This is explicitly used by Sidekiq and is an optional dependency.
+# We tell Sidekiq to use the namespace "sidekiq" which triggers this
+# gem to be used. There is no explicit dependency in sidekiq cause
+# redis namespace support is optional
+# We already namespace stuff in DiscourseRedis, so we should consider
+# just using a single implementation in core vs having 2 namespace implementations
+gem 'redis-namespace'
+
+# NOTE: AM serializer gets a lot slower with recent updates
+# we used an old branch which is the fastest one out there
+# are long term goal here is to fork this gem so we have a
+# better maintained living fork
+gem 'active_model_serializers', '~> 0.8.3'
+
+gem 'onebox'
+
+gem 'http_accept_language', require: false
+
+# Ember related gems need to be pinned cause they control client side
+# behavior, we will push these versions up when upgrading ember
+gem 'discourse-ember-rails', '0.18.6', require: 'ember-rails'
+gem 'discourse-ember-source', '~> 3.12.2'
+gem 'ember-handlebars-template', '0.8.0'
+gem 'discourse-fonts'
+
+gem 'barber'
+
+gem 'message_bus'
+
+gem 'rails_multisite'
+
+gem 'fast_xs', platform: :ruby
+
+gem 'xorcist'
+
+gem 'fastimage'
+
+gem 'aws-sdk-s3', require: false
+gem 'aws-sdk-sns', require: false
+gem 'excon', require: false
+gem 'unf', require: false
+
+gem 'email_reply_trimmer'
+
+# Forked until https://github.com/toy/image_optim/pull/162 is merged
+# https://github.com/discourse/image_optim
+gem 'discourse_image_optim', require: 'image_optim'
+gem 'multi_json'
+gem 'mustache'
+gem 'nokogiri'
+gem 'css_parser', require: false
+
+gem 'omniauth'
+gem 'omniauth-facebook'
+gem 'omniauth-twitter'
+gem 'omniauth-github'
+
+gem 'omniauth-oauth2', require: false
+
+gem 'omniauth-google-oauth2'
+
+gem 'oj'
+gem 'pg'
+gem 'mini_sql'
+gem 'pry-rails', require: false
+gem 'pry-byebug', require: false
+gem 'r2', require: false
+gem 'rake'
+
+gem 'thor', require: false
+gem 'diffy', require: false
+gem 'rinku'
+gem 'sidekiq'
+gem 'mini_scheduler'
+
+gem 'execjs', require: false
+gem 'mini_racer'
+
+gem 'highline', require: false
+
+gem 'rack'
+
+gem 'rack-protection' # security
+gem 'cbor', require: false
+gem 'cose', require: false
+gem 'addressable'
+
+# Gems used only for assets and not required in production environments by default.
+# Allow everywhere for now cause we are allowing asset debugging in production
+group :assets do
+  gem 'uglifier'
+  gem 'rtlit', require: false # for css rtling
+end
+
+group :test do
+  gem 'webmock', require: false
+  gem 'fakeweb', require: false
+  gem 'minitest', require: false
+  gem 'simplecov', require: false
+  gem "test-prof"
+end
+
+group :test, :development do
+  gem 'rspec'
+  gem 'mock_redis'
+  gem 'listen', require: false
+  gem 'certified', require: false
+  gem 'fabrication', require: false
+  gem 'mocha', require: false
+
+  gem 'rb-fsevent', require: RUBY_PLATFORM =~ /darwin/i ? 'rb-fsevent' : false
+
+  gem 'rspec-rails'
+
+  gem 'shoulda-matchers', require: false
+  gem 'rspec-html-matchers'
+  gem 'byebug', require: ENV['RM_INFO'].nil?, platform: :mri
+  gem "rubocop-discourse", require: false
+  gem 'parallel_tests'
+
+  gem 'rswag-specs'
+end
+
+group :development do
+  gem 'ruby-prof', require: false, platform: :mri
+  gem 'bullet', require: !!ENV['BULLET']
+  gem 'better_errors', platform: :mri, require: !!ENV['BETTER_ERRORS']
+  gem 'binding_of_caller'
+  gem 'yaml-lint'
+  gem 'annotate'
+end
+
+# this is an optional gem, it provides a high performance replacement
+# to String#blank? a method that is called quite frequently in current
+# ActiveRecord, this may change in the future
+gem 'fast_blank', platform: :ruby
+
+# this provides a very efficient lru cache
+gem 'lru_redux'
+
+gem 'htmlentities', require: false
+
+# IMPORTANT: mini profiler monkey patches, so it better be required last
+#  If you want to amend mini profiler to do the monkey patches in the railties
+#  we are open to it. by deferring require to the initializer we can configure discourse installs without it
+
+gem 'flamegraph', require: false
+gem 'rack-mini-profiler', require: ['enable_rails_patches']
+
+gem 'unicorn', require: false, platform: :ruby
+gem 'puma', require: false
+gem 'rbtrace', require: false, platform: :mri
+gem 'gc_tracer', require: false, platform: :mri
+
+# required for feed importing and embedding
+gem 'ruby-readability', require: false
+
+gem 'stackprof', require: false, platform: :mri
+gem 'memory_profiler', require: false, platform: :mri
+
+gem 'cppjieba_rb', require: false
+
+gem 'lograge', require: false
+gem 'logstash-event', require: false
+gem 'logstash-logger', require: false
+gem 'logster'
+
+# NOTE: later versions of sassc are causing a segfault, possibly dependent on processer architecture
+# and until resolved should be locked at 2.0.1
+gem 'sassc', '2.0.1', require: false
+gem "sassc-rails"
+
+gem 'rotp', require: false
+
+gem 'rqrcode'
+
+gem 'rubyzip', require: false
+
+gem 'sshkey', require: false
+
+gem 'rchardet', require: false
+gem 'lz4-ruby', require: false, platform: :ruby
+
+if ENV["IMPORT"] == "1"
+  gem 'mysql2'
+  gem 'redcarpet'
+
+  # NOTE: in import mode the version of sqlite can matter a lot, so we stick it to a specific one
+  gem 'sqlite3', '~> 1.3', '>= 1.3.13'
+  gem 'ruby-bbcode-to-md', git: 'https://github.com/nlalonde/ruby-bbcode-to-md'
+  gem 'reverse_markdown'
+  gem 'tiny_tds'
+  gem 'csv'
+end
+
+gem 'webpush', require: false
+gem 'colored2', require: false
+gem 'maxminddb'
+
+gem 'rails_failover', require: false
diff --git a/pkgs/servers/web-apps/discourse/rubyEnv/Gemfile.lock b/pkgs/servers/web-apps/discourse/rubyEnv/Gemfile.lock
new file mode 100644
index 00000000000..4f067493227
--- /dev/null
+++ b/pkgs/servers/web-apps/discourse/rubyEnv/Gemfile.lock
@@ -0,0 +1,561 @@
+GEM
+  remote: https://rubygems.org/
+  specs:
+    actionmailer (6.0.3.3)
+      actionpack (= 6.0.3.3)
+      actionview (= 6.0.3.3)
+      activejob (= 6.0.3.3)
+      mail (~> 2.5, >= 2.5.4)
+      rails-dom-testing (~> 2.0)
+    actionpack (6.0.3.3)
+      actionview (= 6.0.3.3)
+      activesupport (= 6.0.3.3)
+      rack (~> 2.0, >= 2.0.8)
+      rack-test (>= 0.6.3)
+      rails-dom-testing (~> 2.0)
+      rails-html-sanitizer (~> 1.0, >= 1.2.0)
+    actionview (6.0.3.3)
+      activesupport (= 6.0.3.3)
+      builder (~> 3.1)
+      erubi (~> 1.4)
+      rails-dom-testing (~> 2.0)
+      rails-html-sanitizer (~> 1.1, >= 1.2.0)
+    actionview_precompiler (0.2.3)
+      actionview (>= 6.0.a)
+    active_model_serializers (0.8.4)
+      activemodel (>= 3.0)
+    activejob (6.0.3.3)
+      activesupport (= 6.0.3.3)
+      globalid (>= 0.3.6)
+    activemodel (6.0.3.3)
+      activesupport (= 6.0.3.3)
+    activerecord (6.0.3.3)
+      activemodel (= 6.0.3.3)
+      activesupport (= 6.0.3.3)
+    activesupport (6.0.3.3)
+      concurrent-ruby (~> 1.0, >= 1.0.2)
+      i18n (>= 0.7, < 2)
+      minitest (~> 5.1)
+      tzinfo (~> 1.1)
+      zeitwerk (~> 2.2, >= 2.2.2)
+    addressable (2.7.0)
+      public_suffix (>= 2.0.2, < 5.0)
+    annotate (3.1.1)
+      activerecord (>= 3.2, < 7.0)
+      rake (>= 10.4, < 14.0)
+    ast (2.4.1)
+    aws-eventstream (1.1.0)
+    aws-partitions (1.390.0)
+    aws-sdk-core (3.109.2)
+      aws-eventstream (~> 1, >= 1.0.2)
+      aws-partitions (~> 1, >= 1.239.0)
+      aws-sigv4 (~> 1.1)
+      jmespath (~> 1.0)
+    aws-sdk-kms (1.39.0)
+      aws-sdk-core (~> 3, >= 3.109.0)
+      aws-sigv4 (~> 1.1)
+    aws-sdk-s3 (1.83.2)
+      aws-sdk-core (~> 3, >= 3.109.0)
+      aws-sdk-kms (~> 1)
+      aws-sigv4 (~> 1.1)
+    aws-sdk-sns (1.35.0)
+      aws-sdk-core (~> 3, >= 3.109.0)
+      aws-sigv4 (~> 1.1)
+    aws-sigv4 (1.2.2)
+      aws-eventstream (~> 1, >= 1.0.2)
+    barber (0.12.2)
+      ember-source (>= 1.0, < 3.1)
+      execjs (>= 1.2, < 3)
+    better_errors (2.9.1)
+      coderay (>= 1.0.0)
+      erubi (>= 1.0.0)
+      rack (>= 0.9.0)
+    binding_of_caller (0.8.0)
+      debug_inspector (>= 0.0.1)
+    bootsnap (1.5.1)
+      msgpack (~> 1.0)
+    builder (3.2.4)
+    bullet (6.1.0)
+      activesupport (>= 3.0.0)
+      uniform_notifier (~> 1.11)
+    byebug (11.1.3)
+    cbor (0.5.9.6)
+    certified (1.0.0)
+    chunky_png (1.3.14)
+    coderay (1.1.3)
+    colored2 (3.1.2)
+    concurrent-ruby (1.1.7)
+    connection_pool (2.2.3)
+    cose (1.2.0)
+      cbor (~> 0.5.9)
+      openssl-signature_algorithm (~> 1.0)
+    cppjieba_rb (0.3.3)
+    crack (0.4.4)
+    crass (1.0.6)
+    css_parser (1.7.1)
+      addressable
+    debug_inspector (0.0.3)
+    diff-lcs (1.4.4)
+    diffy (3.4.0)
+    discourse-ember-rails (0.18.6)
+      active_model_serializers
+      ember-data-source (>= 1.0.0.beta.5)
+      ember-handlebars-template (>= 0.1.1, < 1.0)
+      ember-source (>= 1.1.0)
+      jquery-rails (>= 1.0.17)
+      railties (>= 3.1)
+    discourse-ember-source (3.12.2.2)
+    discourse-fonts (0.0.5)
+    discourse_image_optim (0.26.2)
+      exifr (~> 1.2, >= 1.2.2)
+      fspath (~> 3.0)
+      image_size (~> 1.5)
+      in_threads (~> 1.3)
+      progress (~> 3.0, >= 3.0.1)
+    docile (1.3.2)
+    email_reply_trimmer (0.1.13)
+    ember-data-source (3.0.2)
+      ember-source (>= 2, < 3.0)
+    ember-handlebars-template (0.8.0)
+      barber (>= 0.11.0)
+      sprockets (>= 3.3, < 4.1)
+    ember-source (2.18.2)
+    erubi (1.10.0)
+    excon (0.78.0)
+    execjs (2.7.0)
+    exifr (1.3.9)
+    fabrication (2.21.1)
+    fakeweb (1.3.0)
+    faraday (1.1.0)
+      multipart-post (>= 1.2, < 3)
+      ruby2_keywords
+    fast_blank (1.0.0)
+    fast_xs (0.8.0)
+    fastimage (2.2.0)
+    ffi (1.13.1)
+    flamegraph (0.9.5)
+    fspath (3.1.2)
+    gc_tracer (1.5.1)
+    globalid (0.4.2)
+      activesupport (>= 4.2.0)
+    guess_html_encoding (0.0.11)
+    hashdiff (1.0.1)
+    hashie (4.1.0)
+    highline (2.0.3)
+    hkdf (0.3.0)
+    htmlentities (4.3.4)
+    http_accept_language (2.1.1)
+    i18n (1.8.5)
+      concurrent-ruby (~> 1.0)
+    image_size (1.5.0)
+    in_threads (1.5.4)
+    jmespath (1.4.0)
+    jquery-rails (4.4.0)
+      rails-dom-testing (>= 1, < 3)
+      railties (>= 4.2.0)
+      thor (>= 0.14, < 2.0)
+    json (2.3.1)
+    json-schema (2.8.1)
+      addressable (>= 2.4)
+    jwt (2.2.2)
+    kgio (2.11.3)
+    libv8 (8.4.255.0)
+    listen (3.3.1)
+      rb-fsevent (~> 0.10, >= 0.10.3)
+      rb-inotify (~> 0.9, >= 0.9.10)
+    lograge (0.11.2)
+      actionpack (>= 4)
+      activesupport (>= 4)
+      railties (>= 4)
+      request_store (~> 1.0)
+    logstash-event (1.2.02)
+    logstash-logger (0.26.1)
+      logstash-event (~> 1.2)
+    logster (2.9.4)
+    loofah (2.8.0)
+      crass (~> 1.0.2)
+      nokogiri (>= 1.5.9)
+    lru_redux (1.1.0)
+    lz4-ruby (0.3.3)
+    mail (2.7.1)
+      mini_mime (>= 0.1.1)
+    maxminddb (0.1.22)
+    memory_profiler (0.9.14)
+    message_bus (3.3.4)
+      rack (>= 1.1.3)
+    method_source (1.0.0)
+    mini_mime (1.0.2)
+    mini_portile2 (2.4.0)
+    mini_racer (0.3.1)
+      libv8 (~> 8.4.255)
+    mini_scheduler (0.12.3)
+      sidekiq
+    mini_sql (0.3)
+    mini_suffix (0.3.0)
+      ffi (~> 1.9)
+    minitest (5.14.2)
+    mocha (1.11.2)
+    mock_redis (0.26.0)
+    msgpack (1.3.3)
+    multi_json (1.15.0)
+    multi_xml (0.6.0)
+    multipart-post (2.1.1)
+    mustache (1.1.1)
+    nio4r (2.5.4)
+    nokogiri (1.10.10)
+      mini_portile2 (~> 2.4.0)
+    nokogumbo (2.0.2)
+      nokogiri (~> 1.8, >= 1.8.4)
+    oauth (0.5.4)
+    oauth2 (1.4.4)
+      faraday (>= 0.8, < 2.0)
+      jwt (>= 1.0, < 3.0)
+      multi_json (~> 1.3)
+      multi_xml (~> 0.5)
+      rack (>= 1.2, < 3)
+    oj (3.10.16)
+    omniauth (1.9.1)
+      hashie (>= 3.4.6)
+      rack (>= 1.6.2, < 3)
+    omniauth-facebook (8.0.0)
+      omniauth-oauth2 (~> 1.2)
+    omniauth-github (1.4.0)
+      omniauth (~> 1.5)
+      omniauth-oauth2 (>= 1.4.0, < 2.0)
+    omniauth-google-oauth2 (0.8.0)
+      jwt (>= 2.0)
+      omniauth (>= 1.1.1)
+      omniauth-oauth2 (>= 1.6)
+    omniauth-oauth (1.1.0)
+      oauth
+      omniauth (~> 1.0)
+    omniauth-oauth2 (1.7.0)
+      oauth2 (~> 1.4)
+      omniauth (~> 1.9)
+    omniauth-twitter (1.4.0)
+      omniauth-oauth (~> 1.1)
+      rack
+    onebox (2.2.1)
+      addressable (~> 2.7.0)
+      htmlentities (~> 4.3)
+      multi_json (~> 1.11)
+      mustache
+      nokogiri (~> 1.7)
+      sanitize
+    openssl-signature_algorithm (1.0.0)
+    optimist (3.0.1)
+    parallel (1.20.1)
+    parallel_tests (3.4.0)
+      parallel
+    parser (2.7.2.0)
+      ast (~> 2.4.1)
+    pg (1.2.3)
+    progress (3.5.2)
+    pry (0.13.1)
+      coderay (~> 1.1)
+      method_source (~> 1.0)
+    pry-byebug (3.9.0)
+      byebug (~> 11.0)
+      pry (~> 0.13.0)
+    pry-rails (0.3.9)
+      pry (>= 0.10.4)
+    public_suffix (4.0.6)
+    puma (5.0.4)
+      nio4r (~> 2.0)
+    r2 (0.2.7)
+    rack (2.2.3)
+    rack-mini-profiler (2.2.0)
+      rack (>= 1.2.0)
+    rack-protection (2.1.0)
+      rack
+    rack-test (1.1.0)
+      rack (>= 1.0, < 3)
+    rails-dom-testing (2.0.3)
+      activesupport (>= 4.2.0)
+      nokogiri (>= 1.6)
+    rails-html-sanitizer (1.3.0)
+      loofah (~> 2.3)
+    rails_failover (0.6.2)
+      activerecord (~> 6.0)
+      concurrent-ruby
+      railties (~> 6.0)
+    rails_multisite (2.5.0)
+      activerecord (> 5.0, < 7)
+      railties (> 5.0, < 7)
+    railties (6.0.3.3)
+      actionpack (= 6.0.3.3)
+      activesupport (= 6.0.3.3)
+      method_source
+      rake (>= 0.8.7)
+      thor (>= 0.20.3, < 2.0)
+    rainbow (3.0.0)
+    raindrops (0.19.1)
+    rake (13.0.1)
+    rb-fsevent (0.10.4)
+    rb-inotify (0.10.1)
+      ffi (~> 1.0)
+    rbtrace (0.4.14)
+      ffi (>= 1.0.6)
+      msgpack (>= 0.4.3)
+      optimist (>= 3.0.0)
+    rchardet (1.8.0)
+    redis (4.2.5)
+    redis-namespace (1.8.0)
+      redis (>= 3.0.4)
+    regexp_parser (2.0.0)
+    request_store (1.5.0)
+      rack (>= 1.4)
+    rexml (3.2.4)
+    rinku (2.0.6)
+    rotp (6.2.0)
+    rqrcode (1.1.2)
+      chunky_png (~> 1.0)
+      rqrcode_core (~> 0.1)
+    rqrcode_core (0.1.2)
+    rspec (3.10.0)
+      rspec-core (~> 3.10.0)
+      rspec-expectations (~> 3.10.0)
+      rspec-mocks (~> 3.10.0)
+    rspec-core (3.10.0)
+      rspec-support (~> 3.10.0)
+    rspec-expectations (3.10.0)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.10.0)
+    rspec-html-matchers (0.9.4)
+      nokogiri (~> 1)
+      rspec (>= 3.0.0.a, < 4)
+    rspec-mocks (3.10.0)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.10.0)
+    rspec-rails (4.0.1)
+      actionpack (>= 4.2)
+      activesupport (>= 4.2)
+      railties (>= 4.2)
+      rspec-core (~> 3.9)
+      rspec-expectations (~> 3.9)
+      rspec-mocks (~> 3.9)
+      rspec-support (~> 3.9)
+    rspec-support (3.10.0)
+    rswag-specs (2.3.1)
+      activesupport (>= 3.1, < 7.0)
+      json-schema (~> 2.2)
+      railties (>= 3.1, < 7.0)
+    rtlit (0.0.5)
+    rubocop (1.4.2)
+      parallel (~> 1.10)
+      parser (>= 2.7.1.5)
+      rainbow (>= 2.2.2, < 4.0)
+      regexp_parser (>= 1.8)
+      rexml
+      rubocop-ast (>= 1.1.1)
+      ruby-progressbar (~> 1.7)
+      unicode-display_width (>= 1.4.0, < 2.0)
+    rubocop-ast (1.2.0)
+      parser (>= 2.7.1.5)
+    rubocop-discourse (2.4.1)
+      rubocop (>= 1.1.0)
+      rubocop-rspec (>= 2.0.0)
+    rubocop-rspec (2.0.0)
+      rubocop (~> 1.0)
+      rubocop-ast (>= 1.1.0)
+    ruby-prof (1.4.2)
+    ruby-progressbar (1.10.1)
+    ruby-readability (0.7.0)
+      guess_html_encoding (>= 0.0.4)
+      nokogiri (>= 1.6.0)
+    ruby2_keywords (0.0.2)
+    rubyzip (2.3.0)
+    sanitize (5.2.1)
+      crass (~> 1.0.2)
+      nokogiri (>= 1.8.0)
+      nokogumbo (~> 2.0)
+    sassc (2.0.1)
+      ffi (~> 1.9)
+      rake
+    sassc-rails (2.1.2)
+      railties (>= 4.0.0)
+      sassc (>= 2.0)
+      sprockets (> 3.0)
+      sprockets-rails
+      tilt
+    seed-fu (2.3.9)
+      activerecord (>= 3.1)
+      activesupport (>= 3.1)
+    shoulda-matchers (4.4.1)
+      activesupport (>= 4.2.0)
+    sidekiq (6.1.2)
+      connection_pool (>= 2.2.2)
+      rack (~> 2.0)
+      redis (>= 4.2.0)
+    simplecov (0.20.0)
+      docile (~> 1.1)
+      simplecov-html (~> 0.11)
+      simplecov_json_formatter (~> 0.1)
+    simplecov-html (0.12.3)
+    simplecov_json_formatter (0.1.2)
+    sprockets (3.7.2)
+      concurrent-ruby (~> 1.0)
+      rack (> 1, < 3)
+    sprockets-rails (3.2.2)
+      actionpack (>= 4.0)
+      activesupport (>= 4.0)
+      sprockets (>= 3.0.0)
+    sshkey (2.0.0)
+    stackprof (0.2.16)
+    test-prof (0.12.2)
+    thor (1.0.1)
+    thread_safe (0.3.6)
+    tilt (2.0.10)
+    tzinfo (1.2.8)
+      thread_safe (~> 0.1)
+    uglifier (4.2.0)
+      execjs (>= 0.3.0, < 3)
+    unf (0.1.4)
+      unf_ext
+    unf_ext (0.0.7.7)
+    unicode-display_width (1.7.0)
+    unicorn (5.7.0)
+      kgio (~> 2.6)
+      raindrops (~> 0.7)
+    uniform_notifier (1.13.0)
+    webmock (3.10.0)
+      addressable (>= 2.3.6)
+      crack (>= 0.3.2)
+      hashdiff (>= 0.4.0, < 2.0.0)
+    webpush (1.1.0)
+      hkdf (~> 0.2)
+      jwt (~> 2.0)
+    xorcist (1.1.2)
+    yaml-lint (0.0.10)
+    zeitwerk (2.4.1)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  actionmailer (= 6.0.3.3)
+  actionpack (= 6.0.3.3)
+  actionview (= 6.0.3.3)
+  actionview_precompiler
+  active_model_serializers (~> 0.8.3)
+  activemodel (= 6.0.3.3)
+  activerecord (= 6.0.3.3)
+  activesupport (= 6.0.3.3)
+  addressable
+  annotate
+  aws-sdk-s3
+  aws-sdk-sns
+  barber
+  better_errors
+  binding_of_caller
+  bootsnap
+  bullet
+  byebug
+  cbor
+  certified
+  colored2
+  cose
+  cppjieba_rb
+  css_parser
+  diffy
+  discourse-ember-rails (= 0.18.6)
+  discourse-ember-source (~> 3.12.2)
+  discourse-fonts
+  discourse_image_optim
+  email_reply_trimmer
+  ember-handlebars-template (= 0.8.0)
+  excon
+  execjs
+  fabrication
+  fakeweb
+  fast_blank
+  fast_xs
+  fastimage
+  flamegraph
+  gc_tracer
+  highline
+  htmlentities
+  http_accept_language
+  json
+  listen
+  lograge
+  logstash-event
+  logstash-logger
+  logster
+  lru_redux
+  lz4-ruby
+  mail
+  maxminddb
+  memory_profiler
+  message_bus
+  mini_mime
+  mini_racer
+  mini_scheduler
+  mini_sql
+  mini_suffix
+  minitest
+  mocha
+  mock_redis
+  multi_json
+  mustache
+  nokogiri
+  oj
+  omniauth
+  omniauth-facebook
+  omniauth-github
+  omniauth-google-oauth2
+  omniauth-oauth2
+  omniauth-twitter
+  onebox
+  parallel_tests
+  pg
+  pry-byebug
+  pry-rails
+  puma
+  r2
+  rack
+  rack-mini-profiler
+  rack-protection
+  rails_failover
+  rails_multisite
+  railties (= 6.0.3.3)
+  rake
+  rb-fsevent
+  rbtrace
+  rchardet
+  redis
+  redis-namespace
+  rinku
+  rotp
+  rqrcode
+  rspec
+  rspec-html-matchers
+  rspec-rails
+  rswag-specs
+  rtlit
+  rubocop-discourse
+  ruby-prof
+  ruby-readability
+  rubyzip
+  sassc (= 2.0.1)
+  sassc-rails
+  seed-fu
+  shoulda-matchers
+  sidekiq
+  simplecov
+  sprockets (= 3.7.2)
+  sprockets-rails
+  sshkey
+  stackprof
+  test-prof
+  thor
+  uglifier
+  unf
+  unicorn
+  webmock
+  webpush
+  xorcist
+  yaml-lint
+
+BUNDLED WITH
+   2.1.4
diff --git a/pkgs/servers/web-apps/discourse/rubyEnv/gemset.nix b/pkgs/servers/web-apps/discourse/rubyEnv/gemset.nix
new file mode 100644
index 00000000000..b2cf191a444
--- /dev/null
+++ b/pkgs/servers/web-apps/discourse/rubyEnv/gemset.nix
@@ -0,0 +1,2272 @@
+{
+  actionmailer = {
+    dependencies = ["actionpack" "actionview" "activejob" "mail" "rails-dom-testing"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1spq0dbfn0qkqg9sq0rsjn360b4j36zly8hawaivkrwr3rsvyz75";
+      type = "gem";
+    };
+    version = "6.0.3.3";
+  };
+  actionpack = {
+    dependencies = ["actionview" "activesupport" "rack" "rack-test" "rails-dom-testing" "rails-html-sanitizer"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1p873nqwmpsvmkb5n86d70wndx1qhy15pc9mbcd1mc8sj174578b";
+      type = "gem";
+    };
+    version = "6.0.3.3";
+  };
+  actionview = {
+    dependencies = ["activesupport" "builder" "erubi" "rails-dom-testing" "rails-html-sanitizer"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "08pvmjddlw01q5r9zdfgddwp4csndpf5i2w47677z5r36jznz36q";
+      type = "gem";
+    };
+    version = "6.0.3.3";
+  };
+  actionview_precompiler = {
+    dependencies = ["actionview"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "07dx8vkwig8han4zccs0chahcf9ibd4abzx9n56qah8zak5cyrhd";
+      type = "gem";
+    };
+    version = "0.2.3";
+  };
+  active_model_serializers = {
+    dependencies = ["activemodel"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0k3mgia2ahh7mbk30hjq9pzqbk0kh281s91kq2z6p555nv9y6l3k";
+      type = "gem";
+    };
+    version = "0.8.4";
+  };
+  activejob = {
+    dependencies = ["activesupport" "globalid"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0w54ckvc229iaax879hkhyc93j7z8p0v7acp6mk3h8xjfvmwy5jp";
+      type = "gem";
+    };
+    version = "6.0.3.3";
+  };
+  activemodel = {
+    dependencies = ["activesupport"];
+    groups = ["default" "development"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "166jlx6kbby01vr37srh081a9fykgsz873yg5i9gl2ar3vw9gs56";
+      type = "gem";
+    };
+    version = "6.0.3.3";
+  };
+  activerecord = {
+    dependencies = ["activemodel" "activesupport"];
+    groups = ["default" "development"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0y2a4ss6ld6yrhpcbcb3kjn5gj6zk9qklp2aq5rl1awl8vbdbdb7";
+      type = "gem";
+    };
+    version = "6.0.3.3";
+  };
+  activesupport = {
+    dependencies = ["concurrent-ruby" "i18n" "minitest" "tzinfo" "zeitwerk"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1dmkqbvndbz011a1byg6f990936vfadbnwjwjw9vjzr4kd8bxk96";
+      type = "gem";
+    };
+    version = "6.0.3.3";
+  };
+  addressable = {
+    dependencies = ["public_suffix"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1fvchp2rhp2rmigx7qglf69xvjqvzq7x0g49naliw29r2bz656sy";
+      type = "gem";
+    };
+    version = "2.7.0";
+  };
+  annotate = {
+    dependencies = ["activerecord" "rake"];
+    groups = ["development"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1dxrfppwfg13vqmambbs56xjj8qsdgcy58r2yc44vvy3z1g5yflw";
+      type = "gem";
+    };
+    version = "3.1.1";
+  };
+  ast = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1l3468czzjmxl93ap40hp7z94yxp4nbag0bxqs789bm30md90m2a";
+      type = "gem";
+    };
+    version = "2.4.1";
+  };
+  aws-eventstream = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0r0pn66yqrdkrfdin7qdim0yj2x75miyg4wp6mijckhzhrjb7cv5";
+      type = "gem";
+    };
+    version = "1.1.0";
+  };
+  aws-partitions = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "17xranmng1mg6238zdmnfvaig82r2ymp2apra9yh5d8rhvn8hkwm";
+      type = "gem";
+    };
+    version = "1.390.0";
+  };
+  aws-sdk-core = {
+    dependencies = ["aws-eventstream" "aws-partitions" "aws-sigv4" "jmespath"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "05dq7jfv5qf1y00ib96nqsipf08hflw8n8fwkyjw4qav84wjqaq4";
+      type = "gem";
+    };
+    version = "3.109.2";
+  };
+  aws-sdk-kms = {
+    dependencies = ["aws-sdk-core" "aws-sigv4"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0ly1m631qm2ciif7sysbzrgczjvz95ga3g6w6vrzvfdv31jjnl9a";
+      type = "gem";
+    };
+    version = "1.39.0";
+  };
+  aws-sdk-s3 = {
+    dependencies = ["aws-sdk-core" "aws-sdk-kms" "aws-sigv4"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1mld0yh6q6i2nbb143g5xc6gm70sqpvpwxfknlihrd8jmw3xc0bs";
+      type = "gem";
+    };
+    version = "1.83.2";
+  };
+  aws-sdk-sns = {
+    dependencies = ["aws-sdk-core" "aws-sigv4"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1dw80ldqhb1mny5irgi2jh36hykcmyd07xalv21xncxqzmf8aiag";
+      type = "gem";
+    };
+    version = "1.35.0";
+  };
+  aws-sigv4 = {
+    dependencies = ["aws-eventstream"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1ll9382c1x2hp750cilh01h1cycgyhdr4cmmgx23k94hyyb8chv5";
+      type = "gem";
+    };
+    version = "1.2.2";
+  };
+  barber = {
+    dependencies = ["ember-source" "execjs"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "07rnlbh7kgamcbnl1sqlcdrjj8src4qc687klqq4a3vqq2slnscx";
+      type = "gem";
+    };
+    version = "0.12.2";
+  };
+  better_errors = {
+    dependencies = ["coderay" "erubi" "rack"];
+    groups = ["development"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "11220lfzhsyf5fcril3qd689kgg46qlpiiaj00hc9mh4mcbc3vrr";
+      type = "gem";
+    };
+    version = "2.9.1";
+  };
+  binding_of_caller = {
+    dependencies = ["debug_inspector"];
+    groups = ["development"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "05syqlks7463zsy1jdfbbdravdhj9hpj5pv2m74blqpv8bq4vv5g";
+      type = "gem";
+    };
+    version = "0.8.0";
+  };
+  bootsnap = {
+    dependencies = ["msgpack"];
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1qx1f729bgh391agsqb4ngzn22wdn4cc6mkp0cipf0d5hsg9cpaq";
+      type = "gem";
+    };
+    version = "1.5.1";
+  };
+  builder = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "045wzckxpwcqzrjr353cxnyaxgf0qg22jh00dcx7z38cys5g1jlr";
+      type = "gem";
+    };
+    version = "3.2.4";
+  };
+  bullet = {
+    dependencies = ["activesupport" "uniform_notifier"];
+    groups = ["development"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "18ifwnvn13755qkfigapyj5bflpby3phxzbb7x5336d0kzv5k7d9";
+      type = "gem";
+    };
+    version = "6.1.0";
+  };
+  byebug = {
+    groups = ["development" "test"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0nx3yjf4xzdgb8jkmk2344081gqr22pgjqnmjg2q64mj5d6r9194";
+      type = "gem";
+    };
+    version = "11.1.3";
+  };
+  cbor = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0511idr8xps9625nh3kxr68sdy6l3xy2kcz7r57g47fxb1v18jj3";
+      type = "gem";
+    };
+    version = "0.5.9.6";
+  };
+  certified = {
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1706p6p0a8adyvd943af2a3093xakvislgffw3v9dvp7j07dyk5a";
+      type = "gem";
+    };
+    version = "1.0.0";
+  };
+  chunky_png = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1v52ndgx9r4jybq8yzr8anzfbnjk4y2hvz97nm9924wi4bad3xkf";
+      type = "gem";
+    };
+    version = "1.3.14";
+  };
+  coderay = {
+    groups = ["default" "development"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0jvxqxzply1lwp7ysn94zjhh57vc14mcshw1ygw14ib8lhc00lyw";
+      type = "gem";
+    };
+    version = "1.1.3";
+  };
+  colored2 = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0jlbqa9q4mvrm73aw9mxh23ygzbjiqwisl32d8szfb5fxvbjng5i";
+      type = "gem";
+    };
+    version = "3.1.2";
+  };
+  concurrent-ruby = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1vnxrbhi7cq3p4y2v9iwd10v1c7l15is4var14hwnb2jip4fyjzz";
+      type = "gem";
+    };
+    version = "1.1.7";
+  };
+  connection_pool = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1qikl4av1z8kqnk5ba18136dpqzw8wjawc2w9b4zb5psdd5z8nwf";
+      type = "gem";
+    };
+    version = "2.2.3";
+  };
+  cose = {
+    dependencies = ["cbor" "openssl-signature_algorithm"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1gx239d2fracq9az74wfdwmp5zm7zpzkcgchwnv2ng33d8r33p3m";
+      type = "gem";
+    };
+    version = "1.2.0";
+  };
+  cppjieba_rb = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1sslff7yy8jvp4rcn1b6jn9v0d3iibb68i79shgd94rs2yq8k117";
+      type = "gem";
+    };
+    version = "0.3.3";
+  };
+  crack = {
+    groups = ["default" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1awi8jy4jn0f7vxpdvz3xvn1zzjbjh33n28lfkijh77dla5zb7lc";
+      type = "gem";
+    };
+    version = "0.4.4";
+  };
+  crass = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0pfl5c0pyqaparxaqxi6s4gfl21bdldwiawrc0aknyvflli60lfw";
+      type = "gem";
+    };
+    version = "1.0.6";
+  };
+  css_parser = {
+    dependencies = ["addressable"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "04c4dl8cm5rjr50k9qa6yl9r05fk9zcb1zxh0y0cdahxlsgcydfw";
+      type = "gem";
+    };
+    version = "1.7.1";
+  };
+  debug_inspector = {
+    groups = ["default" "development"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0vxr0xa1mfbkfcrn71n7c4f2dj7la5hvphn904vh20j3x4j5lrx0";
+      type = "gem";
+    };
+    version = "0.0.3";
+  };
+  diff-lcs = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0m925b8xc6kbpnif9dldna24q1szg4mk0fvszrki837pfn46afmz";
+      type = "gem";
+    };
+    version = "1.4.4";
+  };
+  diffy = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0nrg7kpgz6cn1gv2saj2fa5sfiykamvd7vn9lw2v625k7pjwf31l";
+      type = "gem";
+    };
+    version = "3.4.0";
+  };
+  discourse-ember-rails = {
+    dependencies = ["active_model_serializers" "ember-data-source" "ember-handlebars-template" "ember-source" "jquery-rails" "railties"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0ax5x2d6q6hkm7r58ai9p0sahlg842aqlm7dpv6svrfpnjlaz7sf";
+      type = "gem";
+    };
+    version = "0.18.6";
+  };
+  discourse-ember-source = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0mqkwiqb5n64lc5jdjnmpgb9apq08ywkz9yk8mj1sx2lqcsw11pc";
+      type = "gem";
+    };
+    version = "3.12.2.2";
+  };
+  discourse-fonts = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0xhwgqclh3jncjr55m0hyq3w3iw8jw2r7ickzq1zn1282pc3n2i7";
+      type = "gem";
+    };
+    version = "0.0.5";
+  };
+  discourse_image_optim = {
+    dependencies = ["exifr" "fspath" "image_size" "in_threads" "progress"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "11nqmga5ygxyhjmsc07gsa0fwwyhdpwi20yyr4fnh263xs1xylvv";
+      type = "gem";
+    };
+    version = "0.26.2";
+  };
+  docile = {
+    groups = ["default" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0qrwiyagxzl8zlx3dafb0ay8l14ib7imb2rsmx70i5cp420v8gif";
+      type = "gem";
+    };
+    version = "1.3.2";
+  };
+  email_reply_trimmer = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1jgcxifm48xq5dz9k47q43pqm5bfnf14l62l3bqhmv8f6z8dw4ki";
+      type = "gem";
+    };
+    version = "0.1.13";
+  };
+  ember-data-source = {
+    dependencies = ["ember-source"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1803nh3knvwl12h63jd48qvbbrp42yy291wcb35960daklip0fd8";
+      type = "gem";
+    };
+    version = "3.0.2";
+  };
+  ember-handlebars-template = {
+    dependencies = ["barber" "sprockets"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1wxj3vi4xs3vjxrdbzi4j4w6vv45r5dkz2rg2ldid3p8dp3irlf4";
+      type = "gem";
+    };
+    version = "0.8.0";
+  };
+  ember-source = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0sixy30ym9j2slhlr0lfq943g958w8arlb0lsizh59iv1w5gmxxy";
+      type = "gem";
+    };
+    version = "2.18.2";
+  };
+  erubi = {
+    groups = ["default" "development" "test"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "09l8lz3j00m898li0yfsnb6ihc63rdvhw3k5xczna5zrjk104f2l";
+      type = "gem";
+    };
+    version = "1.10.0";
+  };
+  excon = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1hi89v53pm2abfv9j8lgqdd7hgkr7fr0gwrczr940iwbb3xv7rrs";
+      type = "gem";
+    };
+    version = "0.78.0";
+  };
+  execjs = {
+    groups = ["assets" "default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1yz55sf2nd3l666ms6xr18sm2aggcvmb8qr3v53lr4rir32y1yp1";
+      type = "gem";
+    };
+    version = "2.7.0";
+  };
+  exifr = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0mylhwmh6n4xihxr9s3zj0lc286f5maxbqd4dgk3paqnd7afz88s";
+      type = "gem";
+    };
+    version = "1.3.9";
+  };
+  fabrication = {
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1pdrl55xf76pbc5kjzp7diawxxvgbk2cm38532in6df823431n6z";
+      type = "gem";
+    };
+    version = "2.21.1";
+  };
+  fakeweb = {
+    groups = ["test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1a09z9nb369bvwpghncgd5y4f95lh28w0q258srh02h22fz9dj8y";
+      type = "gem";
+    };
+    version = "1.3.0";
+  };
+  faraday = {
+    dependencies = ["multipart-post" "ruby2_keywords"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "16dapwi5pivrl25r4lkr1mxjrzkznj4wlcb08fzkmxnj4g5c6y35";
+      type = "gem";
+    };
+    version = "1.1.0";
+  };
+  fast_blank = {
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "rbx";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "16s1ilyvwzmkcgmklbrn0c2pch5n02vf921njx0bld4crgdr6z56";
+      type = "gem";
+    };
+    version = "1.0.0";
+  };
+  fast_xs = {
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "rbx";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1iydzaqmvqq7ncxkr182aybkk6xap0cb2w9amr73vbdxi2qf3wjz";
+      type = "gem";
+    };
+    version = "0.8.0";
+  };
+  fastimage = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "11ny2pj0j6pljszrf1w3iqdv2pcl2iwwghjbgcjlizy424zbh0hb";
+      type = "gem";
+    };
+    version = "2.2.0";
+  };
+  ffi = {
+    groups = ["default" "development" "test"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "12lpwaw82bb0rm9f52v1498bpba8aj2l2q359mkwbxsswhpga5af";
+      type = "gem";
+    };
+    version = "1.13.1";
+  };
+  flamegraph = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1p785nmhdzbwj0qpxn5fzrmr4kgimcds83v4f95f387z6w3050x6";
+      type = "gem";
+    };
+    version = "0.9.5";
+  };
+  fspath = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0xcxikkrjv8ws328nn5ax5pyfjs8pn7djg1hks7qyb3yp6prpb5m";
+      type = "gem";
+    };
+    version = "3.1.2";
+  };
+  gc_tracer = {
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1yv3mp8lx74lfzs04fd5h4g89209iwhzpc407y35p7cmzgx6a4kv";
+      type = "gem";
+    };
+    version = "1.5.1";
+  };
+  globalid = {
+    dependencies = ["activesupport"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1zkxndvck72bfw235bd9nl2ii0lvs5z88q14706cmn702ww2mxv1";
+      type = "gem";
+    };
+    version = "0.4.2";
+  };
+  guess_html_encoding = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "16700fk6kmif3q3kpc1ldhy3nsc9pkxlgl8sqhznff2zjj5lddna";
+      type = "gem";
+    };
+    version = "0.0.11";
+  };
+  hashdiff = {
+    groups = ["default" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1nynpl0xbj0nphqx1qlmyggq58ms1phf5i03hk64wcc0a17x1m1c";
+      type = "gem";
+    };
+    version = "1.0.1";
+  };
+  hashie = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "02bsx12ihl78x0vdm37byp78jjw2ff6035y7rrmbd90qxjwxr43q";
+      type = "gem";
+    };
+    version = "4.1.0";
+  };
+  highline = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0yclf57n2j3cw8144ania99h1zinf8q3f5zrhqa754j6gl95rp9d";
+      type = "gem";
+    };
+    version = "2.0.3";
+  };
+  hkdf = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "04fixg0a51n4vy0j6c1hvisa2yl33m3jrrpxpb5sq6j511vjriil";
+      type = "gem";
+    };
+    version = "0.3.0";
+  };
+  htmlentities = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1nkklqsn8ir8wizzlakncfv42i32wc0w9hxp00hvdlgjr7376nhj";
+      type = "gem";
+    };
+    version = "4.3.4";
+  };
+  http_accept_language = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0d0nlfz9vm4jr1l6q0chx4rp2hrnrfbx3gadc1dz930lbbaz0hq0";
+      type = "gem";
+    };
+    version = "2.1.1";
+  };
+  i18n = {
+    dependencies = ["concurrent-ruby"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "153sx77p16vawrs4qpkv7qlzf9v5fks4g7xqcj1dwk40i6g7rfzk";
+      type = "gem";
+    };
+    version = "1.8.5";
+  };
+  image_size = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0zrn2mqaf1kk548wn1y35i1a6kwh3320q62m929kn9m8sqpy4fk7";
+      type = "gem";
+    };
+    version = "1.5.0";
+  };
+  in_threads = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0m71806p1gm4kxiz4gvkyr8qip16hifn2kdf926jz44jj6kc6bbs";
+      type = "gem";
+    };
+    version = "1.5.4";
+  };
+  jmespath = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1d4wac0dcd1jf6kc57891glih9w57552zgqswgy74d1xhgnk0ngf";
+      type = "gem";
+    };
+    version = "1.4.0";
+  };
+  jquery-rails = {
+    dependencies = ["rails-dom-testing" "railties" "thor"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0dkhm8lan1vnyl3ll0ks2q06576pdils8a1dr354vfc1y5dqw15i";
+      type = "gem";
+    };
+    version = "4.4.0";
+  };
+  json = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "158fawfwmv2sq4whqqaksfykkiad2xxrrj0nmpnc6vnlzi1bp7iz";
+      type = "gem";
+    };
+    version = "2.3.1";
+  };
+  json-schema = {
+    dependencies = ["addressable"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1yv5lfmr2nzd14af498xqd5p89f3g080q8wk0klr3vxgypsikkb5";
+      type = "gem";
+    };
+    version = "2.8.1";
+  };
+  jwt = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "14ynyq1q483spj20ffl4xayfqx1a8qr761mqjfxczf8lwlap392n";
+      type = "gem";
+    };
+    version = "2.2.2";
+  };
+  kgio = {
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "rbx";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0ai6bzlvxbzpdl466p1qi4dlhx8ri2wcrp6x1l19y3yfs3a29rng";
+      type = "gem";
+    };
+    version = "2.11.3";
+  };
+  libv8 = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0317sr3nrl51sp844bps71smkrwim3fjn47wdfpbycixnbxspivm";
+      type = "gem";
+    };
+    version = "8.4.255.0";
+  };
+  listen = {
+    dependencies = ["rb-fsevent" "rb-inotify"];
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0028p1fss6pvw4mlpjqdmxfzsm8ww79irsadbibrr7f23qfn8ykr";
+      type = "gem";
+    };
+    version = "3.3.1";
+  };
+  lograge = {
+    dependencies = ["actionpack" "activesupport" "railties" "request_store"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1vrjm4yqn5l6q5gsl72fmk95fl6j9z1a05gzbrwmsm3gp1a1bgac";
+      type = "gem";
+    };
+    version = "0.11.2";
+  };
+  logstash-event = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1bk7fhhryjxp1klr3hq6i6srrc21wl4p980bysjp0w66z9hdr9w9";
+      type = "gem";
+    };
+    version = "1.2.02";
+  };
+  logstash-logger = {
+    dependencies = ["logstash-event"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1nh0jgz4rl46axqb9l0fa866kh34wb7yf11qc3j30xhprdqb8yjp";
+      type = "gem";
+    };
+    version = "0.26.1";
+  };
+  logster = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1ldikj3p0bakxg57didaw05pldjn0i5r20zawhqa34knlsqm66r6";
+      type = "gem";
+    };
+    version = "2.9.4";
+  };
+  loofah = {
+    dependencies = ["crass" "nokogiri"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0ndimir6k3kfrh8qrb7ir1j836l4r3qlwyclwjh88b86clblhszh";
+      type = "gem";
+    };
+    version = "2.8.0";
+  };
+  lru_redux = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1yxghzg7476sivz8yyr9nkak2dlbls0b89vc2kg52k0nmg6d0wgf";
+      type = "gem";
+    };
+    version = "1.1.0";
+  };
+  lz4-ruby = {
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "rbx";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "12fymsvcb9kw6ycyfzc8b9svriq0afqf1qnl121xrz8c4gpfa6q1";
+      type = "gem";
+    };
+    version = "0.3.3";
+  };
+  mail = {
+    dependencies = ["mini_mime"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "00wwz6ys0502dpk8xprwcqfwyf3hmnx6lgxaiq6vj43mkx43sapc";
+      type = "gem";
+    };
+    version = "2.7.1";
+  };
+  maxminddb = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0zlhqilyggiryywgswfi624bv10qnkm66hggmg79vvgv73j3p4sh";
+      type = "gem";
+    };
+    version = "0.1.22";
+  };
+  memory_profiler = {
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "04ivhv1bilwqm33jv28gar2vwzsichb5nipaq395d3axabv8qmfy";
+      type = "gem";
+    };
+    version = "0.9.14";
+  };
+  message_bus = {
+    dependencies = ["rack"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0hckijk9aa628nx66vr7axfsk7zfdkskaxj1mdzikk019q3h54fr";
+      type = "gem";
+    };
+    version = "3.3.4";
+  };
+  method_source = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1pnyh44qycnf9mzi1j6fywd5fkskv3x7nmsqrrws0rjn5dd4ayfp";
+      type = "gem";
+    };
+    version = "1.0.0";
+  };
+  mini_mime = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1axm0rxyx3ss93wbmfkm78a6x03l8y4qy60rhkkiq0aza0vwq3ha";
+      type = "gem";
+    };
+    version = "1.0.2";
+  };
+  mini_portile2 = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "15zplpfw3knqifj9bpf604rb3wc1vhq6363pd6lvhayng8wql5vy";
+      type = "gem";
+    };
+    version = "2.4.0";
+  };
+  mini_racer = {
+    dependencies = ["libv8"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0r7j241mvhyyc017bqgp0pvf3jyrwbcqvz2pzm0r8zn2r85ks1jl";
+      type = "gem";
+    };
+    version = "0.3.1";
+  };
+  mini_scheduler = {
+    dependencies = ["sidekiq"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0vigv7f1q5bkcb55ab2lyhq15yqfkg5mq61p7m7mw9b3jac7qjz1";
+      type = "gem";
+    };
+    version = "0.12.3";
+  };
+  mini_sql = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0qi4bj5jkh3673ybsxvsf7y485znyxb72vxg84gk9x65mf0y0m6h";
+      type = "gem";
+    };
+    version = "0.3";
+  };
+  mini_suffix = {
+    dependencies = ["ffi"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0bxd1fgzb20gvfvhbkrxym9fr7skm5x6fzvqfg4a0jijb34ww50h";
+      type = "gem";
+    };
+    version = "0.3.0";
+  };
+  minitest = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "170y2cvx51gm3cm3nhdf7j36sxnkh6vv8ls36p90ric7w8w16h4v";
+      type = "gem";
+    };
+    version = "5.14.2";
+  };
+  mocha = {
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0hxmkm8qxd04vwj8mqnpyrf2dwy7g1k9zipdfhl4y71cw7ijm9n4";
+      type = "gem";
+    };
+    version = "1.11.2";
+  };
+  mock_redis = {
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "06yj6j9x4zjckah4ixiwhy3hb6xzjp7yk7lmmcvcb8hpd0z0x95q";
+      type = "gem";
+    };
+    version = "0.26.0";
+  };
+  msgpack = {
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1lva6bkvb4mfa0m3bqn4lm4s4gi81c40jvdcsrxr6vng49q9daih";
+      type = "gem";
+    };
+    version = "1.3.3";
+  };
+  multi_json = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0pb1g1y3dsiahavspyzkdy39j4q377009f6ix0bh1ag4nqw43l0z";
+      type = "gem";
+    };
+    version = "1.15.0";
+  };
+  multi_xml = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0lmd4f401mvravi1i1yq7b2qjjli0yq7dfc4p1nj5nwajp7r6hyj";
+      type = "gem";
+    };
+    version = "0.6.0";
+  };
+  multipart-post = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1zgw9zlwh2a6i1yvhhc4a84ry1hv824d6g2iw2chs3k5aylpmpfj";
+      type = "gem";
+    };
+    version = "2.1.1";
+  };
+  mustache = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1l0p4wx15mi3wnamfv92ipkia4nsx8qi132c6g51jfdma3fiz2ch";
+      type = "gem";
+    };
+    version = "1.1.1";
+  };
+  nio4r = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1cbwp1kbv6b2qfxv8sarv0d0ilb257jihlvdqj8f5pdm0ksq1sgk";
+      type = "gem";
+    };
+    version = "2.5.4";
+  };
+  nokogiri = {
+    dependencies = ["mini_portile2"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0xmf60nj5kg9vaj5bysy308687sgmkasgx06vbbnf94p52ih7si2";
+      type = "gem";
+    };
+    version = "1.10.10";
+  };
+  nokogumbo = {
+    dependencies = ["nokogiri"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0sxjnpjvrn10gdmfw2dimhch861lz00f28hvkkz0b1gc2rb65k9s";
+      type = "gem";
+    };
+    version = "2.0.2";
+  };
+  oauth = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1zszdg8q1b135z7l7crjj234k4j0m347hywp5kj6zsq7q78pw09y";
+      type = "gem";
+    };
+    version = "0.5.4";
+  };
+  oauth2 = {
+    dependencies = ["faraday" "jwt" "multi_json" "multi_xml" "rack"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1bhakjh30vi8scqwnhd1c9qkac9r8hh2lr0dbs5ynwmrc5djxknm";
+      type = "gem";
+    };
+    version = "1.4.4";
+  };
+  oj = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1xqmzqldi9a0wpilwx87yh61xd7647gg8ffammg4ava0bsx375g2";
+      type = "gem";
+    };
+    version = "3.10.16";
+  };
+  omniauth = {
+    dependencies = ["hashie" "rack"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "002vi9gwamkmhf0dsj2im1d47xw2n1jfhnzl18shxf3ampkqfmyz";
+      type = "gem";
+    };
+    version = "1.9.1";
+  };
+  omniauth-facebook = {
+    dependencies = ["omniauth-oauth2"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1z0f5sr2ddnvfva0jrfd4926nlv4528rfj7z595288n39304r092";
+      type = "gem";
+    };
+    version = "8.0.0";
+  };
+  omniauth-github = {
+    dependencies = ["omniauth" "omniauth-oauth2"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0xbk0dbxqfpyfb33ghz6vrlz3m6442rp18ryf13gwzlnifcawhlb";
+      type = "gem";
+    };
+    version = "1.4.0";
+  };
+  omniauth-google-oauth2 = {
+    dependencies = ["jwt" "omniauth" "omniauth-oauth2"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "17pgqasl048irs2c6w6g57zvk0ygb5ml1krwir4qi4b6y53zyr55";
+      type = "gem";
+    };
+    version = "0.8.0";
+  };
+  omniauth-oauth = {
+    dependencies = ["oauth" "omniauth"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1n5vk4by7hkyc09d9blrw2argry5awpw4gbw1l4n2s9b3j4qz037";
+      type = "gem";
+    };
+    version = "1.1.0";
+  };
+  omniauth-oauth2 = {
+    dependencies = ["oauth2" "omniauth"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0v6rw7sd223k7qw0l13wikgfcqbvbk81r53a9i2z0k7jl5vd97w5";
+      type = "gem";
+    };
+    version = "1.7.0";
+  };
+  omniauth-twitter = {
+    dependencies = ["omniauth-oauth" "rack"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0r5j65hkpgzhvvbs90id3nfsjgsad6ymzggbm7zlaxvnrmvnrk65";
+      type = "gem";
+    };
+    version = "1.4.0";
+  };
+  onebox = {
+    dependencies = ["addressable" "htmlentities" "multi_json" "mustache" "nokogiri" "sanitize"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0b2aih0d5cva9bris36gh1mk3ym61wgxlpwvzjd6qphdrjfzqx8v";
+      type = "gem";
+    };
+    version = "2.2.1";
+  };
+  openssl-signature_algorithm = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0h1pfx49j8d9vbdbi8jyj0mr63l7rhflgvgc0nhfygm1v77d7nkn";
+      type = "gem";
+    };
+    version = "1.0.0";
+  };
+  optimist = {
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1vg2chy1cfmdj6c1gryl8zvjhhmb3plwgyh1jfnpq4fnfqv7asrk";
+      type = "gem";
+    };
+    version = "3.0.1";
+  };
+  parallel = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0055br0mibnqz0j8wvy20zry548dhkakws681bhj3ycb972awkzd";
+      type = "gem";
+    };
+    version = "1.20.1";
+  };
+  parallel_tests = {
+    dependencies = ["parallel"];
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1mvdk8vgzqjv2pvadxwc8w2vf8dmiw145rjf47c36nn6l5hh02j6";
+      type = "gem";
+    };
+    version = "3.4.0";
+  };
+  parser = {
+    dependencies = ["ast"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1f7gmm60yla325wlnd3qkxs59qm2y0aan8ljpg6k18rwzrrfil6z";
+      type = "gem";
+    };
+    version = "2.7.2.0";
+  };
+  pg = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "13mfrysrdrh8cka1d96zm0lnfs59i5x2g6ps49r2kz5p3q81xrzj";
+      type = "gem";
+    };
+    version = "1.2.3";
+  };
+  progress = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1pm3bv5n8c8j0vfm7wghd7xf6yq4m068cksxjldmna11qi0h0s8s";
+      type = "gem";
+    };
+    version = "3.5.2";
+  };
+  pry = {
+    dependencies = ["coderay" "method_source"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0iyw4q4an2wmk8v5rn2ghfy2jaz9vmw2nk8415nnpx2s866934qk";
+      type = "gem";
+    };
+    version = "0.13.1";
+  };
+  pry-byebug = {
+    dependencies = ["byebug" "pry"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "096y5vmzpyy4x9h4ky4cs4y7d19vdq9vbwwrqafbh5gagzwhifiv";
+      type = "gem";
+    };
+    version = "3.9.0";
+  };
+  pry-rails = {
+    dependencies = ["pry"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1cf4ii53w2hdh7fn8vhqpzkymmchjbwij4l3m7s6fsxvb9bn51j6";
+      type = "gem";
+    };
+    version = "0.3.9";
+  };
+  public_suffix = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1xqcgkl7bwws1qrlnmxgh8g4g9m10vg60bhlw40fplninb3ng6d9";
+      type = "gem";
+    };
+    version = "4.0.6";
+  };
+  puma = {
+    dependencies = ["nio4r"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0mkmfbf4qyiknwi9bb5432cpbbz06r855gknxb8grn24gmgs4d9i";
+      type = "gem";
+    };
+    version = "5.0.4";
+  };
+  r2 = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0wk0p55zp3l96xy5ps28b33dn5z0jwsjl74bwfdn6z81pzjs5sfk";
+      type = "gem";
+    };
+    version = "0.2.7";
+  };
+  rack = {
+    groups = ["default" "development" "test"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0i5vs0dph9i5jn8dfc6aqd6njcafmb20rwqngrf759c9cvmyff16";
+      type = "gem";
+    };
+    version = "2.2.3";
+  };
+  rack-mini-profiler = {
+    dependencies = ["rack"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "05s7y56ayn56bn7y5ah3krm5d53vsj7apmcxlwc2qp7ik0xlypvq";
+      type = "gem";
+    };
+    version = "2.2.0";
+  };
+  rack-protection = {
+    dependencies = ["rack"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "159a4j4kragqh0z0z8vrpilpmaisnlz3n7kgiyf16bxkwlb3qlhz";
+      type = "gem";
+    };
+    version = "2.1.0";
+  };
+  rack-test = {
+    dependencies = ["rack"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0rh8h376mx71ci5yklnpqqn118z3bl67nnv5k801qaqn1zs62h8m";
+      type = "gem";
+    };
+    version = "1.1.0";
+  };
+  rails-dom-testing = {
+    dependencies = ["activesupport" "nokogiri"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1lfq2a7kp2x64dzzi5p4cjcbiv62vxh9lyqk2f0rqq3fkzrw8h5i";
+      type = "gem";
+    };
+    version = "2.0.3";
+  };
+  rails-html-sanitizer = {
+    dependencies = ["loofah"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1icpqmxbppl4ynzmn6dx7wdil5hhq6fz707m9ya6d86c7ys8sd4f";
+      type = "gem";
+    };
+    version = "1.3.0";
+  };
+  rails_failover = {
+    dependencies = ["activerecord" "concurrent-ruby" "railties"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0ibxn7lk6rqk7q76cd9ir3xnh19p2pqr9mzam46n3h37f12yyax5";
+      type = "gem";
+    };
+    version = "0.6.2";
+  };
+  rails_multisite = {
+    dependencies = ["activerecord" "railties"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0p7g9gkcmw030zfqlw3k933i40j31wf3jh4bj1niihzk7slha97y";
+      type = "gem";
+    };
+    version = "2.5.0";
+  };
+  railties = {
+    dependencies = ["actionpack" "activesupport" "method_source" "rake" "thor"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "05b79r0ms8jrs91zml1190qfxmnmks90g0sd820ks9msyr8xdp7j";
+      type = "gem";
+    };
+    version = "6.0.3.3";
+  };
+  rainbow = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0bb2fpjspydr6x0s8pn1pqkzmxszvkfapv0p4627mywl7ky4zkhk";
+      type = "gem";
+    };
+    version = "3.0.0";
+  };
+  raindrops = {
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "rbx";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0zjja00mzgx2lddb7qrn14k7qrnwhf4bpmnlqj78m1pfxh7svync";
+      type = "gem";
+    };
+    version = "0.19.1";
+  };
+  rake = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0w6qza25bq1s825faaglkx1k6d59aiyjjk3yw3ip5sb463mhhai9";
+      type = "gem";
+    };
+    version = "13.0.1";
+  };
+  rb-fsevent = {
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1k9bsj7ni0g2fd7scyyy1sk9dy2pg9akniahab0iznvjmhn54h87";
+      type = "gem";
+    };
+    version = "0.10.4";
+  };
+  rb-inotify = {
+    dependencies = ["ffi"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1jm76h8f8hji38z3ggf4bzi8vps6p7sagxn3ab57qc0xyga64005";
+      type = "gem";
+    };
+    version = "0.10.1";
+  };
+  rbtrace = {
+    dependencies = ["ffi" "msgpack" "optimist"];
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0s8prj0klfgpmpfcpdzbf149qrrsdxgnb6w6kkqc9gyars4vyaqn";
+      type = "gem";
+    };
+    version = "0.4.14";
+  };
+  rchardet = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1isj1b3ywgg2m1vdlnr41lpvpm3dbyarf1lla4dfibfmad9csfk9";
+      type = "gem";
+    };
+    version = "1.8.0";
+  };
+  redis = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "15x2sr6h094rjbvg8pkq6m3lcd5abpyx93aifvfdz3wv6x55xa48";
+      type = "gem";
+    };
+    version = "4.2.5";
+  };
+  redis-namespace = {
+    dependencies = ["redis"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "05i6s898z5w31z385cba1683pgg5nnmj4m686cbravg7j4pgbcgv";
+      type = "gem";
+    };
+    version = "1.8.0";
+  };
+  regexp_parser = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1racz3w9s4w0ls32bvjypfifk4a7qxngm2cv1rh16jyz0c1wjd70";
+      type = "gem";
+    };
+    version = "2.0.0";
+  };
+  request_store = {
+    dependencies = ["rack"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0cx74kispmnw3ljwb239j65a2j14n8jlsygy372hrsa8mxc71hxi";
+      type = "gem";
+    };
+    version = "1.5.0";
+  };
+  rexml = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1mkvkcw9fhpaizrhca0pdgjcrbns48rlz4g6lavl5gjjq3rk2sq3";
+      type = "gem";
+    };
+    version = "3.2.4";
+  };
+  rinku = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0zcdha17s1wzxyc5814j6319wqg33jbn58pg6wmxpws36476fq4b";
+      type = "gem";
+    };
+    version = "2.0.6";
+  };
+  rotp = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "11q7rkjx40yi6lpylgl2jkpy162mjw7mswrcgcax86vgpbpjx6i3";
+      type = "gem";
+    };
+    version = "6.2.0";
+  };
+  rqrcode = {
+    dependencies = ["chunky_png" "rqrcode_core"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "06lw8b6wfshxd61xw98xyp1a0zsz6av4nls2c9fwb7q59wb05sci";
+      type = "gem";
+    };
+    version = "1.1.2";
+  };
+  rqrcode_core = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "071jqmhk3hf0grsvi0jx5sl449pf82p40ls5b3likbq4q516zc0j";
+      type = "gem";
+    };
+    version = "0.1.2";
+  };
+  rspec = {
+    dependencies = ["rspec-core" "rspec-expectations" "rspec-mocks"];
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1dwai7jnwmdmd7ajbi2q0k0lx1dh88knv5wl7c34wjmf94yv8w5q";
+      type = "gem";
+    };
+    version = "3.10.0";
+  };
+  rspec-core = {
+    dependencies = ["rspec-support"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0n2rdv8f26yw8c6asymc0mgddyr5d2b5n6mfvpd3n6lnpf1jdyv2";
+      type = "gem";
+    };
+    version = "3.10.0";
+  };
+  rspec-expectations = {
+    dependencies = ["diff-lcs" "rspec-support"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0j37dvnvfbjwj8dqx27yfvz0frl7f2jc1abqg99h0ppriz9za6dc";
+      type = "gem";
+    };
+    version = "3.10.0";
+  };
+  rspec-html-matchers = {
+    dependencies = ["nokogiri" "rspec"];
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0883rqv77n2wawnk5lp3la48l7pckyz8l013qddngzmksi5p1v3f";
+      type = "gem";
+    };
+    version = "0.9.4";
+  };
+  rspec-mocks = {
+    dependencies = ["diff-lcs" "rspec-support"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1pz89y1522i6f8wzrg72ykmch3318ih87nlpl0y1ghsrs5hqymw3";
+      type = "gem";
+    };
+    version = "3.10.0";
+  };
+  rspec-rails = {
+    dependencies = ["actionpack" "activesupport" "railties" "rspec-core" "rspec-expectations" "rspec-mocks" "rspec-support"];
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0lzik01ziaskgpdpy8knffpw0fsy9151f5lfigyhb89wq4q45hfs";
+      type = "gem";
+    };
+    version = "4.0.1";
+  };
+  rspec-support = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0j0n28i6zci5j7gg370bdy87dy43hlwx6dw428d9kamf5a0i2klz";
+      type = "gem";
+    };
+    version = "3.10.0";
+  };
+  rswag-specs = {
+    dependencies = ["activesupport" "json-schema" "railties"];
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0lyp2m76p960bvgy4xcz0dilp4w5lq2cwh8md5z7cwxdg8qsbr83";
+      type = "gem";
+    };
+    version = "2.3.1";
+  };
+  rtlit = {
+    groups = ["assets"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0srfh7cl95srjiwbyc9pmn3w739zlvyj89hyj0bm7g92zrsd27qm";
+      type = "gem";
+    };
+    version = "0.0.5";
+  };
+  rubocop = {
+    dependencies = ["parallel" "parser" "rainbow" "regexp_parser" "rexml" "rubocop-ast" "ruby-progressbar" "unicode-display_width"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1kvzhzhzcdd5bqwjilb0fpp51sqjniww2b0g713n0cvhnlgchn2y";
+      type = "gem";
+    };
+    version = "1.4.2";
+  };
+  rubocop-ast = {
+    dependencies = ["parser"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0q0kdi89ad7dd1xmzrdf5ikk32bllzr68hf4x8fd7azcv5jnch2l";
+      type = "gem";
+    };
+    version = "1.2.0";
+  };
+  rubocop-discourse = {
+    dependencies = ["rubocop" "rubocop-rspec"];
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1z1h8spsjnsqz6c25n9ib1yimkwr7a76bas8w1k9c404hcqhlahv";
+      type = "gem";
+    };
+    version = "2.4.1";
+  };
+  rubocop-rspec = {
+    dependencies = ["rubocop" "rubocop-ast"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1gl7hdd9lq0si4gb510g33dbysmk3iydas2b0sbl5pwfkhv0k4g1";
+      type = "gem";
+    };
+    version = "2.0.0";
+  };
+  ruby-prof = {
+    groups = ["development"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1lm3wdxc6gjldkb5pdwwipapf84lgrvxck4h5kg8jdfd8arrpyis";
+      type = "gem";
+    };
+    version = "1.4.2";
+  };
+  ruby-progressbar = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1k77i0d4wsn23ggdd2msrcwfy0i376cglfqypkk2q77r2l3408zf";
+      type = "gem";
+    };
+    version = "1.10.1";
+  };
+  ruby-readability = {
+    dependencies = ["guess_html_encoding" "nokogiri"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "15ivhbry7hf82lww1bzcrwfyjymijfb3rb0wdd32g2z0942wdspa";
+      type = "gem";
+    };
+    version = "0.7.0";
+  };
+  ruby2_keywords = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "17pcc0wgvh3ikrkr7bm3nx0qhyiqwidd13ij0fa50k7gsbnr2p0l";
+      type = "gem";
+    };
+    version = "0.0.2";
+  };
+  rubyzip = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0590m2pr9i209pp5z4mx0nb1961ishdiqb28995hw1nln1d1b5ji";
+      type = "gem";
+    };
+    version = "2.3.0";
+  };
+  sanitize = {
+    dependencies = ["crass" "nokogiri" "nokogumbo"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "18m3zcf207gcrmghx288w3n2kpphc22lbmbc1wdx1nzcn8g2yddh";
+      type = "gem";
+    };
+    version = "5.2.1";
+  };
+  sassc = {
+    dependencies = ["ffi" "rake"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1sr4825rlwsrl7xrsm0sgalcpf5zgp4i56dbi3qxfa9lhs8r6zh4";
+      type = "gem";
+    };
+    version = "2.0.1";
+  };
+  sassc-rails = {
+    dependencies = ["railties" "sassc" "sprockets" "sprockets-rails" "tilt"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1d9djmwn36a5m8a83bpycs48g8kh1n2xkyvghn7dr6zwh4wdyksz";
+      type = "gem";
+    };
+    version = "2.1.2";
+  };
+  seed-fu = {
+    dependencies = ["activerecord" "activesupport"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0y7lzcshsq6i20qn1p8zczir4fivr6nbl1km91ns320vvh92v43d";
+      type = "gem";
+    };
+    version = "2.3.9";
+  };
+  shoulda-matchers = {
+    dependencies = ["activesupport"];
+    groups = ["development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1wd1bblxr4dfmrnh3j83kvfds6a7nak4ifq37ab0pg1kdi6iiw7l";
+      type = "gem";
+    };
+    version = "4.4.1";
+  };
+  sidekiq = {
+    dependencies = ["connection_pool" "rack" "redis"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0mjxrxppv08a1hwqi8gpg6n168cxqhp7c2r2jwc4rbz9j5k41vcw";
+      type = "gem";
+    };
+    version = "6.1.2";
+  };
+  simplecov = {
+    dependencies = ["docile" "simplecov-html" "simplecov_json_formatter"];
+    groups = ["test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1mm20dvd64w46l5k11il9z5sjgdpp0bknml76glcngvl2w03k3cb";
+      type = "gem";
+    };
+    version = "0.20.0";
+  };
+  simplecov-html = {
+    groups = ["default" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0yx01bxa8pbf9ip4hagqkp5m0mqfnwnw2xk8kjraiywz4lrss6jb";
+      type = "gem";
+    };
+    version = "0.12.3";
+  };
+  simplecov_json_formatter = {
+    groups = ["default" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0cl3j7p3b5q7sxsx1va63c8imc5x6g99xablz08qrmqhpi0d6g6j";
+      type = "gem";
+    };
+    version = "0.1.2";
+  };
+  sprockets = {
+    dependencies = ["concurrent-ruby" "rack"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "182jw5a0fbqah5w9jancvfmjbk88h8bxdbwnl4d3q809rpxdg8ay";
+      type = "gem";
+    };
+    version = "3.7.2";
+  };
+  sprockets-rails = {
+    dependencies = ["actionpack" "activesupport" "sprockets"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0mwmz36265646xqfyczgr1mhkm1hfxgxxvgdgr4xfcbf2g72p1k2";
+      type = "gem";
+    };
+    version = "3.2.2";
+  };
+  sshkey = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "03bkn55qsng484iqwz2lmm6rkimj01vsvhwk661s3lnmpkl65lbp";
+      type = "gem";
+    };
+    version = "2.0.0";
+  };
+  stackprof = {
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "147rb66p3n062vc433afqhkd99iazvkrqnghxgh871r62yhha93f";
+      type = "gem";
+    };
+    version = "0.2.16";
+  };
+  test-prof = {
+    groups = ["test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1jfq8ylxpxanc3f0i6qb3nchawx9hj6qcqj6ccfyixrnvzswwjvi";
+      type = "gem";
+    };
+    version = "0.12.2";
+  };
+  thor = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1xbhkmyhlxwzshaqa7swy2bx6vd64mm0wrr8g3jywvxy7hg0cwkm";
+      type = "gem";
+    };
+    version = "1.0.1";
+  };
+  thread_safe = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0nmhcgq6cgz44srylra07bmaw99f5271l0dpsvl5f75m44l0gmwy";
+      type = "gem";
+    };
+    version = "0.3.6";
+  };
+  tilt = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0rn8z8hda4h41a64l0zhkiwz2vxw9b1nb70gl37h1dg2k874yrlv";
+      type = "gem";
+    };
+    version = "2.0.10";
+  };
+  tzinfo = {
+    dependencies = ["thread_safe"];
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0skr6ih9cr3pwp8l84f0z7fy3q9kiq8hw0sg3zqw0hpbbyj05743";
+      type = "gem";
+    };
+    version = "1.2.8";
+  };
+  uglifier = {
+    dependencies = ["execjs"];
+    groups = ["assets"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0wgh7bzy68vhv9v68061519dd8samcy8sazzz0w3k8kqpy3g4s5f";
+      type = "gem";
+    };
+    version = "4.2.0";
+  };
+  unf = {
+    dependencies = ["unf_ext"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0bh2cf73i2ffh4fcpdn9ir4mhq8zi50ik0zqa1braahzadx536a9";
+      type = "gem";
+    };
+    version = "0.1.4";
+  };
+  unf_ext = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0wc47r23h063l8ysws8sy24gzh74mks81cak3lkzlrw4qkqb3sg4";
+      type = "gem";
+    };
+    version = "0.0.7.7";
+  };
+  unicode-display_width = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "06i3id27s60141x6fdnjn5rar1cywdwy64ilc59cz937303q3mna";
+      type = "gem";
+    };
+    version = "1.7.0";
+  };
+  unicorn = {
+    dependencies = ["kgio" "raindrops"];
+    groups = ["default"];
+    platforms = [{
+      engine = "maglev";
+    } {
+      engine = "rbx";
+    } {
+      engine = "ruby";
+    }];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1qzdhbmab2w034wpdj5ippnyyvgqm8gpx9wbchb4zgs4i1mswzhv";
+      type = "gem";
+    };
+    version = "5.7.0";
+  };
+  uniform_notifier = {
+    groups = ["default" "development"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0vm4aix8jmv42s1x58m3lj3xwkbxyn9qn6lzhhig0d1j8fv6j30c";
+      type = "gem";
+    };
+    version = "1.13.0";
+  };
+  webmock = {
+    dependencies = ["addressable" "crack" "hashdiff"];
+    groups = ["test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0wbdjagk2qpr76k3zw2gmkfp5aqlrc1a4qrpjv7sq1q39qbn8xax";
+      type = "gem";
+    };
+    version = "3.10.0";
+  };
+  webpush = {
+    dependencies = ["hkdf" "jwt"];
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1z9ma580q80czw46gi1bvsr2iwxr63aiyr7i9gilav6hbhg3sxv3";
+      type = "gem";
+    };
+    version = "1.1.0";
+  };
+  xorcist = {
+    groups = ["default"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1q7hr3qyn1hczv9fglqc2cbaax0fb37gjjr0y24x19mmp817csdn";
+      type = "gem";
+    };
+    version = "1.1.2";
+  };
+  yaml-lint = {
+    groups = ["development"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1m9n4sg7i0334yac7dcrhnhv5rzvrccgnh687n9x77ba3awk4yx1";
+      type = "gem";
+    };
+    version = "0.0.10";
+  };
+  zeitwerk = {
+    groups = ["default" "development" "test"];
+    platforms = [];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "12n0hiawqayzchi0yga5n19hi63b2snd49fv3n23n2i4pp05jzrp";
+      type = "gem";
+    };
+    version = "2.4.1";
+  };
+}
diff --git a/pkgs/servers/web-apps/discourse/unicorn_logging_and_timeout.patch b/pkgs/servers/web-apps/discourse/unicorn_logging_and_timeout.patch
new file mode 100644
index 00000000000..1dbfed67919
--- /dev/null
+++ b/pkgs/servers/web-apps/discourse/unicorn_logging_and_timeout.patch
@@ -0,0 +1,25 @@
+diff --git a/config/unicorn.conf.rb b/config/unicorn.conf.rb
+index 373e235b3f..57d4d7a55b 100644
+--- a/config/unicorn.conf.rb
++++ b/config/unicorn.conf.rb
+@@ -27,18 +27,10 @@ pid (ENV["UNICORN_PID_PATH"] || "#{discourse_path}/tmp/pids/unicorn.pid")
+ 
+ if ENV["RAILS_ENV"] == "development" || !ENV["RAILS_ENV"]
+   logger Logger.new($stdout)
+-  # we want a longer timeout in dev cause first request can be really slow
+-  timeout (ENV["UNICORN_TIMEOUT"] && ENV["UNICORN_TIMEOUT"].to_i || 60)
+-else
+-  # By default, the Unicorn logger will write to stderr.
+-  # Additionally, some applications/frameworks log to stderr or stdout,
+-  # so prevent them from going to /dev/null when daemonized here:
+-  stderr_path "#{discourse_path}/log/unicorn.stderr.log"
+-  stdout_path "#{discourse_path}/log/unicorn.stdout.log"
+-  # nuke workers after 30 seconds instead of 60 seconds (the default)
+-  timeout 30
+ end
+ 
++timeout (ENV["UNICORN_TIMEOUT"] && ENV["UNICORN_TIMEOUT"].to_i || 60)
++
+ # important for Ruby 2.0
+ preload_app true
+ 
diff --git a/pkgs/servers/web-apps/discourse/update.py b/pkgs/servers/web-apps/discourse/update.py
new file mode 100755
index 00000000000..c401ab552bb
--- /dev/null
+++ b/pkgs/servers/web-apps/discourse/update.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env nix-shell
+#! nix-shell -i python3 -p bundix bundler nix-update python3 python3Packages.requests python3Packages.click python3Packages.click-log
+
+import click
+import click_log
+import shutil
+import tempfile
+import re
+import logging
+import subprocess
+import pathlib
+from distutils.version import LooseVersion
+from typing import Iterable
+
+import requests
+
+logger = logging.getLogger(__name__)
+
+
+class DiscourseRepo:
+    version_regex = re.compile(r'^v\d+\.\d+\.\d+$')
+    def __init__(self, owner: str = 'discourse', repo: str = 'discourse'):
+        self.owner = owner
+        self.repo = repo
+
+    @property
+    def tags(self) -> Iterable[str]:
+        r = requests.get(f'https://api.github.com/repos/{self.owner}/{self.repo}/git/refs/tags').json()
+        tags = [x['ref'].replace('refs/tags/', '') for x in r]
+
+        # filter out versions not matching version_regex
+        versions = list(filter(self.version_regex.match, tags))
+
+        # sort, but ignore v for sorting comparisons
+        versions.sort(key=lambda x: LooseVersion(x.replace('v', '')), reverse=True)
+        return versions
+
+    @staticmethod
+    def rev2version(tag: str) -> str:
+        """
+        normalize a tag to a version number.
+        This obviously isn't very smart if we don't pass something that looks like a tag
+        :param tag: the tag to normalize
+        :return: a normalized version number
+        """
+        # strip v prefix
+        return re.sub(r'^v', '', tag)
+
+    def get_file(self, filepath, rev):
+        """returns file contents at a given rev :param filepath: the path to
+        the file, relative to the repo root :param rev: the rev to
+        fetch at :return:
+
+        """
+        return requests.get(f'https://raw.githubusercontent.com/{self.owner}/{self.repo}/{rev}/{filepath}').text
+
+
+def _call_nix_update(pkg, version):
+    """calls nix-update from nixpkgs root dir"""
+    nixpkgs_path = pathlib.Path(__file__).parent / '../../../../'
+    return subprocess.check_output(['nix-update', pkg, '--version', version], cwd=nixpkgs_path)
+
+
+def _get_current_package_version(pkg: str):
+    nixpkgs_path = pathlib.Path(__file__).parent / '../../../../'
+    return subprocess.check_output(['nix', 'eval', '--raw', f'nixpkgs.{pkg}.version'], text=True)
+
+
+def _diff_file(filepath: str, old_version: str, new_version: str):
+    repo = DiscourseRepo()
+
+    current_dir = pathlib.Path(__file__).parent
+
+    old = repo.get_file(filepath, 'v' + old_version)
+    new = repo.get_file(filepath, 'v' + new_version)
+
+    if old == new:
+        click.secho(f'{filepath} is unchanged', fg='green')
+        return
+
+    with tempfile.NamedTemporaryFile(mode='w') as o, tempfile.NamedTemporaryFile(mode='w') as n:
+        o.write(old), n.write(new)
+        width = shutil.get_terminal_size((80, 20)).columns
+        diff_proc = subprocess.run(
+            ['diff', '--color=always', f'--width={width}', '-y', o.name, n.name],
+            stdout=subprocess.PIPE,
+            cwd=current_dir,
+            text=True
+        )
+
+    click.secho(f'Diff for {filepath} ({old_version} -> {new_version}):', fg='bright_blue', bold=True)
+    click.echo(diff_proc.stdout + '\n')
+    return
+
+
+@click_log.simple_verbosity_option(logger)
+
+
+@click.group()
+def cli():
+    pass
+
+
+@cli.command()
+@click.argument('rev', default='latest')
+@click.option('--reverse/--no-reverse', default=False, help='Print diffs from REV to current.')
+def print_diffs(rev, reverse):
+    """Print out diffs for files used as templates for the NixOS module.
+
+    The current package version found in the nixpkgs worktree the
+    script is run from will be used to download the "from" file and
+    REV used to download the "to" file for the diff, unless the
+    '--reverse' flag is specified.
+
+    REV should be the git rev to find changes in ('vX.Y.Z') or
+    'latest'; defaults to 'latest'.
+
+    """
+    if rev == 'latest':
+        repo = DiscourseRepo()
+        rev = repo.tags[0]
+
+    old_version = _get_current_package_version('discourse')
+    new_version = DiscourseRepo.rev2version(rev)
+
+    if reverse:
+        old_version, new_version = new_version, old_version
+
+    for f in ['config/nginx.sample.conf', 'config/discourse_defaults.conf']:
+        _diff_file(f, old_version, new_version)
+
+
+@cli.command()
+@click.argument('rev', default='latest')
+def update(rev):
+    """Update gem files and version.
+
+    REV should be the git rev to update to ('vX.Y.Z') or 'latest';
+    defaults to 'latest'.
+
+    """
+    repo = DiscourseRepo()
+
+    if rev == 'latest':
+        rev = repo.tags[0]
+    logger.debug(f"Using rev {rev}")
+
+    version = repo.rev2version(rev)
+    logger.debug(f"Using version {version}")
+
+    rubyenv_dir = pathlib.Path(__file__).parent / "rubyEnv"
+
+    for fn in ['Gemfile.lock', 'Gemfile']:
+        with open(rubyenv_dir / fn, 'w') as f:
+            f.write(repo.get_file(fn, rev))
+
+    subprocess.check_output(['bundle', 'lock'], cwd=rubyenv_dir)
+    subprocess.check_output(['bundix'], cwd=rubyenv_dir)
+
+    _call_nix_update('discourse', repo.rev2version(rev))
+
+
+if __name__ == '__main__':
+    cli()
diff --git a/pkgs/tools/admin/awscli2/default.nix b/pkgs/tools/admin/awscli2/default.nix
index 1f5ff48d25a..a2ea7bb35db 100644
--- a/pkgs/tools/admin/awscli2/default.nix
+++ b/pkgs/tools/admin/awscli2/default.nix
@@ -3,12 +3,12 @@ let
   py = python3.override {
     packageOverrides = self: super: {
       botocore = super.botocore.overridePythonAttrs (oldAttrs: rec {
-        version = "2.0.0dev97";
+        version = "2.0.0dev103";
         src = fetchFromGitHub {
           owner = "boto";
           repo = "botocore";
-          rev = "f240d284994b521b0bd099161bc0ab5786caf700";
-          sha256 = "sha256-Ot3w/4OcQ+pXq6bJnQqV5uvG50/uIOa1pwMWqor5NXM=";
+          rev = "e30d580042687a79776fdf93264e80746e08d21f";
+          sha256 = "sha256-+cTQQO6dPctvf3WZOk8Mgo1eQUdqRdGCcz7jcVhEvNo=";
         };
       });
       prompt_toolkit = super.prompt_toolkit.overridePythonAttrs (oldAttrs: rec {
@@ -24,18 +24,18 @@ let
 in
 with py.pkgs; buildPythonApplication rec {
   pname = "awscli2";
-  version = "2.1.29"; # N.B: if you change this, change botocore to a matching version too
+  version = "2.1.35"; # N.B: if you change this, change botocore to a matching version too
 
   src = fetchFromGitHub {
     owner = "aws";
     repo = "aws-cli";
     rev = version;
-    sha256 = "sha256-6SVDJeyPJQX4XIH8RYRzJG2LFDHxIrW/b1a0JZ5kIFY=";
+    sha256 = "sha256-YgzagbbVLlGSPIhck0YaJg3gQGEdoqXtLapN04Q6hLw=";
   };
 
   postPatch = ''
     substituteInPlace setup.py --replace "colorama>=0.2.5,<0.4.4" "colorama>=0.2.5"
-    substituteInPlace setup.py --replace "cryptography>=2.8.0,<=2.9.0" "cryptography>=2.8.0"
+    substituteInPlace setup.py --replace "cryptography>=3.3.2,<3.4.0" "cryptography>=3.3.2"
     substituteInPlace setup.py --replace "docutils>=0.10,<0.16" "docutils>=0.10"
     substituteInPlace setup.py --replace "ruamel.yaml>=0.15.0,<0.16.0" "ruamel.yaml>=0.15.0"
     substituteInPlace setup.py --replace "wcwidth<0.2.0" "wcwidth"
diff --git a/pkgs/tools/filesystems/sshfs-fuse/common.nix b/pkgs/tools/filesystems/sshfs-fuse/common.nix
new file mode 100644
index 00000000000..f85faa712dd
--- /dev/null
+++ b/pkgs/tools/filesystems/sshfs-fuse/common.nix
@@ -0,0 +1,61 @@
+{ version, sha256, platforms, patches ? [ ] }:
+
+{ lib, stdenv, fetchFromGitHub
+, meson, pkg-config, ninja, docutils, makeWrapper
+, fuse3, macfuse-stubs, glib
+, which, python3Packages
+, openssh
+}:
+
+let
+  fuse = if stdenv.isDarwin then macfuse-stubs else fuse3;
+in stdenv.mkDerivation rec {
+  pname = "sshfs-fuse";
+  inherit version;
+
+  src = fetchFromGitHub {
+    owner = "libfuse";
+    repo = "sshfs";
+    rev = "sshfs-${version}";
+    inherit sha256;
+  };
+
+  inherit patches;
+
+  nativeBuildInputs = [ meson pkg-config ninja docutils makeWrapper ];
+  buildInputs = [ fuse glib ];
+  checkInputs = [ which python3Packages.pytest ];
+
+  NIX_CFLAGS_COMPILE = lib.optionalString
+    (stdenv.hostPlatform.system == "i686-linux")
+    "-D_FILE_OFFSET_BITS=64";
+
+  postInstall = ''
+    mkdir -p $out/sbin
+    ln -sf $out/bin/sshfs $out/sbin/mount.sshfs
+  '' + lib.optionalString (!stdenv.isDarwin) ''
+    wrapProgram $out/bin/sshfs --prefix PATH : "${openssh}/bin"
+  '';
+
+  # doCheck = true;
+  checkPhase = lib.optionalString (!stdenv.isDarwin) ''
+    # The tests need fusermount:
+    mkdir bin
+    cp ${fuse}/bin/fusermount3 bin/fusermount
+    export PATH=bin:$PATH
+    # Can't access /dev/fuse within the sandbox: "FUSE kernel module does not seem to be loaded"
+    substituteInPlace test/util.py --replace "/dev/fuse" "/dev/null"
+    # TODO: "fusermount executable not setuid, and we are not root"
+    # We should probably use a VM test instead
+    ${python3Packages.python.interpreter} -m pytest test/
+  '';
+
+  meta = with lib; {
+    inherit platforms;
+    description = "FUSE-based filesystem that allows remote filesystems to be mounted over SSH";
+    longDescription = macfuse-stubs.warning;
+    homepage = "https://github.com/libfuse/sshfs";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ primeos ];
+  };
+}
diff --git a/pkgs/tools/filesystems/sshfs-fuse/default.nix b/pkgs/tools/filesystems/sshfs-fuse/default.nix
index 69826941d00..e575bd3e138 100644
--- a/pkgs/tools/filesystems/sshfs-fuse/default.nix
+++ b/pkgs/tools/filesystems/sshfs-fuse/default.nix
@@ -1,52 +1,28 @@
-{ lib, stdenv, fetchFromGitHub
-, meson, pkg-config, ninja, docutils, makeWrapper
-, fuse3, glib
-, which, python3Packages
-, openssh
-}:
+{ lib, stdenv, callPackage, fetchpatch }:
 
-stdenv.mkDerivation rec {
-  version = "3.7.1";
-  pname = "sshfs-fuse";
+let mkSSHFS = args: callPackage (import ./common.nix args) { };
+in if stdenv.isDarwin then
+  mkSSHFS {
+    version = "2.10"; # macFUSE isn't yet compatible with libfuse 3.x
+    sha256 = "1dmw4kx6vyawcywiv8drrajnam0m29mxfswcp4209qafzx3mjlp1";
+    patches = [
+      # remove reference to fuse_darwin.h which doens't exist on recent macFUSE
+      ./fix-fuse-darwin-h.patch
 
-  src = fetchFromGitHub {
-    owner = "libfuse";
-    repo = "sshfs";
-    rev = "sshfs-${version}";
+      # From https://github.com/libfuse/sshfs/pull/185:
+      # > With this patch, setting I/O size to a reasonable large value, will
+      # > result in much improved performance, e.g.: -o iosize=1048576
+      (fetchpatch {
+        name = "fix-configurable-blksize.patch";
+        url = "https://github.com/libfuse/sshfs/commit/667cf34622e2e873db776791df275c7a582d6295.patch";
+        sha256 = "0d65lawd2g2aisk1rw2vl65dgxywf4vqgv765n9zj9zysyya8a54";
+      })
+    ];
+    platforms = lib.platforms.darwin;
+  }
+else
+  mkSSHFS {
+    version = "3.7.1";
     sha256 = "088mgcsqv9f2vly4xn6lvvkmqkgr9jjmjs9qp8938hl7j6rrgd17";
-  };
-
-  nativeBuildInputs = [ meson pkg-config ninja docutils makeWrapper ];
-  buildInputs = [ fuse3 glib ];
-  checkInputs = [ which python3Packages.pytest ];
-
-  NIX_CFLAGS_COMPILE = lib.optionalString
-    (stdenv.hostPlatform.system == "i686-linux")
-    "-D_FILE_OFFSET_BITS=64";
-
-  postInstall = ''
-    mkdir -p $out/sbin
-    ln -sf $out/bin/sshfs $out/sbin/mount.sshfs
-    wrapProgram $out/bin/sshfs --prefix PATH : "${openssh}/bin"
-  '';
-
-  #doCheck = true;
-  checkPhase = ''
-    # The tests need fusermount:
-    mkdir bin && cp ${fuse3}/bin/fusermount3 bin/fusermount
-    export PATH=bin:$PATH
-    # Can't access /dev/fuse within the sandbox: "FUSE kernel module does not seem to be loaded"
-    substituteInPlace test/util.py --replace "/dev/fuse" "/dev/null"
-    # TODO: "fusermount executable not setuid, and we are not root"
-    # We should probably use a VM test instead
-    python3 -m pytest test/
-  '';
-
-  meta = with lib; {
-    inherit (src.meta) homepage;
-    description = "FUSE-based filesystem that allows remote filesystems to be mounted over SSH";
-    platforms = platforms.linux;
-    license = licenses.gpl2;
-    maintainers = with maintainers; [ primeos ];
-  };
-}
+    platforms = lib.platforms.linux;
+  }
diff --git a/pkgs/tools/filesystems/sshfs-fuse/fix-fuse-darwin-h.patch b/pkgs/tools/filesystems/sshfs-fuse/fix-fuse-darwin-h.patch
new file mode 100644
index 00000000000..045cc0e61f3
--- /dev/null
+++ b/pkgs/tools/filesystems/sshfs-fuse/fix-fuse-darwin-h.patch
@@ -0,0 +1,14 @@
+diff --git a/sshfs.c b/sshfs.c
+index 97eaf06..d442577 100644
+--- a/sshfs.c
++++ b/sshfs.c
+@@ -14,9 +14,6 @@
+ #if !defined(__CYGWIN__)
+ #include <fuse_lowlevel.h>
+ #endif
+-#ifdef __APPLE__
+-#  include <fuse_darwin.h>
+-#endif
+ #include <assert.h>
+ #include <stdio.h>
+ #include <stdlib.h>
diff --git a/pkgs/tools/networking/openssh/copyid.nix b/pkgs/tools/networking/openssh/copyid.nix
new file mode 100644
index 00000000000..71baa6a23f1
--- /dev/null
+++ b/pkgs/tools/networking/openssh/copyid.nix
@@ -0,0 +1,11 @@
+{ runCommandNoCC, openssh }:
+
+runCommandNoCC "ssh-copy-id-${openssh.version}" {
+  meta = openssh.meta // {
+    description = "A tool to copy SSH public keys to a remote machine";
+    priority = (openssh.meta.priority or 0) - 1;
+  };
+} ''
+  install -Dm 755 {${openssh},$out}/bin/ssh-copy-id
+  install -Dm 644 {${openssh},$out}/share/man/man1/ssh-copy-id.1.gz
+''
diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix
index ee99757f8fd..2bbe0630aa8 100644
--- a/pkgs/top-level/aliases.nix
+++ b/pkgs/top-level/aliases.nix
@@ -626,7 +626,7 @@ mapAliases ({
   qt-3 = throw "qt-3 has been removed from nixpkgs, as it's unmaintained and insecure"; # added 2021-02-15
   rfkill = throw "rfkill has been removed, as it's included in util-linux"; # added 2020-08-23
   riak-cs = throw "riak-cs is not maintained anymore"; # added 2020-10-14
-  radare2-cutter = cutter;
+  radare2-cutter = cutter; # added 2021-03-30
   rkt = throw "rkt was archived by upstream"; # added 2020-05-16
   ruby_2_0_0 = throw "ruby_2_0_0 was deprecated on 2018-02-13: use a newer version of ruby";
   ruby_2_1_0 = throw "ruby_2_1_0 was deprecated on 2018-02-13: use a newer version of ruby";
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 859924cb8d2..86ce8bc34f7 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -2252,6 +2252,14 @@ in
 
   discount = callPackage ../tools/text/discount { };
 
+  discourse = callPackage ../servers/web-apps/discourse {
+    ruby = ruby_2_7;
+  };
+
+  discourse-mail-receiver = callPackage ../servers/web-apps/discourse/mail_receiver {
+    ruby = ruby_2_7;
+  };
+
   discocss = callPackage ../tools/misc/discocss { };
 
   disfetch = callPackage ../tools/misc/disfetch { };
@@ -7111,6 +7119,8 @@ in
     etcDir = "/etc/ssh";
   };
 
+  ssh-copy-id = callPackage ../tools/networking/openssh/copyid.nix { };
+
   opensp = callPackage ../tools/text/sgml/opensp { };
 
   opentracker = callPackage ../applications/networking/p2p/opentracker { };
@@ -17633,12 +17643,8 @@ in
     stdenv = gcc6Stdenv;
   });
 
-  v8_6_x = v8;
   v8 = callPackage ../development/libraries/v8 {
     inherit (python2Packages) python;
-  } // lib.optionalAttrs stdenv.isLinux {
-    # doesn't build with gcc7
-    stdenv = gcc6Stdenv;
   };
 
   vaapiIntel = callPackage ../development/libraries/vaapi-intel { };
@@ -18305,6 +18311,10 @@ in
     python3Packages = python36Packages;
   };
 
+  doh-proxy-rust = callPackage ../servers/dns/doh-proxy-rust {
+    inherit (darwin.apple_sdk.frameworks) Security;
+  };
+
   dgraph = callPackage ../servers/dgraph { };
 
   dico = callPackage ../servers/dico { };
@@ -21991,6 +22001,10 @@ in
 
   blogc = callPackage ../applications/misc/blogc { };
 
+  blucontrol = callPackage ../applications/misc/blucontrol/wrapper.nix {
+    inherit (haskellPackages) ghcWithPackages;
+  };
+
   bluefish = callPackage ../applications/editors/bluefish {
     gtk = gtk3;
   };
@@ -22043,7 +22057,9 @@ in
 
   caerbannog = callPackage ../applications/misc/caerbannog { };
 
-  cage = callPackage ../applications/window-managers/cage { };
+  cage = callPackage ../applications/window-managers/cage {
+    wlroots = wlroots_0_12;
+  };
 
   calf = callPackage ../applications/audio/calf {
       inherit (gnome2) libglade;
@@ -23482,7 +23498,11 @@ in
 
   super-productivity = callPackage ../applications/networking/super-productivity { };
 
-  wlroots = callPackage ../development/libraries/wlroots { };
+  wlroots = callPackage ../development/libraries/wlroots {
+    inherit (xorg) xcbutilrenderutil;
+  };
+
+  wlroots_0_12 = callPackage ../development/libraries/wlroots/0.12.nix {};
 
   sway-unwrapped = callPackage ../applications/window-managers/sway { };
   sway = callPackage ../applications/window-managers/sway/wrapper.nix { };
@@ -23504,7 +23524,9 @@ in
 
   wbg = callPackage ../applications/misc/wbg { };
 
-  hikari = callPackage ../applications/window-managers/hikari { };
+  hikari = callPackage ../applications/window-managers/hikari {
+    wlroots = wlroots_0_12;
+  };
 
   i3 = callPackage ../applications/window-managers/i3 {
     xcb-util-cursor = if stdenv.isDarwin then xcb-util-cursor-HEAD else xcb-util-cursor;
@@ -23566,7 +23588,9 @@ in
 
   i3-wk-switch = callPackage ../applications/window-managers/i3/wk-switch.nix { };
 
-  waybox = callPackage ../applications/window-managers/waybox { };
+  waybox = callPackage ../applications/window-managers/waybox {
+    wlroots = wlroots_0_12;
+  };
 
   windowchef = callPackage ../applications/window-managers/windowchef/default.nix { };
 
@@ -26437,10 +26461,15 @@ in
 
   wayfireApplications = wayfireApplications-unwrapped.withPlugins (plugins: [ plugins.wf-shell ]);
   inherit (wayfireApplications) wayfire wcm;
-  wayfireApplications-unwrapped = recurseIntoAttrs (callPackage ../applications/window-managers/wayfire/applications.nix { });
-  wayfirePlugins = recurseIntoAttrs (callPackage ../applications/window-managers/wayfire/plugins.nix {
-    inherit (wayfireApplications-unwrapped) wayfire;
-  });
+  wayfireApplications-unwrapped = recurseIntoAttrs (
+    (callPackage ../applications/window-managers/wayfire/applications.nix { }).
+    extend (_: _: { wlroots = wlroots_0_12; })
+  );
+  wayfirePlugins = recurseIntoAttrs (
+    callPackage ../applications/window-managers/wayfire/plugins.nix {
+      inherit (wayfireApplications-unwrapped) wayfire;
+    }
+  );
   wf-config = callPackage ../applications/window-managers/wayfire/wf-config.nix { };
 
   waypipe = callPackage ../applications/networking/remote/waypipe { };
@@ -26482,7 +26511,9 @@ in
 
   weston = callPackage ../applications/window-managers/weston { pipewire = pipewire_0_2; };
 
-  wio = callPackage ../applications/window-managers/wio { };
+  wio = callPackage ../applications/window-managers/wio {
+    wlroots = wlroots_0_12;
+  };
 
   whitebox-tools = callPackage ../applications/gis/whitebox-tools {
     inherit (darwin.apple_sdk.frameworks) Security;
@@ -30811,7 +30842,9 @@ in
 
   bottom = callPackage ../tools/system/bottom {};
 
-  cagebreak = callPackage ../applications/window-managers/cagebreak/default.nix {};
+  cagebreak = callPackage ../applications/window-managers/cagebreak/default.nix {
+    wlroots = wlroots_0_12;
+  };
 
   psftools = callPackage ../os-specific/linux/psftools {};
 
diff --git a/pkgs/top-level/php-packages.nix b/pkgs/top-level/php-packages.nix
index 7db0eb4d6a4..3bbcb453a3c 100644
--- a/pkgs/top-level/php-packages.nix
+++ b/pkgs/top-level/php-packages.nix
@@ -146,8 +146,8 @@ lib.makeScope pkgs.newScope (self: with self; {
 
       sha256 = "103nys7zkpi1hifqp9miyl0m1mn07xqshw3sapyz365nb35g5q71";
 
-      buildInputs = [ pkgs.v8_6_x ];
-      configureFlags = [ "--with-v8=${pkgs.v8_6_x}" ];
+      buildInputs = [ pkgs.v8 ];
+      configureFlags = [ "--with-v8=${pkgs.v8}" ];
 
       meta.maintainers = lib.teams.php.members;
       meta.broken = true;
@@ -159,8 +159,8 @@ lib.makeScope pkgs.newScope (self: with self; {
 
       sha256 = "0g63dyhhicngbgqg34wl91nm3556vzdgkq19gy52gvmqj47rj6rg";
 
-      buildInputs = [ pkgs.v8_6_x ];
-      configureFlags = [ "--with-v8js=${pkgs.v8_6_x}" ];
+      buildInputs = [ pkgs.v8 ];
+      configureFlags = [ "--with-v8js=${pkgs.v8}" ];
 
       meta.maintainers = lib.teams.php.members;
       meta.broken = true;
diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix
index b1e89d0ab3c..3cf978de2ab 100644
--- a/pkgs/top-level/python-packages.nix
+++ b/pkgs/top-level/python-packages.nix
@@ -533,6 +533,8 @@ in {
 
   asyncio-mqtt = callPackage ../development/python-modules/asyncio_mqtt { };
 
+  asyncio-nats-client = callPackage ../development/python-modules/asyncio-nats-client { };
+
   asyncio-throttle = callPackage ../development/python-modules/asyncio-throttle { };
 
   asyncpg = callPackage ../development/python-modules/asyncpg { };
@@ -4221,6 +4223,8 @@ in {
 
   nassl = callPackage ../development/python-modules/nassl { };
 
+  nats-python = callPackage ../development/python-modules/nats-python { };
+
   natsort = callPackage ../development/python-modules/natsort { };
 
   naturalsort = callPackage ../development/python-modules/naturalsort { };
@@ -6701,6 +6705,10 @@ in {
 
   recaptcha_client = callPackage ../development/python-modules/recaptcha_client { };
 
+  recoll = disabledIf (!isPy3k) (toPythonModule (pkgs.recoll.override {
+    python3Packages = self;
+  }));
+
   recommonmark = callPackage ../development/python-modules/recommonmark { };
 
   redbaron = callPackage ../development/python-modules/redbaron { };