diff --git a/nixos/doc/manual/release-notes/rl-2511.section.md b/nixos/doc/manual/release-notes/rl-2511.section.md index 150cee196967..3cb90a10e0a3 100644 --- a/nixos/doc/manual/release-notes/rl-2511.section.md +++ b/nixos/doc/manual/release-notes/rl-2511.section.md @@ -120,6 +120,8 @@ - `services.libvirtd.autoSnapshot`, a backup service for libvirt managed vms. +- [Sshwifty](https://github.com/nirui/sshwifty), a Telnet and SSH client for your browser. Available as [services.sshwifty](#opt-services.sshwifty.enable). + ## Backward Incompatibilities {#sec-release-25.11-incompatibilities} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 42147814225b..30f542ac1cc9 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1694,6 +1694,7 @@ ./services/web-apps/snipe-it.nix ./services/web-apps/snips-sh.nix ./services/web-apps/sogo.nix + ./services/web-apps/sshwifty.nix ./services/web-apps/stash.nix ./services/web-apps/stirling-pdf.nix ./services/web-apps/strfry.nix diff --git a/nixos/modules/services/web-apps/sshwifty.nix b/nixos/modules/services/web-apps/sshwifty.nix new file mode 100644 index 000000000000..40dbd6ec725d --- /dev/null +++ b/nixos/modules/services/web-apps/sshwifty.nix @@ -0,0 +1,128 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.services.sshwifty; + format = pkgs.formats.json { }; + settings = format.generate "sshwifty.json" cfg.settings; +in +{ + options.services.sshwifty = { + enable = lib.mkEnableOption "Sshwifty"; + package = lib.mkPackageOption pkgs "sshwifty" { }; + settings = lib.mkOption { + type = format.type; + description = '' + Configuration for Sshwifty. See + [the Sshwifty documentation](https://github.com/nirui/sshwifty/tree/master?tab=readme-ov-file#configuration) + for possible options. + ''; + }; + sharedKeyFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = "Path to a file containing the shared key."; + }; + socks5PasswordFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = "Path to a file containing the SOCKS5 password."; + }; + }; + config = lib.mkIf cfg.enable { + systemd.services.sshwifty = { + description = "Sshwifty"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + script = '' + ${lib.optionalString (cfg.sharedKeyFile != null || cfg.socks5PasswordFile != null) ( + lib.concatStringsSep " " [ + (lib.getExe pkgs.jq) + "-s" + "'.[0] * .[1]" + (lib.optionalString (cfg.sharedKeyFile != null && cfg.socks5PasswordFile != null) "* .[2]") + "'" + settings + (lib.optionalString ( + cfg.sharedKeyFile != null + ) "<(echo \"{\\\"SharedKey\\\":\\\"$(cat $CREDENTIALS_DIRECTORY/sharedkey)\\\"}\")") + (lib.optionalString ( + cfg.socks5PasswordFile != null + ) "<(echo \"{\\\"Socks5Password\\\":\\\"$(cat $CREDENTIALS_DIRECTORY/socks5pass)\\\"}\")") + "> /run/sshwifty/sshwifty.json" + ] + )} + ${lib.optionalString ( + cfg.sharedKeyFile != null || cfg.socks5PasswordFile != null + ) "export SSHWIFTY_CONFIG=/run/sshwifty/sshwifty.json"} + ${lib.optionalString ( + cfg.sharedKeyFile == null && cfg.socks5PasswordFile == null + ) "export SSHWIFTY_CONFIG=${settings}"} + exec ${lib.getExe cfg.package} + ''; + serviceConfig = { + DynamicUser = true; + RuntimeDirectory = "sshwifty"; + RuntimeDirectoryMode = "0750"; + LoadCredential = + [ ] + ++ lib.optionals (cfg.sharedKeyFile != null) [ "sharedkey:${cfg.sharedKeyFile}" ] + ++ lib.optionals (cfg.socks5PasswordFile != null) [ "socks5pass:${cfg.socks5PasswordFile}" ]; + # Hardening + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateMounts = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + RemoveIPC = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + CapabilityBoundingSet = "CAP_NET_BIND_SERVICE"; + AmbientCapabilities = "CAP_NET_BIND_SERVICE"; + PrivateTmp = "disconnected"; + ProcSubset = "pid"; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + ]; + RestrictNamespaces = [ + "~cgroup" + "~ipc" + "~mnt" + "~net" + "~pid" + "~user" + "~uts" + ]; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "~@clock" + "~@cpu-emulation" + "~@debug" + "~@module" + "~@mount" + "~@obsolete" + "~@privileged" + "~@raw-io" + "~@reboot" + "~@resources" + "~@swap" + ]; + UMask = "0077"; + }; + }; + }; + meta.maintainers = [ lib.maintainers.ungeskriptet ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index bca01159e1f7..70de75dc6355 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1373,6 +1373,7 @@ in sslh = handleTest ./sslh.nix { }; ssh-agent-auth = runTest ./ssh-agent-auth.nix; ssh-audit = runTest ./ssh-audit.nix; + sshwifty = runTest ./web-apps/sshwifty/default.nix; sssd = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./sssd.nix { }; sssd-ldap = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./sssd-ldap.nix { }; stalwart-mail = runTest ./stalwart/stalwart-mail.nix; diff --git a/nixos/tests/web-apps/sshwifty/default.nix b/nixos/tests/web-apps/sshwifty/default.nix new file mode 100644 index 000000000000..ac6ac689de71 --- /dev/null +++ b/nixos/tests/web-apps/sshwifty/default.nix @@ -0,0 +1,32 @@ +{ lib, pkgs, ... }: +{ + name = "sshwifty"; + + nodes.machine = + { ... }: + { + services.sshwifty = { + enable = true; + sharedKeyFile = pkgs.writeText "sharedkey" "rpz2E4QI6uPMLr"; + settings = { + HostName = "localhost"; + Servers = [ + { + ListenInterface = "::1"; + ListenPort = 80; + ServerMessage = "NixOS test"; + } + ]; + }; + }; + }; + + testScript = '' + machine.wait_for_unit("sshwifty.service") + machine.wait_for_open_port(80) + machine.wait_until_succeeds("curl --fail -6 http://localhost/", timeout=60) + machine.wait_until_succeeds("${lib.getExe pkgs.nodejs} ${./sshwifty-test.js}", timeout=60) + ''; + + meta.maintainers = [ lib.maintainers.ungeskriptet ]; +} diff --git a/nixos/tests/web-apps/sshwifty/sshwifty-test.js b/nixos/tests/web-apps/sshwifty/sshwifty-test.js new file mode 100644 index 000000000000..0236ed215897 --- /dev/null +++ b/nixos/tests/web-apps/sshwifty/sshwifty-test.js @@ -0,0 +1,83 @@ +#!/usr/bin/env node +/* Based on ui/app.js from Sshwifty. */ +const { subtle } = require('node:crypto') +const sshwiftyURL = 'http://localhost/sshwifty/socket/verify' +const sharedKey = 'rpz2E4QI6uPMLr' +const serverMessage = 'NixOS test' + +async function hmac512(secret, data) { + const key = await subtle.importKey( + 'raw', + secret, + { name: 'HMAC', hash: { name: 'SHA-512' } }, + false, + ['sign', 'verify'], + ) + return subtle.sign(key.algorithm, key, data) +} + +async function getSocketAuthKey(privateKey) { + const enc = new TextEncoder(), + rTime = Number(Math.trunc(Date.now() / 100000)) + return new Uint8Array( + await hmac512(enc.encode(privateKey), enc.encode(rTime)), + ).slice(0, 32) +} + +async function requestAuth(privateKey) { + const authKey = await getSocketAuthKey(privateKey) + const h = await fetch(sshwiftyURL, { + headers: { 'X-Key': btoa(String.fromCharCode.apply(null, authKey)) }, + }) + const serverDate = h.headers.get('Date') + return { + result: h.status, + date: serverDate ? new Date(serverDate) : null, + text: await h.text(), + } +} + +async function tryInitialAuth() { + try { + const result = await requestAuth(sharedKey) + if (result.date) { + const serverRespondTime = result.date, + serverRespondTimestamp = serverRespondTime.getTime(), + clientCurrent = new Date(), + clientTimestamp = clientCurrent.getTime(), + timeDiff = Math.abs(serverRespondTimestamp - clientTimestamp) + if (timeDiff > 30000) { + console.log('Time difference between client and server too big.') + process.exit(1) + } + } + switch (result.result) { + case 200: + if (result.text.includes(serverMessage)) { + console.log('All good.') + process.exit() + } else { + console.log('Server message not found') + process.exit(1) + } + break + case 403: + console.log('We need auth.') + process.exit(1) + break + case 0: + console.log('Timeout?') + process.exit(1) + break + default: + console.log('wghat') + process.exit(1) + } + } catch { + console.log('Something went horribly wrong, ouch.') + process.exit(1) + } +} + +console.log('Testing Sshwifty') +tryInitialAuth() diff --git a/pkgs/applications/audio/youtube-music/default.nix b/pkgs/applications/audio/youtube-music/default.nix index cde0d6cd26ad..4c5af2ba3914 100644 --- a/pkgs/applications/audio/youtube-music/default.nix +++ b/pkgs/applications/audio/youtube-music/default.nix @@ -14,13 +14,13 @@ stdenv.mkDerivation (finalAttrs: { pname = "youtube-music"; - version = "3.10.0"; + version = "3.11.0"; src = fetchFromGitHub { owner = "th-ch"; repo = "youtube-music"; tag = "v${finalAttrs.version}"; - hash = "sha256-+PCDA7lHaUQw9DhODRsEScyJC+9v8UPiZ1W8w2h/Ljg="; + hash = "sha256-M8YFpeauM55fpNyHSGQm8iZieV0oWqOieVThhglKKPE="; }; patches = [ @@ -31,7 +31,7 @@ stdenv.mkDerivation (finalAttrs: { pnpmDeps = pnpm.fetchDeps { inherit (finalAttrs) pname version src; fetcherVersion = 2; - hash = "sha256-b5I0n3CedA6qCL68lePU3pwyGp1JlQHzUpfCvhqw2qI="; + hash = "sha256-xZQ8rnLGD0ZxxUUPLHmNJ6mA+lnUHCTBvtJTiIPxaZU="; }; nativeBuildInputs = [ diff --git a/pkgs/build-support/fetchsourcehut/default.nix b/pkgs/build-support/fetchsourcehut/default.nix index 1b4a18a8837f..f22746a64f74 100644 --- a/pkgs/build-support/fetchsourcehut/default.nix +++ b/pkgs/build-support/fetchsourcehut/default.nix @@ -82,7 +82,7 @@ makeOverridable ( postFetch = optionalString (vc == "hg") '' rm -f "$out/.hg_archival.txt" ''; # impure file; see #12002 - passthru = { + passthru = (args.passthru or { }) // { gitRepoUrl = urlFor "git"; }; }; diff --git a/pkgs/by-name/gy/gyb/package.nix b/pkgs/by-name/gy/gyb/package.nix index ce093a3f302a..e214204f5ce6 100644 --- a/pkgs/by-name/gy/gyb/package.nix +++ b/pkgs/by-name/gy/gyb/package.nix @@ -6,14 +6,14 @@ python3.pkgs.buildPythonApplication rec { pname = "gyb"; - version = "1.82"; + version = "1.95"; format = "other"; src = fetchFromGitHub { owner = "GAM-team"; repo = "got-your-back"; tag = "v${version}"; - hash = "sha256-eKeT2tVBK2DcTOEC6Tvo+igPXPOD1wy66+kr0ltnMIU="; + hash = "sha256-WCM+8Qvu8EF5gC5BSEbkqcyITIiHELFp1RP+Oko4MRE="; }; dependencies = with python3.pkgs; [ diff --git a/pkgs/by-name/he/herwig/package.nix b/pkgs/by-name/he/herwig/package.nix index cf9a4ac9094b..9473750925cd 100644 --- a/pkgs/by-name/he/herwig/package.nix +++ b/pkgs/by-name/he/herwig/package.nix @@ -53,6 +53,7 @@ stdenv.mkDerivation rec { configureFlags = [ "--with-thepeg=${thepeg}" + "--with-boost=${lib.getDev boost}" ]; enableParallelBuilding = true; diff --git a/pkgs/by-name/ma/mattermostLatest/package.nix b/pkgs/by-name/ma/mattermostLatest/package.nix index cdf9b2a73fc6..72f9a283389f 100644 --- a/pkgs/by-name/ma/mattermostLatest/package.nix +++ b/pkgs/by-name/ma/mattermostLatest/package.nix @@ -11,10 +11,10 @@ mattermost.override { # and make sure the version regex is up to date here. # Ensure you also check ../mattermost/package.nix for ESR releases. regex = "^v(10\\.[0-9]+\\.[0-9]+)$"; - version = "10.11.2"; - srcHash = "sha256-lqMdH7jvnO6Z+dP+DHbxeM4iHU6EoJ3/bx8t/oJau0Q="; + version = "10.12.0"; + srcHash = "sha256-oVZlXprw0NddHrtx1g2WRoGm1ATq/pqncD0mewN12nw="; vendorHash = "sha256-Lqa463LLy41aaRbrtJFclfOj55vLjK4pWFAFLzX3TJE="; - npmDepsHash = "sha256-p9dq31qw0EZDQIl2ysKE38JgDyLA6XvSv+VtHuRh+8A="; + npmDepsHash = "sha256-O9iX6hnwkEHK0kkHqWD6RYXqoSEW6zs+utiYHnt54JY="; lockfileOverlay = '' unlock(.; "@floating-ui/react"; "channels/node_modules/@floating-ui/react") ''; diff --git a/pkgs/by-name/pe/percollate/package.nix b/pkgs/by-name/pe/percollate/package.nix index 2b7c761ae05c..4578bbd8554d 100644 --- a/pkgs/by-name/pe/percollate/package.nix +++ b/pkgs/by-name/pe/percollate/package.nix @@ -8,21 +8,21 @@ buildNpmPackage rec { pname = "percollate"; - version = "4.2.3"; + version = "4.3.0"; src = fetchFromGitHub { owner = "danburzo"; repo = "percollate"; rev = "v${version}"; - hash = "sha256-JpdSEockALXtuuMMi5mgD5AXcayojyK0qMMWF+XFfZE="; + hash = "sha256-nu72jkqGt2ntlCxKptRlfTTd3SAVlv/QPTwkIUpVd2g="; }; - npmDepsHash = "sha256-qWu1YYi4ddpAUtbDxF4YA8OO6BLZ6gfeb4pw0n9BaZw="; + npmDepsHash = "sha256-O74AVF3PwLzkWPAqTmfsxPefevvv3VRIstb0OI2/bQ0="; dontNpmBuild = true; # Dev dependencies include an unnecessary Java dependency (epubchecker) - # https://github.com/danburzo/percollate/blob/v4.2.3/package.json#L40 + # https://github.com/danburzo/percollate/blob/v4.3.0/package.json#L40 npmInstallFlags = [ "--omit=dev" ]; nativeBuildInputs = [ makeWrapper ]; diff --git a/pkgs/by-name/si/signal-desktop/package.nix b/pkgs/by-name/si/signal-desktop/package.nix index 2a6c02f481a9..0df70c12eafb 100644 --- a/pkgs/by-name/si/signal-desktop/package.nix +++ b/pkgs/by-name/si/signal-desktop/package.nix @@ -112,6 +112,18 @@ stdenv.mkDerivation (finalAttrs: { } ); + postPatch = '' + # The spell checker dictionary URL interpolates the electron version, + # however, the official website only provides dictionaries for electron + # versions which they vendor into the binary releases. Since we unpin + # electron to use the one from nixpkgs the URL may point to nonexistent + # resource if the nixpkgs version is different. To fix this we hardcode + # the electron version to the declared one here instead of interpolating + # it at runtime. + substituteInPlace app/updateDefaultSession.ts \ + --replace-fail "\''${process.versions.electron}" "`jq -r '.devDependencies.electron' < package.json`" + ''; + pnpmDeps = pnpm.fetchDeps { inherit (finalAttrs) pname diff --git a/pkgs/by-name/ss/sshwifty/package.nix b/pkgs/by-name/ss/sshwifty/package.nix index fd9ac10b25f2..934fc1a2186e 100644 --- a/pkgs/by-name/ss/sshwifty/package.nix +++ b/pkgs/by-name/ss/sshwifty/package.nix @@ -4,6 +4,7 @@ buildNpmPackage, fetchFromGitHub, versionCheckHook, + nixosTests, nix-update-script, go_1_25, }: @@ -52,7 +53,10 @@ buildGo125Module (finalAttrs: { nativeInstallCheckInputs = [ versionCheckHook ]; doInstallCheck = true; - passthru.updateScript = nix-update-script { }; + passthru = { + tests = { inherit (nixosTests) sshwifty; }; + updateScript = nix-update-script { }; + }; meta = { description = "WebSSH & WebTelnet client"; diff --git a/pkgs/development/python-modules/niquests/default.nix b/pkgs/development/python-modules/niquests/default.nix new file mode 100644 index 000000000000..e9e52639cd98 --- /dev/null +++ b/pkgs/development/python-modules/niquests/default.nix @@ -0,0 +1,97 @@ +{ + buildPythonPackage, + charset-normalizer, + cryptography, + fetchFromGitHub, + hatchling, + lib, + orjson, + pytest-asyncio, + pytest-httpbin, + pytestCheckHook, + stdenv, + urllib3-future, + wassima, +}: + +buildPythonPackage rec { + pname = "niquests"; + version = "3.15.2"; + pyproject = true; + + src = fetchFromGitHub { + owner = "jawah"; + repo = "niquests"; + tag = "v${version}"; + hash = "sha256-QRVefE/85k6fT0zhAzX4wFB79ANf7LUshWsbi+fpSgk="; + }; + + build-system = [ hatchling ]; + + pythonRelaxDeps = [ + "wassima" + ]; + + dependencies = [ + charset-normalizer + urllib3-future + wassima + ]; + + optional-dependencies = { + inherit (urllib3-future.optional-dependencies) + brotli + socks + ws + zstd + ; + full = [ + orjson + ] + ++ urllib3-future.optional-dependencies.brotli + ++ urllib3-future.optional-dependencies.socks + ++ urllib3-future.optional-dependencies.qh3 + ++ urllib3-future.optional-dependencies.ws + ++ urllib3-future.optional-dependencies.zstd; + http3 = urllib3-future.optional-dependencies.qh3; + ocsp = urllib3-future.optional-dependencies.qh3; + speedups = [ + orjson + ] + ++ urllib3-future.optional-dependencies.brotli + ++ urllib3-future.optional-dependencies.zstd; + }; + + pythonImportsCheck = [ "niquests" ]; + + nativeCheckInputs = [ + cryptography + pytest-asyncio + pytest-httpbin + pytestCheckHook + ] + ++ optional-dependencies.socks; + + disabledTestPaths = [ + # tests connect to the internet + "tests/test_requests.py" + ] + ++ lib.optionals stdenv.hostPlatform.isDarwin [ + # NameResolutionError: Failed to resolve 'localhost' + "tests/test_lowlevel.py" + "tests/test_testserver.py" + ]; + + disabledTests = lib.optionals stdenv.hostPlatform.isDarwin [ + # PermissionError: [Errno 1] Operation not permitted + "test_use_proxy_from_environment" + ]; + + meta = { + changelog = "https://github.com/jawah/niquests/blob/${src.tag}/HISTORY.md"; + description = "Simple HTTP library that is a drop-in replacement for Requests"; + homepage = "https://github.com/jawah/niquests"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ dotlambda ]; + }; +} diff --git a/pkgs/development/python-modules/qh3/default.nix b/pkgs/development/python-modules/qh3/default.nix new file mode 100644 index 000000000000..b53871ad97d5 --- /dev/null +++ b/pkgs/development/python-modules/qh3/default.nix @@ -0,0 +1,74 @@ +{ + buildPythonPackage, + cmake, + cryptography, + fetchFromGitHub, + lib, + pytest-asyncio, + pytest-mock, + pytestCheckHook, + rustPlatform, + stdenv, +}: + +buildPythonPackage rec { + pname = "qh3"; + version = "1.5.4"; + pyproject = true; + + src = fetchFromGitHub { + owner = "jawah"; + repo = "qh3"; + tag = "v${version}"; + hash = "sha256-VlqkZk+7803dzwMBFpsSSQUSVu5/1jKouwuK7jNuMGU="; + }; + + cargoDeps = rustPlatform.fetchCargoVendor { + inherit pname version src; + hash = "sha256-Dgx7CSH+XyVZSVHAcr65QULsY//rxgeQe5jYQQkSjHc="; + }; + + nativeBuildInputs = [ + cmake + rustPlatform.bindgenHook + rustPlatform.cargoSetupHook + rustPlatform.maturinBuildHook + ]; + + dontUseCmakeConfigure = true; + + env.NIX_CFLAGS_COMPILE = toString ( + lib.optionals stdenv.cc.isGNU [ + "-Wno-error=stringop-overflow" + ] + ); + + pythonImportsCheck = [ "qh3" ]; + + nativeCheckInputs = [ + cryptography + pytest-asyncio + pytest-mock + pytestCheckHook + ]; + + __darwinAllowLocalNetworking = true; + + preCheck = '' + # import from $out + rm -r qh3 + ''; + + disabledTests = lib.optionals stdenv.buildPlatform.isDarwin [ + # ConnectionError + "test_connect_and_serve_ipv4" + ]; + + meta = { + changelog = "https://github.com/jawah/qh3/blob/${src.tag}/CHANGELOG.rst"; + description = "Lightweight QUIC and HTTP/3 implementation in Python"; + homepage = "https://github.com/jawah/qh3"; + license = lib.licenses.bsd3; + maintainers = with lib.maintainers; [ dotlambda ]; + }; +} diff --git a/pkgs/development/python-modules/urllib3-future/default.nix b/pkgs/development/python-modules/urllib3-future/default.nix new file mode 100644 index 000000000000..15c374b1a7f5 --- /dev/null +++ b/pkgs/development/python-modules/urllib3-future/default.nix @@ -0,0 +1,95 @@ +{ + aiofile, + brotli, + brotlicffi, + buildPythonPackage, + fetchFromGitHub, + hatchling, + h11, + isPyPy, + jh2, + lib, + pytest-asyncio, + pytest-timeout, + pytestCheckHook, + python-socks, + pythonOlder, + qh3, + stdenv, + tornado, + trustme, + wsproto, + zstandard, +}: + +buildPythonPackage rec { + pname = "urllib3-future"; + version = "2.13.907"; + pyproject = true; + + src = fetchFromGitHub { + owner = "jawah"; + repo = "urllib3.future"; + tag = version; + hash = "sha256-JDN37PxeiJhlRFEJ8vkB/2Vt0Xmv0JTpD8LCsVwh3Q4="; + }; + + postPatch = '' + substituteInPlace pyproject.toml \ + --replace-fail "''''ignore:.*but not measured.*:coverage.exceptions.CoverageWarning''''," "" \ + --replace-fail "''''ignore:.*No data was collected.*:coverage.exceptions.CoverageWarning''''," "" + ''; + + build-system = [ hatchling ]; + + # prevents installing a urllib3 module and thereby shadow the urllib3 package + env.URLLIB3_NO_OVERRIDE = "true"; + + dependencies = [ + h11 + jh2 + qh3 + ]; + + optional-dependencies = { + brotli = [ (if isPyPy then brotlicffi else brotli) ]; + qh3 = [ qh3 ]; + secure = [ ]; + socks = [ python-socks ]; + ws = [ wsproto ]; + zstd = lib.optionals (pythonOlder "3.14") [ zstandard ]; + }; + + pythonImportsCheck = [ "urllib3_future" ]; + + # PermissionError: [Errno 1] Operation not permitted + doCheck = !stdenv.buildPlatform.isDarwin; + + nativeCheckInputs = [ + aiofile + pytest-asyncio + pytest-timeout + pytestCheckHook + tornado + trustme + ] + ++ lib.flatten (lib.attrValues optional-dependencies); + + disabledTestPaths = [ + # test connects to the internet + "test/contrib/test_resolver.py::test_url_resolver" + ]; + + disabledTests = [ + # test hangs + "test_proxy_rejection" + ]; + + meta = { + changelog = "https://github.com/jawah/urllib3.future/blob/${src.tag}/CHANGES.rst"; + description = "Powerful HTTP 1.1, 2, and 3 client with both sync and async interfaces"; + homepage = "https://github.com/jawah/urllib3.future"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ dotlambda ]; + }; +} diff --git a/pkgs/development/python-modules/wassima/default.nix b/pkgs/development/python-modules/wassima/default.nix new file mode 100644 index 000000000000..813c6c3de917 --- /dev/null +++ b/pkgs/development/python-modules/wassima/default.nix @@ -0,0 +1,39 @@ +{ + buildPythonPackage, + fetchFromGitHub, + hatchling, + lib, + pytestCheckHook, +}: + +buildPythonPackage rec { + pname = "wassima"; + version = "2.0.1"; + pyproject = true; + + src = fetchFromGitHub { + owner = "jawah"; + repo = "wassima"; + tag = version; + hash = "sha256-MUGB8x4+G+B4cknCeiCcTqKwa8Gea8QrRyM4sYbVxdA="; + }; + + build-system = [ hatchling ]; + + pythonImportsCheck = [ "wassima" ]; + + nativeCheckInputs = [ + pytestCheckHook + ]; + + # tests connect to the internet + doCheck = false; + + meta = { + changelog = "https://github.com/jawah/wassima/blob/${src.tag}/CHANGELOG.md"; + description = "Access your OS root certificates with utmost ease"; + homepage = "https://github.com/jawah/wassima"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ dotlambda ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index b7650413807f..0224baca7efe 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -10516,6 +10516,8 @@ self: super: with self; { nipype = callPackage ../development/python-modules/nipype { inherit (pkgs) which; }; + niquests = callPackage ../development/python-modules/niquests { }; + nitime = callPackage ../development/python-modules/nitime { }; nitransforms = callPackage ../development/python-modules/nitransforms { }; @@ -15455,6 +15457,10 @@ self: super: with self; { qgrid = callPackage ../development/python-modules/qgrid { }; + qh3 = callPackage ../development/python-modules/qh3 { + inherit (pkgs) cmake; + }; + qiling = callPackage ../development/python-modules/qiling { }; qimage2ndarray = callPackage ../development/python-modules/qimage2ndarray { }; @@ -19522,6 +19528,8 @@ self: super: with self; { urllib3 = callPackage ../development/python-modules/urllib3 { }; + urllib3-future = callPackage ../development/python-modules/urllib3-future { }; + urlman = callPackage ../development/python-modules/urlman { }; urlmatch = callPackage ../development/python-modules/urlmatch { }; @@ -19848,6 +19856,8 @@ self: super: with self; { wasserstein = callPackage ../development/python-modules/wasserstein { }; + wassima = callPackage ../development/python-modules/wassima { }; + wat = callPackage ../development/python-modules/wat { }; watchdog = callPackage ../development/python-modules/watchdog { };