Merge master into staging-next

This commit is contained in:
nixpkgs-ci[bot]
2025-07-09 18:05:44 +00:00
committed by GitHub
57 changed files with 10609 additions and 8745 deletions
+11
View File
@@ -6242,6 +6242,17 @@
github = "Dettorer";
githubId = 2761682;
};
deudz = {
name = "Danilo Soares";
email = "deudzdev@gmail.com";
github = "deudz";
githubId = 77695632;
keys = [
{
fingerprint = "42B9 5F7C 4FC2 CA13 FD4E 86B6 F0D8 B7CE 0B7E C148";
}
];
};
developer-guy = {
name = "Batuhan Apaydın";
email = "developerguyn@gmail.com";
@@ -53,7 +53,7 @@ def get_tmp_dir() -> Path:
def pythonize_name(name: str) -> str:
return re.sub(r"^[^A-z_]|[^A-z0-9_]", "_", name)
return re.sub(r"^[^A-Za-z_]|[^A-Za-z0-9_]", "_", name)
class Driver:
+5 -21
View File
@@ -24,8 +24,6 @@ let
BOOTSNAP_CACHE_DIR = "/var/cache/mastodon/precompile";
LD_PRELOAD = "${pkgs.jemalloc}/lib/libjemalloc.so";
MASTODON_USE_LIBVIPS = "true";
# Concurrency mastodon-web
WEB_CONCURRENCY = toString cfg.webProcesses;
MAX_THREADS = toString cfg.webThreads;
@@ -196,7 +194,6 @@ let
path = with pkgs; [
ffmpeg-headless
file
imagemagick
];
}
)
@@ -257,6 +254,11 @@ in
"mastodon"
"streamingPort"
] "Mastodon currently doesn't support streaming via TCP ports. Please open a PR if you need this.")
(lib.mkRemovedOptionModule [
"services"
"mastodon"
"otpSecretFile"
] "The OTP_SECRET option was removed from Mastodon in version 4.4.0")
];
options = {
@@ -490,19 +492,6 @@ in
type = lib.types.str;
};
otpSecretFile = lib.mkOption {
description = ''
Path to file containing the OTP secret.
A new OTP secret can be generated by running:
`nix build -f '<nixpkgs>' mastodon; cd result; bin/bundle exec rails secret`
If this file does not exist, it will be created with a new OTP secret.
'';
default = "/var/lib/mastodon/secrets/otp-secret";
type = lib.types.str;
};
trustedProxy = lib.mkOption {
description = ''
You need to set it to the IP from which your reverse proxy sends requests to Mastodon's web process,
@@ -892,10 +881,6 @@ in
mkdir -p $(dirname ${cfg.secretKeyBaseFile})
bin/bundle exec rails secret > ${cfg.secretKeyBaseFile}
fi
if ! test -f ${cfg.otpSecretFile}; then
mkdir -p $(dirname ${cfg.otpSecretFile})
bin/bundle exec rails secret > ${cfg.otpSecretFile}
fi
if ! test -f ${cfg.vapidPrivateKeyFile}; then
mkdir -p $(dirname ${cfg.vapidPrivateKeyFile}) $(dirname ${cfg.vapidPublicKeyFile})
keypair=$(bin/rake webpush:generate_keys)
@@ -908,7 +893,6 @@ in
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT="$(cat ${cfg.activeRecordEncryptionKeyDerivationSaltFile})"
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY="$(cat ${cfg.activeRecordEncryptionPrimaryKeyFile})"
SECRET_KEY_BASE="$(cat ${cfg.secretKeyBaseFile})"
OTP_SECRET="$(cat ${cfg.otpSecretFile})"
VAPID_PRIVATE_KEY="$(cat ${cfg.vapidPrivateKeyFile})"
VAPID_PUBLIC_KEY="$(cat ${cfg.vapidPublicKeyFile})"
''
+10 -10
View File
@@ -445,7 +445,7 @@ in
fscrypt = runTest ./fscrypt.nix;
fastnetmon-advanced = runTest ./fastnetmon-advanced.nix;
lauti = runTest ./lauti.nix;
easytier = handleTest ./easytier.nix { };
easytier = runTest ./easytier.nix;
ejabberd = runTest ./xmpp/ejabberd.nix;
elk = handleTestOn [ "x86_64-linux" ] ./elk.nix { };
emacs-daemon = runTest ./emacs-daemon.nix;
@@ -613,7 +613,7 @@ in
gokapi = runTest ./gokapi.nix;
gollum = runTest ./gollum.nix;
gonic = runTest ./gonic.nix;
google-oslogin = handleTest ./google-oslogin { };
google-oslogin = runTest ./google-oslogin;
gopro-tool = runTest ./gopro-tool.nix;
goss = runTest ./goss.nix;
gotenberg = runTest ./gotenberg.nix;
@@ -853,7 +853,7 @@ in
mautrix-meta-sqlite = runTest ./matrix/mautrix-meta-sqlite.nix;
mealie = runTest ./mealie.nix;
mediamtx = runTest ./mediamtx.nix;
mediatomb = handleTest ./mediatomb.nix { };
mediatomb = runTest ./mediatomb.nix;
mediawiki = handleTest ./mediawiki.nix { };
meilisearch = runTest ./meilisearch.nix;
memcached = runTest ./memcached.nix;
@@ -901,11 +901,11 @@ in
mumble = runTest ./mumble.nix;
# Fails on aarch64-linux at the PDF creation step - need to debug this on an
# aarch64 machine..
musescore = handleTestOn [ "x86_64-linux" ] ./musescore.nix { };
musescore = runTestOn [ "x86_64-linux" ] ./musescore.nix;
music-assistant = runTest ./music-assistant.nix;
munin = runTest ./munin.nix;
mutableUsers = runTest ./mutable-users.nix;
mycelium = handleTest ./mycelium { };
mycelium = runTest ./mycelium;
mympd = runTest ./mympd.nix;
mysql = handleTest ./mysql/mysql.nix { };
mysql-autobackup = handleTest ./mysql/mysql-autobackup.nix { };
@@ -935,7 +935,7 @@ in
};
ndppd = runTest ./ndppd.nix;
nebula = runTest ./nebula.nix;
neo4j = handleTest ./neo4j.nix { };
neo4j = runTest ./neo4j.nix;
netbird = runTest ./netbird.nix;
netdata = runTest ./netdata.nix;
nimdow = runTest ./nimdow.nix;
@@ -1261,11 +1261,11 @@ in
sanoid = runTest ./sanoid.nix;
saunafs = runTest ./saunafs.nix;
scaphandre = handleTest ./scaphandre.nix { };
schleuder = handleTest ./schleuder.nix { };
schleuder = runTest ./schleuder.nix;
scion-freestanding-deployment = handleTest ./scion/freestanding-deployment { };
scrutiny = runTest ./scrutiny.nix;
scx = runTest ./scx/default.nix;
sddm = handleTest ./sddm.nix { };
sddm = import ./sddm.nix { inherit runTest; };
sdl3 = runTest ./sdl3.nix;
seafile = runTest ./seafile.nix;
searx = runTest ./searx.nix;
@@ -1454,7 +1454,7 @@ in
tracee = handleTestOn [ "x86_64-linux" ] ./tracee.nix { };
trezord = runTest ./trezord.nix;
trickster = runTest ./trickster.nix;
trilium-server = handleTestOn [ "x86_64-linux" ] ./trilium-server.nix { };
trilium-server = runTestOn [ "x86_64-linux" ] ./trilium-server.nix;
tsm-client-gui = runTest ./tsm-client-gui.nix;
ttyd = runTest ./web-servers/ttyd.nix;
tt-rss = runTest ./web-apps/tt-rss.nix;
@@ -1511,7 +1511,7 @@ in
velocity = runTest ./velocity.nix;
vengi-tools = runTest ./vengi-tools.nix;
victorialogs = runTest ./victorialogs.nix;
victoriametrics = handleTest ./victoriametrics { };
victoriametrics = import ./victoriametrics { inherit runTest; };
vikunja = runTest ./vikunja.nix;
virtualbox = handleTestOn [ "x86_64-linux" ] ./virtualbox.nix { };
vm-variant = handleTest ./vm-variant.nix { };
+106 -108
View File
@@ -1,121 +1,119 @@
import ./make-test-python.nix (
{ lib, ... }:
{
name = "easytier";
meta.maintainers = with lib.maintainers; [ ltrump ];
{ lib, ... }:
{
name = "easytier";
meta.maintainers = with lib.maintainers; [ ltrump ];
nodes =
let
genPeer =
hostConfig: settings:
lib.mkMerge [
{
services.easytier = {
enable = true;
instances.default = {
settings = {
network_name = "easytier_test";
network_secret = "easytier_test_secret";
} // settings;
};
nodes =
let
genPeer =
hostConfig: settings:
lib.mkMerge [
{
services.easytier = {
enable = true;
instances.default = {
settings = {
network_name = "easytier_test";
network_secret = "easytier_test_secret";
} // settings;
};
networking.useDHCP = false;
networking.firewall.allowedTCPPorts = [
11010
11011
];
networking.firewall.allowedUDPPorts = [
11010
11011
];
}
hostConfig
];
in
{
relay =
genPeer
{
virtualisation.vlans = [
1
2
];
networking.interfaces.eth1.ipv4.addresses = [
{
address = "192.168.1.11";
prefixLength = 24;
}
];
networking.interfaces.eth2.ipv4.addresses = [
{
address = "192.168.2.11";
prefixLength = 24;
}
];
}
{
ipv4 = "10.144.144.1";
listeners = [
"tcp://0.0.0.0:11010"
"wss://0.0.0.0:11011"
];
};
peer1 =
genPeer
{
virtualisation.vlans = [ 1 ];
}
{
ipv4 = "10.144.144.2";
peers = [ "tcp://192.168.1.11:11010" ];
};
networking.useDHCP = false;
networking.firewall.allowedTCPPorts = [
11010
11011
];
networking.firewall.allowedUDPPorts = [
11010
11011
];
}
hostConfig
];
in
{
relay =
genPeer
{
virtualisation.vlans = [
1
2
];
peer2 =
genPeer
{
virtualisation.vlans = [ 2 ];
}
{
ipv4 = "10.144.144.3";
peers = [ "wss://192.168.2.11:11011" ];
};
};
networking.interfaces.eth1.ipv4.addresses = [
{
address = "192.168.1.11";
prefixLength = 24;
}
];
testScript = ''
start_all()
networking.interfaces.eth2.ipv4.addresses = [
{
address = "192.168.2.11";
prefixLength = 24;
}
];
}
{
ipv4 = "10.144.144.1";
listeners = [
"tcp://0.0.0.0:11010"
"wss://0.0.0.0:11011"
];
};
relay.wait_for_unit("easytier-default.service")
peer1.wait_for_unit("easytier-default.service")
peer2.wait_for_unit("easytier-default.service")
peer1 =
genPeer
{
virtualisation.vlans = [ 1 ];
}
{
ipv4 = "10.144.144.2";
peers = [ "tcp://192.168.1.11:11010" ];
};
# relay is accessible by the other hosts
peer1.succeed("ping -c5 192.168.1.11")
peer2.succeed("ping -c5 192.168.2.11")
peer2 =
genPeer
{
virtualisation.vlans = [ 2 ];
}
{
ipv4 = "10.144.144.3";
peers = [ "wss://192.168.2.11:11011" ];
};
};
# The other hosts are in separate vlans
peer1.fail("ping -c5 192.168.2.11")
peer2.fail("ping -c5 192.168.1.11")
testScript = ''
start_all()
# Each host can ping themselves through EasyTier
relay.succeed("ping -c5 10.144.144.1")
peer1.succeed("ping -c5 10.144.144.2")
peer2.succeed("ping -c5 10.144.144.3")
relay.wait_for_unit("easytier-default.service")
peer1.wait_for_unit("easytier-default.service")
peer2.wait_for_unit("easytier-default.service")
# Relay is accessible by the other hosts through EasyTier
peer1.succeed("ping -c5 10.144.144.1")
peer2.succeed("ping -c5 10.144.144.1")
# relay is accessible by the other hosts
peer1.succeed("ping -c5 192.168.1.11")
peer2.succeed("ping -c5 192.168.2.11")
# Relay can access the other hosts through EasyTier
relay.succeed("ping -c5 10.144.144.2")
relay.succeed("ping -c5 10.144.144.3")
# The other hosts are in separate vlans
peer1.fail("ping -c5 192.168.2.11")
peer2.fail("ping -c5 192.168.1.11")
# The other hosts in separate vlans can access each other through EasyTier
peer1.succeed("ping -c5 10.144.144.3")
peer2.succeed("ping -c5 10.144.144.2")
'';
}
)
# Each host can ping themselves through EasyTier
relay.succeed("ping -c5 10.144.144.1")
peer1.succeed("ping -c5 10.144.144.2")
peer2.succeed("ping -c5 10.144.144.3")
# Relay is accessible by the other hosts through EasyTier
peer1.succeed("ping -c5 10.144.144.1")
peer2.succeed("ping -c5 10.144.144.1")
# Relay can access the other hosts through EasyTier
relay.succeed("ping -c5 10.144.144.2")
relay.succeed("ping -c5 10.144.144.3")
# The other hosts in separate vlans can access each other through EasyTier
peer1.succeed("ping -c5 10.144.144.3")
peer2.succeed("ping -c5 10.144.144.2")
'';
}
+70 -67
View File
@@ -1,78 +1,81 @@
import ../make-test-python.nix (
{ pkgs, ... }:
let
inherit (import ./../ssh-keys.nix pkgs)
snakeOilPrivateKey
snakeOilPublicKey
;
{
lib,
pkgs,
hostPkgs,
...
}:
let
inherit (import ./../ssh-keys.nix hostPkgs)
snakeOilPrivateKey
snakeOilPublicKey
;
# don't check host keys or known hosts, use the snakeoil ssh key
ssh-config = builtins.toFile "ssh.conf" ''
UserKnownHostsFile=/dev/null
StrictHostKeyChecking=no
IdentityFile=~/.ssh/id_snakeoil
'';
in
{
name = "google-oslogin";
meta = with pkgs.lib.maintainers; {
maintainers = [ ];
};
# don't check host keys or known hosts, use the snakeoil ssh key
ssh-config = builtins.toFile "ssh.conf" ''
UserKnownHostsFile=/dev/null
StrictHostKeyChecking=no
IdentityFile=~/.ssh/id_snakeoil
'';
in
{
name = "google-oslogin";
meta = with lib.maintainers; {
maintainers = [ ];
};
nodes = {
# the server provides both the the mocked google metadata server and the ssh server
server = (import ./server.nix pkgs);
nodes = {
# the server provides both the the mocked google metadata server and the ssh server
server = ./server.nix;
client = { ... }: { };
};
testScript = ''
MOCKUSER = "mockuser_nixos_org"
MOCKADMIN = "mockadmin_nixos_org"
start_all()
client = { ... }: { };
};
testScript = ''
MOCKUSER = "mockuser_nixos_org"
MOCKADMIN = "mockadmin_nixos_org"
start_all()
server.wait_for_unit("mock-google-metadata.service")
server.wait_for_open_port(80)
server.wait_for_unit("mock-google-metadata.service")
server.wait_for_open_port(80)
# mockserver should return a non-expired ssh key for both mockuser and mockadmin
server.succeed(
f'${pkgs.google-guest-oslogin}/bin/google_authorized_keys {MOCKUSER} | grep -q "${snakeOilPublicKey}"'
)
server.succeed(
f'${pkgs.google-guest-oslogin}/bin/google_authorized_keys {MOCKADMIN} | grep -q "${snakeOilPublicKey}"'
)
# mockserver should return a non-expired ssh key for both mockuser and mockadmin
server.succeed(
f'${pkgs.google-guest-oslogin}/bin/google_authorized_keys {MOCKUSER} | grep -q "${snakeOilPublicKey}"'
)
server.succeed(
f'${pkgs.google-guest-oslogin}/bin/google_authorized_keys {MOCKADMIN} | grep -q "${snakeOilPublicKey}"'
)
# install snakeoil ssh key on the client, and provision .ssh/config file
client.succeed("mkdir -p ~/.ssh")
client.succeed(
"cat ${snakeOilPrivateKey} > ~/.ssh/id_snakeoil"
)
client.succeed("chmod 600 ~/.ssh/id_snakeoil")
client.succeed("cp ${ssh-config} ~/.ssh/config")
# install snakeoil ssh key on the client, and provision .ssh/config file
client.succeed("mkdir -p ~/.ssh")
client.succeed(
"cat ${snakeOilPrivateKey} > ~/.ssh/id_snakeoil"
)
client.succeed("chmod 600 ~/.ssh/id_snakeoil")
client.succeed("cp ${ssh-config} ~/.ssh/config")
client.wait_for_unit("network.target")
server.wait_for_unit("sshd.service")
client.wait_for_unit("network.target")
server.wait_for_unit("sshd.service")
# we should not be able to connect as non-existing user
client.fail("ssh ghost@server 'true'")
# we should not be able to connect as non-existing user
client.fail("ssh ghost@server 'true'")
# we should be able to connect as mockuser
client.succeed(f"ssh {MOCKUSER}@server 'true'")
# but we shouldn't be able to sudo
client.fail(
f"ssh {MOCKUSER}@server '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'"
)
# we should be able to connect as mockuser
client.succeed(f"ssh {MOCKUSER}@server 'true'")
# but we shouldn't be able to sudo
client.fail(
f"ssh {MOCKUSER}@server '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'"
)
# we should also be able to log in as mockadmin
client.succeed(f"ssh {MOCKADMIN}@server 'true'")
# pam_oslogin_admin.so should now have generated a sudoers file
server.succeed(
f"find /run/google-sudoers.d | grep -q '/run/google-sudoers.d/{MOCKADMIN}'"
)
# we should also be able to log in as mockadmin
client.succeed(f"ssh {MOCKADMIN}@server 'true'")
# pam_oslogin_admin.so should now have generated a sudoers file
server.succeed(
f"find /run/google-sudoers.d | grep -q '/run/google-sudoers.d/{MOCKADMIN}'"
)
# and we should be able to sudo
client.succeed(
f"ssh {MOCKADMIN}@server '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'"
)
'';
}
)
# and we should be able to sudo
client.succeed(
f"ssh {MOCKADMIN}@server '/run/wrappers/bin/sudo /run/current-system/sw/bin/id' | grep -q 'root'"
)
'';
}
+1 -1
View File
@@ -1,4 +1,4 @@
import ./make-test-python.nix {
{
name = "mediatomb";
nodes = {
+73 -76
View File
@@ -1,98 +1,95 @@
import ./make-test-python.nix (
{ pkgs, ... }:
{ lib, hostPkgs, ... }:
let
# Make sure we don't have to go through the startup tutorial
customMuseScoreConfig = pkgs.writeText "MuseScore4.ini" ''
[application]
hasCompletedFirstLaunchSetup=true
let
# Make sure we don't have to go through the startup tutorial
customMuseScoreConfig = hostPkgs.writeText "MuseScore4.ini" ''
[application]
hasCompletedFirstLaunchSetup=true
[project]
preferredScoreCreationMode=1
'';
in
{
name = "musescore";
meta = with pkgs.lib.maintainers; {
maintainers = [ turion ];
[project]
preferredScoreCreationMode=1
'';
in
{
name = "musescore";
meta = with lib.maintainers; {
maintainers = [ turion ];
};
nodes.machine =
{ pkgs, ... }:
{
imports = [
./common/x11.nix
];
services.xserver.enable = true;
environment.systemPackages = with pkgs; [
musescore
pdfgrep
];
};
nodes.machine =
{ ... }:
enableOCR = true;
{
imports = [
./common/x11.nix
];
testScript =
{ ... }:
''
start_all()
machine.wait_for_x()
services.xserver.enable = true;
environment.systemPackages = with pkgs; [
musescore
pdfgrep
];
};
# Inject custom settings
machine.succeed("mkdir -p /root/.config/MuseScore/")
machine.succeed(
"cp ${customMuseScoreConfig} /root/.config/MuseScore/MuseScore4.ini"
)
enableOCR = true;
# Start MuseScore window
machine.execute("env XDG_RUNTIME_DIR=$PWD DISPLAY=:0.0 mscore >&2 &")
testScript =
{ ... }:
''
start_all()
machine.wait_for_x()
# Wait until MuseScore has launched
machine.wait_for_window("MuseScore Studio")
# Inject custom settings
machine.succeed("mkdir -p /root/.config/MuseScore/")
machine.succeed(
"cp ${customMuseScoreConfig} /root/.config/MuseScore/MuseScore4.ini"
)
machine.screenshot("MuseScore0")
# Start MuseScore window
machine.execute("env XDG_RUNTIME_DIR=$PWD DISPLAY=:0.0 mscore >&2 &")
# Create a new score
machine.send_key("ctrl-n")
# Wait until MuseScore has launched
machine.wait_for_window("MuseScore Studio")
# Wait until the creation wizard appears
machine.wait_for_window("New score")
machine.screenshot("MuseScore0")
machine.screenshot("MuseScore1")
# Create a new score
machine.send_key("ctrl-n")
machine.send_key("tab")
machine.send_key("tab")
machine.send_key("ret")
# Wait until the creation wizard appears
machine.wait_for_window("New score")
machine.sleep(2)
machine.screenshot("MuseScore1")
machine.send_key("tab")
# Type the beginning of https://de.wikipedia.org/wiki/Alle_meine_Entchen
machine.send_chars("cdef6gg5aaaa7g")
machine.sleep(1)
machine.send_key("tab")
machine.send_key("tab")
machine.send_key("ret")
machine.screenshot("MuseScore2")
machine.sleep(2)
# Go to the export dialogue and create a PDF
machine.send_key("ctrl-p")
machine.send_key("tab")
# Type the beginning of https://de.wikipedia.org/wiki/Alle_meine_Entchen
machine.send_chars("cdef6gg5aaaa7g")
machine.sleep(1)
# Wait until the Print dialogue appears.
machine.wait_for_window("Print")
machine.screenshot("MuseScore2")
machine.screenshot("MuseScore4")
machine.send_key("alt-p")
machine.sleep(1)
# Go to the export dialogue and create a PDF
machine.send_key("ctrl-p")
machine.screenshot("MuseScore5")
# Wait until the Print dialogue appears.
machine.wait_for_window("Print")
# Wait until PDF is exported
machine.wait_for_file('"/root/Untitled score.pdf"')
machine.screenshot("MuseScore4")
machine.send_key("alt-p")
machine.sleep(1)
machine.screenshot("MuseScore5")
# Wait until PDF is exported
machine.wait_for_file('"/root/Untitled score.pdf"')
## Check that it contains the title of the score
machine.succeed('pdfgrep "Untitled score" "/root/Untitled score.pdf"')
machine.copy_from_vm("/root/Untitled score.pdf")
'';
}
)
## Check that it contains the title of the score
machine.succeed('pdfgrep "Untitled score" "/root/Untitled score.pdf"')
machine.copy_from_vm("/root/Untitled score.pdf")
'';
}
+57 -64
View File
@@ -1,73 +1,66 @@
import ../make-test-python.nix (
{ lib, ... }:
let
peer1-ip = "538:f40f:1c51:9bd9:9569:d3f6:d0a1:b2df";
peer2-ip = "5b6:6776:fee0:c1f3:db00:b6a8:d013:d38f";
in
{
name = "mycelium";
meta.maintainers = with lib.maintainers; [ lassulus ];
{ lib, ... }:
let
peer1-ip = "538:f40f:1c51:9bd9:9569:d3f6:d0a1:b2df";
peer2-ip = "5b6:6776:fee0:c1f3:db00:b6a8:d013:d38f";
in
{
name = "mycelium";
meta.maintainers = with lib.maintainers; [ lassulus ];
nodes = {
peer1 =
{ config, pkgs, ... }:
nodes = {
peer1 = {
virtualisation.vlans = [ 1 ];
networking.interfaces.eth1.ipv4.addresses = [
{
virtualisation.vlans = [ 1 ];
networking.interfaces.eth1.ipv4.addresses = [
{
address = "192.168.1.11";
prefixLength = 24;
}
];
address = "192.168.1.11";
prefixLength = 24;
}
];
services.mycelium = {
enable = true;
addHostedPublicNodes = false;
openFirewall = true;
keyFile = ./peer1.key;
peers = [
"quic://192.168.1.12:9651"
"tcp://192.168.1.12:9651"
];
};
};
peer2 =
{ config, pkgs, ... }:
{
virtualisation.vlans = [ 1 ];
networking.interfaces.eth1.ipv4.addresses = [
{
address = "192.168.1.12";
prefixLength = 24;
}
];
services.mycelium = {
enable = true;
addHostedPublicNodes = false;
openFirewall = true;
keyFile = ./peer2.key;
};
};
services.mycelium = {
enable = true;
addHostedPublicNodes = false;
openFirewall = true;
keyFile = ./peer1.key;
peers = [
"quic://192.168.1.12:9651"
"tcp://192.168.1.12:9651"
];
};
};
testScript = ''
start_all()
peer2 = {
virtualisation.vlans = [ 1 ];
networking.interfaces.eth1.ipv4.addresses = [
{
address = "192.168.1.12";
prefixLength = 24;
}
];
peer1.wait_for_unit("network-online.target")
peer2.wait_for_unit("network-online.target")
peer1.wait_for_unit("mycelium.service")
peer2.wait_for_unit("mycelium.service")
services.mycelium = {
enable = true;
addHostedPublicNodes = false;
openFirewall = true;
keyFile = ./peer2.key;
};
};
};
# Give mycelium some time to discover the other peer
peer1.wait_until_succeeds("ping -c1 ${peer2-ip}", timeout=10)
peer2.succeed("ping -c1 ${peer1-ip}")
testScript = ''
start_all()
peer1.succeed("mycelium peers list | grep 192.168.1.12")
peer2.succeed("mycelium peers list | grep 192.168.1.11")
peer1.wait_for_unit("network-online.target")
peer2.wait_for_unit("network-online.target")
peer1.wait_for_unit("mycelium.service")
peer2.wait_for_unit("mycelium.service")
'';
}
)
# Give mycelium some time to discover the other peer
peer1.wait_until_succeeds("ping -c1 ${peer2-ip}", timeout=10)
peer2.succeed("ping -c1 ${peer1-ip}")
peer1.succeed("mycelium peers list | grep 192.168.1.12")
peer2.succeed("mycelium peers list | grep 192.168.1.11")
'';
}
+8 -13
View File
@@ -1,19 +1,14 @@
import ./make-test-python.nix {
{
name = "neo4j";
nodes = {
server =
{ ... }:
nodes.server = {
virtualisation.memorySize = 4096;
virtualisation.diskSize = 1024;
{
virtualisation.memorySize = 4096;
virtualisation.diskSize = 1024;
services.neo4j.enable = true;
# require tls certs to be available
services.neo4j.https.enable = false;
services.neo4j.bolt.enable = false;
};
services.neo4j.enable = true;
# require tls certs to be available
services.neo4j.https.enable = false;
services.neo4j.bolt.enable = false;
};
testScript = ''
+1 -1
View File
@@ -2,7 +2,7 @@ let
certs = import ./common/acme/server/snakeoil-certs.nix;
domain = certs.domain;
in
import ./make-test-python.nix {
{
name = "schleuder";
nodes.machine =
{ pkgs, ... }:
+51 -66
View File
@@ -1,77 +1,62 @@
{ runTest }:
{
system ? builtins.currentSystem,
config ? { },
pkgs ? import ../.. { inherit system config; },
}:
default = runTest {
name = "sddm";
with import ../lib/testing-python.nix { inherit system pkgs; };
let
inherit (pkgs) lib;
tests = {
default = {
name = "sddm";
nodes.machine =
{ ... }:
{
imports = [ ./common/user-account.nix ];
services.xserver.enable = true;
services.displayManager.sddm.enable = true;
services.displayManager.defaultSession = "none+icewm";
services.xserver.windowManager.icewm.enable = true;
};
enableOCR = true;
testScript =
{ nodes, ... }:
let
user = nodes.machine.users.users.alice;
in
''
start_all()
machine.wait_for_text("(?i)select your user")
machine.screenshot("sddm")
machine.send_chars("${user.password}\n")
machine.wait_for_file("/tmp/xauth_*")
machine.succeed("xauth merge /tmp/xauth_*")
machine.wait_for_window("^IceWM ")
'';
nodes.machine = {
imports = [ ./common/user-account.nix ];
services.xserver.enable = true;
services.displayManager.sddm.enable = true;
services.displayManager.defaultSession = "none+icewm";
services.xserver.windowManager.icewm.enable = true;
};
autoLogin = {
enableOCR = true;
testScript =
{ nodes, ... }:
let
user = nodes.machine.users.users.alice;
in
''
start_all()
machine.wait_for_text("(?i)select your user")
machine.screenshot("sddm")
machine.send_chars("${user.password}\n")
machine.wait_for_file("/tmp/xauth_*")
machine.succeed("xauth merge /tmp/xauth_*")
machine.wait_for_window("^IceWM ")
'';
};
autoLogin = runTest (
{ lib, ... }:
{
name = "sddm-autologin";
meta = with pkgs.lib.maintainers; {
meta = with lib.maintainers; {
maintainers = [ ttuegel ];
};
nodes.machine =
{ ... }:
{
imports = [ ./common/user-account.nix ];
services.xserver.enable = true;
services.displayManager = {
sddm.enable = true;
autoLogin = {
enable = true;
user = "alice";
};
nodes.machine = {
imports = [ ./common/user-account.nix ];
services.xserver.enable = true;
services.displayManager = {
sddm.enable = true;
autoLogin = {
enable = true;
user = "alice";
};
services.displayManager.defaultSession = "none+icewm";
services.xserver.windowManager.icewm.enable = true;
};
services.displayManager.defaultSession = "none+icewm";
services.xserver.windowManager.icewm.enable = true;
};
testScript =
{ nodes, ... }:
''
start_all()
machine.wait_for_file("/tmp/xauth_*")
machine.succeed("xauth merge /tmp/xauth_*")
machine.wait_for_window("^IceWM ")
'';
};
};
in
lib.mapAttrs (lib.const makeTest) tests
testScript = ''
start_all()
machine.wait_for_file("/tmp/xauth_*")
machine.succeed("xauth merge /tmp/xauth_*")
machine.wait_for_window("^IceWM ")
'';
}
);
}
+43 -46
View File
@@ -1,55 +1,52 @@
import ./make-test-python.nix (
{ ... }:
{
name = "trilium-server";
nodes = {
default = {
services.trilium-server.enable = true;
};
configured = {
services.trilium-server = {
enable = true;
dataDir = "/data/trilium";
};
};
nginx = {
services.trilium-server = {
enable = true;
nginx.enable = true;
nginx.hostName = "trilium.example.com";
};
{
name = "trilium-server";
nodes = {
default = {
services.trilium-server.enable = true;
};
configured = {
services.trilium-server = {
enable = true;
dataDir = "/data/trilium";
};
};
testScript = ''
start_all()
nginx = {
services.trilium-server = {
enable = true;
nginx.enable = true;
nginx.hostName = "trilium.example.com";
};
};
};
with subtest("by default works without configuration"):
default.wait_for_unit("trilium-server.service")
testScript = ''
start_all()
with subtest("by default available on port 8080"):
default.wait_for_unit("trilium-server.service")
default.wait_for_open_port(8080)
# we output to /dev/null here to avoid a python UTF-8 decode error
# but the check will still fail if the service doesn't respond
default.succeed("curl --fail -o /dev/null 127.0.0.1:8080")
with subtest("by default works without configuration"):
default.wait_for_unit("trilium-server.service")
with subtest("by default creates empty document"):
default.wait_for_unit("trilium-server.service")
default.succeed("test -f /var/lib/trilium/document.db")
with subtest("by default available on port 8080"):
default.wait_for_unit("trilium-server.service")
default.wait_for_open_port(8080)
# we output to /dev/null here to avoid a python UTF-8 decode error
# but the check will still fail if the service doesn't respond
default.succeed("curl --fail -o /dev/null 127.0.0.1:8080")
with subtest("configured with custom data store"):
configured.wait_for_unit("trilium-server.service")
configured.succeed("test -f /data/trilium/document.db")
with subtest("by default creates empty document"):
default.wait_for_unit("trilium-server.service")
default.succeed("test -f /var/lib/trilium/document.db")
with subtest("nginx with custom host name"):
nginx.wait_for_unit("trilium-server.service")
nginx.wait_for_unit("nginx.service")
with subtest("configured with custom data store"):
configured.wait_for_unit("trilium-server.service")
configured.succeed("test -f /data/trilium/document.db")
nginx.succeed(
"curl --resolve 'trilium.example.com:80:127.0.0.1' http://trilium.example.com/"
)
'';
}
)
with subtest("nginx with custom host name"):
nginx.wait_for_unit("trilium-server.service")
nginx.wait_for_unit("nginx.service")
nginx.succeed(
"curl --resolve 'trilium.example.com:80:127.0.0.1' http://trilium.example.com/"
)
'';
}
+4 -9
View File
@@ -1,11 +1,6 @@
{ runTest }:
{
system ? builtins.currentSystem,
config ? { },
pkgs ? import ../../.. { inherit system config; },
}:
{
remote-write = import ./remote-write.nix { inherit system pkgs; };
vmalert = import ./vmalert.nix { inherit system pkgs; };
external-promscrape-config = import ./external-promscrape-config.nix { inherit system pkgs; };
remote-write = runTest ./remote-write.nix;
vmalert = runTest ./vmalert.nix;
external-promscrape-config = runTest ./external-promscrape-config.nix;
}
@@ -1,82 +1,70 @@
import ../make-test-python.nix (
{
lib,
pkgs,
...
}:
let
nodeExporterPort = 9100;
promscrapeConfig = {
global = {
scrape_interval = "2s";
};
scrape_configs = [
{
job_name = "node";
static_configs = [
{
targets = [
"node:${toString nodeExporterPort}"
];
}
];
}
];
{ lib, pkgs, ... }:
let
nodeExporterPort = 9100;
promscrapeConfig = {
global = {
scrape_interval = "2s";
};
settingsFormat = pkgs.formats.yaml { };
promscrapeConfigYaml = settingsFormat.generate "prometheusConfig.yaml" promscrapeConfig;
in
{
name = "victoriametrics-external-promscrape-config";
meta = with pkgs.lib.maintainers; {
maintainers = [
ryan4yin
];
};
nodes = {
victoriametrics =
{
config,
pkgs,
...
}:
{
environment.systemPackages = [ pkgs.jq ];
networking.firewall.allowedTCPPorts = [ 8428 ];
services.victoriametrics = {
enable = true;
extraOptions = [
"-promscrape.config=${toString promscrapeConfigYaml}"
scrape_configs = [
{
job_name = "node";
static_configs = [
{
targets = [
"node:${toString nodeExporterPort}"
];
};
};
}
];
}
];
};
settingsFormat = pkgs.formats.yaml { };
promscrapeConfigYaml = settingsFormat.generate "prometheusConfig.yaml" promscrapeConfig;
in
{
name = "victoriametrics-external-promscrape-config";
meta = with lib.maintainers; {
maintainers = [
ryan4yin
];
};
node =
{ ... }:
{
services.prometheus.exporters.node = {
enable = true;
openFirewall = true;
};
nodes = {
victoriametrics =
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.jq ];
networking.firewall.allowedTCPPorts = [ 8428 ];
services.victoriametrics = {
enable = true;
extraOptions = [
"-promscrape.config=${toString promscrapeConfigYaml}"
];
};
};
node = {
services.prometheus.exporters.node = {
enable = true;
openFirewall = true;
};
};
};
testScript = ''
node.wait_for_unit("prometheus-node-exporter")
node.wait_for_open_port(${toString nodeExporterPort})
testScript = ''
node.wait_for_unit("prometheus-node-exporter")
node.wait_for_open_port(${toString nodeExporterPort})
victoriametrics.wait_for_unit("victoriametrics")
victoriametrics.wait_for_open_port(8428)
victoriametrics.wait_for_unit("victoriametrics")
victoriametrics.wait_for_open_port(8428)
promscrape_config = victoriametrics.succeed("journalctl -u victoriametrics -o cat | grep 'promscrape.config'")
assert '${toString promscrapeConfigYaml}' in promscrape_config
promscrape_config = victoriametrics.succeed("journalctl -u victoriametrics -o cat | grep 'promscrape.config'")
assert '${toString promscrapeConfigYaml}' in promscrape_config
victoriametrics.wait_until_succeeds(
"curl -sf 'http://localhost:8428/api/v1/query?query=node_exporter_build_info\{instance=\"node:9100\"\}' | "
+ "jq '.data.result[0].value[1]' | grep '\"1\"'"
)
'';
}
)
victoriametrics.wait_until_succeeds(
"curl -sf 'http://localhost:8428/api/v1/query?query=node_exporter_build_info\{instance=\"node:9100\"\}' | "
+ "jq '.data.result[0].value[1]' | grep '\"1\"'"
)
'';
}
+76 -92
View File
@@ -1,103 +1,87 @@
# Primarily reference the implementation of <nixos/tests/prometheus/remote-write.nix>
import ../make-test-python.nix (
{
lib,
pkgs,
...
}:
let
username = "vmtest";
password = "fsddfy8233rb"; # random string
passwordFile = pkgs.writeText "password-file" password;
in
{
name = "victoriametrics-remote-write";
meta = with pkgs.lib.maintainers; {
maintainers = [
yorickvp
ryan4yin
];
};
{ lib, pkgs, ... }:
let
username = "vmtest";
password = "fsddfy8233rb"; # random string
passwordFile = pkgs.writeText "password-file" password;
in
{
name = "victoriametrics-remote-write";
meta = with lib.maintainers; {
maintainers = [
yorickvp
ryan4yin
];
};
nodes = {
victoriametrics =
{
config,
pkgs,
...
}:
{
environment.systemPackages = [ pkgs.jq ];
networking.firewall.allowedTCPPorts = [ 8428 ];
services.victoriametrics = {
enable = true;
extraOptions = [
"-httpAuth.username=${username}"
"-httpAuth.password=file://${toString passwordFile}"
nodes = {
victoriametrics =
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.jq ];
networking.firewall.allowedTCPPorts = [ 8428 ];
services.victoriametrics = {
enable = true;
extraOptions = [
"-httpAuth.username=${username}"
"-httpAuth.password=file://${toString passwordFile}"
];
};
};
vmagent =
{ config, pkgs, ... }:
{
environment.systemPackages = [ pkgs.jq ];
services.vmagent = {
enable = true;
remoteWrite = {
url = "http://victoriametrics:8428/api/v1/write";
basicAuthUsername = username;
basicAuthPasswordFile = toString passwordFile;
};
prometheusConfig = {
global = {
scrape_interval = "2s";
};
scrape_configs = [
{
job_name = "node";
static_configs = [
{
targets = [
"node:${toString config.services.prometheus.exporters.node.port}"
];
}
];
}
];
};
};
};
vmagent =
{
config,
pkgs,
...
}:
{
environment.systemPackages = [ pkgs.jq ];
services.vmagent = {
enable = true;
remoteWrite = {
url = "http://victoriametrics:8428/api/v1/write";
basicAuthUsername = username;
basicAuthPasswordFile = toString passwordFile;
};
prometheusConfig = {
global = {
scrape_interval = "2s";
};
scrape_configs = [
{
job_name = "node";
static_configs = [
{
targets = [
"node:${toString config.services.prometheus.exporters.node.port}"
];
}
];
}
];
};
};
};
node =
{ ... }:
{
services.prometheus.exporters.node = {
enable = true;
openFirewall = true;
};
};
node = {
services.prometheus.exporters.node = {
enable = true;
openFirewall = true;
};
};
};
testScript = ''
node.wait_for_unit("prometheus-node-exporter")
node.wait_for_open_port(9100)
testScript = ''
node.wait_for_unit("prometheus-node-exporter")
node.wait_for_open_port(9100)
victoriametrics.wait_for_unit("victoriametrics")
victoriametrics.wait_for_open_port(8428)
victoriametrics.wait_for_unit("victoriametrics")
victoriametrics.wait_for_open_port(8428)
vmagent.wait_for_unit("vmagent")
vmagent.wait_for_unit("vmagent")
# check remote write
victoriametrics.wait_until_succeeds(
"curl --user '${username}:${password}' -sf 'http://localhost:8428/api/v1/query?query=node_exporter_build_info\{instance=\"node:9100\"\}' | "
+ "jq '.data.result[0].value[1]' | grep '\"1\"'"
)
'';
}
)
# check remote write
victoriametrics.wait_until_succeeds(
"curl --user '${username}:${password}' -sf 'http://localhost:8428/api/v1/query?query=node_exporter_build_info\{instance=\"node:9100\"\}' | "
+ "jq '.data.result[0].value[1]' | grep '\"1\"'"
)
'';
}
+142 -164
View File
@@ -1,179 +1,157 @@
# Primarily reference the implementation of <nixos/tests/prometheus/alertmanager.nix>
import ../make-test-python.nix (
{
lib,
pkgs,
...
}:
{
name = "victoriametrics-vmalert";
meta = with pkgs.lib.maintainers; {
maintainers = [
yorickvp
ryan4yin
];
{ lib, pkgs, ... }:
{
name = "victoriametrics-vmalert";
meta = with lib.maintainers; {
maintainers = [
yorickvp
ryan4yin
];
};
nodes = {
victoriametrics =
{ config, pkgs, ... }:
{
environment.systemPackages = [ pkgs.jq ];
networking.firewall.allowedTCPPorts = [ 8428 ];
services.victoriametrics = {
enable = true;
prometheusConfig = {
global = {
scrape_interval = "2s";
};
scrape_configs = [
{
job_name = "alertmanager";
static_configs = [
{
targets = [
"alertmanager:${toString config.services.prometheus.alertmanager.port}"
];
}
];
}
{
job_name = "node";
static_configs = [
{
targets = [
"node:${toString config.services.prometheus.exporters.node.port}"
];
}
];
}
];
};
};
services.vmalert.instances."" = {
enable = true;
settings = {
"datasource.url" = "http://localhost:8428"; # victoriametrics' api
"notifier.url" = [
"http://alertmanager:${toString config.services.prometheus.alertmanager.port}"
]; # alertmanager's api
rule = [
(pkgs.writeText "instance-down.yml" ''
groups:
- name: test
rules:
- alert: InstanceDown
expr: up == 0
for: 5s
labels:
severity: page
annotations:
summary: "Instance {{ $labels.instance }} down"
'')
];
};
};
};
alertmanager = {
services.prometheus.alertmanager = {
enable = true;
openFirewall = true;
configuration = {
global = {
resolve_timeout = "1m";
};
route = {
# Root route node
receiver = "test";
group_by = [ "..." ];
continue = false;
group_wait = "1s";
group_interval = "15s";
repeat_interval = "24h";
};
receivers = [
{
name = "test";
webhook_configs = [
{
url = "http://logger:6725";
send_resolved = true;
max_alerts = 0;
}
];
}
];
};
};
};
nodes = {
victoriametrics =
{
config,
pkgs,
...
}:
{
environment.systemPackages = [ pkgs.jq ];
networking.firewall.allowedTCPPorts = [ 8428 ];
services.victoriametrics = {
enable = true;
prometheusConfig = {
global = {
scrape_interval = "2s";
};
scrape_configs = [
{
job_name = "alertmanager";
static_configs = [
{
targets = [
"alertmanager:${toString config.services.prometheus.alertmanager.port}"
];
}
];
}
{
job_name = "node";
static_configs = [
{
targets = [
"node:${toString config.services.prometheus.exporters.node.port}"
];
}
];
}
];
};
};
logger = {
networking.firewall.allowedTCPPorts = [ 6725 ];
services.vmalert.instances."" = {
enable = true;
settings = {
"datasource.url" = "http://localhost:8428"; # victoriametrics' api
"notifier.url" = [
"http://alertmanager:${toString config.services.prometheus.alertmanager.port}"
]; # alertmanager's api
rule = [
(pkgs.writeText "instance-down.yml" ''
groups:
- name: test
rules:
- alert: InstanceDown
expr: up == 0
for: 5s
labels:
severity: page
annotations:
summary: "Instance {{ $labels.instance }} down"
'')
];
};
};
};
alertmanager =
{
config,
pkgs,
...
}:
{
services.prometheus.alertmanager = {
enable = true;
openFirewall = true;
configuration = {
global = {
resolve_timeout = "1m";
};
route = {
# Root route node
receiver = "test";
group_by = [ "..." ];
continue = false;
group_wait = "1s";
group_interval = "15s";
repeat_interval = "24h";
};
receivers = [
{
name = "test";
webhook_configs = [
{
url = "http://logger:6725";
send_resolved = true;
max_alerts = 0;
}
];
}
];
};
};
};
logger =
{
config,
pkgs,
...
}:
{
networking.firewall.allowedTCPPorts = [ 6725 ];
services.prometheus.alertmanagerWebhookLogger.enable = true;
};
services.prometheus.alertmanagerWebhookLogger.enable = true;
};
};
testScript = ''
alertmanager.wait_for_unit("alertmanager")
alertmanager.wait_for_open_port(9093)
alertmanager.wait_until_succeeds("curl -s http://127.0.0.1:9093/-/ready")
testScript = ''
alertmanager.wait_for_unit("alertmanager")
alertmanager.wait_for_open_port(9093)
alertmanager.wait_until_succeeds("curl -s http://127.0.0.1:9093/-/ready")
logger.wait_for_unit("alertmanager-webhook-logger")
logger.wait_for_open_port(6725)
logger.wait_for_unit("alertmanager-webhook-logger")
logger.wait_for_open_port(6725)
victoriametrics.wait_for_unit("victoriametrics")
victoriametrics.wait_for_unit("vmalert")
victoriametrics.wait_for_open_port(8428)
victoriametrics.wait_for_unit("victoriametrics")
victoriametrics.wait_for_unit("vmalert")
victoriametrics.wait_for_open_port(8428)
victoriametrics.wait_until_succeeds(
"curl -sf 'http://127.0.0.1:8428/api/v1/query?query=count(up\{job=\"alertmanager\"\}==1)' | "
+ "jq '.data.result[0].value[1]' | grep '\"1\"'"
)
victoriametrics.wait_until_succeeds(
"curl -sf 'http://127.0.0.1:8428/api/v1/query?query=count(up\{job=\"alertmanager\"\}==1)' | "
+ "jq '.data.result[0].value[1]' | grep '\"1\"'"
)
victoriametrics.wait_until_succeeds(
"curl -sf 'http://127.0.0.1:8428/api/v1/query?query=sum(alertmanager_build_info)%20by%20(version)' | "
+ "jq '.data.result[0].metric.version' | grep '\"${pkgs.prometheus-alertmanager.version}\"'"
)
victoriametrics.wait_until_succeeds(
"curl -sf 'http://127.0.0.1:8428/api/v1/query?query=sum(alertmanager_build_info)%20by%20(version)' | "
+ "jq '.data.result[0].metric.version' | grep '\"${pkgs.prometheus-alertmanager.version}\"'"
)
victoriametrics.wait_until_succeeds(
"curl -sf 'http://127.0.0.1:8428/api/v1/query?query=count(up\{job=\"node\"\}!=1)' | "
+ "jq '.data.result[0].value[1]' | grep '\"1\"'"
)
victoriametrics.wait_until_succeeds(
"curl -sf 'http://127.0.0.1:8428/api/v1/query?query=count(up\{job=\"node\"\}!=1)' | "
+ "jq '.data.result[0].value[1]' | grep '\"1\"'"
)
victoriametrics.wait_until_succeeds(
"curl -sf 'http://127.0.0.1:8428/api/v1/query?query=alertmanager_notifications_total\{integration=\"webhook\"\}' | "
+ "jq '.data.result[0].value[1]' | grep -v '\"0\"'"
)
victoriametrics.wait_until_succeeds(
"curl -sf 'http://127.0.0.1:8428/api/v1/query?query=alertmanager_notifications_total\{integration=\"webhook\"\}' | "
+ "jq '.data.result[0].value[1]' | grep -v '\"0\"'"
)
logger.wait_until_succeeds(
"journalctl -o cat -u alertmanager-webhook-logger.service | grep '\"alertname\":\"InstanceDown\"'"
)
logger.wait_until_succeeds(
"journalctl -o cat -u alertmanager-webhook-logger.service | grep '\"alertname\":\"InstanceDown\"'"
)
logger.log(logger.succeed("systemd-analyze security alertmanager-webhook-logger.service | grep -v ''"))
logger.log(logger.succeed("systemd-analyze security alertmanager-webhook-logger.service | grep -v ''"))
alertmanager.log(alertmanager.succeed("systemd-analyze security alertmanager.service | grep -v ''"))
'';
}
)
alertmanager.log(alertmanager.succeed("systemd-analyze security alertmanager.service | grep -v ''"))
'';
}
@@ -0,0 +1,47 @@
{
lib,
stdenv,
fetchFromGitHub,
deadbeef,
pkg-config,
gtk3,
sqlite,
}:
stdenv.mkDerivation {
pname = "deadbeef-waveform-seekbar-plugin";
version = "0-unstable-2024-11-13";
# using a fork because original throws a compilation error
src = fetchFromGitHub {
owner = "Jbsco";
repo = "ddb_waveform_seekbar";
rev = "2e5ea867a77e37698524d22f41fc59ffae16e63d";
hash = "sha256-m6lBF+Yq1gah6kjb9VvIsjVg1i++08JPLzcLLMt+8J8=";
};
nativeBuildInputs = [ pkg-config ];
buildInputs = [
deadbeef
gtk3
sqlite
];
makeFlags = [ "gtk3" ];
installPhase = ''
runHook preInstall
mkdir -p $out/lib/deadbeef/
install -v -c -m 644 gtk3/ddb_misc_waveform_GTK3.so $out/lib/deadbeef/
runHook postInstall
'';
meta = {
description = "Waveform Seekbar plugin for DeaDBeeF audio player";
homepage = "https://github.com/cboxdoerfer/ddb_waveform_seekbar";
license = lib.licenses.gpl2Plus;
platforms = lib.platforms.linux;
maintainers = [ lib.maintainers.deudz ];
};
}
@@ -6,16 +6,16 @@
buildGoModule rec {
pname = "helm-diff";
version = "3.12.2";
version = "3.12.3";
src = fetchFromGitHub {
owner = "databus23";
repo = pname;
repo = "helm-diff";
rev = "v${version}";
hash = "sha256-N7n9/MjZR9jCRk2iZmFBOxwn6GVUNuUBaQHJqcgOQc4=";
hash = "sha256-zYeZwR8hDNYVJGdYjQNrQmyD5AwGcgyO7LzC5bd10k0=";
};
vendorHash = "sha256-uJxLpbFKdH5t08wZD/zPS5UPZO7YPtiBqcdN6997ik4=";
vendorHash = "sha256-rz5RZiKGM1AdDm4R2IPOYn///fKKmo96u2LROShFPJM=";
ldflags = [
"-s"
@@ -60,34 +60,35 @@
libvpl,
qrcodegencpp,
nix-update-script,
extra-cmake-modules,
}:
let
inherit (lib) optional optionals;
cef = cef-binary.overrideAttrs (oldAttrs: {
version = "127.3.5";
version = "138.0.17";
__intentionallyOverridingVersion = true; # `cef-binary` uses the overridden `srcHash` values in its source FOD
gitRevision = "114ea2a";
chromiumVersion = "127.0.6533.120";
gitRevision = "ac9b751";
chromiumVersion = "138.0.7204.97";
srcHash =
{
aarch64-linux = "sha256-s8dR97rAO0mCUwbpYnPWyY3t8movq05HhZZKllhZdBs=";
x86_64-linux = "sha256-57E7bZKpViWno9W4AaaSjL9B4uxq+rDXAou1tsiODUg=";
aarch64-linux = "sha256-kdO7c9oUfv0HK8wTmvYzw9S6EapnSGEQNCGN9D1JSL0=";
x86_64-linux = "sha256-3qgIhen6l/kxttyw0z78nmwox62riVhlmFSGPkUot7g=";
}
.${stdenv.hostPlatform.system} or (throw "unsupported system ${stdenv.hostPlatform.system}");
});
in
stdenv.mkDerivation (finalAttrs: {
pname = "obs-studio";
version = "31.0.4";
version = "31.1.0";
src = fetchFromGitHub {
owner = "obsproject";
repo = "obs-studio";
rev = finalAttrs.version;
hash = "sha256-YxBPVXin8oJlo++oJogY1WMamIJmRqtSmKZDBsIZPU4=";
hash = "sha256-espGKoKldgjWoCEE+Xor7+N5N86HvWCf0V18tb8GaC8=";
fetchSubmodules = true;
};
@@ -107,6 +108,7 @@ stdenv.mkDerivation (finalAttrs: {
pkg-config
wrapGAppsHook3
wrapQtAppsHook
extra-cmake-modules
]
++ optional scriptingSupport swig
++ optional cudaSupport autoAddDriverRunpath;
+3 -3
View File
@@ -7,13 +7,13 @@
buildGoModule (finalAttrs: {
pname = "atlantis";
version = "0.34.0";
version = "0.35.0";
src = fetchFromGitHub {
owner = "runatlantis";
repo = "atlantis";
tag = "v${finalAttrs.version}";
hash = "sha256-2xgU3H6X9EcbySV9RXN5oCn+7EkfdwebeYsL5+Vl69E=";
hash = "sha256-mdUh/fJo4pA80++nJoYdiAS5oTPpvBsR0TIMHrQO4u8=";
};
ldflags = [
@@ -21,7 +21,7 @@ buildGoModule (finalAttrs: {
"-X=main.date=1970-01-01T00:00:00Z"
];
vendorHash = "sha256-1xII3GIQQCku3UzwPJnJu//zAJGuGCOSETR6sU4lPR8=";
vendorHash = "sha256-QtAR0vO2K014WlzAriAYg7272tZ1iu72g4a3OBsy6Wo=";
subPackages = [ "." ];
+2
View File
@@ -52,6 +52,7 @@ let
"8.1" = "sha256-5EW9BkG154HQ6TrMyan5EhXiGlSRFPXMMTUasIwuC/U=";
"8.2" = "sha256-hRjh9Bf04LVBtS08fWMxrE1iyn6SGBQfNNLuSyQPjes=";
"8.3" = "sha256-WWsDPQhu1GXMDe6NhlMuVcwi7wGzRLJcJwxItxFCOiI=";
"8.4" = "sha256-tRxQfrFJmyaGRTa5ZWXhSHLx3V6QcBGe0EzKYbOjmG8=";
};
};
"x86_64-darwin" = {
@@ -60,6 +61,7 @@ let
"8.1" = "sha256-w56HItrNtHA8jj9K5LhGTKFRX5i9UYJpxVwR0eFQe4E=";
"8.2" = "sha256-vkEAVyZ6Vs3VjWb3oNrlRz5zAzPbgIngeoDAHZLme3Q=";
"8.3" = "sha256-uzobd13RzYGFrXHyFH0Ud9Qg7AWMPAA5dvHCp7R3HrU=";
"8.4" = "sha256-PtMXo/NTV8E32b9aWuuxBoHeeFN3vP2ufEo1Ed0w2iI=";
};
};
};
+554 -324
View File
File diff suppressed because it is too large Load Diff
+4814 -5070
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -34,7 +34,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
ln -s ${./package-lock.json} package-lock.json
'';
npmDepsHash = "sha256-6oSm3H6RItHOrBIvP6uvR7sBboBRWFuP3VwU38GMfgQ=";
npmDepsHash = "sha256-yYTRoxKnTF9y3RA4fuDlVYxv9d37Fc905TYVc/gPIRw=";
installPhase = ''
runHook preInstall
+3 -3
View File
@@ -6,7 +6,7 @@
}:
let
version = "0.17.75";
version = "0.17.76";
in
buildGoModule {
pname = "gqlgen";
@@ -16,10 +16,10 @@ buildGoModule {
owner = "99designs";
repo = "gqlgen";
tag = "v${version}";
hash = "sha256-VtpD7UfrypaREUu/uon6OTi3jvSzUaj1Y0yTiUw9u0A=";
hash = "sha256-b226pRpO693e48OlzVwSaDlPM5RAivIoX/KHXESVEJI=";
};
vendorHash = "sha256-sOiEgSGxIp4COfSQjDXv5sm/iryOcRK8MUbnvrglpbc=";
vendorHash = "sha256-cqNRfKPneq4BxVA+kGAxSalwfeNI/hFxsrOgVhkUbLs=";
subPackages = [ "." ];
+2 -2
View File
@@ -7,13 +7,13 @@
buildNpmPackage (finalAttrs: {
pname = "hypercore";
version = "11.9.1";
version = "11.10.0";
src = fetchFromGitHub {
owner = "holepunchto";
repo = "hypercore";
tag = "v${finalAttrs.version}";
hash = "sha256-aOF/wsq3m+CBrnZkkheukSmYuujOzRb8nJKp4AhZ3kc=";
hash = "sha256-6Z6HbolPa3b4EKjUwNGw7gDAg4ijFadBDwpt3l6GUqo=";
};
npmDepsHash = "sha256-ZJxVmQWKgHyKkuYfGIlANXFcROjI7fibg6mxIhDZowM=";
+2 -2
View File
@@ -17,13 +17,13 @@
stdenv.mkDerivation (finalAttrs: {
pname = "hyprgraphics";
version = "0.1.3";
version = "0.1.4";
src = fetchFromGitHub {
owner = "hyprwm";
repo = "hyprgraphics";
tag = "v${finalAttrs.version}";
hash = "sha256-prQ5JKopXtzCMX2eT3dXbaVvGmzjMRE2bXStQDdazpM=";
hash = "sha256-8u6b5oAdX0rCuoR8wFenajBRmI+mzbpNig6hSCuWUzE=";
};
nativeBuildInputs = [
@@ -17,13 +17,13 @@
stdenv.mkDerivation (finalAttrs: {
pname = "lua-language-server";
version = "3.14.0";
version = "3.15.0";
src = fetchFromGitHub {
owner = "luals";
repo = "lua-language-server";
tag = finalAttrs.version;
hash = "sha256-+pxDCjBcNYpSGZJpwJhL/PsARNhqdIXRHKj9DQvOyLE=";
hash = "sha256-frsq5OA3giLOJ/KPcAqVhme+0CtJuZrS3F4zHN1PnFM=";
fetchSubmodules = true;
};
+5
View File
@@ -18,6 +18,11 @@ buildNpmPackage rec {
dontNpmBuild = true;
# remove broken links to build tools
postInstall = ''
rm -r $out/lib/node_modules/mapscii/node_modules/.bin
'';
meta = with lib; {
description = "MapSCII is a Braille & ASCII world map renderer for your console";
homepage = "https://github.com/rastapasta/mapscii";
+4 -3
View File
@@ -27,18 +27,18 @@
stdenv.mkDerivation (finalAttrs: {
pname = "newsflash";
version = "3.3.5";
version = "4.0.3";
src = fetchFromGitLab {
owner = "news-flash";
repo = "news_flash_gtk";
tag = "v.${finalAttrs.version}";
hash = "sha256-H2/qKnsByidziUldX5MZBrMyMHfuQ4SN9wXizJUGQ8I=";
hash = "sha256-TVQZq+Akb7EFUazAgUqvlwC7htVpUf7Hck8p7vY0o3M=";
};
cargoDeps = rustPlatform.fetchCargoVendor {
inherit (finalAttrs) pname version src;
hash = "sha256-hyu1sk/VcRLjxUFYiFeTvwlFVYq5crMMg+4Afb34Hvc=";
hash = "sha256-fjb/AVvWbSq+Mc+5D7wCncLQ8OPjnTqHMzFFYgmCCjY=";
};
postPatch = ''
@@ -56,6 +56,7 @@ stdenv.mkDerivation (finalAttrs: {
ninja
pkg-config
rustc
rustPlatform.bindgenHook
rustPlatform.cargoSetupHook
wrapGAppsHook4
@@ -17,6 +17,7 @@ from .html import HTMLRenderer, UnresolvedXrefError
from .manual_structure import check_structure, FragmentType, is_include, make_xml_id, TocEntry, TocEntryType, XrefTarget
from .md import Converter, Renderer
from .redirects import Redirects
from .src_error import SrcError
class BaseConverter(Converter[md.TR], Generic[md.TR]):
# per-converter configuration for ns:arg=value arguments to include blocks, following
@@ -44,14 +45,18 @@ class BaseConverter(Converter[md.TR], Generic[md.TR]):
def _postprocess(self, infile: Path, outfile: Path, tokens: Sequence[Token]) -> None:
pass
def _handle_headings(self, tokens: list[Token], *, on_heading: Callable[[Token,str],None]) -> None:
def _handle_headings(self, tokens: list[Token], *, src: str, on_heading: Callable[[Token,str],None]) -> None:
# Headings in a globally numbered order
# h1 to h6
curr_heading_pos: list[int] = []
for token in tokens:
if token.type == "heading_open":
if token.tag not in ["h1", "h2", "h3", "h4", "h5", "h6"]:
raise RuntimeError(f"Got invalid heading tag {token.tag} in line {token.map[0] + 1 if token.map else 'NOT FOUND'}. Only h1 to h6 headings are allowed.")
raise SrcError(
src=src,
description=f"Got invalid heading tag {token.tag!r}. Only h1 to h6 headings are allowed.",
token=token,
)
idx = int(token.tag[1:]) - 1
@@ -75,10 +80,10 @@ class BaseConverter(Converter[md.TR], Generic[md.TR]):
if "id" not in token.attrs:
token.attrs["id"] = f"{auto_id_prefix}-{ident}"
self._handle_headings(tokens, on_heading=set_token_ident)
self._handle_headings(tokens, src=src, on_heading=set_token_ident)
check_structure(self._current_type[-1], tokens)
check_structure(src, self._current_type[-1], tokens)
for token in tokens:
if not is_include(token):
continue
@@ -89,35 +94,46 @@ class BaseConverter(Converter[md.TR], Generic[md.TR]):
typ = directive[0]
if typ == 'options':
token.type = 'included_options'
self._process_include_args(token, args, self.INCLUDE_OPTIONS_ALLOWED_ARGS)
self._parse_options(token, args)
self._process_include_args(src, token, args, self.INCLUDE_OPTIONS_ALLOWED_ARGS)
self._parse_options(src, token, args)
else:
fragment_type = typ.removesuffix('s')
if fragment_type not in get_args(FragmentType):
raise RuntimeError(f"unsupported structural include type '{typ}'")
raise SrcError(
src=src,
description=f"unsupported structural include type {typ!r}",
token=token,
)
self._current_type.append(cast(FragmentType, fragment_type))
token.type = 'included_' + typ
self._process_include_args(token, args, self.INCLUDE_FRAGMENT_ALLOWED_ARGS)
self._parse_included_blocks(token, args)
self._process_include_args(src, token, args, self.INCLUDE_FRAGMENT_ALLOWED_ARGS)
self._parse_included_blocks(src, token, args)
self._current_type.pop()
return tokens
def _process_include_args(self, token: Token, args: dict[str, str], allowed: set[str]) -> None:
def _process_include_args(self, src: str, token: Token, args: dict[str, str], allowed: set[str]) -> None:
ns = self.INCLUDE_ARGS_NS + ":"
args = { k[len(ns):]: v for k, v in args.items() if k.startswith(ns) }
if unknown := set(args.keys()) - allowed:
assert token.map
raise RuntimeError(f"unrecognized include argument in line {token.map[0] + 1}", unknown)
raise SrcError(
src=src,
description=f"unrecognized include argument(s): {unknown}",
token=token,
)
token.meta['include-args'] = args
def _parse_included_blocks(self, token: Token, block_args: dict[str, str]) -> None:
def _parse_included_blocks(self, src: str, token: Token, block_args: dict[str, str]) -> None:
assert token.map
included = token.meta['included'] = []
for (lnum, line) in enumerate(token.content.splitlines(), token.map[0] + 2):
for (lnum, line) in enumerate(token.content.splitlines(), token.map[0] + 1):
line = line.strip()
path = self._base_paths[-1].parent / line
if path in self._base_paths:
raise RuntimeError(f"circular include found in line {lnum}")
raise SrcError(
src=src,
description="circular include found",
token=token,
)
try:
self._base_paths.append(path)
with open(path, 'r') as f:
@@ -130,29 +146,57 @@ class BaseConverter(Converter[md.TR], Generic[md.TR]):
included.append((tokens, path))
self._base_paths.pop()
except Exception as e:
raise RuntimeError(f"processing included file {path} from line {lnum}") from e
raise SrcError(
src=src,
description=f"processing included file {path}",
token=lnum,
) from e
def _parse_options(self, token: Token, block_args: dict[str, str]) -> None:
def _parse_options(self, src: str, token: Token, block_args: dict[str, str]) -> None:
assert token.map
items = {}
for (lnum, line) in enumerate(token.content.splitlines(), token.map[0] + 2):
for (lnum, line) in enumerate(token.content.splitlines(), token.map[0] + 1):
if len(args := line.split(":", 1)) != 2:
raise RuntimeError(f"options directive with no argument in line {lnum}")
raise SrcError(
src=src,
description=f"options directive with no argument",
tokens={
"Directive": lnum,
"Block": token,
},
)
(k, v) = (args[0].strip(), args[1].strip())
if k in items:
raise RuntimeError(f"duplicate options directive {k} in line {lnum}")
raise SrcError(
src=src,
description=f"duplicate options directive {k!r}",
tokens={
"Directive": lnum,
"Block": token,
},
)
items[k] = v
try:
id_prefix = items.pop('id-prefix')
varlist_id = items.pop('list-id')
source = items.pop('source')
except KeyError as e:
raise RuntimeError(f"options directive {e} missing in block at line {token.map[0] + 1}")
raise SrcError(
src=src,
description=f"options directive {e} missing",
tokens={
"Block": token,
},
) from e
if items.keys():
raise RuntimeError(
f"unsupported options directives in block at line {token.map[0] + 1}",
" ".join(items.keys()))
raise SrcError(
src=src,
description=f"unsupported options directives: {set(items.keys())}",
token=token,
)
try:
with open(self._base_paths[-1].parent / source, 'r') as f:
@@ -160,7 +204,11 @@ class BaseConverter(Converter[md.TR], Generic[md.TR]):
token.meta['list-id'] = varlist_id
token.meta['source'] = json.load(f)
except Exception as e:
raise RuntimeError(f"processing options block in line {token.map[0] + 1}") from e
raise SrcError(
src=src,
description="processing options block",
token=token,
) from e
class RendererMixin(Renderer):
_toplevel_tag: str
@@ -542,14 +590,26 @@ class HTMLConverter(BaseConverter[ManualHTMLRenderer]):
continue
assert token.map
if len(token.meta['included']) == 0:
raise RuntimeError(f"redirection target {into} in line {token.map[0] + 1} is empty!")
raise SrcError(
src=src,
description=f"redirection target {into!r} is empty!",
token=token,
)
# we use blender-style //path to denote paths relative to the origin file
# (usually index.html). this makes everything a lot easier and clearer.
if not into.startswith("//") or '/' in into[2:]:
raise RuntimeError("html:into-file must be a relative-to-origin //filename", into)
raise SrcError(
src=src,
description=f"html:into-file must be a relative-to-origin //filename: {into}",
token=token,
)
into = token.meta['include-args']['into-file'] = into[2:]
if into in self._redirection_targets:
raise RuntimeError(f"redirection target {into} in line {token.map[0] + 1} is already in use")
raise SrcError(
src=src,
description=f"redirection target {into} is already in use",
token=token,
)
self._redirection_targets.add(into)
return tokens
@@ -9,6 +9,7 @@ from typing import cast, get_args, Iterable, Literal, Sequence
from markdown_it.token import Token
from .utils import Freezeable
from .src_error import SrcError
# FragmentType is used to restrict structural include blocks.
FragmentType = Literal['preface', 'part', 'chapter', 'section', 'appendix']
@@ -21,37 +22,45 @@ def is_include(token: Token) -> bool:
# toplevel file must contain only the title headings and includes, anything else
# would cause strange rendering.
def _check_book_structure(tokens: Sequence[Token]) -> None:
def _check_book_structure(src: str, tokens: Sequence[Token]) -> None:
for token in tokens[6:]:
if not is_include(token):
assert token.map
raise RuntimeError(f"unexpected content in line {token.map[0] + 1}, "
"expected structural include")
raise SrcError(
src=src,
description=f"unexpected content; expected structural include",
token=token,
)
# much like books, parts may not contain headings other than their title heading.
# this is a limitation of the current renderers and TOC generators that do not handle
# this case well even though it is supported in docbook (and probably supportable
# anywhere else).
def _check_part_structure(tokens: Sequence[Token]) -> None:
_check_fragment_structure(tokens)
def _check_part_structure(src: str,tokens: Sequence[Token]) -> None:
_check_fragment_structure(src, tokens)
for token in tokens[3:]:
if token.type == 'heading_open':
assert token.map
raise RuntimeError(f"unexpected heading in line {token.map[0] + 1}")
raise SrcError(
src=src,
description="unexpected heading",
token=token,
)
# two include blocks must either be adjacent or separated by a heading, otherwise
# we cannot generate a correct TOC (since there'd be nothing to link to between
# the two includes).
def _check_fragment_structure(tokens: Sequence[Token]) -> None:
def _check_fragment_structure(src: str, tokens: Sequence[Token]) -> None:
for i, token in enumerate(tokens):
if is_include(token) \
and i + 1 < len(tokens) \
and not (is_include(tokens[i + 1]) or tokens[i + 1].type == 'heading_open'):
assert token.map
raise RuntimeError(f"unexpected content in line {token.map[0] + 1}, "
"expected heading or structural include")
raise SrcError(
src=src,
description="unexpected content; expected heading or structural include",
token=token,
)
def check_structure(kind: TocEntryType, tokens: Sequence[Token]) -> None:
def check_structure(src: str, kind: TocEntryType, tokens: Sequence[Token]) -> None:
wanted = { 'h1': 'title' }
wanted |= { 'h2': 'subtitle' } if kind == 'book' else {}
for (i, (tag, role)) in enumerate(wanted.items()):
@@ -59,17 +68,21 @@ def check_structure(kind: TocEntryType, tokens: Sequence[Token]) -> None:
raise RuntimeError(f"missing {role} ({tag}) heading")
token = tokens[3 * i]
if token.type != 'heading_open' or token.tag != tag:
assert token.map
raise RuntimeError(f"expected {role} ({tag}) heading in line {token.map[0] + 1}", token)
raise SrcError(
src=src,
description=f"expected {role} ({tag}) heading",
token=token,
)
for t in tokens[3 * len(wanted):]:
if t.type != 'heading_open' or not (role := wanted.get(t.tag, '')):
continue
assert t.map
raise RuntimeError(
f"only one {role} heading ({t.markup} [text...]) allowed per "
f"{kind}, but found a second in line {t.map[0] + 1}. "
"please remove all such headings except the first or demote the subsequent headings.",
t)
raise SrcError(
src=src,
description=f"only one {role} heading ({t.markup} [text...]) allowed per "
f"{kind}, but found a second. "
"Please remove all such headings except the first or demote the subsequent headings.",
token=t,
)
last_heading_level = 0
for token in tokens:
@@ -80,22 +93,28 @@ def check_structure(kind: TocEntryType, tokens: Sequence[Token]) -> None:
# every other headings needs one too. we need this to build a TOC and to
# provide stable links if the manual changes shape.
if 'id' not in token.attrs and (kind != 'book' or token.tag != 'h2'):
assert token.map
raise RuntimeError(f"heading in line {token.map[0] + 1} does not have an id")
raise SrcError(
src=src,
description=f"heading does not have an id",
token=token,
)
level = int(token.tag[1:]) # because tag = h1..h6
if level > last_heading_level + 1:
assert token.map
raise RuntimeError(f"heading in line {token.map[0] + 1} skips one or more heading levels, "
"which is currently not allowed")
raise SrcError(
src=src,
description=f"heading skips one or more heading levels, "
"which is currently not allowed",
token=token,
)
last_heading_level = level
if kind == 'book':
_check_book_structure(tokens)
_check_book_structure(src, tokens)
elif kind == 'part':
_check_part_structure(tokens)
_check_part_structure(src, tokens)
else:
_check_fragment_structure(tokens)
_check_fragment_structure(src, tokens)
@dc.dataclass(frozen=True)
class XrefTarget:
@@ -6,6 +6,7 @@ import dataclasses
import re
from .types import RenderFn
from .src_error import SrcError
import markdown_it
from markdown_it.token import Token
@@ -446,12 +447,16 @@ def _footnote_ids(md: markdown_it.MarkdownIt) -> None:
generate here are derived from the footnote label, making numeric footnote
labels invalid.
"""
def generate_ids(tokens: Sequence[Token]) -> None:
def generate_ids(src: str, tokens: Sequence[Token]) -> None:
for token in tokens:
if token.type == 'footnote_open':
if token.meta["label"][:1].isdigit():
assert token.map
raise RuntimeError(f"invalid footnote label in line {token.map[0] + 1}")
raise SrcError(
src=src,
description="invalid footnote label",
token=token,
)
token.attrs['id'] = token.meta["label"]
elif token.type == 'footnote_anchor':
token.meta['target'] = f'{token.meta["label"]}.__back.{token.meta["subId"]}'
@@ -460,10 +465,10 @@ def _footnote_ids(md: markdown_it.MarkdownIt) -> None:
token.meta['target'] = token.meta["label"]
elif token.type == 'inline':
assert token.children is not None
generate_ids(token.children)
generate_ids(src, token.children)
def footnote_ids(state: markdown_it.rules_core.StateCore) -> None:
generate_ids(state.tokens)
generate_ids(state.src, state.tokens)
md.core.ruler.after("footnote_tail", "footnote_ids", footnote_ids)
@@ -537,7 +542,7 @@ def _block_titles(block: str) -> Callable[[markdown_it.MarkdownIt], None]:
non-title heading since those would make toc generation extremely complicated.
"""
def block_titles(state: markdown_it.rules_core.StateCore) -> None:
in_example = [False]
in_example = [None]
for i, token in enumerate(state.tokens):
if token.type == open:
if state.tokens[i + 1].type == 'heading_open':
@@ -545,14 +550,29 @@ def _block_titles(block: str) -> Callable[[markdown_it.MarkdownIt], None]:
state.tokens[i + 1].type = title_open
state.tokens[i + 3].type = title_close
else:
assert token.map
raise RuntimeError(f"found {block} without title in line {token.map[0] + 1}")
in_example.append(True)
raise SrcError(
src=state.src,
description=f"found {block} without title",
token=token,
)
in_example.append(token)
elif token.type == close:
in_example.pop()
elif token.type == 'heading_open' and in_example[-1]:
assert token.map
raise RuntimeError(f"unexpected non-title heading in {block} in line {token.map[0] + 1}")
started_at = in_example[-1]
block_display = ":::{." + block + "}"
raise SrcError(
description=f"unexpected non-title heading in `{block_display}`; are you missing a `:::`?\n"
f"Note: blocks like `{block_display}` are only allowed to contain a single heading in order to simplify TOC generation.",
src=state.src,
tokens={
f"`{block_display}` block": started_at,
"Unexpected heading": token,
},
)
def do_add(md: markdown_it.MarkdownIt) -> None:
md.core.ruler.push(f"{block}_titles", block_titles)
@@ -0,0 +1,154 @@
from typing import Tuple
from markdown_it.token import Token
LineSpan = int | Tuple[int, int] | Token
class SrcError(Exception):
"""An error associated with a source file and location."""
def __init__(
self,
*,
description: str,
src: str,
tokens: dict[str, LineSpan] | None = None,
token: LineSpan | None = None,
):
"""Create a new `SrcError`.
Arguments:
- `description`: A description of the error.
- `src`: The source text the `token`s are from.
- `tokens`: A dictionary from descriptions to `Tokens` (or lines) associated with
the error.
The tokens are used for their source location.
A location like ` at lines 6-9` will be added to the description.
If the description is empty, the location will be described as `At
lines 6-9`.
- `token`: Shorthand for `tokens={"": token}`.
"""
self.src = src
tokens = tokens or {}
if token:
tokens[""] = token
self.tokens = tokens
self.description = description
self.message = _src_error_str(src=src, tokens=tokens, description=description)
super().__init__(self.message)
def __str__(self) -> str:
return self.message
def _get_line_span(location: LineSpan) -> Tuple[int, int] | None:
if isinstance(location, Token):
if location.map:
return (location.map[0], location.map[1])
else:
return None
elif isinstance(location, int):
return (location, location + 1)
else:
return location
def _src_error_str(*, src: str, tokens: dict[str, LineSpan], description: str) -> str:
"""Python exceptions are a bit goofy and need a `message` string attribute
right away, so we basically need a way to generate the string before we
actually finish `__init__`.
"""
result = [description]
src_lines = src.splitlines()
for description, token in tokens.items():
result.append("\n\n\x1b[33m")
if description:
result.append(description)
result.append(" at ")
else:
result.append("At ")
maybe_span = _get_line_span(token)
if not maybe_span:
result.append("unknown location\x1b[0m")
continue
start, end = maybe_span
# Note: `end` is exclusive, so single-line spans are represented as
# `(n, n+1)`.
if start == end - 1:
result.append("line ")
result.append(str(start + 1))
else:
result.append("lines ")
result.append(str(start + 1))
result.append("-")
result.append(str(end))
result.append(":\x1b[0m\n")
result.append(src_excerpt(src_lines=src_lines, start=start, end=end))
return "".join(result)
def src_excerpt(
*, src_lines: list[str], start: int, end: int, context: int = 3, max_lines: int = 20
) -> str:
output = []
def clamp_line(line_num: int) -> int:
return max(0, min(len(src_lines), line_num))
def add_line(line_num: int, *, is_context: bool) -> None:
# Lines start with the line number, dimmed.
prefix = "\x1b[2m\x1b[37m" + format(line_num + 1, " 4d") + "\x1b[0m"
# Context lines are prefixed with a dotted line, non-context lines are
# prefixed with a bold yellow line.
if is_context:
# Note: No reset here because context lines are dimmed.
prefix += " \x1b[2m\x1b[37m┆ "
else:
prefix += " \x1b[1m\x1b[33m┃\x1b[0m "
output.append(prefix + src_lines[line_num] + "\x1b[0m")
def add_lines(start: int, end: int, is_context: bool) -> None:
for i in range(clamp_line(start), clamp_line(end)):
add_line(i, is_context=is_context)
if end - start > max_lines:
# If we have more than `max_lines` in the range, show a `...` in the middle.
half_max_lines = max_lines // 2
add_lines(start - context, start, is_context=True)
add_lines(start, start + half_max_lines, is_context=False)
output.append(" \x1b[2m\x1b[37m...\x1b[0m")
add_lines(end - half_max_lines, end, is_context=False)
add_lines(end, end + context, is_context=True)
else:
add_lines(start - context, start, is_context=True)
add_lines(start, end, is_context=False)
add_lines(end, end + context, is_context=True)
return "\n".join(output)
@@ -3,7 +3,6 @@ from pathlib import Path
from markdown_it.token import Token
from nixos_render_docs.manual import HTMLConverter, HTMLParameters
from nixos_render_docs.md import Converter
from nixos_render_docs.redirects import Redirects
auto_id_prefix="TEST_PREFIX"
def set_prefix(token: Token, ident: str) -> None:
@@ -19,7 +18,7 @@ def test_auto_id_prefix_simple() -> None:
## subtitle
"""
tokens = Converter()._parse(src)
md._handle_headings(tokens, on_heading=set_prefix)
md._handle_headings(tokens, src=src, on_heading=set_prefix)
assert [
{**token.attrs, "tag": token.tag}
@@ -44,7 +43,7 @@ def test_auto_id_prefix_repeated() -> None:
## subtitle2
"""
tokens = Converter()._parse(src)
md._handle_headings(tokens, on_heading=set_prefix)
md._handle_headings(tokens, src=src, on_heading=set_prefix)
assert [
{**token.attrs, "tag": token.tag}
@@ -76,7 +75,7 @@ def test_auto_id_prefix_maximum_nested() -> None:
## h2.2
"""
tokens = Converter()._parse(src)
md._handle_headings(tokens, on_heading=set_prefix)
md._handle_headings(tokens, src=src, on_heading=set_prefix)
assert [
{**token.attrs, "tag": token.tag}
@@ -1,10 +1,10 @@
import nixos_render_docs
from nixos_render_docs.options import AnchorStyle
import json
from markdown_it.token import Token
from pathlib import Path
import pytest
from markdown_it.token import Token
import nixos_render_docs
from nixos_render_docs.options import AnchorStyle
def test_option_headings() -> None:
c = nixos_render_docs.options.HTMLConverter({}, 'local', 'vars', 'opt-', {})
@@ -1,8 +1,11 @@
import nixos_render_docs as nrd
import pytest
import textwrap
import pytest
from markdown_it.token import Token
import nixos_render_docs as nrd
from nixos_render_docs.src_error import SrcError
class Converter(nrd.md.Converter[nrd.html.HTMLRenderer]):
# actual renderer doesn't matter, we're just parsing.
def __init__(self, manpage_urls: dict[str, str]) -> None:
@@ -498,9 +501,27 @@ def test_example() -> None:
Token(type='paragraph_close', tag='p', nesting=-1, block=True)
]
with pytest.raises(RuntimeError) as exc:
with pytest.raises(SrcError) as exc:
c._parse("::: {.example}\n### foo\n### bar\n:::")
assert exc.value.args[0] == 'unexpected non-title heading in example in line 3'
assert str(exc.value) == textwrap.dedent(
"""
unexpected non-title heading in `:::{.example}`; are you missing a `:::`?
Note: blocks like `:::{.example}` are only allowed to contain a single heading in order to simplify TOC generation.
\x1b[33m`:::{.example}` block at lines 1-3:\x1b[0m
\x1b[2m\x1b[37m 1\x1b[0m \x1b[1m\x1b[33m┃\x1b[0m ::: {.example}\x1b[0m
\x1b[2m\x1b[37m 2\x1b[0m \x1b[1m\x1b[33m┃\x1b[0m ### foo\x1b[0m
\x1b[2m\x1b[37m 3\x1b[0m \x1b[1m\x1b[33m┃\x1b[0m ### bar\x1b[0m
\x1b[2m\x1b[37m 4\x1b[0m \x1b[2m\x1b[37m┆ :::\x1b[0m
\x1b[33mUnexpected heading at line 3:\x1b[0m
\x1b[2m\x1b[37m 1\x1b[0m \x1b[2m\x1b[37m┆ ::: {.example}\x1b[0m
\x1b[2m\x1b[37m 2\x1b[0m \x1b[2m\x1b[37m┆ ### foo\x1b[0m
\x1b[2m\x1b[37m 3\x1b[0m \x1b[1m\x1b[33m┃\x1b[0m ### bar\x1b[0m
\x1b[2m\x1b[37m 4\x1b[0m \x1b[2m\x1b[37m┆ :::\x1b[0m
"""
).strip()
def test_footnotes() -> None:
c = Converter({})
+3 -3
View File
@@ -16,17 +16,17 @@ let
in
rustPlatform.buildRustPackage rec {
pname = "onefetch";
version = "2.24.0";
version = "2.25.0";
src = fetchFromGitHub {
owner = "o2sh";
repo = "onefetch";
rev = version;
hash = "sha256-Q74iqCSH8sdGFWC5DmMZhvUoL/Hzz4XNj548Gls6Hzk=";
hash = "sha256-ZaaSuHWkhJx0q1CBAiRhwoLeeyyoAj6/vP3AJwybjAo=";
};
useFetchCargoVendor = true;
cargoHash = "sha256-BpWc1GEj94vGEXDJEyocItggP1vQC441wp8r3DwalFw=";
cargoHash = "sha256-56Net4nNRndePhdsQPbmqiPHpOUGMmnQt6BuplQpvSU=";
cargoPatches = [
# enable pkg-config feature of zstd
+9 -3
View File
@@ -3,20 +3,26 @@
buildNpmPackage,
fetchFromGitHub,
nix-update-script,
npm-lockfile-fix,
}:
buildNpmPackage rec {
pname = "opencommit";
version = "3.2.7";
version = "3.2.9";
src = fetchFromGitHub {
owner = "di-sukharev";
repo = "opencommit";
rev = "v${version}";
hash = "sha256-vmVOrNwUsgB3iBvO8QhpJfI2OO0Kb9ZthcAXVaQ2cBM=";
hash = "sha256-nn+Whjs3qLXhydrELXzogr66H6btY/TPbmWT/MH6w+M=";
postFetch = ''
cd $out
# Fix lockfile issues with bundled dependencies
${lib.getExe npm-lockfile-fix} package-lock.json
'';
};
npmDepsHash = "sha256-F19xbiZoIC2JA+3rLqJBbFZvs2XbAk94F2borp/7gMo=";
npmDepsHash = "sha256-1lUMtQFGlM1Z2oQ4nktsePyce/EwAu75BbkBiqBrdnQ=";
passthru.updateScript = nix-update-script { };
@@ -9,13 +9,13 @@
stdenvNoCC.mkDerivation (finalAttrs: {
pname = "sketchybar-app-font";
version = "2.0.35";
version = "2.0.39";
src = fetchFromGitHub {
owner = "kvndrsslr";
repo = "sketchybar-app-font";
rev = "v2.0.35";
hash = "sha256-qXXxpx/thEJuFnNUWmMXYMoir5CGqCktV1emzVPcTIY=";
rev = "v2.0.39";
hash = "sha256-TTkw/LhRnqJYBn6Mt+T3qgyLHhLIyACdUoShq/mIONY=";
};
pnpmDeps = pnpm_9.fetchDeps {
+61
View File
@@ -0,0 +1,61 @@
{
lib,
stdenv,
rustPlatform,
fetchFromGitHub,
installShellFiles,
versionCheckHook,
nix-update-script,
}:
rustPlatform.buildRustPackage (finalAttrs: {
pname = "somo";
version = "1.1.0";
src = fetchFromGitHub {
owner = "theopfr";
repo = "somo";
tag = "v${finalAttrs.version}";
hash = "sha256-HUTaBSy3FemAQH1aKZYTJnUWiq0bU/H6c5Gz3yamPiA=";
};
cargoHash = "sha256-e3NrEfbWz6h9q4TJnn8jnRmMJbeaEc4Yo3hFlaRLzzQ=";
nativeBuildInputs =
[
installShellFiles
]
++ lib.optionals stdenv.hostPlatform.isDarwin [
# Avoids "couldn't find any valid shared libraries matching: ['libclang.dylib']" error on darwin in sandbox mode.
rustPlatform.bindgenHook
];
postInstall = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
installShellCompletion --cmd somo \
--bash <("$out/bin/somo" generate-completions bash) \
--zsh <("$out/bin/somo" generate-completions zsh) \
--fish <("$out/bin/somo" generate-completions fish)
'';
nativeInstallCheckInputs = [
versionCheckHook
];
doInstallCheck = true;
versionCheckProgramArg = "--version";
passthru = {
updateScript = nix-update-script { };
};
meta = {
description = "Socket and port monitoring tool";
homepage = "https://github.com/theopfr/somo";
changelog = "https://github.com/theopfr/somo/blob/v${finalAttrs.version}/CHANGELOG.md";
license = lib.licenses.mit;
platforms = with lib.platforms; linux ++ darwin;
maintainers = with lib.maintainers; [
kachick
];
mainProgram = "somo";
};
})
+2 -2
View File
@@ -9,11 +9,11 @@
stdenv.mkDerivation (finalAttrs: {
pname = "tcsh";
version = "6.24.15";
version = "6.24.16";
src = fetchurl {
url = "mirror://tcsh/tcsh-${finalAttrs.version}.tar.gz";
hash = "sha256-1NCypN8yD1elGORMNZ7za7z4XWT1FG0MuP80mE4NI/0=";
hash = "sha256-QgjPRjD7ZNkdgZh/hU+VcKWg6KABqSgn3vN9Dtjzc2Q=";
};
strictDeps = true;
+1 -1
View File
@@ -27,7 +27,7 @@
stdenv.mkDerivation {
pname = "wlvncc";
version = "0-unstable-2025-04-21";
version = "0-unstable-2025-04-20";
src = fetchFromGitHub {
owner = "any1";
@@ -10,13 +10,13 @@
buildPythonPackage rec {
pname = "pyside6-fluent-widgets";
version = "1.8.2";
version = "1.8.3";
pyproject = true;
src = fetchPypi {
pname = "pyside6_fluent_widgets";
inherit version;
hash = "sha256-FspFnfu4f3PS2ARTOqaH7NCKMpg9r4YTj5LYsHyduBI=";
hash = "sha256-A9lKRFGpfrWKGAKJS9ETIbSTBF/Ba6KUBBc4Pht2eBE=";
};
build-system = [ setuptools ];
@@ -8,13 +8,13 @@
buildPythonPackage rec {
pname = "weblate-language-data";
version = "2025.7";
version = "2025.8";
pyproject = true;
src = fetchPypi {
pname = "weblate_language_data";
inherit version;
hash = "sha256-eDefK2g4EwJJttFHCNurOYifC2OXQXjRcqRT36nfLOc=";
hash = "sha256-buZNp7iWF7Ppx5RcTRs2kawwmzCPmwXSqarRbmgP0i8=";
};
build-system = [ setuptools ];
@@ -629,6 +629,12 @@ in
'';
};
hiredis-client = attrs: {
buildInputs = [
openssl
];
};
hpricot = attrs: {
dontBuild = false;
patches = [
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+5 -6
View File
@@ -33,7 +33,7 @@ stdenv.mkDerivation rec {
gemdir = src;
};
mastodonModules = stdenv.mkDerivation {
mastodonModules = stdenv.mkDerivation (finalAttrs: {
pname = "${pname}-modules";
inherit src version;
@@ -80,8 +80,9 @@ stdenv.mkDerivation rec {
find public/assets -type f -regextype posix-extended -iregex '.*\.(css|html|js|json|svg)' \
-exec gzip --best --keep --force {} ';' \
-exec brotli --best --keep {} ';'
gzip --best --keep public/packs/report.html
brotli --best --keep public/packs/report.html
gzip --best --keep public/packs/sw.js
brotli --best --keep public/packs/sw.js
runHook postBuild
'';
@@ -96,7 +97,7 @@ stdenv.mkDerivation rec {
runHook postInstall
'';
};
});
propagatedBuildInputs = [ mastodonGems.wrappedRuby ];
nativeBuildInputs = [ brotli ];
@@ -135,8 +136,6 @@ stdenv.mkDerivation rec {
ln -s assets/500.html.br public/500.html.br
ln -s packs/sw.js.gz public/sw.js.gz
ln -s packs/sw.js.br public/sw.js.br
ln -s packs/sw.js.map.gz public/sw.js.map.gz
ln -s packs/sw.js.map.br public/sw.js.map.br
rm -rf log
ln -s /var/log/mastodon log
File diff suppressed because it is too large Load Diff
+75
View File
@@ -0,0 +1,75 @@
{
"@esbuild/aix-ppc64@npm:0.25.5": "fb872b34a2843293dc60e809968fedf93e0d8f7174b062decffae6ba861eb56aaea0cd0aba87ba99162ceb2a690f0cde4fc29c000b52c035e40c91ec7861d43e",
"@esbuild/android-arm64@npm:0.25.5": "c818e799b19b5587466bf68a27b578ccaaf866c1d144573fbde7659e3fd3f555422ec3e67f5bd186a87648957d1b6e74df4f847edea7219c16979c9916f36e91",
"@esbuild/android-arm@npm:0.25.5": "a5384933f9f2ffcadce2be49da6ff43249fe42f32a04071316434e9f633fc20c8d4029072e9a53555620c3531045786297607b852579eee30b6dbc3bc9d98cd9",
"@esbuild/android-x64@npm:0.25.5": "8ce115dc7e1e6735f23b4aadb2dfca29c0abd8577ce34802ea3d017a64e388928949134fe225dfe190babdc5ec01be5fc7794eca84738cdefc12c5e3789ce43b",
"@esbuild/darwin-arm64@npm:0.25.5": "a009eab62f2bd284a6f2001d5e08217059186ffc16907bbe873e1de40fe9b5ed92c0db2f4c4d0dc41545838850a430c8f2f35d7bdb9cd01a1a04293acd97afca",
"@esbuild/darwin-x64@npm:0.25.5": "cac8021a7a0c549263e076913346b35a5bb81f76ffbc1abfad5e7b67303f013ac0c76f111bf624ea8447b327ec86c18a60c6ff307d743a2269f5d47313f5b2de",
"@esbuild/freebsd-arm64@npm:0.25.5": "d248e7103b7094eb4288db7c9a78b2905a25b4a957f2b945531ca88d3394f45ceca2343a7c84954734534af6159bc741eb3d5c1ed9df990f7395337a1b14192c",
"@esbuild/freebsd-x64@npm:0.25.5": "8a7be0740f07f5dbb3e24bf782ca6ef518a8ce9b53e5d864221722045713586d41774cbd531df97dc868b291b3b303c12e50ca8611c3cb7b5fe09a30b38285eb",
"@esbuild/linux-arm64@npm:0.25.5": "ce3c8fca47cf0a92148fb288eb35a5c4a4dcf7a700730b3a48fdd63c13e17c719eb6b350378203fba773477eb5be637f47a6d52c5d4ce5bdc0075ee917156006",
"@esbuild/linux-arm@npm:0.25.5": "cc81ea76ab86ed2a837c9da329f7c63412d288dc0aa608c8dcdf51705dc93d5b7f966a429be4896babe611074e5898c7e6c8e07ad7f50123a05478975294fbb4",
"@esbuild/linux-ia32@npm:0.25.5": "bfed6750923afd56148f658f6ec8995479f5115116dc212ecb9e4c556064422e22eda855177e7c02cbc945494e4db1167101918c5fa932278115db2c7025a3f6",
"@esbuild/linux-loong64@npm:0.25.5": "e5c20140bbbdba53f0d86dd72961ed73e6255d2ada2d3a626f390b352170605644822ad7592f695b6e520edcefe0c5f6ba19d10694b5d11d725745d9792bde01",
"@esbuild/linux-mips64el@npm:0.25.5": "6b3559517efd0dd1301debc7af7e275b055859c26facdda2e229b1aaab6ebea4c480a1da151c46211ee4035d95bfa7f0cdacf735b57ee99d41b69c77357310b9",
"@esbuild/linux-ppc64@npm:0.25.5": "a1a1af99d758efce928335637924dcd8ddec4201af51014e1f831b012d53a0a673b1e0c31036ec9e8c5a0311439283419ec8abdfc67ecb245fa7f7b653006ed0",
"@esbuild/linux-riscv64@npm:0.25.5": "6cd8dce6723b73e0f89898ab6cd52e0d009afdacdfc0d5529134de7b832c92c2e0421fbb5cbfc0e0c0b2b00a9b1ff2c4cdb9695b2c535ebc174960e986c727a7",
"@esbuild/linux-s390x@npm:0.25.5": "31b86dbc93d19eb362bad3353e65d6da771118346e723582d06c05f1b6ffad1c3765001b5215ef1e8f0c2bb29130d98815359bbc88e5c08304354d5a92e6ea94",
"@esbuild/linux-x64@npm:0.25.5": "f878a3e40edfd8a50de94bf982a9eaf03e636a0332af163a6c905490063aae652384fb392d4765c4338fb6f991034949c92ec768ee65c3b2fceeb494b89fe8b3",
"@esbuild/netbsd-arm64@npm:0.25.5": "941c5e28a63a93f19122271b5490e196db12815702c2266c6d66401b6909a4364ab889611ba81c5359624e3ce61f0505a680a1179ed9a555d1415fa1c485d75d",
"@esbuild/netbsd-x64@npm:0.25.5": "edbefdd88ca24a373497a7c8d1fdab418827ff89c6eee1c574159dbb4d9174552aa87753f35525a894964b77c14b012164ec5582b9f19dd4d6c1f5d45df411c7",
"@esbuild/openbsd-arm64@npm:0.25.5": "d44633a374c109d2fb9c678882016e3ec3d79f0c5f21a6e6fb0114ea709bc539200b037a4e3ec52304eea2f8c5957bf16c6f0a7af5cfde41b652c4bac604bba6",
"@esbuild/openbsd-x64@npm:0.25.5": "efc4641ea653dedc9886f0603c2e7cfc6fbe94c34d4cdaee9b060a8b9d8143d1192c45da93b3e802af2c26f72ab1ad3a3fad0e0cb297d06de55814fe83ccd32c",
"@esbuild/sunos-x64@npm:0.25.5": "29860663381b6098c0fda6f69235407654dfad953e83b3f9f06a270950d5c37da4ca60a4b5915b8e2606d468b560be6179870f64a22d5b046e8a930c31a7b554",
"@esbuild/win32-arm64@npm:0.25.5": "a77d395251c8a62ab0cec07d5230222823fa02fbf3ef008d94b5213a335c9f949872c3f1c2f947abaa28098b669018e429af42f59616e049860a0072f3b006de",
"@esbuild/win32-ia32@npm:0.25.5": "ff1b6cbe835082aef5b93c3e2012d51be431d05c6ae5f90a5bc89687c687e8e2340c262dedddd124b27b511616bbc4088b5a4a949d3147f677084dc6ec572629",
"@esbuild/win32-x64@npm:0.25.5": "266e69e8d37bd4deb77443588e49472e4e9791178cb39e1692eabb67cf65d8e85a932ac468e7ebb2072c8a9ee23ad413c8f0f7d954c474f643cedbbf7aad952a",
"@parcel/watcher-android-arm64@npm:2.5.0": "2d5d66f4e904546cff638d0b27a871d695dda1205e32902f917723dc1b09a5edef4ed8064fc5c85192a4e5e5b531eb4a2d3b349015ff6170c8228e3c098d5376",
"@parcel/watcher-darwin-arm64@npm:2.5.0": "bbdbaeb31ccea5ec172adab2bb2b1a5f4b2e18ed31054d7f6b1db718238f5880e3b8bc8ac1b55c00048c7a1973e75c0c86fa04c02679f99c0bb355145c8b685b",
"@parcel/watcher-darwin-x64@npm:2.5.0": "85089bf1c0f7fb0b4007d54f97e890bf2173d1a11166e9e601b9afe6e260e9cff2eed150ea80f51aae358436376c36af75a70523f53711f16a773987422cf93b",
"@parcel/watcher-freebsd-x64@npm:2.5.0": "1355a42a68beb177f9d15b8e379b63dd2e633494e0f09a7e28a778c6a5eb082206d6690e3776e79da5263ecc8791be047c33943cfd2d09019f8f545800ed583b",
"@parcel/watcher-linux-arm-glibc@npm:2.5.0": "3c78f9ab9e9d52745f3d44200e290a64843a9346bbe6628485cc6d777a1d329fd0345a5c919daad05fb436fda59143ec2f1810789c8e594a51c7f5d8099ac682",
"@parcel/watcher-linux-arm-musl@npm:2.5.0": "80f7f97115e4d98d95735149c6b210ed1902dbf0020d20b245801272a1459f3cef75307c124c1a947450dff9d7d62440ad85e46a98e06523523170fdffab5bf1",
"@parcel/watcher-linux-arm64-glibc@npm:2.5.0": "f82fb66b301754f9bf67c7abfe41b18c987ed47f8de05750395ac7453a2c396104d44090b20450d90d5af3e9de54e06aed1520e8401343b824f3c19747cf0aa1",
"@parcel/watcher-linux-arm64-musl@npm:2.5.0": "914ebc3387884a8948594fa91520726ef9a7dfbbf7663fd00e7c0de13e08a4e7a525c9132b5439b64b9deb9b62fdfb8c5e02148013cd2383d171334ea76641c0",
"@parcel/watcher-linux-x64-glibc@npm:2.5.0": "5db33f6a134d20e8bfd8bed6d13107e7d30947e832a4f677136abee8e1c2855ea19629ccf220e95056dbff753b55fe2b698dd936f31e492b095cc6434451e9d4",
"@parcel/watcher-linux-x64-musl@npm:2.5.0": "dbf3f903c4eb6014660f4c3c0d44dcef0e21ee16908288ad0149d6c1a5c9fd7f0405d8d0e91a2493fbeef83df5784bd43f7d1426a0150e00a415b6c0eab38c98",
"@parcel/watcher-win32-arm64@npm:2.5.0": "cff6516b1dad597ca1ec8c385cf8251f5050b32ab46fc15360f2eff3a40b61b7107eee56df73764007d9bd6b826960d2f3589c8e0ce270bb5b2a292313bd7a1b",
"@parcel/watcher-win32-ia32@npm:2.5.0": "ad9d2c9ae3a7031105fc90418050a910d4b679ead36e5fdcbb1b3e4afbaf56aec6566863e3a374c645c82f57073d8f643183f19c67c8c48b0aa62224c05fdb9d",
"@parcel/watcher-win32-x64@npm:2.5.0": "aa9660bdb2fe70de5163f9f8419e263711fd30612244fb7feb58fce49a653b88ac0e1e29646fb1fc76b86fd8215e62eea5ded0616725987dfca5372041925bd2",
"@rollup/rollup-android-arm-eabi@npm:4.40.2": "cb502d6933de94860f9d49a4b4e849a206d10d9b1a424847cb2545667f8937ac891a37854e2934992b39521dc8b8daa2ec6b683da6bb47ef893ab24f9424c887",
"@rollup/rollup-android-arm64@npm:4.40.2": "42e04ae6605f8a31cc7daf484f9104e6d2174a99e39d829c24d77780cd257a6dab67f5c6a38e84e5a967ad4a64a042f1e6dfbe75444aa03517e83d8436179726",
"@rollup/rollup-darwin-arm64@npm:4.40.2": "8e641fd8a888504c516e76e525a7fcc099d363a82ce8569a1a5bb2fdcf632fa262e1a73b47932a922d132e0c46fab6ba04490053f63e6e4fb30c313a499b139f",
"@rollup/rollup-darwin-x64@npm:4.40.2": "9dca62986fa2afef8c5addcb1eb4ee08afbd3aa03ece3c5372a82a785af67ae441b9782dd542018fa5bb39a6de34ea53f10795d6f6f801a0469ce7979c52c729",
"@rollup/rollup-freebsd-arm64@npm:4.40.2": "f21c73712c4cb74a797998e8adfa83bb7ff0d6cc3e7353eae5b213b4bb3f9f481e025d37dd67aeee7488b9fc9ecd0bc8f85a61469cfa6592ed9292d14ba868d0",
"@rollup/rollup-freebsd-x64@npm:4.40.2": "9f8b6abb5be2527e6cffdaf0dd95a8bbb6f4aa5599be2bfe919e8252f57558f0a06b66748d29cb1e42d0b65e1d2ef0ec2d6a429d3c8a1a85352269d88ffbda17",
"@rollup/rollup-linux-arm-gnueabihf@npm:4.40.2": "fc205b61c54ddaac7bb45768c3b4bbd79632df3f7bbe65532f5453d54e1a31c1d3f1e4508a00323cf0656d6c5a69f0793989d11fd0805dc2621053c8c6fbcaa3",
"@rollup/rollup-linux-arm-musleabihf@npm:4.40.2": "14fde6bac72d734462b9c2fa3594934454069d01422fe12e650ae6fc9e998daac3d43d1726a0aa040cac9d4de43cf75ca34d82932e0a2c3f564f49f0b6fba4af",
"@rollup/rollup-linux-arm64-gnu@npm:4.40.2": "1a7c361022d74025076d322cdeb741923f1d3e0d5e1a12fd4dcc678a7c3dc8a07002f6ec4d537b6f089c75b90273cd700580b9ac1b1d45fa68908eadb524f1c7",
"@rollup/rollup-linux-arm64-musl@npm:4.40.2": "2fbf7f6f28bfe5148b1a82b04569574bc865b65f6e8f874aa8b175ad3c3ee9197a9a22bc3693153f0d55ff2bd78938b15e162cafa4b77756d1933036b0520bf0",
"@rollup/rollup-linux-loongarch64-gnu@npm:4.40.2": "ae77d9e7a797868fbd6887b8b4a8a26bcd96ea632022ddc47c570d90ad6e47b2ac0b3a933885c06a0af5ad57b5f818f4531ff6961b351e9705f5af6dd26b2427",
"@rollup/rollup-linux-powerpc64le-gnu@npm:4.40.2": "867b6bc576e07110181f41c588b1a7ee22a6571bf5a3ceff0527c1e7c4540b5122d34b99f0c56c00d5c33a2e517fbb16c3e269cc4c08110e69dc0f0e4b2fbf26",
"@rollup/rollup-linux-riscv64-gnu@npm:4.40.2": "52f07f3e5e008cd0d277d5290524682c8ec5c03e08659b07a800fddc00b450dbf8df08612921b9fe6e4e16d60d5e282027d9b260ff520c40bf3e7c5e1efabb60",
"@rollup/rollup-linux-riscv64-musl@npm:4.40.2": "6483ab13ac5626c5b94d72aad3ffafe63a3572899824b1d37e59bc071b147f3d498864a0e19942e013a4488aa9262a92817232ca6c38339e3de62c3c4aca87e3",
"@rollup/rollup-linux-s390x-gnu@npm:4.40.2": "842ad92a20ff994091d4ba4c16f87e2f8a57e1eb9e3004c20aaeeb692bc2061619dd43ba4dd246712f8904fe1480e6211b43e9fd2e11a5faebbeebea0c79da63",
"@rollup/rollup-linux-x64-gnu@npm:4.40.2": "c440df4beca32d238b0a0f0b1017fb30da52c0f705946177c01a08d7d214ae190b2070885d93e15ff5fb5741e0964e1370bdd45f8a94e9a4689816f06f18c5a0",
"@rollup/rollup-linux-x64-musl@npm:4.40.2": "9874b4cce42573d460634443ddb730d348360089bf93667309e660301e4e389d8ae80abe7f33fa9a20db5e67984e107e17d1479bdfee278d74bc60dde6ab5f83",
"@rollup/rollup-win32-arm64-msvc@npm:4.40.2": "b61552ab831efde1ca4823cab1982d3d681e1be269d67d60558cd2ac86fe3802f6d569300d9ada084acebae27257b00c68f9d858261a579b5d8686956aa92ba0",
"@rollup/rollup-win32-ia32-msvc@npm:4.40.2": "13ad059483b26bbf12af5108207d66a98ae2aef7599f27a506b998c781921b653dacc63ee0db57bb6f37c920163fd8bc40072e0be0ec6b1e5f52eb3f1455efeb",
"@rollup/rollup-win32-x64-msvc@npm:4.40.2": "98ab8600ecbeab358c53ed563a7b586da0c5cdf26c03456a982a016b2f8eff6e2ec07055d15fe039b982a18a970744390d85a05970c9a8b1533c54702026f8df",
"@unrs/resolver-binding-darwin-arm64@npm:1.3.2": "c8c61120e2bead2e0fec054399107e1ebd39455a2b7d59a5446cafad86cca376e0010e65644c41da0958a065869dcbe0509a29394b52a469a48990d32bf7a6e8",
"@unrs/resolver-binding-darwin-x64@npm:1.3.2": "ee67a4043d2e297cb1362b7aa25be3f5defef9eb13f4e80358c3f22ffdef043ef905ac661fc9e70359383bafed5837a52bd001b49a8ea4f70372051d89ee6eff",
"@unrs/resolver-binding-freebsd-x64@npm:1.3.2": "5f19ef3991435a96e682d427a8d9b28886b4afc9ea5b723e51c4bca51f25bb24add8819ed91c9f228bd39e139d51625cc127ddd35efd6c3f6e1d88106808fad1",
"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.3.2": "f77b2345c2b572b569089092fa6c08b5a55fdb08d26e1db3cdfa0d195511a0efbe109c558e77bfd78d7aed4ffe47b6542890c9cad032cc00bb0fcd5f373f5090",
"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.3.2": "8b7156d8c641994c39626522ba42e69eef8d868a69b319c9ea5f7584ef0c4ea98bc698c1a4417d209dd3a786630be404d459680cf5b5b2500d3c4b0eb1be894f",
"@unrs/resolver-binding-linux-arm64-gnu@npm:1.3.2": "93b28c2ea0dae2d452659e0afde6099107b70362043e19800e35b7ae86350856dfa0a4d6ba2be566c225965b458b5fba78a10219cf78e6fc0c581373cd2e2a52",
"@unrs/resolver-binding-linux-arm64-musl@npm:1.3.2": "49ed9f24838e876eb1bba9b5f3e283af0716ee23f7d11a799a6376a47fa59a2e28b724431ca165a3874d60b1ed5a6b6c7650fe207f0610a788c88baa7862688f",
"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.3.2": "9fad22ffbf7aadf471a6d054c833a9b4cea74e2c38be40d546e6ba71058a6be10fa4e28947425ef33d42dc77de1c81b631fbff5a96a637c3a7652910f3e27d76",
"@unrs/resolver-binding-linux-s390x-gnu@npm:1.3.2": "dd28e351f19268c4735da984e96301d8433603cf109b2b6880aab9bb8f448242699b7f84c36c536ca4a9443f944153098a3d3e78fce26d0c56fe3406d73d4b55",
"@unrs/resolver-binding-linux-x64-gnu@npm:1.3.2": "e1cc70d8e012bc61bf5af85c2e9905aa1953c06daaab9b3857d780424c62807ccd0c5a20acb919e3accec7152badee426b1514ab9a4256b77945c3e7c8df3496",
"@unrs/resolver-binding-linux-x64-musl@npm:1.3.2": "e97b95e53d029e4ccaf7cf32072e644c495d8e1f097b6fdeb417860db4db4b752d84f5fa6310b9f170a1fbf0562696f0145005dda4a95d658ea0857fac6c51dd",
"@unrs/resolver-binding-wasm32-wasi@npm:1.3.2": "d3f16f36ba5dd714ef3eaf7bc57597e9f9a1fab7c6b5fb5dc5bf688d81a1bd4a574da16bd3e2b383181032a71001583b6534c21e5ffde1ee43fcfa95bc292f3b",
"@unrs/resolver-binding-win32-arm64-msvc@npm:1.3.2": "de65010d133e99a062827f698a7e50c30db15d9f6b9011d351762cc8809497e97c4617b7d6ca3052583ca3f6b8c3cb1f2857fd0c9afd944c7ebb65d5e1da74f6",
"@unrs/resolver-binding-win32-ia32-msvc@npm:1.3.2": "f214a8950e823c60656d2d113584c3cd20c6e92668f43f73c13c3ddfe38a7063615e42537645e2aa52a0652ace9c82e8fd5d9411043a6985ccb49d8dc8bb2595",
"@unrs/resolver-binding-win32-x64-msvc@npm:1.3.2": "38ca5f5912d7cddd3f3e1983ad8e79d084ab3f5990189ce8cdfcfc3b58d97cc0dd7b543cc78ff43eb1769d15a8c235339a5942c688ab680192caa4c97116a511"
}
+4 -5
View File
@@ -5,19 +5,18 @@
patches ? [ ],
}:
let
version = "4.3.9";
version = "4.4.0";
in
applyPatches {
src = fetchFromGitHub {
owner = "mastodon";
repo = "mastodon";
rev = "v${version}";
hash = "sha256-A2WxVwaarT866s97uwfStBVtv7T5czF7ymRswtZ2K4M=";
hash = "sha256-boAf0TnUlr+o4UqjFPzoRk2K6yFlxTo74BbkRowwkhw=";
passthru = {
inherit version;
yarnHash = "sha256-IC4d/skIHEzJPuKlq4rMAqV+ydqquA6toq4WWCfuDxo=";
yarnMissingHashes = null;
yarnHash = "sha256-Qh2jli99rxrT10KVGKnePxP6RXYIjtehDCJB5PfOngM=";
yarnMissingHashes = ./missing-hashes.json;
};
};
patches = patches ++ [ ];
+9 -7
View File
@@ -90,19 +90,19 @@ cat > source.nix << EOF
let
version = "$VERSION";
in
(applyPatches {
applyPatches {
src = fetchFromGitHub {
owner = "$OWNER";
repo = "$REPO";
rev = "v\${version}";
hash = "$HASH";
passthru = {
inherit version;
yarnHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
yarnMissingHashes = ./missing-hashes.json;
};
};
patches = patches ++ [$PATCHES];
})
// {
inherit version;
yarnHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
yarnMissingHashes = null;
patches = patches ++ [ $PATCHES];
}
EOF
SOURCE_DIR="$(nix-build --no-out-link -E '(import <nixpkgs> {}).callPackage ./source.nix {}')"
@@ -112,5 +112,7 @@ bundix --lockfile="$SOURCE_DIR/Gemfile.lock" --gemfile="$SOURCE_DIR/Gemfile"
echo "" >> gemset.nix # Create trailing newline to please EditorConfig checks
echo "Updating yarnHash"
yarn-berry-fetcher missing-hashes "$SOURCE_DIR/yarn.lock" > missing-hashes.json
YARN_HASH="$(yarn-berry-fetcher prefetch "$SOURCE_DIR/yarn.lock" 2>/dev/null)"
sed -i "s;sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=;$YARN_HASH;g" source.nix
@@ -3,6 +3,9 @@
buildGoModule,
fetchFromGitHub,
nixosTests,
# Test dependencies
redisTestHook,
}:
buildGoModule rec {
@@ -24,8 +27,31 @@ buildGoModule rec {
"-X main.BuildDate=unknown"
];
# needs a redis server
doCheck = false;
nativeCheckInputs = [
redisTestHook
];
preCheck = ''
export TEST_REDIS_URI="redis://localhost:6379"
'';
__darwinAllowLocalNetworking = true;
checkFlags =
let
skippedTests = [
"TestLatencySpike" # timing-sensitive
# The following tests require ad-hoc generated TLS certificates in the source dir.
# This is not possible in the read-only Nix store.
"TestCreateClientTLSConfig"
"TestValkeyTLSScheme"
"TestCreateServerTLSConfig"
"TestGetServerCertificateFunc"
"TestGetConfigForClientFunc"
];
in
[ "-skip=^${builtins.concatStringsSep "$|^" skippedTests}$" ];
passthru.tests = { inherit (nixosTests.prometheus-exporters) redis; };
@@ -17,13 +17,13 @@ let
in
postgresqlBuildExtension (finalAttrs: {
pname = "plv8";
version = "3.2.3";
version = "3.2.4";
src = fetchFromGitHub {
owner = "plv8";
repo = "plv8";
tag = "v${finalAttrs.version}";
hash = "sha256-ivQZJSNn5giWF351fqZ7mBZoJkGtby5T7beK45g3Zqs=";
hash = "sha256-v4r/6qwDwb3+PQPYV3FqmIcDEkSr8F46PVlFnhUWUGc=";
};
patches = [
@@ -132,7 +132,7 @@ postgresqlBuildExtension (finalAttrs: {
meta = {
description = "V8 Engine Javascript Procedural Language add-on for PostgreSQL";
homepage = "https://plv8.github.io/";
changelog = "https://github.com/plv8/plv8/blob/r${finalAttrs.version}/Changes";
changelog = "https://github.com/plv8/plv8/blob/v${finalAttrs.version}/Changes";
maintainers = [ ];
platforms = postgresql.meta.platforms;
license = lib.licenses.postgresql;
+1
View File
@@ -11976,6 +11976,7 @@ with pkgs;
musical-spectrum = callPackage ../applications/audio/deadbeef/plugins/musical-spectrum.nix { };
statusnotifier = callPackage ../applications/audio/deadbeef/plugins/statusnotifier.nix { };
playlist-manager = callPackage ../applications/audio/deadbeef/plugins/playlist-manager.nix { };
waveform-seekbar = callPackage ../applications/audio/deadbeef/plugins/waveform-seekbar.nix { };
};
deadbeef-with-plugins = callPackage ../applications/audio/deadbeef/wrapper.nix {