Merge master into staging-next

This commit is contained in:
github-actions[bot] 2024-03-27 00:02:10 +00:00 committed by GitHub
commit b289464fb6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
299 changed files with 6243 additions and 5042 deletions

View File

@ -1,11 +1,9 @@
# Checks pkgs/by-name (see pkgs/by-name/README.md)
# using the nixpkgs-check-by-name tool (see pkgs/test/nixpkgs-check-by-name)
# using the nixpkgs-check-by-name tool (see https://github.com/NixOS/nixpkgs-check-by-name)
#
# When you make changes to this workflow, also update pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh adequately
# When you make changes to this workflow, also update pkgs/test/check-by-name/run-local.sh adequately
name: Check pkgs/by-name
# The tool is pinned to a pre-built version on Hydra,
# see pkgs/test/nixpkgs-check-by-name/scripts/README.md
on:
# Using pull_request_target instead of pull_request avoids having to approve first time contributors
pull_request_target:
@ -24,8 +22,7 @@ permissions:
jobs:
check:
# This is x86_64-linux, for which the tool is always prebuilt on the nixos-* channels,
# as specified in nixos/release-combined.nix
# This needs to be x86_64-linux, because we depend on the tooling being pre-built in the GitHub releases
runs-on: ubuntu-latest
# This should take 1 minute at most, but let's be generous.
# The default of 6 hours is definitely too long
@ -100,11 +97,14 @@ jobs:
echo "base=$base" >> "$GITHUB_ENV"
- uses: cachix/install-nix-action@8887e596b4ee1134dae06b98d573bd674693f47c # v26
- name: Fetching the pinned tool
# Update the pinned version using pkgs/test/nixpkgs-check-by-name/scripts/update-pinned-tool.sh
# Update the pinned version using pkgs/test/check-by-name/update-pinned-tool.sh
run: |
# Get the direct /nix/store path from the pin to avoid having to evaluate Nixpkgs
toolPath=$(jq -r '."ci-path"' pkgs/test/nixpkgs-check-by-name/scripts/pinned-tool.json)
# This asks the substituter for the path, which should be there because Hydra will have pre-built and pushed it
# The pinned version of the tooling to use
toolVersion=$(<pkgs/test/check-by-name/pinned-version.txt)
# Fetch the x86_64-linux-specific release artifact containing the Gzipped NAR of the pre-built tool
toolPath=$(curl -sSfL https://github.com/NixOS/nixpkgs-check-by-name/releases/download/"$toolVersion"/x86_64-linux.nar.gz \
| gzip -cd | nix-store --import | tail -1)
# Adds a result symlink as a GC root
nix-store --realise "$toolPath" --add-root result
- name: Running nixpkgs-check-by-name
run: |

View File

@ -11,7 +11,7 @@ What follows is a (very incomplete) overview of available scripts.
### `check-by-name.sh`
An alias for `pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh`, see [documentation](../../pkgs/test/nixpkgs-check-by-name/scripts/README.md).
An alias for `pkgs/test/check-by-name/run-local.sh`, see [documentation](../../pkgs/test/check-by-name/README.md).
### `get-maintainer.sh`

View File

@ -1 +1 @@
../../pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh
../../pkgs/test/check-by-name/run-local.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p "python3.withPackages(ps: [ ps.beautifulsoup4 ps.click ps.httpx ps.jinja2 ps.pyyaml ])
#!nix-shell -i python3 -p "python3.withPackages(ps: [ ps.beautifulsoup4 ps.click ps.httpx ps.jinja2 ps.pyyaml ])"
import base64
import binascii
import json

View File

@ -257,7 +257,7 @@ foreach my $path (glob "/sys/class/{block,mmc_host}/*") {
# Add bcache module, if needed.
my @bcacheDevices = glob("/dev/bcache*");
@bcacheDevices = grep(!qr#dev/bcachefs.*#, @bcacheDevices);
@bcacheDevices = grep(!m#dev/bcachefs.*#, @bcacheDevices);
if (scalar @bcacheDevices > 0) {
push @initrdAvailableKernelModules, "bcache";
}

View File

@ -27,6 +27,8 @@ let
name = "paperless_ngx_nltk_data";
paths = pkg.nltkData;
};
} // optionalAttrs (cfg.openMPThreadingWorkaround) {
OMP_NUM_THREADS = "1";
} // (lib.mapAttrs (_: s:
if (lib.isAttrs s || lib.isList s) then builtins.toJSON s
else if lib.isBool s then lib.boolToString s
@ -199,6 +201,20 @@ in
};
package = mkPackageOption pkgs "paperless-ngx" { };
openMPThreadingWorkaround = mkEnableOption ''
a workaround for document classifier timeouts.
Paperless uses OpenBLAS via scikit-learn for document classification.
The default is to use threading for OpenMP but this would cause the
document classifier to spin on one core seemingly indefinitely if there
are large amounts of classes per classification; causing it to
effectively never complete due to running into timeouts.
This sets `OMP_NUM_THREADS` to `1` in order to mitigate the issue. See
https://github.com/NixOS/nixpkgs/issues/240591 for more information.
'' // mkOption { default = true; };
};
config = mkIf cfg.enable {

View File

@ -392,7 +392,10 @@ in {
boot.kernelParams = [
"root=${config.boot.initrd.systemd.root}"
] ++ lib.optional (config.boot.resumeDevice != "") "resume=${config.boot.resumeDevice}";
] ++ lib.optional (config.boot.resumeDevice != "") "resume=${config.boot.resumeDevice}"
# `systemd` mounts root in initrd as read-only unless "rw" is on the kernel command line.
# For NixOS activation to succeed, we need to have root writable in initrd.
++ lib.optional (config.boot.initrd.systemd.root == "gpt-auto") "rw";
boot.initrd.systemd = {
initrdBin = [pkgs.bash pkgs.coreutils cfg.package.kmod cfg.package];

View File

@ -169,11 +169,6 @@ in rec {
(onFullSupported "nixpkgs.jdk")
(onSystems ["x86_64-linux"] "nixpkgs.mesa_i686") # i686 sanity check + useful
["nixpkgs.tarball"]
# Ensure that nixpkgs-check-by-name is available in nixos-unstable,
# so that a pre-built version can be used in CI for PR's
# See ../pkgs/test/nixpkgs-check-by-name/README.md
(onSystems ["x86_64-linux"] "nixpkgs.tests.nixpkgs-check-by-name")
];
};
}

View File

@ -22,16 +22,26 @@
rustPlatform.buildRustPackage rec {
pname = "termusic";
version = "0.7.11";
version = "0.9.0";
src = fetchFromGitHub {
owner = "tramhao";
repo = "termusic";
rev = "v${version}";
hash = "sha256-ykOBXM/WF+zasAt+6mgY2aSFCpGaYcqk+YI7YLM3MWs=";
hash = "sha256-FOFZg32hrWpKVsjkMDkiqah7jmUZw0HRWGqOvsN0t8Q=";
};
cargoHash = "sha256-BrOpU0RFdlRXQIMjfHfs/XYIdBCYKFSA+5by/rGzC8Y=";
postPatch = ''
pushd $cargoDepsCopy/stream-download
oldHash=$(sha256sum src/lib.rs | cut -d " " -f 1)
substituteInPlace $cargoDepsCopy/stream-download/src/lib.rs \
--replace-warn '#![doc = include_str!("../README.md")]' ""
substituteInPlace .cargo-checksum.json \
--replace $oldHash $(sha256sum src/lib.rs | cut -d " " -f 1)
popd
'';
cargoHash = "sha256-r5FOl3Bp3GYhOhvWj/y6FXsuG2wvuFcMcYKBzVBVqiM=";
nativeBuildInputs = [
pkg-config
@ -62,5 +72,6 @@ rustPlatform.buildRustPackage rec {
homepage = "https://github.com/tramhao/termusic";
license = with lib.licenses; [ gpl3Only ];
maintainers = with lib.maintainers; [ devhell ];
mainProgram = "termusic";
};
}

View File

@ -17033,5 +17033,17 @@ final: prev:
meta.homepage = "https://github.com/lukas-reineke/virt-column.nvim/";
};
jupytext-nvim = buildVimPlugin {
pname = "jupytest-nvim";
version = "2024-01-24";
src = fetchFromGitHub {
owner = "GCBallesteros";
repo = "jupytext.nvim";
rev = "68fddf28119dbaddfaea6b71f3d6aa1e081afb93";
sha256 = "sha256-x5emW+qfUTUDR72B9QdDgVdrb8wGH9D7AdtRrQm80sI=";
};
meta.homepage = "https://github.com/GCBallesteros/jupytext.nvim/";
};
}

View File

@ -747,6 +747,10 @@
dependencies = with self; [ lush-nvim ];
};
jupytext-nvim = super.jupytext-nvim.overrideAttrs {
passthru.python3Dependencies = ps: [ ps.jupytext ];
};
LanguageClient-neovim =
let
version = "0.1.161";

View File

@ -419,6 +419,7 @@ https://github.com/HiPhish/jinja.vim/,HEAD,
https://github.com/vito-c/jq.vim/,,
https://github.com/neoclide/jsonc.vim/,,
https://github.com/JuliaEditorSupport/julia-vim/,,
https://github.com/GCBallesteros/jupytext.nvim/,HEAD,
https://github.com/rebelot/kanagawa.nvim/,,
https://github.com/anuvyklack/keymap-layer.nvim/,HEAD,
https://github.com/kmonad/kmonad-vim/,,

View File

@ -2,28 +2,22 @@
, stdenv
, fetchFromGitLab
, writeText
, cmake
, cjson
, doxygen
, glslang
, pkg-config
, python3
, SDL2
, bluez
, cjson
, cmake
, dbus
, doxygen
, eigen
, elfutils
, ffmpeg
, glslang
, gst-plugins-base
, gstreamer
, hidapi
, libGL
, libXau
, libXdmcp
, libXrandr
, libXext
, libbsd
, libdrm
, libffi
, libGL
, libjpeg
, librealsense
, libsurvive
@ -32,13 +26,20 @@
, libuv
, libuvc
, libv4l
, libXau
, libxcb
, libXdmcp
, libXext
, libXrandr
, onnxruntime
, opencv4
, openhmd
, openvr
, orc
, pcre2
, pkg-config
, python3
, SDL2
, shaderc
, udev
, vulkan-headers
@ -46,7 +47,6 @@
, wayland
, wayland-protocols
, wayland-scanner
, libdrm
, zlib
, zstd
, nixosTests
@ -83,7 +83,6 @@ stdenv.mkDerivation {
];
buildInputs = [
SDL2
bluez
cjson
dbus
@ -93,13 +92,11 @@ stdenv.mkDerivation {
gst-plugins-base
gstreamer
hidapi
libGL
libXau
libXdmcp
libXrandr
libbsd
libjpeg
libdrm
libffi
libGL
libjpeg
librealsense
libsurvive
libunwind
@ -107,21 +104,25 @@ stdenv.mkDerivation {
libuv
libuvc
libv4l
libXau
libxcb
libXdmcp
libXext
libXrandr
onnxruntime
opencv4
openhmd
openvr
orc
pcre2
SDL2
shaderc
udev
vulkan-headers
vulkan-loader
wayland
wayland-scanner
wayland-protocols
libdrm
wayland-scanner
zlib
zstd
];

View File

@ -14,6 +14,10 @@ stdenv.mkDerivation rec {
postPatch = lib.optionalString stdenv.cc.isClang ''
substituteInPlace Makefile --replace "-fno-guess-branch-probability" ""
for f in $(find -name "*.h" -or -name "*.cpp"); do
substituteInPlace "$f" --replace-quiet "log2" "_log2"
done
'';
buildFlags = [ "CC=${stdenv.cc.targetPrefix}cc" "CXX=${stdenv.cc.targetPrefix}c++" ];

View File

@ -39,7 +39,6 @@
, ecm
, lcalc
, rubiks
, flintqs
, blas
, lapack
, flint3
@ -93,7 +92,6 @@ let
ecm
lcalc
rubiks
flintqs
jdk # only needed for `jmol` which may be replaced in the future
less # needed to prevent transient test errors until https://github.com/ipython/ipython/pull/11864 is resolved
]

View File

@ -13,7 +13,6 @@
, gmp
, gfan
, python3
, flintqs
, eclib
, ntl
, ecm
@ -40,7 +39,6 @@ let
gfan
maxima
eclib
flintqs
ntl
ecm
];

View File

@ -13,12 +13,9 @@
, doxygen
, graphviz
, latex2html
# upstream generates docs with texinfo 4. later versions of texinfo
# use letters instead of numbers for post-appendix chapters, and we
# want it to match the upstream format because sage depends on it.
, texinfo4
, texinfo
, texliveSmall
, enableDocs ? true
, enableDocs ? !stdenv.isDarwin
, enableGfanlib ? true
}:
@ -85,7 +82,7 @@ stdenv.mkDerivation rec {
doxygen
graphviz
latex2html
texinfo4
texinfo
texliveSmall
] ++ lib.optionals stdenv.isDarwin [ getconf ];
depsBuildBuild = [ buildPackages.stdenv.cc ];

View File

@ -108,13 +108,13 @@ There's some limitations as to which packages can be defined using this structur
## Validation
CI performs [certain checks](../test/nixpkgs-check-by-name/README.md#validity-checks) on the `pkgs/by-name` structure.
This is done using the [`nixpkgs-check-by-name` tool](../test/nixpkgs-check-by-name).
CI performs [certain checks](https://github.com/NixOS/nixpkgs-check-by-name?tab=readme-ov-file#validity-checks) on the `pkgs/by-name` structure.
This is done using the [`nixpkgs-check-by-name` tool](https://github.com/NixOS/nixpkgs-check-by-name).
You can locally emulate the CI check using
```
$ ./pkgs/test/nixpkgs-check-by-name/scripts/run-local.sh master
$ ./maintainers/scripts/check-by-name.sh master
```
See [here](../../.github/workflows/check-by-name.yml) for more info.

5174
pkgs/by-name/at/attic-client/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,66 @@
{ lib
, rustPlatform
, fetchFromGitHub
, nix
, boost
, pkg-config
, stdenv
, installShellFiles
, darwin
, crates ? [ "attic-client" ]
}:
rustPlatform.buildRustPackage {
pname = "attic";
version = "0.1.0";
src = fetchFromGitHub {
owner = "zhaofengli";
repo = "attic";
rev = "6eabc3f02fae3683bffab483e614bebfcd476b21";
hash = "sha256-wSZjK+rOXn+UQiP1NbdNn5/UW6UcBxjvlqr2wh++MbM=";
};
nativeBuildInputs = [
pkg-config
installShellFiles
];
buildInputs = [
nix
boost
] ++ lib.optionals stdenv.isDarwin (with darwin.apple_sdk.frameworks; [
SystemConfiguration
]);
cargoLock = {
lockFile = ./Cargo.lock;
outputHashes = {
"nix-base32-0.1.2-alpha.0" = "sha256-wtPWGOamy3+ViEzCxMSwBcoR4HMMD0t8eyLwXfCDFdo=";
};
};
cargoBuildFlags = lib.concatMapStrings (c: "-p ${c} ") crates;
ATTIC_DISTRIBUTOR = "attic";
# Attic interacts with Nix directly and its tests require trusted-user access
# to nix-daemon to import NARs, which is not possible in the build sandbox.
doCheck = false;
postInstall = lib.optionalString (stdenv.hostPlatform == stdenv.buildPlatform) ''
if [[ -f $out/bin/attic ]]; then
installShellCompletion --cmd attic \
--bash <($out/bin/attic gen-completions bash) \
--zsh <($out/bin/attic gen-completions zsh) \
--fish <($out/bin/attic gen-completions fish)
fi
'';
meta = with lib; {
description = "Multi-tenant Nix Binary Cache";
homepage = "https://github.com/zhaofengli/attic";
license = licenses.asl20;
maintainers = with maintainers; [ zhaofengli aciceri ];
platforms = platforms.linux ++ platforms.darwin;
mainProgram = "attic";
};
}

View File

@ -0,0 +1,7 @@
{ attic-client
}:
(attic-client.override {
crates = [ "attic-server" ];
}).overrideAttrs {
meta.mainProgram = "atticd";
}

View File

@ -0,0 +1,58 @@
{
buildGoModule,
docker-credential-gcr,
fetchFromGitHub,
lib,
nix-update-script,
testers,
}:
buildGoModule rec {
pname = "docker-credential-gcr";
version = "2.1.22";
src = fetchFromGitHub {
owner = "GoogleCloudPlatform";
repo = "docker-credential-gcr";
rev = "refs/tags/v${version}";
sha256 = "sha256-vGX6Jhh91dUqZ+y+h1SlPiFE3dL0UO3iJyyzvQVoUsQ=";
};
postPatch = ''
rm -rf ./test
'';
vendorHash = "sha256-VsJ5OI8D1u9qZqtirYf682+z0wLJr/vAxRLHAEGwKSY=";
CGO_ENABLED = 0;
ldflags = [
"-s"
"-w"
"-X github.com/GoogleCloudPlatform/docker-credential-gcr/v2/config.Version=${version}"
];
passthru = {
tests.version = testers.testVersion {
package = docker-credential-gcr;
command = "docker-credential-gcr version";
};
updateScript = nix-update-script { };
};
__darwinAllowLocalNetworking = true;
meta = with lib; {
description = "A Docker credential helper for GCR (https://gcr.io) users";
longDescription = ''
docker-credential-gcr is Google Container Registry's Docker credential
helper. It allows for Docker clients v1.11+ to easily make
authenticated requests to GCR's repositories (gcr.io, eu.gcr.io, etc.).
'';
homepage = "https://github.com/GoogleCloudPlatform/docker-credential-gcr";
changelog = "https://github.com/GoogleCloudPlatform/docker-credential-gcr/releases/tag/v${version}";
license = licenses.asl20;
maintainers = with maintainers; [ suvash anthonyroussel ];
mainProgram = "docker-credential-gcr";
};
}

View File

@ -1,34 +1,28 @@
{ lib
, elasticsearch-curator
, fetchFromGitHub
, nix-update-script
, python3
, testers
}:
python3.pkgs.buildPythonApplication rec {
pname = "elasticsearch-curator";
version = "8.0.10";
version = "8.0.12";
format = "pyproject";
src = fetchFromGitHub {
owner = "elastic";
repo = "curator";
rev = "refs/tags/v${version}";
hash = "sha256-hGG7lyrVviZSKTUo+AOPIutn/mxtDo+ewFxCRdj/jts=";
hash = "sha256-CU/8l5607eKodcdpMKu0Wdlg+K6YnFX6uoDju12NDR0=";
};
postPatch = ''
substituteInPlace pyproject.toml \
--replace "elasticsearch8==" "elasticsearch8>=" \
--replace "es_client==" "es_client>=" \
--replace "ecs-logging==" "ecs-logging>=" \
--replace "click==" "click>="\
--replace "pyyaml==" "pyyaml>="
'';
nativeBuildInputs = with python3.pkgs; [
build-system = with python3.pkgs; [
hatchling
];
propagatedBuildInputs = with python3.pkgs; [
dependencies = with python3.pkgs; [
certifi
click
ecs-logging
@ -40,7 +34,6 @@ python3.pkgs.buildPythonApplication rec {
];
nativeCheckInputs = with python3.pkgs; [
mock
requests
pytestCheckHook
];
@ -76,6 +69,14 @@ python3.pkgs.buildPythonApplication rec {
"test_api_key_set"
];
passthru = {
tests.version = testers.testVersion {
package = elasticsearch-curator;
command = "${lib.getExe elasticsearch-curator} --version";
};
updateScript = nix-update-script { };
};
meta = with lib; {
description = "Curate, or manage, your Elasticsearch indices and snapshots";
homepage = "https://github.com/elastic/curator";
@ -93,6 +94,7 @@ python3.pkgs.buildPythonApplication rec {
* Perform various actions on the items which remain in the actionable list.
'';
mainProgram = "curator";
maintainers = with maintainers; [ basvandijk ];
};
}

View File

@ -0,0 +1,27 @@
{ lib,
fetchFromGitHub,
buildGoModule
}:
buildGoModule rec {
pname = "hacompanion";
version = "1.0.11";
src = fetchFromGitHub {
owner = "tobias-kuendig";
repo = "hacompanion";
rev = "v${version}";
hash = "sha256-gTsA5XBjLlm/cITwQwYNudPK9SbSEaiAIjjdvRS3+8Q=";
};
vendorHash = "sha256-ZZ8nxN+zUeFhSXyoHLMgzeFllnIkKdoVnbVK5KjrLEQ=";
meta = {
changelog = "https://github.com/tobias-kuendig/hacompanion/releases/tag/v${version}";
description = "Daemon that sends local hardware information to Home Assistant";
homepage = "https://github.com/tobias-kuendig/hacompanion";
license = lib.licenses.mit;
platforms = lib.platforms.linux;
maintainers = with lib.maintainers; [ ramblurr ];
};
}

View File

@ -3,7 +3,7 @@
, fetchFromGitHub
, emptyDirectory
, writeText
, makeWrapper
, makeBinaryWrapper
, gradle
, jdk21
, llvmPackages
@ -49,7 +49,7 @@ stdenv.mkDerivation {
nativeBuildInputs = [
gradle
makeWrapper
makeBinaryWrapper
];
env = {
@ -79,18 +79,16 @@ stdenv.mkDerivation {
mkdir -p $out/opt/
cp -r ./build/jextract $out/opt/jextract
makeBinaryWrapper "$out/opt/jextract/bin/jextract" "$out/bin/jextract"
runHook postInstall
'';
postFixup = ''
makeWrapper "$out/opt/jextract/bin/jextract" "$out/bin/jextract"
'';
meta = with lib; {
description = "A tool which mechanically generates Java bindings from a native library headers";
mainProgram = "jextract";
homepage = "https://github.com/openjdk/jextract";
platforms = jdk21.meta.platforms;
license = licenses.gpl2Only;
maintainers = with maintainers; [ sharzy ];
};

View File

@ -0,0 +1,95 @@
{ lib
, stdenv
, fetchFromGitHub
, emptyDirectory
, writeText
, makeBinaryWrapper
, gradle
, jdk22
, llvmPackages
}:
let
gradleInit = writeText "init.gradle" ''
logger.lifecycle 'Replacing Maven repositories with empty directory...'
gradle.projectsLoaded {
rootProject.allprojects {
buildscript {
repositories {
clear()
maven { url '${emptyDirectory}' }
}
}
repositories {
clear()
maven { url '${emptyDirectory}' }
}
}
}
settingsEvaluated { settings ->
settings.pluginManagement {
repositories {
maven { url '${emptyDirectory}' }
}
}
}
'';
in
stdenv.mkDerivation {
pname = "jextract";
version = "unstable-2024-03-13";
src = fetchFromGitHub {
owner = "openjdk";
repo = "jextract";
rev = "b9ec8879cff052b463237fdd76382b3a5cd8ff2b";
hash = "sha256-+4AM8pzXPIO/CS3+Rd/jJf2xDvAo7K7FRyNE8rXvk5U=";
};
nativeBuildInputs = [
gradle
makeBinaryWrapper
];
env = {
ORG_GRADLE_PROJECT_llvm_home = llvmPackages.libclang.lib;
ORG_GRADLE_PROJECT_jdk22_home = jdk22;
};
buildPhase = ''
runHook preBuild
export GRADLE_USER_HOME=$(mktemp -d)
gradle --console plain --init-script "${gradleInit}" assemble
runHook postBuild
'';
doCheck = true;
checkPhase = ''
runHook preCheck
gradle --console plain --init-script "${gradleInit}" verify
runHook postCheck
'';
installPhase = ''
runHook preInstall
mkdir -p $out/opt/
cp -r ./build/jextract $out/opt/jextract
makeBinaryWrapper "$out/opt/jextract/bin/jextract" "$out/bin/jextract"
runHook postInstall
'';
meta = with lib; {
description = "A tool which mechanically generates Java bindings from a native library headers";
mainProgram = "jextract";
homepage = "https://github.com/openjdk/jextract";
platforms = jdk22.meta.platforms;
license = licenses.gpl2Only;
maintainers = with maintainers; [ jlesquembre sharzy ];
};
}

View File

@ -5,16 +5,16 @@
rustPlatform.buildRustPackage rec {
pname = "obs-cmd";
version = "0.17.4";
version = "0.17.5";
src = fetchFromGitHub {
owner = "grigio";
repo = "obs-cmd";
rev = "v${version}";
hash = "sha256-HCvIMIQZKzIkpYL9F9oM4xiE/gOeI+7dMj9QmhetHm4=";
hash = "sha256-AphpIehFHZwcZ7vO5FV6PBZSO3y6oLhH/kQhJjr34VY=";
};
cargoHash = "sha256-AQRjZH3WhZXU6NhDSCv4/HWz5un1nFtuzWPYSJA9XaE=";
cargoHash = "sha256-s/nWJ/8JnZwmROFSd2y6btopk2Cxp0zkMdy7mxVxr6k=";
meta = with lib; {
description = "Minimal CLI to control OBS Studio via obs-websocket";

View File

@ -0,0 +1,94 @@
{ stdenv
, lib
, fetchurl
, dpkg
, autoPatchelfHook
, wrapGAppsHook
, alsa-lib
, cups
, libGL
, libX11
, libXScrnSaver
, libXtst
, mesa
, nss
, gtk3
, libpulseaudio
, systemd
, withTetrioPlus ? false # For backwards compatibility. At the time of writing, the latest released tetrio plus version is not compatible with tetrio desktop.
, tetrio-plus ? false # For backwards compatibility. At the time of writing, the latest released tetrio plus version is not compatible with tetrio desktop.
}:
lib.warnIf (withTetrioPlus != false) "withTetrioPlus: Currently unsupported with tetrio-desktop 9.0.0. Please remove this attribute."
lib.warnIf (tetrio-plus != false) "tetrio-plus: Currently unsupported with tetrio-desktop 9.0.0. Please remove this attribute."
(let
libPath = lib.makeLibraryPath [
libGL
libpulseaudio
systemd
];
in
stdenv.mkDerivation (finalAttrs: {
pname = "tetrio-desktop";
version = "9.0.0";
src = fetchurl {
url = "https://tetr.io/about/desktop/builds/${lib.versions.major finalAttrs.version}/TETR.IO%20Setup.deb";
hash = "sha256-UriLwMB8D+/T32H4rPbkJAy/F/FFhNpd++0AR1lwEfs=";
};
nativeBuildInputs = [
dpkg
autoPatchelfHook
wrapGAppsHook
];
dontWrapGApps = true;
buildInputs = [
alsa-lib
cups
libX11
libXScrnSaver
libXtst
mesa
nss
gtk3
];
unpackCmd = "dpkg -x $curSrc src";
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp -r opt/ usr/share/ $out
ln -s $out/opt/TETR.IO/TETR.IO $out/bin/tetrio
substituteInPlace $out/share/applications/TETR.IO.desktop \
--replace-fail "Exec=/opt/TETR.IO/TETR.IO" "Exec=$out/bin/tetrio"
runHook postInstall
'';
postFixup = ''
wrapProgram $out/opt/TETR.IO/TETR.IO \
--prefix LD_LIBRARY_PATH : ${libPath}:$out/opt/TETR.IO \
''${gappsWrapperArgs[@]}
'';
meta = {
description = "TETR.IO desktop client";
downloadPage = "https://tetr.io/about/desktop/";
homepage = "https://tetr.io";
license = lib.licenses.unfree;
longDescription = ''
TETR.IO is a modern yet familiar online stacker.
Play against friends and foes all over the world, or claim a spot on the leaderboards - the stacker future is yours!
'';
mainProgram = "tetrio";
maintainers = with lib.maintainers; [ wackbyte ];
platforms = [ "x86_64-linux" ];
};
}))

View File

@ -4,16 +4,16 @@
}:
rustPlatform.buildRustPackage rec {
pname = "typos-lsp";
version = "0.1.15";
version = "0.1.16";
src = fetchFromGitHub {
owner = "tekumara";
repo = "typos-lsp";
rev = "refs/tags/v${version}";
hash = "sha256-8mCK/NKik1zf6hqJN4pflDbtFALckHR/8AQborbOoHs=";
hash = "sha256-wXwdAPaj2dY6R6rUl/3WGeUwV+/waQdHv1dmzTqFNow=";
};
cargoHash = "sha256-aL7arYAiTpz9jy7Kh8u7OJmPMjayX4JiKoa7u8K0UiE=";
cargoHash = "sha256-qXQPxMlBwLb2NVae+vKZPzufNrQeuz0cAdMflpsjDf4=";
# fix for compilation on aarch64
# see https://github.com/NixOS/nixpkgs/issues/145726

View File

@ -107,7 +107,7 @@ let
++ lib.optional stdenv.isLinux autoPatchelfHook;
propagatedBuildInputs = [ setJavaClassPath zlib ]
++ lib.optional stdenv.isDarwin darwin.apple_sdk.frameworks.Foundation;
++ lib.optional stdenv.isDarwin darwin.apple_sdk_11_0.frameworks.Foundation;
buildInputs = lib.optionals stdenv.isLinux [
alsa-lib # libasound.so wanted by lib/libjsound.so
@ -165,33 +165,27 @@ let
echo "Testing GraalVM"
$out/bin/java -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler HelloWorld | fgrep 'Hello World'
# Workaround GraalVM issue where the builder does not have access to the
# environment variables since 21.0.0
# Only needed for native-image tests
# https://github.com/oracle/graal/pull/6095
# https://github.com/oracle/graal/pull/6095
# https://github.com/oracle/graal/issues/7502
export NATIVE_IMAGE_DEPRECATED_BUILDER_SANITATION="true";
extraNativeImageArgs="$(export -p | sed -n 's/^declare -x \([^=]\+\)=.*$/ -E\1/p' | tr -d \\n)"
echo "Ahead-Of-Time compilation"
$out/bin/native-image -H:+UnlockExperimentalVMOptions -H:-CheckToolchain -H:+ReportExceptionStackTraces HelloWorld
$out/bin/native-image -H:+UnlockExperimentalVMOptions -H:-CheckToolchain -H:+ReportExceptionStackTraces -march=compatibility $extraNativeImageArgs HelloWorld
./helloworld | fgrep 'Hello World'
${# --static is only available in Linux
lib.optionalString (stdenv.isLinux && !useMusl) ''
echo "Ahead-Of-Time compilation with -H:+StaticExecutableWithDynamicLibC"
$out/bin/native-image -H:+UnlockExperimentalVMOptions -H:+StaticExecutableWithDynamicLibC HelloWorld
$out/bin/native-image -H:+UnlockExperimentalVMOptions -H:+StaticExecutableWithDynamicLibC -march=compatibility $extraNativeImageArgs HelloWorld
./helloworld | fgrep 'Hello World'
echo "Ahead-Of-Time compilation with --static"
$out/bin/native-image --static HelloWorld
$out/bin/native-image $extraNativeImageArgs -march=compatibility --static HelloWorld
./helloworld | fgrep 'Hello World'
''}
${# --static is only available in Linux
lib.optionalString (stdenv.isLinux && useMusl) ''
echo "Ahead-Of-Time compilation with --static and --libc=musl"
$out/bin/native-image --static HelloWorld --libc=musl
$out/bin/native-image $extraNativeImageArgs -march=compatibility --libc=musl --static HelloWorld
./helloworld | fgrep 'Hello World'
''}

View File

@ -1,23 +1,28 @@
{ lib
, stdenv
, callPackage
, fetchurl
, pkgs
}:
lib.makeScope pkgs.newScope (self:
{
buildGraalvm = callPackage ./buildGraalvm.nix;
stdenv =
if pkgs.stdenv.isDarwin then
pkgs.darwin.apple_sdk_11_0.stdenv
else
pkgs.stdenv;
buildGraalvmProduct = callPackage ./buildGraalvmProduct.nix;
buildGraalvm = self.callPackage ./buildGraalvm.nix;
graalvm-ce = callPackage ./graalvm-ce { };
buildGraalvmProduct = self.callPackage ./buildGraalvmProduct.nix;
graalvm-ce-musl = callPackage ./graalvm-ce { useMusl = true; };
graalvm-ce = self.callPackage ./graalvm-ce { };
graaljs = callPackage ./graaljs { };
graalvm-ce-musl = self.callPackage ./graalvm-ce { useMusl = true; };
graalnodejs = callPackage ./graalnodejs { };
graaljs = self.callPackage ./graaljs { };
graalpy = callPackage ./graalpy { };
graalnodejs = self.callPackage ./graalnodejs { };
truffleruby = callPackage ./truffleruby { };
}
graalpy = self.callPackage ./graalpy { };
truffleruby = self.callPackage ./truffleruby { };
})

View File

@ -33,7 +33,7 @@ let
"3.10" = "0.2.4";
}.${gnuradio.versionAttr.major};
src = fetchgit {
url = "git://git.osmocom.org/gr-osmosdr";
url = "https://gitea.osmocom.org/sdr/gr-osmosdr";
rev = "v${version}";
sha256 = {
"3.7" = "0bf9bnc1c3c4yqqqgmg3nhygj6rcfmyk6pybi27f7461d2cw1drv";

View File

@ -50,7 +50,6 @@ stdenv.mkDerivation rec {
doCheck = true;
meta = with lib; {
broken = stdenv.isDarwin;
description = "Finite Field Linear Algebra Subroutines";
mainProgram = "fflas-ffpack-config";
license = licenses.lgpl21Plus;

View File

@ -1,5 +1,6 @@
{ lib
, stdenv
, fetchpatch
, fetchurl
, gmp
, mpfr
@ -24,6 +25,13 @@ stdenv.mkDerivation rec {
sha256 = "sha256-ezEaAFA6hjiB64F32+uEMi8pOZ89fXLzsaTJuh1XlLQ=";
};
patches = [
(fetchpatch {
url = "https://github.com/flintlib/flint/commit/e7d005c369754243cba32bd782ea2a5fc874fde5.diff";
hash = "sha256-IqEtYEpNVXfoTeerh/0ig+eDqUpAlGdBB3uO8ShYh3o=";
})
];
nativeBuildInputs = [
autoconf
automake

View File

@ -1,5 +1,6 @@
{ lib, stdenv
, fetchFromGitHub
, fetchpatch
, pkg-config
, gettext
, autoreconfHook
@ -18,6 +19,13 @@ stdenv.mkDerivation rec {
sha256 = "sha256-taSS7jpVyjVfNe6kSuUDXMD2PgKmtG64V5MjZyQzorI=";
};
patches = [
(fetchpatch {
url = "https://github.com/fplll/fplll/commit/317cf70893eebfb2625da12e5377189908c36240.diff";
sha256 = "sha256-GbYSolBgv/he4QzjuRFdg93wHJABVHvA9x3PjpJTSRE=";
})
];
nativeBuildInputs = [
pkg-config
gettext

View File

@ -25,6 +25,11 @@ stdenv.mkDerivation rec {
url = "https://github.com/linbox-team/givaro/commit/c7744bb133496cd7ac04688f345646d505e1bf52.patch";
hash = "sha256-aAA5o8Va10v0Pqgcpx7qM0TAZiNQgXoR6N9xecj7tDA=";
})
(fetchpatch {
name = "clang-16.patch";
url = "https://github.com/linbox-team/givaro/commit/a81d44b3b57c275bcb04ab00db79be02561deaa2.patch";
hash = "sha256-sSk+VWffoEjZRTJcHRISLHPyW6yuvI1u8knBOfxNUIE=";
})
];
enableParallelBuilding = true;

View File

@ -1,5 +1,6 @@
{ lib, stdenv
, fetchFromGitHub
, fetchpatch
, autoreconfHook
, givaro
, pkg-config
@ -23,6 +24,13 @@ stdenv.mkDerivation rec {
sha256 = "sha256-mW84a98KPLqcHMjX3LIYTmVe0ngUdz6RJLpoDaAqKU8=";
};
patches = [
(fetchpatch {
url = "https://github.com/linbox-team/linbox/commit/4be26e9ef0eaf36a9909e5008940e8bf7dc625b6.patch";
sha256 = "PX0Tik7blXOV2vHUq92xMxaADkNoNGiax4qrjQyGK6U=";
})
];
nativeBuildInputs = [
autoreconfHook
pkg-config

View File

@ -1,7 +1,6 @@
{ lib
, gcc12Stdenv
, fetchFromGitHub
, fetchpatch2
, fetchurl
, cudaSupport ? opencv.cudaSupport or false
@ -11,10 +10,10 @@
, cmake
, git
, libarchive
, patchelf
, pkg-config
, python
, python3Packages
, shellcheck
, sphinx
# runtime
, flatbuffers
@ -36,40 +35,34 @@ let
stdenv = gcc12Stdenv;
# See GNA_VERSION in cmake/dependencies.cmake
gna_version = "03.05.00.2116";
gna = fetchurl {
url = "https://storage.openvinotoolkit.org/dependencies/gna/gna_${gna_version}.zip";
hash = "sha256-lgNQVncCvaFydqxMBg11JPt8587XhQBL2GHIH/K/4sU=";
};
tbbbind_version = "2_5";
tbbbind = fetchurl {
url = "https://storage.openvinotoolkit.org/dependencies/thirdparty/linux/tbbbind_${tbbbind_version}_static_lin_v4.tgz";
hash = "sha256-Tr8wJGUweV8Gb7lhbmcHxrF756ZdKdNRi1eKdp3VTuo=";
};
python = python3Packages.python.withPackages (ps: with ps; [
cython
pybind11
setuptools
sphinx
wheel
]);
in
stdenv.mkDerivation rec {
pname = "openvino";
version = "2023.3.0";
version = "2024.0.0";
src = fetchFromGitHub {
owner = "openvinotoolkit";
repo = "openvino";
rev = "refs/tags/${version}";
fetchSubmodules = true;
hash = "sha256-dXlQhar5gz+1iLmDYXUY0jZKh4rJ+khRpoZQphJXfcU=";
hash = "sha256-Xsrmc1EynkjgPgiQ+ESyVJRJT9Afqyob0/uH+Is4TYA=";
};
patches = [
(fetchpatch2 {
name = "enable-js-toggle.patch";
url = "https://github.com/openvinotoolkit/openvino/commit/0a8f1383826d949c497fe3d05fef9ad2b662fa7e.patch";
hash = "sha256-mQYunouPo3tRlD5Yp4EUth324ccNnVX8zmjPHvJBYKw=";
})
];
outputs = [
"out"
"python"
@ -81,26 +74,15 @@ stdenv.mkDerivation rec {
cmake
git
libarchive
patchelf
pkg-config
(python.withPackages (ps: with ps; [
cython
pybind11
setuptools
]))
python
shellcheck
sphinx
] ++ lib.optionals cudaSupport [
cudaPackages.cuda_nvcc
];
postPatch = ''
mkdir -p temp/gna_${gna_version}
pushd temp/
bsdtar -xf ${gna}
autoPatchelf gna_${gna_version}
echo "${gna.url}" > gna_${gna_version}/ie_dependency.info
popd
mkdir -p temp/tbbbind_${tbbbind_version}
pushd temp/tbbbind_${tbbbind_version}
bsdtar -xf ${tbbbind}
@ -116,6 +98,7 @@ stdenv.mkDerivation rec {
"-DCMAKE_PREFIX_PATH:PATH=${placeholder "out"}"
"-DOpenCV_DIR=${opencv}/lib/cmake/opencv4/"
"-DProtobuf_LIBRARIES=${protobuf}/lib/libprotobuf${stdenv.hostPlatform.extensions.sharedLibrary}"
"-DPython_EXECUTABLE=${python.interpreter}"
(cmakeBool "CMAKE_VERBOSE_MAKEFILE" true)
(cmakeBool "NCC_SYLE" false)
@ -126,7 +109,6 @@ stdenv.mkDerivation rec {
# features
(cmakeBool "ENABLE_INTEL_CPU" true)
(cmakeBool "ENABLE_INTEL_GNA" true)
(cmakeBool "ENABLE_JS" false)
(cmakeBool "ENABLE_LTO" true)
(cmakeBool "ENABLE_ONEDNN_FOR_GPU" false)

View File

@ -1 +1 @@
WGET_ARGS=( https://download.qt.io/official_releases/qt/6.6/6.6.2/submodules/ -A '*.tar.xz' )
WGET_ARGS=( https://download.qt.io/official_releases/qt/6.6/6.6.3/submodules/ -A '*.tar.xz' )

View File

@ -211,10 +211,7 @@ stdenv.mkDerivation rec {
inherit patches;
# https://bugreports.qt.io/browse/QTBUG-97568
postPatch = ''
substituteInPlace src/corelib/CMakeLists.txt --replace-fail "/bin/ls" "${buildPackages.coreutils}/bin/ls"
'' + lib.optionalString stdenv.hostPlatform.isDarwin ''
postPatch = lib.optionalString stdenv.hostPlatform.isDarwin ''
substituteInPlace cmake/QtPublicAppleHelpers.cmake --replace-fail "/usr/bin/xcrun" "${xcbuild}/bin/xcrun"
'';

View File

@ -1,318 +1,318 @@
# DO NOT EDIT! This file is generated automatically.
# Command: ./maintainers/scripts/fetch-kde-qt.sh pkgs/development/libraries/qt-6/fetch.sh
# Command: ./maintainers/scripts/fetch-kde-qt.sh pkgs/development/libraries/qt-6/
{ fetchurl, mirror }:
{
qt3d = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qt3d-everywhere-src-6.6.2.tar.xz";
sha256 = "10l5ldw8g8m1ig3hh78pwg749xqf2gw9vsi8p67gbkanmipfqx4i";
name = "qt3d-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qt3d-everywhere-src-6.6.3.tar.xz";
sha256 = "0v6zprw9r4z4inj7mg364n959c6japklm7ji2952nm3i01zp8jd5";
name = "qt3d-everywhere-src-6.6.3.tar.xz";
};
};
qt5compat = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qt5compat-everywhere-src-6.6.2.tar.xz";
sha256 = "0rqr34lqf4mjdgjj09wzlvkxfknz8arjl9p30xpqbr2qfsmhhyz0";
name = "qt5compat-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qt5compat-everywhere-src-6.6.3.tar.xz";
sha256 = "02zcrrh6rq5p6bqix5nk2h22rfqdrf4d0h7y4rva5zmbbr7czhk8";
name = "qt5compat-everywhere-src-6.6.3.tar.xz";
};
};
qtactiveqt = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtactiveqt-everywhere-src-6.6.2.tar.xz";
sha256 = "16vqb33s0dwxq1rrha81606fdwq1dz7az6mybgx18n7f081h3yl7";
name = "qtactiveqt-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtactiveqt-everywhere-src-6.6.3.tar.xz";
sha256 = "0balhrmzmjrqn6h2r3rr00776vxhdpqzwhk9knrlvix8i1kr86x1";
name = "qtactiveqt-everywhere-src-6.6.3.tar.xz";
};
};
qtbase = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtbase-everywhere-src-6.6.2.tar.xz";
sha256 = "0yv78bwqzy975854h53rbiilsms62f3v02i3jqz7v8ajk1ml56xq";
name = "qtbase-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtbase-everywhere-src-6.6.3.tar.xz";
sha256 = "0qklvzg242ilxw29jd2vsz6s8ni4dpraf4ghfa4dykhc705zv4q4";
name = "qtbase-everywhere-src-6.6.3.tar.xz";
};
};
qtcharts = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtcharts-everywhere-src-6.6.2.tar.xz";
sha256 = "1x7m87lxbza4ynf6dq7yshann6003302a5fxih5l5d07xri64j5i";
name = "qtcharts-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtcharts-everywhere-src-6.6.3.tar.xz";
sha256 = "1rbz2nm8wrdf060cssvs69b5kqv0ybxjqw1clm5mdllg2j38i5jh";
name = "qtcharts-everywhere-src-6.6.3.tar.xz";
};
};
qtconnectivity = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtconnectivity-everywhere-src-6.6.2.tar.xz";
sha256 = "1dzsvs0hngrz6b66r9zb4al5a4r6xxfd29i8g3jqmvw3b0452vx3";
name = "qtconnectivity-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtconnectivity-everywhere-src-6.6.3.tar.xz";
sha256 = "066mf4d6a81ywviwr8bvm1mpm2ykjzysvcc0v2x82h5bl28vl6h9";
name = "qtconnectivity-everywhere-src-6.6.3.tar.xz";
};
};
qtdatavis3d = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtdatavis3d-everywhere-src-6.6.2.tar.xz";
sha256 = "0iqw5afx8y29kjprn1hlz0zr0qwc9j0m7my75qf1av800hlnnjii";
name = "qtdatavis3d-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtdatavis3d-everywhere-src-6.6.3.tar.xz";
sha256 = "1gyz83hkmjin3fr3brg00qchbb0awprwx99idysrc6chckj825wv";
name = "qtdatavis3d-everywhere-src-6.6.3.tar.xz";
};
};
qtdeclarative = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtdeclarative-everywhere-src-6.6.2.tar.xz";
sha256 = "0k6qndjvkkx3g8lr7f64xx86b3cwxzkgpl6fr6cp73s6qjkyk763";
name = "qtdeclarative-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtdeclarative-everywhere-src-6.6.3.tar.xz";
sha256 = "1wwjlwjb3hnlpai4rrrdsm096a6ahb1izs3524r79jpjzhn7n805";
name = "qtdeclarative-everywhere-src-6.6.3.tar.xz";
};
};
qtdoc = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtdoc-everywhere-src-6.6.2.tar.xz";
sha256 = "0hvv40y2h7xa7wj2cqz2rrsvy1xf2l95199vmgx4q27wgmn1xixg";
name = "qtdoc-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtdoc-everywhere-src-6.6.3.tar.xz";
sha256 = "1j7awdbg7c0slbyhld8cdbx4dic7hhqv3g1qka809bjcxa2hb188";
name = "qtdoc-everywhere-src-6.6.3.tar.xz";
};
};
qtgraphs = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtgraphs-everywhere-src-6.6.2.tar.xz";
sha256 = "19j9hdpxrclsdwqqblp4bk94zd2a5rvxnf548hm7r03npznjvb26";
name = "qtgraphs-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtgraphs-everywhere-src-6.6.3.tar.xz";
sha256 = "1ppdas6bl22z69w8wdy7xl0f1kyqja2gwjd4cn6kjmsslws5rhi2";
name = "qtgraphs-everywhere-src-6.6.3.tar.xz";
};
};
qtgrpc = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtgrpc-everywhere-src-6.6.2.tar.xz";
sha256 = "1flfm8j5vw2j6xzms1b470mbqyab1nrnj4z9s4mgwnbsp4m5p85w";
name = "qtgrpc-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtgrpc-everywhere-src-6.6.3.tar.xz";
sha256 = "11q9cqqk8bs3k6n5pxys2r4fisbs3xvv8d8lsi7wm25rqh5qv1kj";
name = "qtgrpc-everywhere-src-6.6.3.tar.xz";
};
};
qthttpserver = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qthttpserver-everywhere-src-6.6.2.tar.xz";
sha256 = "1qzw96y20qr1kc9wmys61wm568jsknvlgvh09bbqjcmm6dm3lhd2";
name = "qthttpserver-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qthttpserver-everywhere-src-6.6.3.tar.xz";
sha256 = "0dbqx36ywfmqi4nxfi4dl17scj9nkl8sbpb670ffy3nh8pbpib21";
name = "qthttpserver-everywhere-src-6.6.3.tar.xz";
};
};
qtimageformats = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtimageformats-everywhere-src-6.6.2.tar.xz";
sha256 = "1cvwm0hnspglydms6qhcp5g0ayz5pamigl52kz8km66l6s8lqn3i";
name = "qtimageformats-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtimageformats-everywhere-src-6.6.3.tar.xz";
sha256 = "0z328i6fix1qdklfbs1w4dsr64zavjj5kzqvzipww0v62xhfm99w";
name = "qtimageformats-everywhere-src-6.6.3.tar.xz";
};
};
qtlanguageserver = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtlanguageserver-everywhere-src-6.6.2.tar.xz";
sha256 = "1bgazi44mwac20biybhp21icgwa8k7jd295j8jsfgzxbw12lq7y3";
name = "qtlanguageserver-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtlanguageserver-everywhere-src-6.6.3.tar.xz";
sha256 = "136gyvkzm6skdv5yhyy4nqhbczfc2mn4nbr9hvpkpljb0awv888h";
name = "qtlanguageserver-everywhere-src-6.6.3.tar.xz";
};
};
qtlocation = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtlocation-everywhere-src-6.6.2.tar.xz";
sha256 = "05glwmasg0rlhybzpb640iibcs6gyrqbs7h1ws4b5vgcmzzdq9cy";
name = "qtlocation-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtlocation-everywhere-src-6.6.3.tar.xz";
sha256 = "1l81z3zq1zg015l6qxx4yzssdspw689m9bpzxp23yshaych2kd6p";
name = "qtlocation-everywhere-src-6.6.3.tar.xz";
};
};
qtlottie = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtlottie-everywhere-src-6.6.2.tar.xz";
sha256 = "1hqhp55jfasavk7p8xb0srbc6lnk70w2q0x4iwn28z5s5kd1cvi7";
name = "qtlottie-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtlottie-everywhere-src-6.6.3.tar.xz";
sha256 = "1d0fjb0080wnd71f50zwal1b504iimln9mpnb3sc5yznmv8gm4cq";
name = "qtlottie-everywhere-src-6.6.3.tar.xz";
};
};
qtmultimedia = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtmultimedia-everywhere-src-6.6.2.tar.xz";
sha256 = "1v0430jnv97ws6cizn9mi8zr9hcg7rixd0jg7smhdq8apacjb572";
name = "qtmultimedia-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtmultimedia-everywhere-src-6.6.3.tar.xz";
sha256 = "1ciswpv8p71j9hwwdhfr5pmsrnizlaijp0dnyc99lk5is8qgh05y";
name = "qtmultimedia-everywhere-src-6.6.3.tar.xz";
};
};
qtnetworkauth = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtnetworkauth-everywhere-src-6.6.2.tar.xz";
sha256 = "1lijsdwbj8gscfllmp358n5ysa8pvhx2msh7gpxvb4x81daxbg9j";
name = "qtnetworkauth-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtnetworkauth-everywhere-src-6.6.3.tar.xz";
sha256 = "153mpg4hv3nclcdrkbzkalg4xf5k6r64fj003b725zyp885s7fax";
name = "qtnetworkauth-everywhere-src-6.6.3.tar.xz";
};
};
qtpositioning = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtpositioning-everywhere-src-6.6.2.tar.xz";
sha256 = "1qn31vps9dj4g8m7d195qlsyj3p4dfqqszdc6yqq097dq5y5d9sd";
name = "qtpositioning-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtpositioning-everywhere-src-6.6.3.tar.xz";
sha256 = "1frzzndsscb6iqschklks2l17ppnjpnx1lq1cypnq3x0598bcdws";
name = "qtpositioning-everywhere-src-6.6.3.tar.xz";
};
};
qtquick3d = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtquick3d-everywhere-src-6.6.2.tar.xz";
sha256 = "0f1sp7d1jzdzaxqs2l2yjprp0axcqbg2w82dza7wl4paan4rzp7w";
name = "qtquick3d-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtquick3d-everywhere-src-6.6.3.tar.xz";
sha256 = "1qls5cydhm7p1g3gqzvnism8k0h6wjzi8x12gn51dapvnzq2cxlr";
name = "qtquick3d-everywhere-src-6.6.3.tar.xz";
};
};
qtquick3dphysics = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtquick3dphysics-everywhere-src-6.6.2.tar.xz";
sha256 = "10209x9hbr5bc4vlhhcvvfsmsn2h3dyb4rlg0f0gpllx68mr58ac";
name = "qtquick3dphysics-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtquick3dphysics-everywhere-src-6.6.3.tar.xz";
sha256 = "0ipma4qdmzyyajs5inp7d3znh2hfx42gia7x9ahqpb515r49pqb7";
name = "qtquick3dphysics-everywhere-src-6.6.3.tar.xz";
};
};
qtquickeffectmaker = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtquickeffectmaker-everywhere-src-6.6.2.tar.xz";
sha256 = "0lywm71wp943dk3w8zkklyxfk97w48v670zs6pc4pj4ja0ns37q7";
name = "qtquickeffectmaker-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtquickeffectmaker-everywhere-src-6.6.3.tar.xz";
sha256 = "0mr350c9kj74g48lavq5z5c604cdgcyycfdpwv5z8bmbr49jl95w";
name = "qtquickeffectmaker-everywhere-src-6.6.3.tar.xz";
};
};
qtquicktimeline = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtquicktimeline-everywhere-src-6.6.2.tar.xz";
sha256 = "06cr9p0hrq77ckqslxh0h3lpyw31fblyap1plcyyj8ssr1rm4klc";
name = "qtquicktimeline-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtquicktimeline-everywhere-src-6.6.3.tar.xz";
sha256 = "0b266w7al90fbbp16w506klba50d4izf6nfcmmp5fpr6h5pxvcyk";
name = "qtquicktimeline-everywhere-src-6.6.3.tar.xz";
};
};
qtremoteobjects = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtremoteobjects-everywhere-src-6.6.2.tar.xz";
sha256 = "0fbkjzykxpkz8myr6dy588gcmhyy3lar17v78zfam8kyxq7s5qxa";
name = "qtremoteobjects-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtremoteobjects-everywhere-src-6.6.3.tar.xz";
sha256 = "16bd4zd3yfzlzk087qphphsh8hv38q3a57n1yknvkc5fchzmfzjz";
name = "qtremoteobjects-everywhere-src-6.6.3.tar.xz";
};
};
qtscxml = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtscxml-everywhere-src-6.6.2.tar.xz";
sha256 = "0gm4805570ds3jmkbwrjigbg93zc561bd5rc52r71042zzq84j89";
name = "qtscxml-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtscxml-everywhere-src-6.6.3.tar.xz";
sha256 = "1dbcw4qnss5rif97gdcimyzl3jqa508yph611dvvhc1xn16nl6qg";
name = "qtscxml-everywhere-src-6.6.3.tar.xz";
};
};
qtsensors = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtsensors-everywhere-src-6.6.2.tar.xz";
sha256 = "0a3w50bfnmxndyxnn9lsy1wxffhm2am0yjxqx3vx0gfjwv79yvsa";
name = "qtsensors-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtsensors-everywhere-src-6.6.3.tar.xz";
sha256 = "0r9p3lm159pji29vq9kii42jkz4rg15hqh6zlq9442i58a0ayddj";
name = "qtsensors-everywhere-src-6.6.3.tar.xz";
};
};
qtserialbus = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtserialbus-everywhere-src-6.6.2.tar.xz";
sha256 = "0g7sx81lrb5r2ipinnghq4iss6clkwbzjb0ck4ay6hmpw54smzww";
name = "qtserialbus-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtserialbus-everywhere-src-6.6.3.tar.xz";
sha256 = "1yyh1bh5pjlilcq84fgfw6wd0jak55wndwf0sn92lbhsp3y5lghl";
name = "qtserialbus-everywhere-src-6.6.3.tar.xz";
};
};
qtserialport = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtserialport-everywhere-src-6.6.2.tar.xz";
sha256 = "16j5fprmdzzc1snnj5184ihq5avg1s0jrqqcjk70dvmimsf0q7ms";
name = "qtserialport-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtserialport-everywhere-src-6.6.3.tar.xz";
sha256 = "0dywalgafvxi2jgdv9dk22hwwd8qsgk5xfybh75n3njmwmwnarg1";
name = "qtserialport-everywhere-src-6.6.3.tar.xz";
};
};
qtshadertools = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtshadertools-everywhere-src-6.6.2.tar.xz";
sha256 = "0bxrczs9nw6az2p4n8x0f660vsmxxynx4iqgj75l4zsfzzbym2v2";
name = "qtshadertools-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtshadertools-everywhere-src-6.6.3.tar.xz";
sha256 = "1rm17hyhq244zskq3ar3h22qjd5dshy84nnyq1ivhg5k7gb0j2cc";
name = "qtshadertools-everywhere-src-6.6.3.tar.xz";
};
};
qtspeech = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtspeech-everywhere-src-6.6.2.tar.xz";
sha256 = "1qvf3p2p1pc5fw40d8zq0iawaaqkc0dp5yx85b1dnw1j809bn8y0";
name = "qtspeech-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtspeech-everywhere-src-6.6.3.tar.xz";
sha256 = "1yh3r5zbhgwkjgs7yk6iv2w23766n1i4z8vjkkw5awdixx3gfa76";
name = "qtspeech-everywhere-src-6.6.3.tar.xz";
};
};
qtsvg = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtsvg-everywhere-src-6.6.2.tar.xz";
sha256 = "10c1dmbv5d39n1q4m67gf2h4n6wfkzrlyk8plnxbyhhvxxcis8ss";
name = "qtsvg-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtsvg-everywhere-src-6.6.3.tar.xz";
sha256 = "1ir57bis27whq7bwqykk1qlxy0522k4ia39brxayjmfadrbixjsa";
name = "qtsvg-everywhere-src-6.6.3.tar.xz";
};
};
qttools = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qttools-everywhere-src-6.6.2.tar.xz";
sha256 = "0ij7djy06xi4v5v29fh31gqq5rnc12vviv3qg3vqf4hiaagrxm76";
name = "qttools-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qttools-everywhere-src-6.6.3.tar.xz";
sha256 = "1h0vz46mpvzbm5w6sgpk0b3mqkn278l45arhxxk41dwc5n14qvda";
name = "qttools-everywhere-src-6.6.3.tar.xz";
};
};
qttranslations = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qttranslations-everywhere-src-6.6.2.tar.xz";
sha256 = "0xqcad8aa9lp6wzh1rs46id6r60zdw82qj3bq9k2b89sxy8c0fna";
name = "qttranslations-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qttranslations-everywhere-src-6.6.3.tar.xz";
sha256 = "1kvkrwbgby4i69dpxbxxcv0qbsz69n6icpyr4wcf8qm2r4m5zqqj";
name = "qttranslations-everywhere-src-6.6.3.tar.xz";
};
};
qtvirtualkeyboard = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtvirtualkeyboard-everywhere-src-6.6.2.tar.xz";
sha256 = "07nqds49g2x748jsk17cnd2ph81165xnzn70jwxd0gpbi3dzshk1";
name = "qtvirtualkeyboard-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtvirtualkeyboard-everywhere-src-6.6.3.tar.xz";
sha256 = "0d517x60birlf8xb3sphchvgm235f8q1868q98kg76plzfhq57wq";
name = "qtvirtualkeyboard-everywhere-src-6.6.3.tar.xz";
};
};
qtwayland = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtwayland-everywhere-src-6.6.2.tar.xz";
sha256 = "0y6x84ckcc53ddclnrlzs08b1kvw6saw9nim0hz4wc5fyz7dbkcv";
name = "qtwayland-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtwayland-everywhere-src-6.6.3.tar.xz";
sha256 = "0gamcqpl302wlznfnlcg9vlnnhfpxgjnz05prwc9wpy0xh7wqvm9";
name = "qtwayland-everywhere-src-6.6.3.tar.xz";
};
};
qtwebchannel = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtwebchannel-everywhere-src-6.6.2.tar.xz";
sha256 = "1incvisc3j758b4k82vnwci8j1bba8zf6xgmgcrsm553k4wpsz1x";
name = "qtwebchannel-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtwebchannel-everywhere-src-6.6.3.tar.xz";
sha256 = "0cwcf4pri901piyj0lvqmks9l84di9rcafnfgrmgg5mls7jjlyvw";
name = "qtwebchannel-everywhere-src-6.6.3.tar.xz";
};
};
qtwebengine = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtwebengine-everywhere-src-6.6.2.tar.xz";
sha256 = "15h3hniszfkxv2vnn3fnbgbar8wb41ypgn4b4iz4iy6csar8f7fn";
name = "qtwebengine-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtwebengine-everywhere-src-6.6.3.tar.xz";
sha256 = "016qvbmdja2abajvsznnjdvblrmzgvs8s2dzlxws30hvna1xqavw";
name = "qtwebengine-everywhere-src-6.6.3.tar.xz";
};
};
qtwebsockets = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtwebsockets-everywhere-src-6.6.2.tar.xz";
sha256 = "1y9q8jmspxbfxf07jdcg4n8zwmchccyzp0z68fxr0hnvr2dymrn0";
name = "qtwebsockets-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtwebsockets-everywhere-src-6.6.3.tar.xz";
sha256 = "0dm066lv3n97ril9iyd5xn8j13m6r7xp844aagj6dpclaxv83x0n";
name = "qtwebsockets-everywhere-src-6.6.3.tar.xz";
};
};
qtwebview = {
version = "6.6.2";
version = "6.6.3";
src = fetchurl {
url = "${mirror}/official_releases/qt/6.6/6.6.2/submodules/qtwebview-everywhere-src-6.6.2.tar.xz";
sha256 = "0z3p1g26yg3dr3hhavwd5wz9b8yi838xj4s57068wykd80v145wb";
name = "qtwebview-everywhere-src-6.6.2.tar.xz";
url = "${mirror}/official_releases/qt/6.6/6.6.3/submodules/qtwebview-everywhere-src-6.6.3.tar.xz";
sha256 = "00jcxzi9wcbviscn5y0h0mkbac88lpjammg3zvfvjih7avgn6r10";
name = "qtwebview-everywhere-src-6.6.3.tar.xz";
};
};
}

View File

@ -1,40 +0,0 @@
{ lib, stdenv
, fetchFromGitHub
, autoreconfHook
, gmp
}:
stdenv.mkDerivation rec {
version = "1.0";
pname = "flintqs";
src = fetchFromGitHub {
owner = "sagemath";
repo = "FlintQS";
rev = "v${version}";
sha256 = "1f0lnayz6j6qgasx8pbq61d2fqam0wwhsmh6h15l4vq58l1vvbwj";
};
preAutoreconf = ''
touch ChangeLog
'';
buildInputs = [
gmp
];
nativeBuildInputs = [
autoreconfHook
];
doCheck = true;
meta = with lib; {
description = "Highly optimized multi-polynomial quadratic sieve for integer factorization";
homepage = "https://github.com/sagemath/FlintQS";
license = with licenses; [ gpl2 ];
maintainers = teams.sage.members;
mainProgram = "QuadraticSieve";
platforms = platforms.all;
};
}

View File

@ -21,6 +21,9 @@ stdenv.mkDerivation rec {
m4ri
];
# does not compile correctly with -O2 on LLVM clang; see
# https://bitbucket.org/malb/m4rie/issues/23/trying-to-compile-on-apple-m1
makeFlags = [] ++ lib.optionals stdenv.isDarwin [ "CFLAGS=-O0" ];
nativeBuildInputs = [
autoreconfHook
];
@ -35,7 +38,5 @@ stdenv.mkDerivation rec {
license = licenses.gpl2Plus;
maintainers = teams.sage.members;
platforms = platforms.unix;
# never built on aarch64-darwin since first introduction in nixpkgs
broken = stdenv.isDarwin && stdenv.isAarch64;
};
}

View File

@ -2,6 +2,7 @@
, fetchurl
, fetchpatch
, coreutils
, dos2unix
}:
stdenv.mkDerivation rec {
@ -24,24 +25,54 @@ stdenv.mkDerivation rec {
"PREFIX=$(out)"
];
nativeBuildInputs = [ dos2unix ];
prePatch = ''
find ./dietz/ -type f -exec dos2unix {} \;
'';
patches = [
# Fix makefiles which use all the variables in all the wrong ways and
# hardcode values for some variables.
(fetchpatch {
url = "https://raw.githubusercontent.com/sagemath/sage/07d6c37d18811e2b377a9689790a7c5e24da16ba/build/pkgs/rubiks/patches/dietz-cu2-Makefile.patch";
sha256 = "1ry3w1mk9q4jqd91zlaa1bdiiplld4hpfjaldbhlmzlgrrc99qmq";
url = "https://raw.githubusercontent.com/sagemath/sage/2a9a4267f93588cf33119cbacc032ed9acc433e5/build/pkgs/rubiks/patches/dietz-cu2-Makefile.patch";
sha256 = "bRU7MJ/6BgCp2PUqZOragJhm38Q3E8ShStXQIYwIjvw=";
})
(fetchpatch {
url = "https://raw.githubusercontent.com/sagemath/sage/07d6c37d18811e2b377a9689790a7c5e24da16ba/build/pkgs/rubiks/patches/dietz-mcube-Makefile.patch";
sha256 = "0zsbh6k3kqdg82fv0kzghr1x7pafisv943gmssqscp107bhg77bz";
url = "https://raw.githubusercontent.com/sagemath/sage/2a9a4267f93588cf33119cbacc032ed9acc433e5/build/pkgs/rubiks/patches/dietz-mcube-Makefile.patch";
sha256 = "f53z4DogXKax1vUNkraOTt3TQ4bvT7CdQK/hOaaBS38=";
})
(fetchpatch {
url = "https://raw.githubusercontent.com/sagemath/sage/07d6c37d18811e2b377a9689790a7c5e24da16ba/build/pkgs/rubiks/patches/dietz-solver-Makefile.patch";
sha256 = "0vhw70ylnmydgjhwx8jjlb2slccj4pfqn6vzirkyz1wp8apsmfhp";
url = "https://raw.githubusercontent.com/sagemath/sage/2a9a4267f93588cf33119cbacc032ed9acc433e5/build/pkgs/rubiks/patches/dietz-solver-Makefile.patch";
sha256 = "7gMC8y9elyIy2KvXYcp7YjPBNqn9PVhUle+/GrYAAdE=";
})
(fetchpatch {
url = "https://raw.githubusercontent.com/sagemath/sage/07d6c37d18811e2b377a9689790a7c5e24da16ba/build/pkgs/rubiks/patches/reid-Makefile.patch";
sha256 = "1r311sn012xs135s0d21qwsig2kld7rdcq19nm0zbnklviid57df";
url = "https://raw.githubusercontent.com/sagemath/sage/2a9a4267f93588cf33119cbacc032ed9acc433e5/build/pkgs/rubiks/patches/reid-Makefile.patch";
sha256 = "rp3SYtx02vVBtSlg1vJpdIoXNcdBNKDLCLqLAKwOYeQ=";
})
(fetchpatch {
url = "https://raw.githubusercontent.com/sagemath/sage/2a9a4267f93588cf33119cbacc032ed9acc433e5/build/pkgs/rubiks/patches/fedora-1-rubiks-includes.patch";
sha256 = "QYJ1KQ73HTEGY/beMVbcU215g/B8rHDjYD1YM2WZ7sk=";
})
(fetchpatch {
url = "https://raw.githubusercontent.com/sagemath/sage/2a9a4267f93588cf33119cbacc032ed9acc433e5/build/pkgs/rubiks/patches/fedora-2-rubiks-ansi-c.patch";
sha256 = "Rnu7uphE9URxnbg2K8mkymnB61magweH+WxVWR9JC4s=";
})
(fetchpatch {
url = "https://raw.githubusercontent.com/sagemath/sage/2a9a4267f93588cf33119cbacc032ed9acc433e5/build/pkgs/rubiks/patches/fedora-3-rubiks-prototypes.patch";
sha256 = "Wi038g+y7No1TNMiITtAdipjRi0+g6h0Sspslm5rZGU=";
})
(fetchpatch {
url = "https://raw.githubusercontent.com/sagemath/sage/2a9a4267f93588cf33119cbacc032ed9acc433e5/build/pkgs/rubiks/patches/fedora-4-rubiks-longtype.patch";
sha256 = "6pNuxFM69CZ/TQGZfHXLlCN5g5lf3RiYYZKzMvLJwkw=";
})
(fetchpatch {
url = "https://raw.githubusercontent.com/sagemath/sage/2a9a4267f93588cf33119cbacc032ed9acc433e5/build/pkgs/rubiks/patches/fedora-5-rubiks-signed.patch";
sha256 = "CCGXBMYvSjTm4YKQZAQMi6pWGjyHDYYQzdMZDSW2vFE=";
})
(fetchpatch {
url = "https://raw.githubusercontent.com/sagemath/sage/2a9a4267f93588cf33119cbacc032ed9acc433e5/build/pkgs/rubiks/patches/fedora-6-rubiks-attributes.patch";
sha256 = "RhlzMb33iaLfeBoF7Y0LIgEzOB/EC+AoWMSkRPCICaU=";
})
];

View File

@ -37,6 +37,7 @@ stdenv.mkDerivation rec {
# see https://github.com/NixOS/nixpkgs/pull/117465
if stdenv.hostPlatform.system == "aarch64-linux" then "linux-arm" else
if stdenv.hostPlatform.system == "armv7l-linux" then "linux-arm" else
if stdenv.hostPlatform.system == "aarch64-darwin" then "macosx" else
if stdenv.hostPlatform.system == "x86_64-darwin" then "macosx-thr" else
if stdenv.hostPlatform.system == "i686-darwin" then "macosx-64-thr" else
if stdenv.hostPlatform.system == "i686-cygwin" then "win32" else

View File

@ -20,16 +20,16 @@
buildPythonPackage rec {
pname = "es-client";
version = "8.12.5";
version = "8.12.8";
pyproject = true;
disabled = pythonOlder "3.7";
disabled = pythonOlder "3.8";
src = fetchFromGitHub {
owner = "untergeek";
repo = "es_client";
rev = "refs/tags/v${version}";
hash = "sha256-gaeNIxHnNulUOGhYHf9dIgBSh2rJIdsYdpPT8OTyEdg=";
hash = "sha256-qv06zb3hIK/TeOZwtMXrV+n8mYSA/UKiyHvRyKEvZkQ=";
};
pythonRelaxDeps = true;

View File

@ -36,6 +36,10 @@ buildPythonPackage rec {
url = "https://github.com/fplll/fpylll/commit/fc432b21fa7e4b9891f5b761b3539989eb958f2b.diff";
hash = "sha256-+UidQ5xnlmjeVeVvR4J2zDzAuXP5LUPXCh4RP4o9oGA=";
})
(fetchpatch {
url = "https://github.com/fplll/fpylll/commit/cece9c9b182dc3ac2c9121549cb427ccf4c4a9fe.diff";
hash = "sha256-epJb8gorQ7gEEylZ2yZFdM9+EZ4ys9mUUUPiJ2D0VOM=";
})
];
nativeBuildInputs = [

View File

@ -26,7 +26,6 @@ buildPythonPackage {
'';
pythonImportsCheck = [
"ngraph"
"openvino"
"openvino.runtime"
];

View File

@ -32,7 +32,7 @@
buildPythonPackage rec {
pname = "reptor";
version = "0.13";
version = "0.14";
pyproject = true;
disabled = pythonOlder "3.8";
@ -41,17 +41,17 @@ buildPythonPackage rec {
owner = "Syslifters";
repo = "reptor";
rev = "refs/tags/${version}";
hash = "sha256-7jFS3GCaPeGBBxB++XTtIYh+m0uXTm5NHuLeIen0KYc=";
hash = "sha256-XZiFVIUyLVVr3ZraOAuXs+shl4vk3S8OJHNHV4p10YY=";
};
pythonRelaxDeps = true;
nativeBuildInputs = [
build-system = [
pythonRelaxDepsHook
setuptools
];
propagatedBuildInputs = [
dependencies = [
asgiref
certifi
charset-normalizer

View File

@ -14,7 +14,7 @@ buildPythonPackage rec {
pname = "rpyc4";
# Pinned version for linien, see also:
# https://github.com/linien-org/pyrp3/pull/10#discussion_r1302816237
version = "6.0.0";
version = "4.1.5";
format = "pyproject";
# Since this is an outdated version, upstream might have fixed the
@ -24,8 +24,8 @@ buildPythonPackage rec {
src = fetchFromGitHub {
owner = "tomerfiliba";
repo = "rpyc";
rev = "refs/tags/${version}";
hash = "sha256-BvXEXZlVbOmKBwnSBCDksUkbT7JPcMX48KZe/Gd5Y8Q=";
rev = version;
hash = "sha256-8NOcXZDR3w0TNj1+LZ7lzQAt7yDgspjOp2zk1bsbVls=";
};
nativeBuildInputs = [

View File

@ -10,16 +10,16 @@
rustPlatform.buildRustPackage rec {
pname = "ruff";
version = "0.3.2";
version = "0.3.4";
src = fetchFromGitHub {
owner = "astral-sh";
repo = "ruff";
rev = "refs/tags/v${version}";
hash = "sha256-2Pt2HuDB9JLD9E1q0JH7jyVoc0II5uVL1l8pAod+9V4=";
hash = "sha256-P0k/0tWbhY2HaxI4QThxpHD48JUjtF/d3iU4MIFhdHI=";
};
cargoHash = "sha256-njHpqWXFNdwenV58+VGznnqbaNK1GoGtHSTfKU2MRbs=";
cargoHash = "sha256-LckX8/c3Yg9i/0C2d0XSxxNJSpaVxmj2s8tkEUDhbmA=";
nativeBuildInputs = [
installShellFiles

View File

@ -1,97 +0,0 @@
{ stdenv
, lib
, fetchurl
, dpkg
, autoPatchelfHook
, wrapGAppsHook
, alsa-lib
, cups
, libGL
, libX11
, libXScrnSaver
, libXtst
, mesa
, nss
, gtk3
, libpulseaudio
, systemd
, callPackage
, withTetrioPlus ? false
, tetrio-plus ? callPackage ./tetrio-plus.nix { }
}:
stdenv.mkDerivation rec {
pname = "tetrio-desktop";
version = "8.0.0";
src = fetchurl {
url = "https://web.archive.org/web/20211228025517if_/https://tetr.io/about/desktop/builds/TETR.IO%20Setup.deb";
name = "tetrio-desktop.deb";
sha256 = "1nlblfhrph4cw8rpic9icrs78mzrxyskl7ggyy2i8bk9i07i21xf";
};
nativeBuildInputs = [
dpkg
autoPatchelfHook
wrapGAppsHook
];
dontWrapGApps = true;
buildInputs = [
alsa-lib
cups
libX11
libXScrnSaver
libXtst
mesa
nss
gtk3
];
libPath = lib.makeLibraryPath [
libGL
libpulseaudio
systemd
];
unpackCmd = "dpkg -x $curSrc src";
installPhase = ''
runHook preInstall
mkdir $out
cp -r opt/ usr/share/ $out
mkdir $out/bin
ln -s $out/opt/TETR.IO/tetrio-desktop $out/bin/
substituteInPlace $out/share/applications/tetrio-desktop.desktop \
--replace "Exec=\"/opt/TETR.IO/tetrio-desktop\"" "Exec=\"$out/opt/TETR.IO/tetrio-desktop\""
runHook postInstall
'';
postInstall = lib.strings.optionalString withTetrioPlus ''
cp ${tetrio-plus} $out/opt/TETR.IO/resources/app.asar
'';
postFixup = ''
wrapProgram $out/opt/TETR.IO/tetrio-desktop \
--prefix LD_LIBRARY_PATH : ${libPath}:$out/opt/TETR.IO \
''${gappsWrapperArgs[@]}
'';
meta = with lib; {
homepage = "https://tetr.io";
downloadPage = "https://tetr.io/about/desktop/";
description = "TETR.IO desktop client";
longDescription = ''
TETR.IO is a modern yet familiar online stacker.
Play against friends and foes all over the world, or claim a spot on the leaderboards - the stacker future is yours!
'';
platforms = [ "x86_64-linux" ];
license = licenses.unfree;
maintainers = with maintainers; [ wackbyte ];
};
}

View File

@ -1,27 +0,0 @@
{ lib, stdenv, fetchzip }:
stdenv.mkDerivation rec {
pname = "tetrio-plus";
version = "0.25.3";
src = fetchzip {
url = "https://gitlab.com/UniQMG/tetrio-plus/uploads/684477053451cd0819e2c84e145966eb/tetrio-plus_0.25.3_app.asar.zip";
sha256 = "sha256-GQgt4GZNeKx/uzmVsuKppW2zg8AAiGqsk2JYJIkqfVE=";
};
installPhase = ''
runHook preInstall
install app.asar $out
runHook postInstall
'';
meta = with lib; {
description = "TETR.IO customization toolkit";
homepage = "https://gitlab.com/UniQMG/tetrio-plus";
license = licenses.mit;
maintainers = with maintainers; [ huantian ];
platforms = [ "x86_64-linux" ];
};
}

View File

@ -6,7 +6,7 @@ ecmEnvHook() {
addToSearchPath XDG_DATA_DIRS "$1/share"
addToSearchPath XDG_CONFIG_DIRS "$1/etc/xdg"
}
addEnvHooks "$targetOffset" ecmEnvHook
addEnvHooks "$hostOffset" ecmEnvHook
ecmPostHook() {
# Because we need to use absolute paths here, we must set *all* the paths.
@ -125,4 +125,4 @@ ecmHostPathHook() {
propagatedUserEnvPkgs+=" $1"
fi
}
addEnvHooks "$targetOffset" ecmHostPathHook
addEnvHooks "$hostOffset" ecmHostPathHook

View File

@ -1,317 +1,317 @@
{
"bluedevil": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/bluedevil-6.0.2.tar.xz",
"hash": "sha256-gV4OEQ7zlQPsBaRr11+9IlVSuehQUKm0Py2KeAPh22A="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/bluedevil-6.0.3.tar.xz",
"hash": "sha256-0mO+VIJaQYnUVrAafOC9tCdaG1VeN4KxCop30r6TyyQ="
},
"breeze": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/breeze-6.0.2.tar.xz",
"hash": "sha256-TGf1pZqaN8lnVFUselB20p6nhkrFD6l2Zxl2TtlPtMw="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/breeze-6.0.3.tar.xz",
"hash": "sha256-WXxGCXBArnmktHCGxcyhIb8rRHm80JkwJunM0mC0sfk="
},
"breeze-grub": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/breeze-grub-6.0.2.tar.xz",
"hash": "sha256-XBZ8FyaLvD42Ua8SpV+bs4UIphig+IHmMpzRcOCNlEY="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/breeze-grub-6.0.3.tar.xz",
"hash": "sha256-e7i9FT8J0Cj1kHWU/A6AhSlLS1GHAKxCUlQrrKCasRU="
},
"breeze-gtk": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/breeze-gtk-6.0.2.tar.xz",
"hash": "sha256-phKZCTfgwMbOOGwg8zv3tqWcMhtrb50qcFFj/96ufdo="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/breeze-gtk-6.0.3.tar.xz",
"hash": "sha256-t8Ew3GsnQ6rTkI1UsLryp7f+cX1SZfdgUEHrN9QQ6jY="
},
"breeze-plymouth": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/breeze-plymouth-6.0.2.tar.xz",
"hash": "sha256-SEVtmnGdxrM6tidOxMVveOQvEnLCWeAGTmpc5qLodOk="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/breeze-plymouth-6.0.3.tar.xz",
"hash": "sha256-AffQVamnYbDKl9fUTbzXMokQPB0K/XUuI330BYBzz0A="
},
"discover": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/discover-6.0.2.tar.xz",
"hash": "sha256-jDuWQYjuNySaob1KzVKWfYgDvEC3Xzt3GFk8HNbM9PA="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/discover-6.0.3.tar.xz",
"hash": "sha256-spGWIR+PhL/eku1ZNmyzu8f9bONAsCJmrQusJsHcd54="
},
"drkonqi": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/drkonqi-6.0.2.tar.xz",
"hash": "sha256-S4HHlDGeBMVwqUh/Cd2gLxiIHiSFR7qFaqhKbt5wwxQ="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/drkonqi-6.0.3.tar.xz",
"hash": "sha256-H6nnUiVRqaq5LYreP2u7f8+4Mpc6AREapESxiOQ04s4="
},
"flatpak-kcm": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/flatpak-kcm-6.0.2.tar.xz",
"hash": "sha256-cxEOEmCqq9Alj632/WPg1mnG1lzBY3TyjNiMZkusJY0="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/flatpak-kcm-6.0.3.tar.xz",
"hash": "sha256-k+tUaLHfzxqFNVm2biXWrkkNZbo5dSY/HlwHGLSuOmU="
},
"kactivitymanagerd": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kactivitymanagerd-6.0.2.tar.xz",
"hash": "sha256-6V6in4tvuIK+xR2UZJEqdDVO9Tlrs+q3iDDa40qk37A="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kactivitymanagerd-6.0.3.tar.xz",
"hash": "sha256-T5IxT8IRfcJv9nHDM04AdtXyt/7KQ09OE4v99XS2fOU="
},
"kde-cli-tools": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kde-cli-tools-6.0.2.tar.xz",
"hash": "sha256-Sr7JMrS0eaQiTg7yVjBVmGVdM4mzaaYf5IY34rXOjlU="
},
"kde-gtk-config": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kde-gtk-config-6.0.2.tar.xz",
"hash": "sha256-iEVwUAzthC8eHFRe32/dUDZnP4OnGIZE+Ln3YeJoL34="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kde-cli-tools-6.0.3.tar.xz",
"hash": "sha256-UN5KvK8mWbqMG+hXvLfxoJVQ0nzEfyWg3uWSEQpVnEI="
},
"kdecoration": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kdecoration-6.0.2.tar.xz",
"hash": "sha256-uZNhbMXXj854ey29BKr+VA6SnC7MzeFLzgxhkDUUvsI="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kdecoration-6.0.3.tar.xz",
"hash": "sha256-PJH2WpseoIzyA+eexO3+pojEY9fSGMlSlsA3a99ZVvk="
},
"kde-gtk-config": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kde-gtk-config-6.0.3.tar.xz",
"hash": "sha256-NtTPT+Ss3sXZF8j/P/FXSOb8s1bc06RIjJ4Ifnm1ZMI="
},
"kdeplasma-addons": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kdeplasma-addons-6.0.2.tar.xz",
"hash": "sha256-Wl4L/PtA1Xpeu5/tXSOMZC0Y5+0tbduxJAthxZi7AgA="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kdeplasma-addons-6.0.3.tar.xz",
"hash": "sha256-LeweAF4uh/PI04OgZ4sb+Y1IhQfT3pSn34zZPju5Z8E="
},
"kgamma": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kgamma-6.0.2.tar.xz",
"hash": "sha256-+A2xpuiVBAQNUcaxT6i6Bqxnh9w3wFvEHsbLzbRjmZA="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kgamma-6.0.3.tar.xz",
"hash": "sha256-gW55sJkvoq5tT23Wsnf1CFYt+E4AYdnAYJVXU7hCJNM="
},
"kglobalacceld": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kglobalacceld-6.0.2.tar.xz",
"hash": "sha256-pPPG2MCGNujAI4xblFWgyXXVciXGYScybR3U3aGjJos="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kglobalacceld-6.0.3.tar.xz",
"hash": "sha256-EqE37lBS/b92xUxO/AfVUO3KWiWntDTVIsFBjj41ssw="
},
"kinfocenter": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kinfocenter-6.0.2.tar.xz",
"hash": "sha256-XX1CmQt73K7ndlEP298n5EtbvhaMTk5NVJ9WHo/iyyA="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kinfocenter-6.0.3.tar.xz",
"hash": "sha256-7pwt2u4si/RTw46CwzJ9yDrTkAQt0QbBnd9LYlGorfs="
},
"kmenuedit": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kmenuedit-6.0.2.tar.xz",
"hash": "sha256-0K7EynTFpVeMp7k0F1qex+ITJLvaVczpb0oN1TJtwZc="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kmenuedit-6.0.3.tar.xz",
"hash": "sha256-fPjU4qqeJjOp0PCSAlxIwKcxoUz5IKa1KNj/57TWxyw="
},
"kpipewire": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kpipewire-6.0.2.tar.xz",
"hash": "sha256-APmGtilgMkYaNYcdvooS/CTC+TtiOdMJjJe3bcvUbMk="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kpipewire-6.0.3.tar.xz",
"hash": "sha256-Grp6BL81yIaQaK84eEUSG1205+YfGZDk3rhstoOgUn4="
},
"kscreen": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kscreen-6.0.2.tar.xz",
"hash": "sha256-8fVuPlxw5dt1pfwBtPCB7cgRy7NoAiu3DEr6viVaAoU="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kscreen-6.0.3.tar.xz",
"hash": "sha256-WRbghsImAEClTdoA/jL6doVA2rp4kV8tdrpd9515mp4="
},
"kscreenlocker": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kscreenlocker-6.0.2.tar.xz",
"hash": "sha256-RRxpojVsVFwRjjLJ+LRYYnKymfjZ3cTJyISxnbQntT8="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kscreenlocker-6.0.3.tar.xz",
"hash": "sha256-Sv7bQ6k1JB/2mORJBbSvbhkBRAMmhoCTFjyjb4OY1mk="
},
"ksshaskpass": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/ksshaskpass-6.0.2.tar.xz",
"hash": "sha256-C+p20xygb3QkQqzmk+LcSJYSMJtapWfRaXisJu4g+sk="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/ksshaskpass-6.0.3.tar.xz",
"hash": "sha256-t+pKW7tQqwyY8ELQAag18P6E8suR5Pb5DxvgxmoYMgk="
},
"ksystemstats": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/ksystemstats-6.0.2.tar.xz",
"hash": "sha256-l1/8/okQHOVc8cDFbGZuAuXcPR+pJF4xWw0jAwNMqEA="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/ksystemstats-6.0.3.tar.xz",
"hash": "sha256-f+w6cF3Qb6/0+YzpS1BfypV+CdgmGSQC+WQ/gY3PREU="
},
"kwallet-pam": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kwallet-pam-6.0.2.tar.xz",
"hash": "sha256-QTIb6oKt0j+Gtry+bTiLyMNZI70df4pm0Iw/KrGrAnM="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kwallet-pam-6.0.3.tar.xz",
"hash": "sha256-Is2LAK4XqSxHOvYZajaFX8PqzpIEtz87ziSJ2A806H8="
},
"kwayland": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kwayland-6.0.2.tar.xz",
"hash": "sha256-vcLnj1datajVor0xCKPMMEZ6M0lYs8/9rASDnbg12DM="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kwayland-6.0.3.tar.xz",
"hash": "sha256-+7EprPuoK7CqOph5C1Vivz/Khn70H0gjxvE8ZgUDZpg="
},
"kwayland-integration": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kwayland-integration-6.0.2.tar.xz",
"hash": "sha256-JcURgey49PxoX332lmXwBWNGp6ljESh8frD9z8NjFPo="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kwayland-integration-6.0.3.tar.xz",
"hash": "sha256-2dz0Ncoy1J8kG5EWyzWa2TrQ8KsgZ/bkG5VaeDTY4bo="
},
"kwin": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kwin-6.0.2.tar.xz",
"hash": "sha256-ZTQGIBVP7eWY2qdsxiRzmpgkaFqhqpQiTv3V8bmwdrs="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kwin-6.0.3.tar.xz",
"hash": "sha256-D0bnds1Qg3TFUsClpVpFvyj5zMyIcAiQCYVKETTXKnk="
},
"kwrited": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/kwrited-6.0.2.tar.xz",
"hash": "sha256-+1IZTV5VmlaWevHIoaCAhex3t9ZRCrSGoPEMk/ro2Sg="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/kwrited-6.0.3.tar.xz",
"hash": "sha256-Od+o/t6t8TmrxhCojFF8q2WNUsulAiOmi3B2C+Ene6s="
},
"layer-shell-qt": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/layer-shell-qt-6.0.2.tar.xz",
"hash": "sha256-qtaCwTBihouUlwy2DeQAH6jRpL3YJ8Y3VuIV0EU95VA="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/layer-shell-qt-6.0.3.tar.xz",
"hash": "sha256-NEPFeo+L4m76QLPy90jRMKxk1hP4lOeY1vpS4ptZtRc="
},
"libkscreen": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/libkscreen-6.0.2.tar.xz",
"hash": "sha256-L4ZclYm2Cuc5WxilMbHm+/6o4s5cFHgRsO8fjAXjBTc="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/libkscreen-6.0.3.tar.xz",
"hash": "sha256-R4X8PipebbOmLMWPFoLddRNOyIydlmudj7IuhwqjNIM="
},
"libksysguard": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/libksysguard-6.0.2.tar.xz",
"hash": "sha256-lp+uvfmXygl+lN2HffJ+xb/0lnFPZnif5izUVXvsbdM="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/libksysguard-6.0.3.tar.xz",
"hash": "sha256-UzYTh/OSk8chrw1LrEi7AIdX5kL9qbmvgZChyp2cK5I="
},
"libplasma": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/libplasma-6.0.2.tar.xz",
"hash": "sha256-NaAhBL3H3BNHETIZdoplNmUDp99fr5i/ANAatgNNEb0="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/libplasma-6.0.3.tar.xz",
"hash": "sha256-HKAgAm3to4pGyzTNcdfEnDsYub7ybK8c73Zav0n99x0="
},
"milou": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/milou-6.0.2.tar.xz",
"hash": "sha256-WKPbHv9ZfLIDlZ6jCqSWiOL0KK2tOIxU4suugQr0GhQ="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/milou-6.0.3.tar.xz",
"hash": "sha256-Lvv54qZEFF0tpKEEDmovTlRwMur8YRkGWbtXH45806I="
},
"ocean-sound-theme": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/ocean-sound-theme-6.0.2.tar.xz",
"hash": "sha256-+gHhW4qZfl3TTn3qZ6gnEph2WC5rD91EMjUvFrZ0VXc="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/ocean-sound-theme-6.0.3.tar.xz",
"hash": "sha256-Y7vfbsFcFOyAgHy8QoZQ5eLeHpxjm33erlx4mcIzxTY="
},
"oxygen": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/oxygen-6.0.2.tar.xz",
"hash": "sha256-Zhqp3BDNGzPOj1agJFD0YUhThKyex9vax8fGhPkiIOM="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/oxygen-6.0.3.tar.xz",
"hash": "sha256-c31dui2KYinXw9ZUtZAKo8Cio6jjbLXIfY7XpzgjPIQ="
},
"oxygen-sounds": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/oxygen-sounds-6.0.2.tar.xz",
"hash": "sha256-Ndoo5SZSvpsabDsmkZ1SR9QapotXL7EMRYOg9cy3C2E="
},
"plasma-activities": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-activities-6.0.2.tar.xz",
"hash": "sha256-Cod9C2cV+x5YSOQC4QK9Buu4ke2FHLrX7/j68WTvMak="
},
"plasma-activities-stats": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-activities-stats-6.0.2.tar.xz",
"hash": "sha256-1+SS0HyVe16mxFMLHxnTiiq97Ga8pTRuCOfvya4VkGw="
},
"plasma-browser-integration": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-browser-integration-6.0.2.tar.xz",
"hash": "sha256-bA76Wl1cT6742zEp00V1Kmr/5bShwRCec/mAKlTfvzI="
},
"plasma-desktop": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-desktop-6.0.2.tar.xz",
"hash": "sha256-BBDldeDxfKqvFhMqo/zLumQx3WG6dG8+LiAtKU9UNgo="
},
"plasma-disks": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-disks-6.0.2.tar.xz",
"hash": "sha256-PWeGm75GqCuYOx9twIYm0NNhdARGxwAFddc1RWUi8LY="
},
"plasma-firewall": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-firewall-6.0.2.tar.xz",
"hash": "sha256-IO4z6ATsdd9xN9a0c89dRqd5q2ZF3QlJT2f30Q7UqSg="
},
"plasma-integration": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-integration-6.0.2.tar.xz",
"hash": "sha256-Jqfbaw63VItADr+stNU/4bu8PAx7Pg6/duVVK8wCoPw="
},
"plasma-mobile": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-mobile-6.0.2.tar.xz",
"hash": "sha256-LQgMq0CvYObKPrA8E6XwttrRECxsCUEZOmTyTDeVf3I="
},
"plasma-nano": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-nano-6.0.2.tar.xz",
"hash": "sha256-xDxCj5OjxwOkfeODSur6ftjHEamwEyws17Zp/t/tcpw="
},
"plasma-nm": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-nm-6.0.2.tar.xz",
"hash": "sha256-QubzGz7G3lHuPO/bUimeZVzdIKXItNeIBCkYTi+S0MY="
},
"plasma-pa": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-pa-6.0.2.tar.xz",
"hash": "sha256-mY2o94MeFgBDFby0iNBdHVOXE0BuI1FVvb+7gNMB5a0="
},
"plasma-sdk": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-sdk-6.0.2.tar.xz",
"hash": "sha256-twvRfWNrJvg3RZsfcusp/QuiJXEcjK73p2LdYL/0ZAU="
},
"plasma-systemmonitor": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-systemmonitor-6.0.2.tar.xz",
"hash": "sha256-vDVzeXuZ3pbjmaKTYuvPbhu5ic7UocQZ8jIgSEJsk4s="
},
"plasma-thunderbolt": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-thunderbolt-6.0.2.tar.xz",
"hash": "sha256-CkWNmJNRiBP/dJeZ0cr068oFAbF5akLU496+F3StG2A="
},
"plasma-vault": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-vault-6.0.2.tar.xz",
"hash": "sha256-X4BqRrZAt+qK2fGNk5yhNDTOy+Ker0Y0k+5vnBl8HJA="
},
"plasma-welcome": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-welcome-6.0.2.tar.xz",
"hash": "sha256-PZiuRZBchM6kWNYmgKHCRx1E0Zu2HOkx47INBfDw908="
},
"plasma-workspace": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-workspace-6.0.2.tar.xz",
"hash": "sha256-nM604rzgRZcPwXe/KEf/rli9OXgGuMz0TaWCCjvWAM4="
},
"plasma-workspace-wallpapers": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma-workspace-wallpapers-6.0.2.tar.xz",
"hash": "sha256-0zDvbxeoltvd/jh7QSGuwFc3LAKcPMHS0iSIQru0vwA="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/oxygen-sounds-6.0.3.tar.xz",
"hash": "sha256-MOoAoJx1lfboRxqgKLRdP1GPWOOxmsFMiBexYkUoT6Y="
},
"plasma5support": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plasma5support-6.0.2.tar.xz",
"hash": "sha256-GLHeNGH183IcXTy7CEEToM7qW/PjdvIbJP6YylbVSm8="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma5support-6.0.3.tar.xz",
"hash": "sha256-yIO7B+UT7cZv05OaVC88TgF8iCwYUShuVbt63ctcNJU="
},
"plasma-activities": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-activities-6.0.3.tar.xz",
"hash": "sha256-xhWV6fR+769H47r0ANz9C6ASquSMaTQtj6DjoeElcP8="
},
"plasma-activities-stats": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-activities-stats-6.0.3.tar.xz",
"hash": "sha256-XdmMwCemN/2279LeDdXmftu0+wRhGNH+ScPpX21EGj0="
},
"plasma-browser-integration": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-browser-integration-6.0.3.tar.xz",
"hash": "sha256-hqcuOkgQf6oIKWdR9W1SBWRSXEA1bPSlrxJqJUjdxfE="
},
"plasma-desktop": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-desktop-6.0.3.tar.xz",
"hash": "sha256-AZsQu40EqAadgqWRE8AhoeWiTTed6lvjCXAXquEb2dA="
},
"plasma-disks": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-disks-6.0.3.tar.xz",
"hash": "sha256-+m8c+QhNf+/a2+DJWFd6ynRHsTl+xNQUYa6uRK9qwyg="
},
"plasma-firewall": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-firewall-6.0.3.tar.xz",
"hash": "sha256-GKV9L6UF2CrM/zUWxOGiA7CTikgU8ERShoFcGe4rdZo="
},
"plasma-integration": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-integration-6.0.3.tar.xz",
"hash": "sha256-W+t3hNEk2eoQjwCAQ6k8g3wHVz9byK/PkhbutGRK/Yo="
},
"plasma-mobile": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-mobile-6.0.3.tar.xz",
"hash": "sha256-oHgh272xMZYdoTidGyR2xsdASVTU50mAw9+nUyF5+Xo="
},
"plasma-nano": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-nano-6.0.3.tar.xz",
"hash": "sha256-mBjOkE8YME0wsirNcTmAV33mzAvXXqDPtkvtJQ0ASyo="
},
"plasma-nm": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-nm-6.0.3.tar.xz",
"hash": "sha256-EFi4WULetceWMvXDLwn3gbcDgd4SOeHOh9/plyhW7T0="
},
"plasma-pa": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-pa-6.0.3.tar.xz",
"hash": "sha256-seGYoBVR6HJ1s/m3GLlN8+3zkdzPK6ceqa8HvFLd7ls="
},
"plasma-sdk": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-sdk-6.0.3.tar.xz",
"hash": "sha256-SuTUlcd7ZQjvhTXTm3OosUwe4Sl8fbp0DpKLJg/b/Xk="
},
"plasma-systemmonitor": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-systemmonitor-6.0.3.tar.xz",
"hash": "sha256-JcMI6Yx4ByoERWIVkythPo+56nHsUgwFANcearC8WEc="
},
"plasma-thunderbolt": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-thunderbolt-6.0.3.tar.xz",
"hash": "sha256-xQ/yiDnu6HYm638ZH/VsDJZhdt0Q0/Qqm84oDjMTTWI="
},
"plasma-vault": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-vault-6.0.3.tar.xz",
"hash": "sha256-UYQtcK+1ecGvixcb2975hpqY2obi4V3kfw0pTuGqifc="
},
"plasma-welcome": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-welcome-6.0.3.tar.xz",
"hash": "sha256-22EjXA90eHBwlbHsmc4TwnD+uBoYHUTrjUMJJRtj1Bw="
},
"plasma-workspace": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-workspace-6.0.3.tar.xz",
"hash": "sha256-5D6oADqHUyed9FgOvtF+6jUulpS1TbpFB0BgJaQfacM="
},
"plasma-workspace-wallpapers": {
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plasma-workspace-wallpapers-6.0.3.tar.xz",
"hash": "sha256-Zuy9JdtjSutSvgX8PcxKcbHP/e4Sq2RRR65fLsQje9s="
},
"plymouth-kcm": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/plymouth-kcm-6.0.2.tar.xz",
"hash": "sha256-lZUuLTwQoXUyUy9yTnWoU0ZO7BLlThw8TyEoEAtXoTA="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/plymouth-kcm-6.0.3.tar.xz",
"hash": "sha256-IGN0fREb2G15T4PkY1glJCCy0TyDVpElZOqMf6GLRu4="
},
"polkit-kde-agent-1": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/polkit-kde-agent-1-6.0.2.tar.xz",
"hash": "sha256-Pi3sf38vQ0LHz4zcZJcr5XNQmoNWT/wa9+DZG/V0Yr0="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/polkit-kde-agent-1-6.0.3.tar.xz",
"hash": "sha256-PbxfR+7HCSzPH0KVo0n+aa6EzoAL6pCSWglrY43Qy/0="
},
"powerdevil": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/powerdevil-6.0.2.tar.xz",
"hash": "sha256-MYjTyMrd32iVXvyW6eThKS6z0Wfk2lkCmtyZPiFR9Ug="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/powerdevil-6.0.3.tar.xz",
"hash": "sha256-HJuQ4wyyIi4PXNKq8Kj4kIyefsEVGtQNzXz3VA6h7ZI="
},
"print-manager": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/print-manager-6.0.2.tar.xz",
"hash": "sha256-Zs4HOBWDgO7sLCWcwtPyWdU+Kdv/Lf2FPlWgnTrKRv8="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/print-manager-6.0.3.tar.xz",
"hash": "sha256-8qLpHnxDtqsdsLmal8QqSEUjDH9stznLMKSMKCRX5Iw="
},
"qqc2-breeze-style": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/qqc2-breeze-style-6.0.2.tar.xz",
"hash": "sha256-kE5jmK7irTEpHAJ6sJahl8lC60pz7vf03kKCy8prMl0="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/qqc2-breeze-style-6.0.3.tar.xz",
"hash": "sha256-QBhE+H4b5I4V8WevZBqzEaIDdsSKmz7iHHbuJeij29k="
},
"sddm-kcm": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/sddm-kcm-6.0.2.tar.xz",
"hash": "sha256-GjF2qqTtS2uCFON0RuvVtK4LnigjuWQfHvfotnI7JMs="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/sddm-kcm-6.0.3.tar.xz",
"hash": "sha256-+qdeD1r+HikPAMaW+/duSqcRiONRv4RFRwQ+BiYAmG4="
},
"systemsettings": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/systemsettings-6.0.2.tar.xz",
"hash": "sha256-3llQvu9jREmE+mHjh0xgE6T/7r/ObYGc97q3yCQCtgY="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/systemsettings-6.0.3.tar.xz",
"hash": "sha256-HHTYkou9DL1Y8B/V7anbjNMl4X5jt0NsDxnTII9Rxaw="
},
"wacomtablet": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/wacomtablet-6.0.2.tar.xz",
"hash": "sha256-s1Vn6OKtKB1csiJRdBPasKRK/iVbWSZPMHe+e9cUB5k="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/wacomtablet-6.0.3.tar.xz",
"hash": "sha256-wMD7IxTGSq3rE/QUEhrnbMGNJ5YD1S/G2xJZ+7/DOwE="
},
"xdg-desktop-portal-kde": {
"version": "6.0.2",
"url": "mirror://kde/stable/plasma/6.0.2/xdg-desktop-portal-kde-6.0.2.tar.xz",
"hash": "sha256-LX5j/LAr+jV/Ml2QA4dFau4Bk+pBSy7emLGhWbUg52U="
"version": "6.0.3",
"url": "mirror://kde/stable/plasma/6.0.3/xdg-desktop-portal-kde-6.0.3.tar.xz",
"hash": "sha256-vWWbfhto3tKNgZmr+MX0n8butDLJtqiEPr9MBMwDWqk="
}
}

View File

@ -1,8 +1,8 @@
diff --git a/src/data/debuggers/internal/gdbrc b/src/data/debuggers/internal/gdbrc
index 9a5c8fee..c32b1510 100644
index 0d163d43..8e2f85f1 100644
--- a/src/data/debuggers/internal/gdbrc
+++ b/src/data/debuggers/internal/gdbrc
@@ -72,17 +72,18 @@ Name[wa]=gdb
@@ -73,17 +73,18 @@ Name[wa]=gdb
Name[x-test]=xxgdbxx
Name[zh_CN]=gdb
Name[zh_TW]=gdb
@ -16,7 +16,7 @@ index 9a5c8fee..c32b1510 100644
-ExecWithSymbolResolution=gdb -nw -n -batch --init-eval-command='set debuginfod enabled on' -x %preamblefile -x %tempfile -p %pid %execpath
+Exec=@gdb@ -nw -n -batch -x %preamblefile -x %tempfile -p %pid %execpath
+ExecWithSymbolResolution=@gdb@ -nw -n -batch --init-eval-command='set debuginfod enabled on' -x %preamblefile -x %tempfile -p %pid %execpath
PreambleCommands=set width 200\nsource %drkonqi_datadir/python/gdb_preamble/preamble.py\npy print_preamble()
PreambleCommands=set width 200\nset backtrace limit 128\nsource %drkonqi_datadir/python/gdb_preamble/preamble.py\npy print_preamble()
BatchCommands=thread\nthread apply all bt
[coredump-core]
@ -24,5 +24,5 @@ index 9a5c8fee..c32b1510 100644
-ExecWithSymbolResolution=gdb --nw --nx --batch --init-eval-command='set debuginfod enabled on' --command=%preamblefile --command=%tempfile --core=%corefile %execpath
+Exec=@gdb@ --nw --nx --batch --command=%preamblefile --command=%tempfile --core=%corefile %execpath
+ExecWithSymbolResolution=@gdb@ --nw --nx --batch --init-eval-command='set debuginfod enabled on' --command=%preamblefile --command=%tempfile --core=%corefile %execpath
PreambleCommands=set width 200\nsource %drkonqi_datadir/python/gdb_preamble/preamble.py\npy print_preamble()
PreambleCommands=set width 200\nset backtrace limit 128\nsource %drkonqi_datadir/python/gdb_preamble/preamble.py\npy print_preamble()
BatchCommands=thread\nthread apply all bt

View File

@ -3192,6 +3192,7 @@ dependencies = [
"hex",
"idlset",
"image 0.24.8",
"itertools 0.12.1",
"kanidm_build_profiles",
"kanidm_lib_crypto",
"kanidm_proto",

View File

@ -25,8 +25,8 @@ rustPlatform.buildRustPackage rec {
owner = pname;
repo = pname;
# Latest revision of 1.1.0-rc.16 stable branch
rev = "4c88d6b27c9b82ad5b2482bda140025d7068293f";
hash = "sha256-tatZ56uIusNvAAGwJ731rfmHvheOtPXjPUxLuAPFxXs=";
rev = "e51d0dee44ecabbf7be9e855753453bb2f61cced";
hash = "sha256-YgrlmSrjOzn/oFWmYy/71xwcq53lJbmiLIFzn2sIFAk=";
};
cargoLock = {

View File

@ -91,6 +91,8 @@ self: super: {
pg_relusage = super.callPackage ./pg_relusage.nix { };
pg_roaringbitmap = super.callPackage ./pg_roaringbitmap.nix { };
pg_safeupdate = super.callPackage ./pg_safeupdate.nix { };
pg_squeeze = super.callPackage ./pg_squeeze.nix { };

View File

@ -0,0 +1,32 @@
{ lib, stdenv, fetchFromGitHub, postgresql, postgresqlTestHook }:
stdenv.mkDerivation (finalAttrs: {
pname = "pg_roaringbitmap";
version = "0.5.4";
src = fetchFromGitHub {
owner = "ChenHuajun";
repo = "pg_roaringbitmap";
rev = "v${finalAttrs.version}";
hash = "sha256-E6vqawnsRsAIajGDgJcTUWV1H8GFFboTjhmVfemUGbs=";
};
buildInputs = [
postgresql
];
installPhase = ''
install -D -t $out/lib roaringbitmap${postgresql.dlSuffix}
install -D -t $out/share/postgresql/extension roaringbitmap-*.sql
install -D -t $out/share/postgresql/extension roaringbitmap.control
'';
meta = with lib; {
description = "RoaringBitmap extension for PostgreSQL";
homepage = "https://github.com/ChenHuajun/pg_roaringbitmap";
changelog = "https://github.com/ChenHuajun/pg_roaringbitmap/blob/${finalAttrs.src.rev}/CHANGELOG.md";
license = licenses.asl20;
maintainers = [ maintainers.marsam ];
inherit (postgresql.meta) platforms;
};
})

View File

@ -1,7 +1,7 @@
# CI-related Scripts
# `pkgs/by-name` check CI scripts
This directory contains scripts and files used and related to the CI running the `pkgs/by-name` checks in Nixpkgs.
See also the [CI GitHub Action](../../../../.github/workflows/check-by-name.yml).
See also the [CI GitHub Action](../../../.github/workflows/check-by-name.yml).
## `./run-local.sh BASE_BRANCH [REPOSITORY]`
@ -18,17 +18,10 @@ Arguments:
## `./update-pinned-tool.sh`
Updates the pinned CI tool in [`./pinned-tool.json`](./pinned-tool.json) to the
[latest version from the `nixos-unstable` channel](https://hydra.nixos.org/job/nixos/trunk-combined/nixpkgs.tests.nixpkgs-check-by-name.x86_64-linux).
Updates the pinned [nixpkgs-check-by-name tool](https://github.com/NixOS/nixpkgs-check-by-name) in [`./pinned-version.txt`](./pinned-version.txt) to the latest [release](https://github.com/NixOS/nixpkgs-check-by-name/releases).
Each release contains a pre-built x86_64-linux version of the tool which is used by CI.
This script needs to be called manually when the CI tooling needs to be updated.
The `pinned-tool.json` file gets populated with both:
- The `/nix/store` path for `x86_64-linux`, such that CI doesn't have to evaluate Nixpkgs and can directly fetch it from the cache instead.
- The Nixpkgs revision, such that the `./run-local.sh` script can be used to run the checks locally on any system.
To ensure that the tool is always pre-built for `x86_64-linux` in the `nixos-unstable` channel,
it's included in the `tested` jobset description in [`nixos/release-combined.nix`](../../../nixos/release-combined.nix).
This script currently needs to be called manually when the CI tooling needs to be updated.
Why not just build the tooling right from the PRs Nixpkgs version?
- Because it allows CI to check all PRs, even if they would break the CI tooling.

View File

@ -0,0 +1 @@
0.1.0

View File

@ -14,7 +14,6 @@ cleanup() {
[[ -e "$tmp/base" ]] && git worktree remove --force "$tmp/base"
[[ -e "$tmp/merged" ]] && git worktree remove --force "$tmp/merged"
[[ -e "$tmp/tool-nixpkgs" ]] && git worktree remove --force "$tmp/tool-nixpkgs"
rm -rf "$tmp"
@ -63,20 +62,12 @@ trace -n "Merging base branch into the HEAD commit in $tmp/merged.. "
git -C "$tmp/merged" merge -q --no-edit "$baseSha"
trace -e "\e[34m$(git -C "$tmp/merged" rev-parse HEAD)\e[0m"
trace -n "Reading pinned nixpkgs-check-by-name revision from pinned-tool.json.. "
toolSha=$(jq -r .rev "$tmp/merged/pkgs/test/nixpkgs-check-by-name/scripts/pinned-tool.json")
trace -e "\e[34m$toolSha\e[0m"
trace -n "Reading pinned nixpkgs-check-by-name version from pinned-version.txt.. "
toolVersion=$(<"$tmp/merged/pkgs/test/check-by-name/pinned-version.txt")
trace -e "\e[34m$toolVersion\e[0m"
trace -n "Creating Git worktree for the nixpkgs-check-by-name revision in $tmp/tool-nixpkgs.. "
git worktree add -q "$tmp/tool-nixpkgs" "$toolSha"
trace "Done"
trace "Building/fetching nixpkgs-check-by-name.."
nix-build -o "$tmp/tool" "$tmp/tool-nixpkgs" \
-A tests.nixpkgs-check-by-name \
--arg config '{}' \
--arg overlays '[]' \
-j 0
trace -n "Building tool.. "
nix-build https://github.com/NixOS/nixpkgs-check-by-name/tarball/"$toolVersion" -o "$tmp/tool" -A build
trace "Running nixpkgs-check-by-name.."
"$tmp/tool/bin/nixpkgs-check-by-name" --base "$tmp/base" "$tmp/merged"

View File

@ -0,0 +1,22 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p jq curl
set -o pipefail -o errexit -o nounset
trace() { echo >&2 "$@"; }
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
repository=NixOS/nixpkgs-check-by-name
pin_file=$SCRIPT_DIR/pinned-version.txt
trace -n "Fetching latest release of $repository.. "
latestRelease=$(curl -sSfL \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/"$repository"/releases/latest)
latestVersion=$(jq .tag_name -r <<< "$latestRelease")
trace "$latestVersion"
trace "Updating $pin_file"
echo "$latestVersion" > "$pin_file"

View File

@ -173,7 +173,7 @@ with pkgs;
buildFHSEnv = recurseIntoAttrs (callPackages ./buildFHSEnv { });
nixpkgs-check-by-name = callPackage ./nixpkgs-check-by-name { };
nixpkgs-check-by-name = throw "tests.nixpkgs-check-by-name is now specified in a separate repository: https://github.com/NixOS/nixpkgs-check-by-name";
auto-patchelf-hook = callPackage ./auto-patchelf-hook { };

View File

@ -1 +0,0 @@
use nix

View File

@ -1,2 +0,0 @@
target
.direnv

View File

@ -1,643 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea"
[[package]]
name = "anstyle-parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "cc"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"libc",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d5f1946157a96594eb2d2c10eb7ad9a2b27518cb3000209dec700c35df9197d"
dependencies = [
"clap_builder",
"clap_derive",
"once_cell",
]
[[package]]
name = "clap_builder"
version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78116e32a042dd73c2901f0dc30790d20ff3447f3e3472fad359e8c3d282bcd6"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9fd1a5729c4548118d7d70ff234a44868d00489a4b6597b0b020918a0e91a1a"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "colored"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6"
dependencies = [
"is-terminal",
"lazy_static",
"windows-sys",
]
[[package]]
name = "countme"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "errno"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "fastrand"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
[[package]]
name = "indoc"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
[[package]]
name = "is-terminal"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
dependencies = [
"hermit-abi",
"rustix",
"windows-sys",
]
[[package]]
name = "itertools"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "linux-raw-sys"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
[[package]]
name = "lock_api"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
dependencies = [
"autocfg",
]
[[package]]
name = "nixpkgs-check-by-name"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"colored",
"indoc",
"itertools",
"lazy_static",
"regex",
"relative-path",
"rnix",
"rowan",
"serde",
"serde_json",
"temp-env",
"tempfile",
"textwrap",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets",
]
[[package]]
name = "proc-macro2"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "regex"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
[[package]]
name = "relative-path"
version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc"
[[package]]
name = "rnix"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb35cedbeb70e0ccabef2a31bcff0aebd114f19566086300b8f42c725fc2cb5f"
dependencies = [
"rowan",
]
[[package]]
name = "rowan"
version = "0.15.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64449cfef9483a475ed56ae30e2da5ee96448789fb2aa240a04beb6a055078bf"
dependencies = [
"countme",
"hashbrown",
"memoffset",
"rustc-hash",
"text-size",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
version = "0.38.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
dependencies = [
"bitflags 2.4.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "ryu"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "smallvec"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
[[package]]
name = "smawk"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "2.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "temp-env"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e010429b1f3ea1311190c658c7570100f03c1dab05c16cfab774181c648d656a"
dependencies = [
"parking_lot",
]
[[package]]
name = "tempfile"
version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
dependencies = [
"cfg-if",
"fastrand",
"redox_syscall",
"rustix",
"windows-sys",
]
[[package]]
name = "text-size"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
[[package]]
name = "textwrap"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
dependencies = [
"smawk",
"unicode-linebreak",
"unicode-width",
]
[[package]]
name = "unicode-ident"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unicode-linebreak"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
[[package]]
name = "unicode-width"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"

View File

@ -1,23 +0,0 @@
[package]
name = "nixpkgs-check-by-name"
version = "0.1.0"
edition = "2021"
[dependencies]
rnix = "0.11.0"
regex = "1.9.3"
clap = { version = "4.3.23", features = ["derive"] }
serde_json = "1.0.105"
tempfile = "3.8.0"
serde = { version = "1.0.185", features = ["derive"] }
anyhow = "1.0"
lazy_static = "1.4.0"
colored = "2.0.4"
itertools = "0.11.0"
rowan = "0.15.11"
indoc = "2.0.4"
relative-path = "1.9.2"
textwrap = "0.16.1"
[dev-dependencies]
temp-env = "0.3.5"

View File

@ -1,102 +0,0 @@
# Nixpkgs pkgs/by-name checker
This directory implements a program to check the [validity](#validity-checks) of the `pkgs/by-name` Nixpkgs directory.
This is part of the implementation of [RFC 140](https://github.com/NixOS/rfcs/pull/140).
A [pinned version](./scripts/pinned-tool.json) of this tool is used by [this GitHub Actions workflow](../../../.github/workflows/check-by-name.yml).
See [./scripts](./scripts/README.md#update-pinned-toolsh) for how to update the pinned version.
The source of the tool being right inside Nixpkgs allows any Nixpkgs committer to make updates to it.
## Interface
The interface of the tool is shown with `--help`:
```
cargo run -- --help
```
The interface may be changed over time only if the CI workflow making use of it is adjusted to deal with the change appropriately.
## Validity checks
These checks are performed by this tool:
### File structure checks
- `pkgs/by-name` must only contain subdirectories of the form `${shard}/${name}`, called _package directories_.
- The `name`'s of package directories must be unique when lowercased.
- `name` is a string only consisting of the ASCII characters `a-z`, `A-Z`, `0-9`, `-` or `_`.
- `shard` is the lowercased first two letters of `name`, expressed in Nix: `shard = toLower (substring 0 2 name)`.
- Each package directory must contain a `package.nix` file and may contain arbitrary other files.
### Nix parser checks
- Each package directory must not refer to files outside itself using symlinks or Nix path expressions.
### Nix evaluation checks
Evaluate Nixpkgs with `system` set to `x86_64-linux` and check that:
- For each package directory, the `pkgs.${name}` attribute must be defined as `callPackage pkgs/by-name/${shard}/${name}/package.nix args` for some `args`.
- For each package directory, `pkgs.lib.isDerivation pkgs.${name}` must be `true`.
### Ratchet checks
Furthermore, this tool implements certain [ratchet](https://qntm.org/ratchet) checks.
This allows gradually phasing out deprecated patterns without breaking the base branch or having to migrate it all at once.
It works by not allowing new instances of the pattern to be introduced, but allowing already existing instances.
The existing instances are coming from `<BASE_NIXPKGS>`, which is then checked against `<NIXPKGS>` for new instances.
Ratchets should be removed eventually once the pattern is not used anymore.
The current ratchets are:
- New manual definitions of `pkgs.${name}` (e.g. in `pkgs/top-level/all-packages.nix`) with `args = { }`
(see [nix evaluation checks](#nix-evaluation-checks)) must not be introduced.
- New top-level packages defined using `pkgs.callPackage` must be defined with a package directory.
- Once a top-level package uses `pkgs/by-name`, it also can't be moved back out of it.
## Development
Enter the development environment in this directory either automatically with `direnv` or with
```
nix-shell
```
Then use `cargo`:
```
cargo build
cargo test
cargo fmt
cargo clippy
```
## Tests
Tests are declared in [`./tests`](./tests) as subdirectories imitating Nixpkgs with these files:
- `default.nix`:
Always contains
```nix
import <test-nixpkgs> { root = ./.; }
```
which makes
```
nix-instantiate <subdir> --eval -A <attr> --arg overlays <overlays>
```
work very similarly to the real Nixpkgs, just enough for the program to be able to test it.
- `pkgs/by-name`:
The `pkgs/by-name` directory to check.
- `all-packages.nix` (optional):
Contains an overlay of the form
```nix
self: super: {
# ...
}
```
allowing the simulation of package overrides to the real [`pkgs/top-level/all-packages.nix`](../../top-level/all-packages.nix`).
The default is an empty overlay.
- `base` (optional):
Contains another subdirectory imitating Nixpkgs with potentially any of the above structures.
This is used for [ratchet checks](#ratchet-checks).
- `expected` (optional):
A file containing the expected standard output.
The default is expecting an empty standard output.

View File

@ -1,82 +0,0 @@
{
lib,
rustPlatform,
nix,
rustfmt,
clippy,
mkShell,
makeWrapper,
runCommand,
}:
let
runtimeExprPath = ./src/eval.nix;
nixpkgsLibPath = ../../../lib;
testNixpkgsPath = ./tests/mock-nixpkgs.nix;
# Needed to make Nix evaluation work inside nix builds
initNix = ''
export TEST_ROOT=$(pwd)/test-tmp
export NIX_CONF_DIR=$TEST_ROOT/etc
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_STORE_DIR=$TEST_ROOT/store
# Ensure that even if tests run in parallel, we don't get an error
# We'd run into https://github.com/NixOS/nix/issues/2706 unless the store is initialised first
nix-store --init
'';
fs = lib.fileset;
package =
rustPlatform.buildRustPackage {
name = "nixpkgs-check-by-name";
src = fs.toSource {
root = ./.;
fileset = fs.unions [
./Cargo.lock
./Cargo.toml
./src
./tests
];
};
cargoLock.lockFile = ./Cargo.lock;
nativeBuildInputs = [
nix
rustfmt
clippy
makeWrapper
];
env.NIX_CHECK_BY_NAME_EXPR_PATH = "${runtimeExprPath}";
env.NIX_PATH = "test-nixpkgs=${testNixpkgsPath}:test-nixpkgs/lib=${nixpkgsLibPath}";
preCheck = initNix;
postCheck = ''
cargo fmt --check
cargo clippy -- -D warnings
'';
postInstall = ''
wrapProgram $out/bin/nixpkgs-check-by-name \
--set NIX_CHECK_BY_NAME_EXPR_PATH "$NIX_CHECK_BY_NAME_EXPR_PATH"
'';
passthru.shell = mkShell {
env.NIX_CHECK_BY_NAME_EXPR_PATH = toString runtimeExprPath;
env.NIX_PATH = "test-nixpkgs=${toString testNixpkgsPath}:test-nixpkgs/lib=${toString nixpkgsLibPath}";
inputsFrom = [ package ];
};
# Tests the tool on the current Nixpkgs tree, this is a good sanity check
passthru.tests.nixpkgs = runCommand "test-nixpkgs-check-by-name" {
nativeBuildInputs = [
package
nix
];
nixpkgsPath = lib.cleanSource ../../..;
} ''
${initNix}
nixpkgs-check-by-name --base "$nixpkgsPath" "$nixpkgsPath"
touch $out
'';
};
in
package

View File

@ -1,4 +0,0 @@
{
"rev": "b8697e57f10292a6165a20f03d2f42920dfaf973",
"ci-path": "/nix/store/w6w7khwfq6qzm4bsyijhg7m2kqv9f9jl-nixpkgs-check-by-name"
}

View File

@ -1,40 +0,0 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p jq
set -o pipefail -o errexit -o nounset
trace() { echo >&2 "$@"; }
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
# Determined by `runs-on: ubuntu-latest` in .github/workflows/check-by-name.yml
CI_SYSTEM=x86_64-linux
channel=nixos-unstable
pin_file=$SCRIPT_DIR/pinned-tool.json
trace -n "Fetching latest version of channel $channel.. "
# This is probably the easiest way to get Nix to output the path to a downloaded channel!
nixpkgs=$(nix-instantiate --find-file nixpkgs -I nixpkgs=channel:"$channel")
trace "$nixpkgs"
# This file only exists in channels
rev=$(<"$nixpkgs/.git-revision")
trace -e "Git revision of channel $channel is \e[34m$rev\e[0m"
trace -n "Fetching the prebuilt version of nixpkgs-check-by-name for $CI_SYSTEM.. "
# This is the architecture used by CI, we want to prefetch the exact path to avoid having to evaluate Nixpkgs
ci_path=$(nix-build --no-out-link "$nixpkgs" \
-A tests.nixpkgs-check-by-name \
--arg config '{}' \
--argstr system "$CI_SYSTEM" \
--arg overlays '[]' \
-j 0 \
| tee /dev/stderr)
trace "Updating $pin_file"
jq -n \
--arg rev "$rev" \
--arg ci-path "$ci_path" \
'$ARGS.named' \
> "$pin_file"

View File

@ -1,6 +0,0 @@
let
pkgs = import ../../.. {
config = {};
overlays = [];
};
in pkgs.tests.nixpkgs-check-by-name.shell

View File

@ -1,116 +0,0 @@
# Takes a path to nixpkgs and a path to the json-encoded list of `pkgs/by-name` attributes.
# Returns a value containing information on all Nixpkgs attributes
# which is decoded on the Rust side.
# See ./eval.rs for the meaning of the returned values
{
attrsPath,
nixpkgsPath,
}:
let
attrs = builtins.fromJSON (builtins.readFile attrsPath);
# We need to check whether attributes are defined manually e.g. in
# `all-packages.nix`, automatically by the `pkgs/by-name` overlay, or
# neither. The only way to do so is to override `callPackage` and
# `_internalCallByNamePackageFile` with our own version that adds this
# information to the result, and then try to access it.
overlay = final: prev: {
# Adds information to each attribute about whether it's manually defined using `callPackage`
callPackage = fn: args:
addVariantInfo (prev.callPackage fn args) {
# This is a manual definition of the attribute, and it's a callPackage, specifically a semantic callPackage
ManualDefinition.is_semantic_call_package = true;
};
# Adds information to each attribute about whether it's automatically
# defined by the `pkgs/by-name` overlay. This internal attribute is only
# used by that overlay.
# This overrides the above `callPackage` information (we don't need that
# one, since `pkgs/by-name` always uses `callPackage` underneath.
_internalCallByNamePackageFile = file:
addVariantInfo (prev._internalCallByNamePackageFile file) {
AutoDefinition = null;
};
};
# We can't just replace attribute values with their info in the overlay,
# because attributes can depend on other attributes, so this would break evaluation.
addVariantInfo = value: variant:
if builtins.isAttrs value then
value // {
_callPackageVariant = variant;
}
else
# It's very rare that callPackage doesn't return an attribute set, but it can occur.
# In such a case we can't really return anything sensible that would include the info,
# so just don't return the value directly and treat it as if it wasn't a callPackage.
value;
pkgs = import nixpkgsPath {
# Don't let the users home directory influence this result
config = { };
overlays = [ overlay ];
# We check evaluation and callPackage only for x86_64-linux.
# Not ideal, but hard to fix
system = "x86_64-linux";
};
# See AttributeInfo in ./eval.rs for the meaning of this
attrInfo = name: value: {
location = builtins.unsafeGetAttrPos name pkgs;
attribute_variant =
if ! builtins.isAttrs value then
{ NonAttributeSet = null; }
else
{
AttributeSet = {
is_derivation = pkgs.lib.isDerivation value;
definition_variant =
if ! value ? _callPackageVariant then
{ ManualDefinition.is_semantic_call_package = false; }
else
value._callPackageVariant;
};
};
};
# Information on all attributes that are in pkgs/by-name.
byNameAttrs = builtins.listToAttrs (map (name: {
inherit name;
value.ByName =
if ! pkgs ? ${name} then
{ Missing = null; }
else
# Evaluation failures are not allowed, so don't try to catch them
{ Existing = attrInfo name pkgs.${name}; };
}) attrs);
# Information on all attributes that exist but are not in pkgs/by-name.
# We need this to enforce pkgs/by-name for new packages
nonByNameAttrs = builtins.mapAttrs (name: value:
let
# Packages outside `pkgs/by-name` often fail evaluation,
# so we need to handle that
output = attrInfo name value;
result = builtins.tryEval (builtins.deepSeq output null);
in
{
NonByName =
if result.success then
{ EvalSuccess = output; }
else
{ EvalFailure = null; };
}
) (builtins.removeAttrs pkgs attrs);
# All attributes
attributes = byNameAttrs // nonByNameAttrs;
in
# We output them in the form [ [ <name> <value> ] ]` such that the Rust side
# doesn't need to sort them again to get deterministic behavior (good for testing)
map (name: [
name
attributes.${name}
]) (builtins.attrNames attributes)

View File

@ -1,559 +0,0 @@
use crate::nix_file::CallPackageArgumentInfo;
use crate::nixpkgs_problem::NixpkgsProblem;
use crate::ratchet;
use crate::ratchet::RatchetState::Loose;
use crate::ratchet::RatchetState::Tight;
use crate::structure;
use crate::utils;
use crate::validation::ResultIteratorExt as _;
use crate::validation::{self, Validation::Success};
use crate::NixFileStore;
use relative_path::RelativePathBuf;
use std::path::Path;
use anyhow::Context;
use serde::Deserialize;
use std::path::PathBuf;
use std::process;
use tempfile::NamedTempFile;
/// Attribute set of this structure is returned by eval.nix
#[derive(Deserialize)]
enum Attribute {
/// An attribute that should be defined via pkgs/by-name
ByName(ByNameAttribute),
/// An attribute not defined via pkgs/by-name
NonByName(NonByNameAttribute),
}
#[derive(Deserialize)]
enum NonByNameAttribute {
/// The attribute doesn't evaluate
EvalFailure,
EvalSuccess(AttributeInfo),
}
#[derive(Deserialize)]
enum ByNameAttribute {
/// The attribute doesn't exist at all
Missing,
Existing(AttributeInfo),
}
#[derive(Deserialize)]
struct AttributeInfo {
/// The location of the attribute as returned by `builtins.unsafeGetAttrPos`
location: Option<Location>,
attribute_variant: AttributeVariant,
}
/// The structure returned by a successful `builtins.unsafeGetAttrPos`
#[derive(Deserialize, Clone, Debug)]
struct Location {
pub file: PathBuf,
pub line: usize,
pub column: usize,
}
impl Location {
// Returns the [file] field, but relative to Nixpkgs
fn relative_file(&self, nixpkgs_path: &Path) -> anyhow::Result<RelativePathBuf> {
let path = self.file.strip_prefix(nixpkgs_path).with_context(|| {
format!(
"The file ({}) is outside Nixpkgs ({})",
self.file.display(),
nixpkgs_path.display()
)
})?;
Ok(RelativePathBuf::from_path(path).expect("relative path"))
}
}
#[derive(Deserialize)]
pub enum AttributeVariant {
/// The attribute is not an attribute set, we're limited in the amount of information we can get
/// from it (though it's obviously not a derivation)
NonAttributeSet,
AttributeSet {
/// Whether the attribute is a derivation (`lib.isDerivation`)
is_derivation: bool,
/// The type of callPackage
definition_variant: DefinitionVariant,
},
}
#[derive(Deserialize)]
pub enum DefinitionVariant {
/// An automatic definition by the `pkgs/by-name` overlay
/// Though it's detected using the internal _internalCallByNamePackageFile attribute,
/// which can in theory also be used by other code
AutoDefinition,
/// A manual definition of the attribute, typically in `all-packages.nix`
ManualDefinition {
/// Whether the attribute is defined as `pkgs.callPackage ...` or something else.
is_semantic_call_package: bool,
},
}
/// Check that the Nixpkgs attribute values corresponding to the packages in pkgs/by-name are
/// of the form `callPackage <package_file> { ... }`.
/// See the `eval.nix` file for how this is achieved on the Nix side
pub fn check_values(
nixpkgs_path: &Path,
nix_file_store: &mut NixFileStore,
package_names: Vec<String>,
keep_nix_path: bool,
) -> validation::Result<ratchet::Nixpkgs> {
// Write the list of packages we need to check into a temporary JSON file.
// This can then get read by the Nix evaluation.
let attrs_file = NamedTempFile::new().with_context(|| "Failed to create a temporary file")?;
// We need to canonicalise this path because if it's a symlink (which can be the case on
// Darwin), Nix would need to read both the symlink and the target path, therefore need 2
// NIX_PATH entries for restrict-eval. But if we resolve the symlinks then only one predictable
// entry is needed.
let attrs_file_path = attrs_file.path().canonicalize()?;
serde_json::to_writer(&attrs_file, &package_names).with_context(|| {
format!(
"Failed to serialise the package names to the temporary path {}",
attrs_file_path.display()
)
})?;
let expr_path = std::env::var("NIX_CHECK_BY_NAME_EXPR_PATH")
.with_context(|| "Could not get environment variable NIX_CHECK_BY_NAME_EXPR_PATH")?;
// With restrict-eval, only paths in NIX_PATH can be accessed, so we explicitly specify the
// ones needed needed
let mut command = process::Command::new("nix-instantiate");
command
// Inherit stderr so that error messages always get shown
.stderr(process::Stdio::inherit())
.args([
"--eval",
"--json",
"--strict",
"--readonly-mode",
"--restrict-eval",
"--show-trace",
])
// Pass the path to the attrs_file as an argument and add it to the NIX_PATH so it can be
// accessed in restrict-eval mode
.args(["--arg", "attrsPath"])
.arg(&attrs_file_path)
.arg("-I")
.arg(&attrs_file_path)
// Same for the nixpkgs to test
.args(["--arg", "nixpkgsPath"])
.arg(nixpkgs_path)
.arg("-I")
.arg(nixpkgs_path);
// Clear NIX_PATH to be sure it doesn't influence the result
// But not when requested to keep it, used so that the tests can pass extra Nix files
if !keep_nix_path {
command.env_remove("NIX_PATH");
}
command.args(["-I", &expr_path]);
command.arg(expr_path);
let result = command
.output()
.with_context(|| format!("Failed to run command {command:?}"))?;
if !result.status.success() {
anyhow::bail!("Failed to run command {command:?}");
}
// Parse the resulting JSON value
let attributes: Vec<(String, Attribute)> = serde_json::from_slice(&result.stdout)
.with_context(|| {
format!(
"Failed to deserialise {}",
String::from_utf8_lossy(&result.stdout)
)
})?;
let check_result = validation::sequence(
attributes
.into_iter()
.map(|(attribute_name, attribute_value)| {
let check_result = match attribute_value {
Attribute::NonByName(non_by_name_attribute) => handle_non_by_name_attribute(
nixpkgs_path,
nix_file_store,
&attribute_name,
non_by_name_attribute,
)?,
Attribute::ByName(by_name_attribute) => by_name(
nix_file_store,
nixpkgs_path,
&attribute_name,
by_name_attribute,
)?,
};
Ok::<_, anyhow::Error>(check_result.map(|value| (attribute_name.clone(), value)))
})
.collect_vec()?,
);
Ok(check_result.map(|elems| ratchet::Nixpkgs {
package_names: elems.iter().map(|(name, _)| name.to_owned()).collect(),
package_map: elems.into_iter().collect(),
}))
}
/// Handles the evaluation result for an attribute in `pkgs/by-name`,
/// turning it into a validation result.
fn by_name(
nix_file_store: &mut NixFileStore,
nixpkgs_path: &Path,
attribute_name: &str,
by_name_attribute: ByNameAttribute,
) -> validation::Result<ratchet::Package> {
use ratchet::RatchetState::*;
use ByNameAttribute::*;
let relative_package_file = structure::relative_file_for_package(attribute_name);
// At this point we know that `pkgs/by-name/fo/foo/package.nix` has to exists.
// This match decides whether the attribute `foo` is defined accordingly
// and whether a legacy manual definition could be removed
let manual_definition_result = match by_name_attribute {
// The attribute is missing
Missing => {
// This indicates a bug in the `pkgs/by-name` overlay, because it's supposed to
// automatically defined attributes in `pkgs/by-name`
NixpkgsProblem::UndefinedAttr {
relative_package_file: relative_package_file.to_owned(),
package_name: attribute_name.to_owned(),
}
.into()
}
// The attribute exists
Existing(AttributeInfo {
// But it's not an attribute set, which limits the amount of information we can get
// about this attribute (see ./eval.nix)
attribute_variant: AttributeVariant::NonAttributeSet,
location: _location,
}) => {
// The only thing we know is that it's definitely not a derivation, since those are
// always attribute sets.
//
// We can't know whether the attribute is automatically or manually defined for sure,
// and while we could check the location, the error seems clear enough as is.
NixpkgsProblem::NonDerivation {
relative_package_file: relative_package_file.to_owned(),
package_name: attribute_name.to_owned(),
}
.into()
}
// The attribute exists
Existing(AttributeInfo {
// And it's an attribute set, which allows us to get more information about it
attribute_variant:
AttributeVariant::AttributeSet {
is_derivation,
definition_variant,
},
location,
}) => {
// Only derivations are allowed in `pkgs/by-name`
let is_derivation_result = if is_derivation {
Success(())
} else {
NixpkgsProblem::NonDerivation {
relative_package_file: relative_package_file.to_owned(),
package_name: attribute_name.to_owned(),
}
.into()
};
// If the definition looks correct
let variant_result = match definition_variant {
// An automatic `callPackage` by the `pkgs/by-name` overlay.
// Though this gets detected by checking whether the internal
// `_internalCallByNamePackageFile` was used
DefinitionVariant::AutoDefinition => {
if let Some(_location) = location {
// Such an automatic definition should definitely not have a location
// Having one indicates that somebody is using `_internalCallByNamePackageFile`,
NixpkgsProblem::InternalCallPackageUsed {
attr_name: attribute_name.to_owned(),
}
.into()
} else {
Success(Tight)
}
}
// The attribute is manually defined, e.g. in `all-packages.nix`.
// This means we need to enforce it to look like this:
// callPackage ../pkgs/by-name/fo/foo/package.nix { ... }
DefinitionVariant::ManualDefinition {
is_semantic_call_package,
} => {
// We should expect manual definitions to have a location, otherwise we can't
// enforce the expected format
if let Some(location) = location {
// Parse the Nix file in the location
let nix_file = nix_file_store.get(&location.file)?;
// The relative path of the Nix file, for error messages
let relative_location_file = location.relative_file(nixpkgs_path).with_context(|| {
format!("Failed to resolve the file where attribute {attribute_name} is defined")
})?;
// Figure out whether it's an attribute definition of the form `= callPackage <arg1> <arg2>`,
// returning the arguments if so.
let (optional_syntactic_call_package, definition) = nix_file
.call_package_argument_info_at(location.line, location.column, nixpkgs_path)
.with_context(|| {
format!("Failed to get the definition info for attribute {attribute_name}")
})?;
by_name_override(
attribute_name,
relative_package_file,
is_semantic_call_package,
optional_syntactic_call_package,
definition,
location,
relative_location_file,
)
} else {
// If manual definitions don't have a location, it's likely `mapAttrs`'d
// over, e.g. if it's defined in aliases.nix.
// We can't verify whether its of the expected `callPackage`, so error out
NixpkgsProblem::CannotDetermineAttributeLocation {
attr_name: attribute_name.to_owned(),
}
.into()
}
}
};
// Independently report problems about whether it's a derivation and the callPackage variant
is_derivation_result.and(variant_result)
}
};
Ok(
// Packages being checked in this function are _always_ already defined in `pkgs/by-name`,
// so instead of repeating ourselves all the time to define `uses_by_name`, just set it
// once at the end with a map
manual_definition_result.map(|manual_definition| ratchet::Package {
manual_definition,
uses_by_name: Tight,
}),
)
}
/// Handles the case for packages in `pkgs/by-name` that are manually overridden, e.g. in
/// all-packages.nix
fn by_name_override(
attribute_name: &str,
expected_package_file: RelativePathBuf,
is_semantic_call_package: bool,
optional_syntactic_call_package: Option<CallPackageArgumentInfo>,
definition: String,
location: Location,
relative_location_file: RelativePathBuf,
) -> validation::Validation<ratchet::RatchetState<ratchet::ManualDefinition>> {
// At this point, we completed two different checks for whether it's a
// `callPackage`
match (is_semantic_call_package, optional_syntactic_call_package) {
// Something like `<attr> = foo`
(_, None) => NixpkgsProblem::NonSyntacticCallPackage {
package_name: attribute_name.to_owned(),
file: relative_location_file,
line: location.line,
column: location.column,
definition,
}
.into(),
// Something like `<attr> = pythonPackages.callPackage ...`
(false, Some(_)) => NixpkgsProblem::NonToplevelCallPackage {
package_name: attribute_name.to_owned(),
file: relative_location_file,
line: location.line,
column: location.column,
definition,
}
.into(),
// Something like `<attr> = pkgs.callPackage ...`
(true, Some(syntactic_call_package)) => {
if let Some(actual_package_file) = syntactic_call_package.relative_path {
if actual_package_file != expected_package_file {
// Wrong path
NixpkgsProblem::WrongCallPackagePath {
package_name: attribute_name.to_owned(),
file: relative_location_file,
line: location.line,
actual_path: actual_package_file,
expected_path: expected_package_file,
}
.into()
} else {
// Manual definitions with empty arguments are not allowed
// anymore, but existing ones should continue to be allowed
let manual_definition_ratchet = if syntactic_call_package.empty_arg {
// This is the state to migrate away from
Loose(NixpkgsProblem::EmptyArgument {
package_name: attribute_name.to_owned(),
file: relative_location_file,
line: location.line,
column: location.column,
definition,
})
} else {
// This is the state to migrate to
Tight
};
Success(manual_definition_ratchet)
}
} else {
// No path
NixpkgsProblem::NonPath {
package_name: attribute_name.to_owned(),
file: relative_location_file,
line: location.line,
column: location.column,
definition,
}
.into()
}
}
}
}
/// Handles the evaluation result for an attribute _not_ in `pkgs/by-name`,
/// turning it into a validation result.
fn handle_non_by_name_attribute(
nixpkgs_path: &Path,
nix_file_store: &mut NixFileStore,
attribute_name: &str,
non_by_name_attribute: NonByNameAttribute,
) -> validation::Result<ratchet::Package> {
use ratchet::RatchetState::*;
use NonByNameAttribute::*;
// The ratchet state whether this attribute uses `pkgs/by-name`.
// This is never `Tight`, because we only either:
// - Know that the attribute _could_ be migrated to `pkgs/by-name`, which is `Loose`
// - Or we're unsure, in which case we use NonApplicable
let uses_by_name =
// This is a big ol' match on various properties of the attribute
// First, it needs to succeed evaluation. We can't know whether an attribute could be
// migrated to `pkgs/by-name` if it doesn't evaluate, since we need to check that it's a
// derivation.
//
// This only has the minor negative effect that if a PR that breaks evaluation
// gets merged, fixing those failures won't force anything into `pkgs/by-name`.
//
// For now this isn't our problem, but in the future we
// might have another check to enforce that evaluation must not be broken.
//
// The alternative of assuming that failing attributes would have been fit for `pkgs/by-name`
// has the problem that if a package evaluation gets broken temporarily,
// fixing it requires a move to pkgs/by-name, which could happen more
// often and isn't really justified.
if let EvalSuccess(AttributeInfo {
// We're only interested in attributes that are attribute sets (which includes
// derivations). Anything else can't be in `pkgs/by-name`.
attribute_variant: AttributeVariant::AttributeSet {
// Indeed, we only care about derivations, non-derivation attribute sets can't be
// in `pkgs/by-name`
is_derivation: true,
// Of the two definition variants, really only the manual one makes sense here.
// Special cases are:
// - Manual aliases to auto-called packages are not treated as manual definitions,
// due to limitations in the semantic callPackage detection. So those should be
// ignored.
// - Manual definitions using the internal _internalCallByNamePackageFile are
// not treated as manual definitions, since _internalCallByNamePackageFile is
// used to detect automatic ones. We can't distinguish from the above case, so we
// just need to ignore this one too, even if that internal attribute should never
// be called manually.
definition_variant: DefinitionVariant::ManualDefinition { is_semantic_call_package }
},
// We need the location of the manual definition, because otherwise
// we can't figure out whether it's a syntactic callPackage
location: Some(location),
}) = non_by_name_attribute {
// Parse the Nix file in the location
let nix_file = nix_file_store.get(&location.file)?;
// The relative path of the Nix file, for error messages
let relative_location_file = location.relative_file(nixpkgs_path).with_context(|| {
format!("Failed to resolve the file where attribute {attribute_name} is defined")
})?;
// Figure out whether it's an attribute definition of the form `= callPackage <arg1> <arg2>`,
// returning the arguments if so.
let (optional_syntactic_call_package, _definition) = nix_file
.call_package_argument_info_at(
location.line,
location.column,
// Passing the Nixpkgs path here both checks that the <arg1> is within Nixpkgs, and
// strips the absolute Nixpkgs path from it, such that
// syntactic_call_package.relative_path is relative to Nixpkgs
nixpkgs_path
)
.with_context(|| {
format!("Failed to get the definition info for attribute {attribute_name}")
})?;
// At this point, we completed two different checks for whether it's a
// `callPackage`
match (is_semantic_call_package, optional_syntactic_call_package) {
// Something like `<attr> = { }`
(false, None)
// Something like `<attr> = pythonPackages.callPackage ...`
| (false, Some(_))
// Something like `<attr> = bar` where `bar = pkgs.callPackage ...`
| (true, None) => {
// In all of these cases, it's not possible to migrate the package to `pkgs/by-name`
NonApplicable
}
// Something like `<attr> = pkgs.callPackage ...`
(true, Some(syntactic_call_package)) => {
// It's only possible to migrate such a definitions if..
match syntactic_call_package.relative_path {
Some(ref rel_path) if rel_path.starts_with(utils::BASE_SUBPATH) => {
// ..the path is not already within `pkgs/by-name` like
//
// foo-variant = callPackage ../by-name/fo/foo/package.nix {
// someFlag = true;
// }
//
// While such definitions could be moved to `pkgs/by-name` by using
// `.override { someFlag = true; }` instead, this changes the semantics in
// relation with overlays, so migration is generally not possible.
//
// See also "package variants" in RFC 140:
// https://github.com/NixOS/rfcs/blob/master/rfcs/0140-simple-package-paths.md#package-variants
NonApplicable
}
_ => {
// Otherwise, the path is outside `pkgs/by-name`, which means it can be
// migrated
Loose((syntactic_call_package, relative_location_file))
}
}
}
}
} else {
// This catches all the cases not matched by the above `if let`, falling back to not being
// able to migrate such attributes
NonApplicable
};
Ok(Success(ratchet::Package {
// Packages being checked in this function _always_ need a manual definition, because
// they're not using `pkgs/by-name` which would allow avoiding it.
// so instead of repeating ourselves all the time to define `manual_definition`,
// just set it once at the end here
manual_definition: Tight,
uses_by_name,
}))
}

View File

@ -1,293 +0,0 @@
use crate::nix_file::NixFileStore;
use std::panic;
mod eval;
mod nix_file;
mod nixpkgs_problem;
mod ratchet;
mod references;
mod structure;
mod utils;
mod validation;
use crate::structure::check_structure;
use crate::validation::Validation::Failure;
use crate::validation::Validation::Success;
use anyhow::Context;
use clap::Parser;
use colored::Colorize;
use std::io;
use std::path::{Path, PathBuf};
use std::process::ExitCode;
use std::thread;
/// Program to check the validity of pkgs/by-name
///
/// This CLI interface may be changed over time if the CI workflow making use of
/// it is adjusted to deal with the change appropriately.
///
/// Exit code:
/// - `0`: If the validation is successful
/// - `1`: If the validation is not successful
/// - `2`: If an unexpected I/O error occurs
///
/// Standard error:
/// - Informative messages
/// - Detected problems if validation is not successful
#[derive(Parser, Debug)]
#[command(about, verbatim_doc_comment)]
pub struct Args {
/// Path to the main Nixpkgs to check.
/// For PRs, this should be set to a checkout of the PR branch.
nixpkgs: PathBuf,
/// Path to the base Nixpkgs to run ratchet checks against.
/// For PRs, this should be set to a checkout of the PRs base branch.
#[arg(long)]
base: PathBuf,
}
fn main() -> ExitCode {
let args = Args::parse();
match process(args.base, args.nixpkgs, false, &mut io::stderr()) {
Ok(true) => ExitCode::SUCCESS,
Ok(false) => ExitCode::from(1),
Err(e) => {
eprintln!("{} {:#}", "I/O error: ".yellow(), e);
ExitCode::from(2)
}
}
}
/// Does the actual work. This is the abstraction used both by `main` and the tests.
///
/// # Arguments
/// - `base_nixpkgs`: Path to the base Nixpkgs to run ratchet checks against.
/// - `main_nixpkgs`: Path to the main Nixpkgs to check.
/// - `keep_nix_path`: Whether the value of the NIX_PATH environment variable should be kept for
/// the evaluation stage, allowing its contents to be accessed.
/// This is used to allow the tests to access e.g. the mock-nixpkgs.nix file
/// - `error_writer`: An `io::Write` value to write validation errors to, if any.
///
/// # Return value
/// - `Err(e)` if an I/O-related error `e` occurred.
/// - `Ok(false)` if there are problems, all of which will be written to `error_writer`.
/// - `Ok(true)` if there are no problems
pub fn process<W: io::Write>(
base_nixpkgs: PathBuf,
main_nixpkgs: PathBuf,
keep_nix_path: bool,
error_writer: &mut W,
) -> anyhow::Result<bool> {
// Very easy to parallelise this, since it's totally independent
let base_thread = thread::spawn(move || check_nixpkgs(&base_nixpkgs, keep_nix_path));
let main_result = check_nixpkgs(&main_nixpkgs, keep_nix_path)?;
let base_result = match base_thread.join() {
Ok(res) => res?,
Err(e) => panic::resume_unwind(e),
};
match (base_result, main_result) {
(Failure(_), Failure(errors)) => {
// Base branch fails and the PR doesn't fix it and may also introduce additional problems
for error in errors {
writeln!(error_writer, "{}", error.to_string().red())?
}
writeln!(error_writer, "{}", "The base branch is broken and still has above problems with this PR, which need to be fixed first.\nConsider reverting the PR that introduced these problems in order to prevent more failures of unrelated PRs.".yellow())?;
Ok(false)
}
(Failure(_), Success(_)) => {
writeln!(
error_writer,
"{}",
"The base branch is broken, but this PR fixes it. Nice job!".green()
)?;
Ok(true)
}
(Success(_), Failure(errors)) => {
for error in errors {
writeln!(error_writer, "{}", error.to_string().red())?
}
writeln!(
error_writer,
"{}",
"This PR introduces the problems listed above. Please fix them before merging, otherwise the base branch would break."
.yellow()
)?;
Ok(false)
}
(Success(base), Success(main)) => {
// Both base and main branch succeed, check ratchet state
match ratchet::Nixpkgs::compare(base, main) {
Failure(errors) => {
for error in errors {
writeln!(error_writer, "{}", error.to_string().red())?
}
writeln!(error_writer, "{}", "This PR introduces additional instances of discouraged patterns as listed above. Merging is discouraged but would not break the base branch.".yellow())?;
Ok(false)
}
Success(()) => {
writeln!(error_writer, "{}", "Validated successfully".green())?;
Ok(true)
}
}
}
}
}
/// Checks whether the pkgs/by-name structure in Nixpkgs is valid.
///
/// This does not include ratchet checks, see ../README.md#ratchet-checks
/// Instead a `ratchet::Nixpkgs` value is returned, whose `compare` method allows performing the
/// ratchet check against another result.
pub fn check_nixpkgs(
nixpkgs_path: &Path,
keep_nix_path: bool,
) -> validation::Result<ratchet::Nixpkgs> {
let mut nix_file_store = NixFileStore::default();
Ok({
let nixpkgs_path = nixpkgs_path.canonicalize().with_context(|| {
format!(
"Nixpkgs path {} could not be resolved",
nixpkgs_path.display()
)
})?;
if !nixpkgs_path.join(utils::BASE_SUBPATH).exists() {
// No pkgs/by-name directory, always valid
Success(ratchet::Nixpkgs::default())
} else {
check_structure(&nixpkgs_path, &mut nix_file_store)?.result_map(|package_names|
// Only if we could successfully parse the structure, we do the evaluation checks
eval::check_values(&nixpkgs_path, &mut nix_file_store, package_names, keep_nix_path))?
}
})
}
#[cfg(test)]
mod tests {
use crate::process;
use crate::utils;
use anyhow::Context;
use std::fs;
use std::path::Path;
use tempfile::{tempdir_in, TempDir};
#[test]
fn tests_dir() -> anyhow::Result<()> {
for entry in Path::new("tests").read_dir()? {
let entry = entry?;
let path = entry.path();
let name = entry.file_name().to_string_lossy().into_owned();
if !path.is_dir() {
continue;
}
let expected_errors = fs::read_to_string(path.join("expected"))
.expect("No expected file for test {name}");
test_nixpkgs(&name, &path, &expected_errors)?;
}
Ok(())
}
// tempfile::tempdir needs to be wrapped in temp_env lock
// because it accesses TMPDIR environment variable.
pub fn tempdir() -> anyhow::Result<TempDir> {
let empty_list: [(&str, Option<&str>); 0] = [];
Ok(temp_env::with_vars(empty_list, tempfile::tempdir)?)
}
// We cannot check case-conflicting files into Nixpkgs (the channel would fail to
// build), so we generate the case-conflicting file instead.
#[test]
fn test_case_sensitive() -> anyhow::Result<()> {
let temp_nixpkgs = tempdir()?;
let path = temp_nixpkgs.path();
if is_case_insensitive_fs(&path)? {
eprintln!("We're on a case-insensitive filesystem, skipping case-sensitivity test");
return Ok(());
}
let base = path.join(utils::BASE_SUBPATH);
fs::create_dir_all(base.join("fo/foo"))?;
fs::write(base.join("fo/foo/package.nix"), "{ someDrv }: someDrv")?;
fs::create_dir_all(base.join("fo/foO"))?;
fs::write(base.join("fo/foO/package.nix"), "{ someDrv }: someDrv")?;
test_nixpkgs(
"case_sensitive",
&path,
"pkgs/by-name/fo: Duplicate case-sensitive package directories \"foO\" and \"foo\".\nThis PR introduces the problems listed above. Please fix them before merging, otherwise the base branch would break.\n",
)?;
Ok(())
}
/// Tests symlinked temporary directories.
/// This is needed because on darwin, `/tmp` is a symlink to `/private/tmp`, and Nix's
/// restrict-eval doesn't also allow access to the canonical path when you allow the
/// non-canonical one.
///
/// The error if we didn't do this would look like this:
/// error: access to canonical path '/private/var/folders/[...]/.tmpFbcNO0' is forbidden in restricted mode
#[test]
fn test_symlinked_tmpdir() -> anyhow::Result<()> {
// Create a directory with two entries:
// - actual (dir)
// - symlinked -> actual (symlink)
let temp_root = tempdir()?;
fs::create_dir(temp_root.path().join("actual"))?;
std::os::unix::fs::symlink("actual", temp_root.path().join("symlinked"))?;
let tmpdir = temp_root.path().join("symlinked");
temp_env::with_var("TMPDIR", Some(&tmpdir), || {
test_nixpkgs(
"symlinked_tmpdir",
Path::new("tests/success"),
"Validated successfully\n",
)
})
}
fn test_nixpkgs(name: &str, path: &Path, expected_errors: &str) -> anyhow::Result<()> {
let base_path = path.join("base");
let base_nixpkgs = if base_path.exists() {
base_path.as_path()
} else {
Path::new("tests/empty-base")
};
// We don't want coloring to mess up the tests
let writer = temp_env::with_var("NO_COLOR", Some("1"), || -> anyhow::Result<_> {
let mut writer = vec![];
process(base_nixpkgs.to_owned(), path.to_owned(), true, &mut writer)
.with_context(|| format!("Failed test case {name}"))?;
Ok(writer)
})?;
let actual_errors = String::from_utf8_lossy(&writer);
if actual_errors != expected_errors {
panic!(
"Failed test case {name}, expected these errors:\n=======\n{}\n=======\nbut got these:\n=======\n{}\n=======",
expected_errors, actual_errors
);
}
Ok(())
}
/// Check whether a path is in a case-insensitive filesystem
fn is_case_insensitive_fs(path: &Path) -> anyhow::Result<bool> {
let dir = tempdir_in(path)?;
let base = dir.path();
fs::write(base.join("aaa"), "")?;
Ok(base.join("AAA").exists())
}
}

View File

@ -1,555 +0,0 @@
//! This is a utility module for interacting with the syntax of Nix files
use crate::utils::LineIndex;
use anyhow::Context;
use itertools::Either::{self, Left, Right};
use relative_path::RelativePathBuf;
use rnix::ast;
use rnix::ast::Expr;
use rnix::ast::HasEntry;
use rowan::ast::AstNode;
use rowan::TextSize;
use rowan::TokenAtOffset;
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::fs::read_to_string;
use std::path::Path;
use std::path::PathBuf;
/// A structure to store parse results of Nix files in memory,
/// making sure that the same file never has to be parsed twice
#[derive(Default)]
pub struct NixFileStore {
entries: HashMap<PathBuf, NixFile>,
}
impl NixFileStore {
/// Get the store entry for a Nix file if it exists, otherwise parse the file, insert it into
/// the store, and return the value
///
/// Note that this function only gives an anyhow::Result::Err for I/O errors.
/// A parse error is anyhow::Result::Ok(Result::Err(error))
pub fn get(&mut self, path: &Path) -> anyhow::Result<&NixFile> {
match self.entries.entry(path.to_owned()) {
Entry::Occupied(entry) => Ok(entry.into_mut()),
Entry::Vacant(entry) => Ok(entry.insert(NixFile::new(path)?)),
}
}
}
/// A structure for storing a successfully parsed Nix file
pub struct NixFile {
/// The parent directory of the Nix file, for more convenient error handling
pub parent_dir: PathBuf,
/// The path to the file itself, for errors
pub path: PathBuf,
pub syntax_root: rnix::Root,
pub line_index: LineIndex,
}
impl NixFile {
/// Creates a new NixFile, failing for I/O or parse errors
fn new(path: impl AsRef<Path>) -> anyhow::Result<NixFile> {
let Some(parent_dir) = path.as_ref().parent() else {
anyhow::bail!("Could not get parent of path {}", path.as_ref().display())
};
let contents = read_to_string(&path)
.with_context(|| format!("Could not read file {}", path.as_ref().display()))?;
let line_index = LineIndex::new(&contents);
// NOTE: There's now another Nixpkgs CI check to make sure all changed Nix files parse
// correctly, though that uses mainline Nix instead of rnix, so it doesn't give the same
// errors. In the future we should unify these two checks, ideally moving the other CI
// check into this tool as well and checking for both mainline Nix and rnix.
rnix::Root::parse(&contents)
// rnix's ::ok returns Result<_, _> , so no error is thrown away like it would be with
// std::result's ::ok
.ok()
.map(|syntax_root| NixFile {
parent_dir: parent_dir.to_path_buf(),
path: path.as_ref().to_owned(),
syntax_root,
line_index,
})
.with_context(|| format!("Could not parse file {} with rnix", path.as_ref().display()))
}
}
/// Information about callPackage arguments
#[derive(Debug, PartialEq)]
pub struct CallPackageArgumentInfo {
/// The relative path of the first argument, or `None` if it's not a path.
pub relative_path: Option<RelativePathBuf>,
/// Whether the second argument is an empty attribute set
pub empty_arg: bool,
}
impl NixFile {
/// Returns information about callPackage arguments for an attribute at a specific line/column
/// index.
/// If the definition at the given location is not of the form `<attr> = callPackage <arg1> <arg2>;`,
/// `Ok((None, String))` is returned, with `String` being the definition itself.
///
/// This function only returns `Err` for problems that can't be caused by the Nix contents,
/// but rather problems in this programs code itself.
///
/// This is meant to be used with the location returned from `builtins.unsafeGetAttrPos`, e.g.:
/// - Create file `default.nix` with contents
/// ```nix
/// self: {
/// foo = self.callPackage ./default.nix { };
/// }
/// ```
/// - Evaluate
/// ```nix
/// builtins.unsafeGetAttrPos "foo" (import ./default.nix { })
/// ```
/// results in `{ file = ./default.nix; line = 2; column = 3; }`
/// - Get the NixFile for `.file` from a `NixFileStore`
/// - Call this function with `.line`, `.column` and `relative_to` as the (absolute) current directory
///
/// You'll get back
/// ```rust
/// Ok((
/// Some(CallPackageArgumentInfo { path = Some("default.nix"), empty_arg: true }),
/// "foo = self.callPackage ./default.nix { };",
/// ))
/// ```
///
/// Note that this also returns the same for `pythonPackages.callPackage`. It doesn't make an
/// attempt at distinguishing this.
pub fn call_package_argument_info_at(
&self,
line: usize,
column: usize,
relative_to: &Path,
) -> anyhow::Result<(Option<CallPackageArgumentInfo>, String)> {
Ok(match self.attrpath_value_at(line, column)? {
Left(definition) => (None, definition),
Right(attrpath_value) => {
let definition = attrpath_value.to_string();
let attrpath_value =
self.attrpath_value_call_package_argument_info(attrpath_value, relative_to)?;
(attrpath_value, definition)
}
})
}
// Internal function mainly to make it independently testable
fn attrpath_value_at(
&self,
line: usize,
column: usize,
) -> anyhow::Result<Either<String, ast::AttrpathValue>> {
let index = self.line_index.fromlinecolumn(line, column);
let token_at_offset = self
.syntax_root
.syntax()
.token_at_offset(TextSize::from(index as u32));
// The token_at_offset function takes indices to mean a location _between_ characters,
// which in this case is some spacing followed by the attribute name:
//
// foo = 10;
// /\
// This is the token offset, we get both the (newline + indentation) on the left side,
// and the attribute name on the right side.
let TokenAtOffset::Between(_space, token) = token_at_offset else {
anyhow::bail!("Line {line} column {column} in {} is not the start of a token, but rather {token_at_offset:?}", self.path.display())
};
// token looks like "foo"
let Some(node) = token.parent() else {
anyhow::bail!(
"Token on line {line} column {column} in {} does not have a parent node: {token:?}",
self.path.display()
)
};
if ast::Attr::can_cast(node.kind()) {
// Something like `foo`, `"foo"` or `${"foo"}`
} else if ast::Inherit::can_cast(node.kind()) {
// Something like `inherit <attr>` or `inherit (<source>) <attr>`
// This is the only other way how `builtins.unsafeGetAttrPos` can return
// attribute positions, but we only look for ones like `<attr-path> = <value>`, so
// ignore this
return Ok(Left(node.to_string()));
} else {
// However, anything else is not expected and smells like a bug
anyhow::bail!(
"Node in {} is neither an attribute node nor an inherit node: {node:?}",
self.path.display()
)
}
// node looks like "foo"
let Some(attrpath_node) = node.parent() else {
anyhow::bail!(
"Node in {} does not have a parent node: {node:?}",
self.path.display()
)
};
if !ast::Attrpath::can_cast(attrpath_node.kind()) {
// We know that `node` is an attribute, its parent should be an attribute path
anyhow::bail!(
"In {}, attribute parent node is not an attribute path node: {attrpath_node:?}",
self.path.display()
)
}
// attrpath_node looks like "foo.bar"
let Some(attrpath_value_node) = attrpath_node.parent() else {
anyhow::bail!(
"Attribute path node in {} does not have a parent node: {attrpath_node:?}",
self.path.display()
)
};
if !ast::AttrpathValue::can_cast(attrpath_value_node.kind()) {
anyhow::bail!(
"Node in {} is not an attribute path value node: {attrpath_value_node:?}",
self.path.display()
)
}
// attrpath_value_node looks like "foo.bar = 10;"
// unwrap is fine because we confirmed that we can cast with the above check.
// We could avoid this `unwrap` for a `clone`, since `cast` consumes the argument,
// but we still need it for the error message when the cast fails.
Ok(Right(
ast::AttrpathValue::cast(attrpath_value_node).unwrap(),
))
}
// Internal function mainly to make attrpath_value_at independently testable
fn attrpath_value_call_package_argument_info(
&self,
attrpath_value: ast::AttrpathValue,
relative_to: &Path,
) -> anyhow::Result<Option<CallPackageArgumentInfo>> {
let Some(attrpath) = attrpath_value.attrpath() else {
anyhow::bail!("attrpath value node doesn't have an attrpath: {attrpath_value:?}")
};
// At this point we know it's something like `foo...bar = ...`
if attrpath.attrs().count() > 1 {
// If the attribute path has multiple entries, the left-most entry is an attribute and
// can't be a `callPackage`.
//
// FIXME: `builtins.unsafeGetAttrPos` will return the same position for all attribute
// paths and we can't really know which one it is. We could have a case like
// `foo.bar = callPackage ... { }` and trying to determine if `bar` is a `callPackage`,
// where this is not correct.
// However, this case typically doesn't occur anyways,
// because top-level packages wouldn't be nested under an attribute set.
return Ok(None);
}
let Some(value) = attrpath_value.value() else {
anyhow::bail!("attrpath value node doesn't have a value: {attrpath_value:?}")
};
// At this point we know it's something like `foo = ...`
let Expr::Apply(apply1) = value else {
// Not even a function call, instead something like `foo = null`
return Ok(None);
};
let Some(function1) = apply1.lambda() else {
anyhow::bail!("apply node doesn't have a lambda: {apply1:?}")
};
let Some(arg1) = apply1.argument() else {
anyhow::bail!("apply node doesn't have an argument: {apply1:?}")
};
// At this point we know it's something like `foo = <fun> <arg>`.
// For a callPackage, `<fun>` would be `callPackage ./file` and `<arg>` would be `{ }`
let empty_arg = if let Expr::AttrSet(attrset) = arg1 {
// We can only statically determine whether the argument is empty if it's an attribute
// set _expression_, even though other kind of expressions could evaluate to an attribute
// set _value_. But this is what we want anyways
attrset.entries().next().is_none()
} else {
false
};
// Because callPackage takes two curried arguments, the first function needs to be a
// function call itself
let Expr::Apply(apply2) = function1 else {
// Not a callPackage, instead something like `foo = import ./foo`
return Ok(None);
};
let Some(function2) = apply2.lambda() else {
anyhow::bail!("apply node doesn't have a lambda: {apply2:?}")
};
let Some(arg2) = apply2.argument() else {
anyhow::bail!("apply node doesn't have an argument: {apply2:?}")
};
// At this point we know it's something like `foo = <fun2> <arg2> <arg1>`.
// For a callPackage, `<fun2>` would be `callPackage`, `<arg2>` would be `./file`
// Check that <arg2> is a path expression
let path = if let Expr::Path(actual_path) = arg2 {
// Try to statically resolve the path and turn it into a nixpkgs-relative path
if let ResolvedPath::Within(p) = self.static_resolve_path(actual_path, relative_to) {
Some(p)
} else {
// We can't statically know an existing path inside Nixpkgs used as <arg2>
None
}
} else {
// <arg2> is not a path, but rather e.g. an inline expression
None
};
// Check that <fun2> is an identifier, or an attribute path with an identifier at the end
let ident = match function2 {
Expr::Ident(ident) => {
// This means it's something like `foo = callPackage <arg2> <arg1>`
ident
}
Expr::Select(select) => {
// This means it's something like `foo = self.callPackage <arg2> <arg1>`.
// We also end up here for e.g. `pythonPackages.callPackage`, but the
// callPackage-mocking method will take care of not triggering for this case.
if select.default_expr().is_some() {
// Very odd case, but this would be `foo = self.callPackage or true ./test.nix {}
// (yes this is valid Nix code)
return Ok(None);
}
let Some(attrpath) = select.attrpath() else {
anyhow::bail!("select node doesn't have an attrpath: {select:?}")
};
let Some(last) = attrpath.attrs().last() else {
// This case shouldn't be possible, it would be `foo = self. ./test.nix {}`,
// which shouldn't parse
anyhow::bail!("select node has an empty attrpath: {select:?}")
};
if let ast::Attr::Ident(ident) = last {
ident
} else {
// Here it's something like `foo = self."callPackage" /test.nix {}`
// which we're not gonna bother with
return Ok(None);
}
}
// Any other expression we're not gonna treat as callPackage
_ => return Ok(None),
};
let Some(token) = ident.ident_token() else {
anyhow::bail!("ident node doesn't have a token: {ident:?}")
};
if token.text() == "callPackage" {
Ok(Some(CallPackageArgumentInfo {
relative_path: path,
empty_arg,
}))
} else {
Ok(None)
}
}
}
/// The result of trying to statically resolve a Nix path expression
pub enum ResolvedPath {
/// Something like `./foo/${bar}/baz`, can't be known statically
Interpolated,
/// Something like `<nixpkgs>`, can't be known statically
SearchPath,
/// Path couldn't be resolved due to an IO error,
/// e.g. if the path doesn't exist or you don't have the right permissions
Unresolvable(std::io::Error),
/// The path is outside the given absolute path
Outside,
/// The path is within the given absolute path.
/// The `RelativePathBuf` is the relative path under the given absolute path.
Within(RelativePathBuf),
}
impl NixFile {
/// Statically resolves a Nix path expression and checks that it's within an absolute path
///
/// E.g. for the path expression `./bar.nix` in `./foo.nix` and an absolute path of the
/// current directory, the function returns `ResolvedPath::Within(./bar.nix)`
pub fn static_resolve_path(&self, node: ast::Path, relative_to: &Path) -> ResolvedPath {
if node.parts().count() != 1 {
// If there's more than 1 interpolated part, it's of the form `./foo/${bar}/baz`.
return ResolvedPath::Interpolated;
}
let text = node.to_string();
if text.starts_with('<') {
// A search path like `<nixpkgs>`. There doesn't appear to be better way to detect
// these in rnix
return ResolvedPath::SearchPath;
}
// Join the file's parent directory and the path expression, then resolve it
// FIXME: Expressions like `../../../../foo/bar/baz/qux` or absolute paths
// may resolve close to the original file, but may have left the relative_to.
// That should be checked more strictly
match self.parent_dir.join(Path::new(&text)).canonicalize() {
Err(resolution_error) => ResolvedPath::Unresolvable(resolution_error),
Ok(resolved) => {
// Check if it's within relative_to
match resolved.strip_prefix(relative_to) {
Err(_prefix_error) => ResolvedPath::Outside,
Ok(suffix) => ResolvedPath::Within(
RelativePathBuf::from_path(suffix).expect("a relative path"),
),
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests;
use indoc::indoc;
#[test]
fn detects_attributes() -> anyhow::Result<()> {
let temp_dir = tests::tempdir()?;
let file = temp_dir.path().join("file.nix");
let contents = indoc! {r#"
toInherit: {
foo = 1;
"bar" = 2;
${"baz"} = 3;
"${"qux"}" = 4;
# A
quux
# B
=
# C
5
# D
;
# E
/**/quuux/**/=/**/5/**/;/*E*/
inherit toInherit;
inherit (toInherit) toInherit;
}
"#};
std::fs::write(&file, contents)?;
let nix_file = NixFile::new(&file)?;
// These are builtins.unsafeGetAttrPos locations for the attributes
let cases = [
(2, 3, Right("foo = 1;")),
(3, 3, Right(r#""bar" = 2;"#)),
(4, 3, Right(r#"${"baz"} = 3;"#)),
(5, 3, Right(r#""${"qux"}" = 4;"#)),
(8, 3, Right("quux\n # B\n =\n # C\n 5\n # D\n ;")),
(17, 7, Right("quuux/**/=/**/5/**/;")),
(19, 10, Left("inherit toInherit;")),
(20, 22, Left("inherit (toInherit) toInherit;")),
];
for (line, column, expected_result) in cases {
let actual_result = nix_file
.attrpath_value_at(line, column)
.context(format!("line {line}, column {column}"))?
.map_right(|node| node.to_string());
let owned_expected_result = expected_result
.map(|x| x.to_string())
.map_left(|x| x.to_string());
assert_eq!(
actual_result, owned_expected_result,
"line {line}, column {column}"
);
}
Ok(())
}
#[test]
fn detects_call_package() -> anyhow::Result<()> {
let temp_dir = tests::tempdir()?;
let file = temp_dir.path().join("file.nix");
let contents = indoc! {r#"
self: with self; {
a.sub = null;
b = null;
c = import ./file.nix;
d = import ./file.nix { };
e = pythonPackages.callPackage ./file.nix { };
f = callPackage ./file.nix { };
g = callPackage ({ }: { }) { };
h = callPackage ./file.nix { x = 0; };
i = callPackage ({ }: { }) (let in { });
}
"#};
std::fs::write(&file, contents)?;
let nix_file = NixFile::new(&file)?;
let cases = [
(2, None),
(3, None),
(4, None),
(5, None),
(
6,
Some(CallPackageArgumentInfo {
relative_path: Some(RelativePathBuf::from("file.nix")),
empty_arg: true,
}),
),
(
7,
Some(CallPackageArgumentInfo {
relative_path: Some(RelativePathBuf::from("file.nix")),
empty_arg: true,
}),
),
(
8,
Some(CallPackageArgumentInfo {
relative_path: None,
empty_arg: true,
}),
),
(
9,
Some(CallPackageArgumentInfo {
relative_path: Some(RelativePathBuf::from("file.nix")),
empty_arg: false,
}),
),
(
10,
Some(CallPackageArgumentInfo {
relative_path: None,
empty_arg: false,
}),
),
];
for (line, expected_result) in cases {
let (actual_result, _definition) = nix_file
.call_package_argument_info_at(line, 3, temp_dir.path())
.context(format!("line {line}"))?;
assert_eq!(actual_result, expected_result, "line {line}");
}
Ok(())
}
}

View File

@ -1,425 +0,0 @@
use crate::structure;
use crate::utils::PACKAGE_NIX_FILENAME;
use indoc::writedoc;
use relative_path::RelativePath;
use relative_path::RelativePathBuf;
use std::ffi::OsString;
use std::fmt;
/// Any problem that can occur when checking Nixpkgs
/// All paths are relative to Nixpkgs such that the error messages can't be influenced by Nixpkgs absolute
/// location
#[derive(Clone)]
pub enum NixpkgsProblem {
ShardNonDir {
relative_shard_path: RelativePathBuf,
},
InvalidShardName {
relative_shard_path: RelativePathBuf,
shard_name: String,
},
PackageNonDir {
relative_package_dir: RelativePathBuf,
},
CaseSensitiveDuplicate {
relative_shard_path: RelativePathBuf,
first: OsString,
second: OsString,
},
InvalidPackageName {
relative_package_dir: RelativePathBuf,
package_name: String,
},
IncorrectShard {
relative_package_dir: RelativePathBuf,
correct_relative_package_dir: RelativePathBuf,
},
PackageNixNonExistent {
relative_package_dir: RelativePathBuf,
},
PackageNixDir {
relative_package_dir: RelativePathBuf,
},
UndefinedAttr {
relative_package_file: RelativePathBuf,
package_name: String,
},
EmptyArgument {
package_name: String,
file: RelativePathBuf,
line: usize,
column: usize,
definition: String,
},
NonToplevelCallPackage {
package_name: String,
file: RelativePathBuf,
line: usize,
column: usize,
definition: String,
},
NonPath {
package_name: String,
file: RelativePathBuf,
line: usize,
column: usize,
definition: String,
},
WrongCallPackagePath {
package_name: String,
file: RelativePathBuf,
line: usize,
actual_path: RelativePathBuf,
expected_path: RelativePathBuf,
},
NonSyntacticCallPackage {
package_name: String,
file: RelativePathBuf,
line: usize,
column: usize,
definition: String,
},
NonDerivation {
relative_package_file: RelativePathBuf,
package_name: String,
},
OutsideSymlink {
relative_package_dir: RelativePathBuf,
subpath: RelativePathBuf,
},
UnresolvableSymlink {
relative_package_dir: RelativePathBuf,
subpath: RelativePathBuf,
io_error: String,
},
PathInterpolation {
relative_package_dir: RelativePathBuf,
subpath: RelativePathBuf,
line: usize,
text: String,
},
SearchPath {
relative_package_dir: RelativePathBuf,
subpath: RelativePathBuf,
line: usize,
text: String,
},
OutsidePathReference {
relative_package_dir: RelativePathBuf,
subpath: RelativePathBuf,
line: usize,
text: String,
},
UnresolvablePathReference {
relative_package_dir: RelativePathBuf,
subpath: RelativePathBuf,
line: usize,
text: String,
io_error: String,
},
MovedOutOfByNameEmptyArg {
package_name: String,
call_package_path: Option<RelativePathBuf>,
file: RelativePathBuf,
},
MovedOutOfByNameNonEmptyArg {
package_name: String,
call_package_path: Option<RelativePathBuf>,
file: RelativePathBuf,
},
NewPackageNotUsingByNameEmptyArg {
package_name: String,
call_package_path: Option<RelativePathBuf>,
file: RelativePathBuf,
},
NewPackageNotUsingByNameNonEmptyArg {
package_name: String,
call_package_path: Option<RelativePathBuf>,
file: RelativePathBuf,
},
InternalCallPackageUsed {
attr_name: String,
},
CannotDetermineAttributeLocation {
attr_name: String,
},
}
impl fmt::Display for NixpkgsProblem {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
NixpkgsProblem::ShardNonDir { relative_shard_path } =>
write!(
f,
"{relative_shard_path}: This is a file, but it should be a directory.",
),
NixpkgsProblem::InvalidShardName { relative_shard_path, shard_name } =>
write!(
f,
"{relative_shard_path}: Invalid directory name \"{shard_name}\", must be at most 2 ASCII characters consisting of a-z, 0-9, \"-\" or \"_\".",
),
NixpkgsProblem::PackageNonDir { relative_package_dir } =>
write!(
f,
"{relative_package_dir}: This path is a file, but it should be a directory.",
),
NixpkgsProblem::CaseSensitiveDuplicate { relative_shard_path, first, second } =>
write!(
f,
"{relative_shard_path}: Duplicate case-sensitive package directories {first:?} and {second:?}.",
),
NixpkgsProblem::InvalidPackageName { relative_package_dir, package_name } =>
write!(
f,
"{relative_package_dir}: Invalid package directory name \"{package_name}\", must be ASCII characters consisting of a-z, A-Z, 0-9, \"-\" or \"_\".",
),
NixpkgsProblem::IncorrectShard { relative_package_dir, correct_relative_package_dir } =>
write!(
f,
"{relative_package_dir}: Incorrect directory location, should be {correct_relative_package_dir} instead.",
),
NixpkgsProblem::PackageNixNonExistent { relative_package_dir } =>
write!(
f,
"{relative_package_dir}: Missing required \"{PACKAGE_NIX_FILENAME}\" file.",
),
NixpkgsProblem::PackageNixDir { relative_package_dir } =>
write!(
f,
"{relative_package_dir}: \"{PACKAGE_NIX_FILENAME}\" must be a file.",
),
NixpkgsProblem::UndefinedAttr { relative_package_file, package_name } =>
write!(
f,
"pkgs.{package_name}: This attribute is not defined but it should be defined automatically as {relative_package_file}",
),
NixpkgsProblem::EmptyArgument { package_name, file, line, column, definition } => {
let relative_package_dir = structure::relative_dir_for_package(package_name);
let relative_package_file = structure::relative_file_for_package(package_name);
let indented_definition = indent_definition(*column, definition.clone());
writedoc!(
f,
"
- Because {relative_package_dir} exists, the attribute `pkgs.{package_name}` must be defined like
{package_name} = callPackage ./{relative_package_file} {{ /* ... */ }};
However, in this PR, the second argument is empty. See the definition in {file}:{line}:
{indented_definition}
Such a definition is provided automatically and therefore not necessary. Please remove it.
",
)
}
NixpkgsProblem::NonToplevelCallPackage { package_name, file, line, column, definition } => {
let relative_package_dir = structure::relative_dir_for_package(package_name);
let relative_package_file = structure::relative_file_for_package(package_name);
let indented_definition = indent_definition(*column, definition.clone());
writedoc!(
f,
"
- Because {relative_package_dir} exists, the attribute `pkgs.{package_name}` must be defined like
{package_name} = callPackage ./{relative_package_file} {{ /* ... */ }};
However, in this PR, a different `callPackage` is used. See the definition in {file}:{line}:
{indented_definition}
",
)
}
NixpkgsProblem::NonPath { package_name, file, line, column, definition } => {
let relative_package_dir = structure::relative_dir_for_package(package_name);
let relative_package_file = structure::relative_file_for_package(package_name);
let indented_definition = indent_definition(*column, definition.clone());
writedoc!(
f,
"
- Because {relative_package_dir} exists, the attribute `pkgs.{package_name}` must be defined like
{package_name} = callPackage ./{relative_package_file} {{ /* ... */ }};
However, in this PR, the first `callPackage` argument is not a path. See the definition in {file}:{line}:
{indented_definition}
",
)
}
NixpkgsProblem::WrongCallPackagePath { package_name, file, line, actual_path, expected_path } => {
let relative_package_dir = structure::relative_dir_for_package(package_name);
let expected_path_expr = create_path_expr(file, expected_path);
let actual_path_expr = create_path_expr(file, actual_path);
writedoc! {
f,
"
- Because {relative_package_dir} exists, the attribute `pkgs.{package_name}` must be defined like
{package_name} = callPackage {expected_path_expr} {{ /* ... */ }};
However, in this PR, the first `callPackage` argument is the wrong path. See the definition in {file}:{line}:
{package_name} = callPackage {actual_path_expr} {{ /* ... */ }};
",
}
}
NixpkgsProblem::NonSyntacticCallPackage { package_name, file, line, column, definition } => {
let relative_package_dir = structure::relative_dir_for_package(package_name);
let relative_package_file = structure::relative_file_for_package(package_name);
let indented_definition = indent_definition(*column, definition.clone());
writedoc!(
f,
"
- Because {relative_package_dir} exists, the attribute `pkgs.{package_name}` must be defined like
{package_name} = callPackage ./{relative_package_file} {{ /* ... */ }};
However, in this PR, it isn't defined that way. See the definition in {file}:{line}
{indented_definition}
",
)
}
NixpkgsProblem::NonDerivation { relative_package_file, package_name } =>
write!(
f,
"pkgs.{package_name}: This attribute defined by {relative_package_file} is not a derivation",
),
NixpkgsProblem::OutsideSymlink { relative_package_dir, subpath } =>
write!(
f,
"{relative_package_dir}: Path {subpath} is a symlink pointing to a path outside the directory of that package.",
),
NixpkgsProblem::UnresolvableSymlink { relative_package_dir, subpath, io_error } =>
write!(
f,
"{relative_package_dir}: Path {subpath} is a symlink which cannot be resolved: {io_error}.",
),
NixpkgsProblem::PathInterpolation { relative_package_dir, subpath, line, text } =>
write!(
f,
"{relative_package_dir}: File {subpath} at line {line} contains the path expression \"{text}\", which is not yet supported and may point outside the directory of that package.",
),
NixpkgsProblem::SearchPath { relative_package_dir, subpath, line, text } =>
write!(
f,
"{relative_package_dir}: File {subpath} at line {line} contains the nix search path expression \"{text}\" which may point outside the directory of that package.",
),
NixpkgsProblem::OutsidePathReference { relative_package_dir, subpath, line, text } =>
write!(
f,
"{relative_package_dir}: File {subpath} at line {line} contains the path expression \"{text}\" which may point outside the directory of that package.",
),
NixpkgsProblem::UnresolvablePathReference { relative_package_dir, subpath, line, text, io_error } =>
write!(
f,
"{relative_package_dir}: File {subpath} at line {line} contains the path expression \"{text}\" which cannot be resolved: {io_error}.",
),
NixpkgsProblem::MovedOutOfByNameEmptyArg { package_name, call_package_path, file } => {
let call_package_arg =
if let Some(path) = &call_package_path {
format!("./{path}")
} else {
"...".into()
};
let relative_package_file = structure::relative_file_for_package(package_name);
writedoc!(
f,
"
- Attribute `pkgs.{package_name}` was previously defined in {relative_package_file}, but is now manually defined as `callPackage {call_package_arg} {{ /* ... */ }}` in {file}.
Please move the package back and remove the manual `callPackage`.
",
)
},
NixpkgsProblem::MovedOutOfByNameNonEmptyArg { package_name, call_package_path, file } => {
let call_package_arg =
if let Some(path) = &call_package_path {
format!("./{}", path)
} else {
"...".into()
};
let relative_package_file = structure::relative_file_for_package(package_name);
// This can happen if users mistakenly assume that for custom arguments,
// pkgs/by-name can't be used.
writedoc!(
f,
"
- Attribute `pkgs.{package_name}` was previously defined in {relative_package_file}, but is now manually defined as `callPackage {call_package_arg} {{ ... }}` in {file}.
While the manual `callPackage` is still needed, it's not necessary to move the package files.
",
)
},
NixpkgsProblem::NewPackageNotUsingByNameEmptyArg { package_name, call_package_path, file } => {
let call_package_arg =
if let Some(path) = &call_package_path {
format!("./{}", path)
} else {
"...".into()
};
let relative_package_file = structure::relative_file_for_package(package_name);
writedoc!(
f,
"
- Attribute `pkgs.{package_name}` is a new top-level package using `pkgs.callPackage {call_package_arg} {{ /* ... */ }}`.
Please define it in {relative_package_file} instead.
See `pkgs/by-name/README.md` for more details.
Since the second `callPackage` argument is `{{ }}`, no manual `callPackage` in {file} is needed anymore.
",
)
},
NixpkgsProblem::NewPackageNotUsingByNameNonEmptyArg { package_name, call_package_path, file } => {
let call_package_arg =
if let Some(path) = &call_package_path {
format!("./{}", path)
} else {
"...".into()
};
let relative_package_file = structure::relative_file_for_package(package_name);
writedoc!(
f,
"
- Attribute `pkgs.{package_name}` is a new top-level package using `pkgs.callPackage {call_package_arg} {{ /* ... */ }}`.
Please define it in {relative_package_file} instead.
See `pkgs/by-name/README.md` for more details.
Since the second `callPackage` argument is not `{{ }}`, the manual `callPackage` in {file} is still needed.
",
)
},
NixpkgsProblem::InternalCallPackageUsed { attr_name } =>
write!(
f,
"pkgs.{attr_name}: This attribute is defined using `_internalCallByNamePackageFile`, which is an internal function not intended for manual use.",
),
NixpkgsProblem::CannotDetermineAttributeLocation { attr_name } =>
write!(
f,
"pkgs.{attr_name}: Cannot determine the location of this attribute using `builtins.unsafeGetAttrPos`.",
),
}
}
}
fn indent_definition(column: usize, definition: String) -> String {
// The entire code should be indented 4 spaces
textwrap::indent(
// But first we want to strip the code's natural indentation
&textwrap::dedent(
// The definition _doesn't_ include the leading spaces, but we can
// recover those from the column
&format!("{}{definition}", " ".repeat(column - 1)),
),
" ",
)
}
/// Creates a Nix path expression that when put into Nix file `from_file`, would point to the `to_file`.
fn create_path_expr(
from_file: impl AsRef<RelativePath>,
to_file: impl AsRef<RelativePath>,
) -> String {
// This `expect` calls should never trigger because we only call this function with files.
// That's why we `expect` them!
let from = from_file.as_ref().parent().expect("a parent for this path");
let rel = from.relative(to_file);
format!("./{rel}")
}

View File

@ -1,184 +0,0 @@
//! This module implements the ratchet checks, see ../README.md#ratchet-checks
//!
//! Each type has a `compare` method that validates the ratchet checks for that item.
use crate::nix_file::CallPackageArgumentInfo;
use crate::nixpkgs_problem::NixpkgsProblem;
use crate::validation::{self, Validation, Validation::Success};
use relative_path::RelativePathBuf;
use std::collections::HashMap;
/// The ratchet value for the entirety of Nixpkgs.
#[derive(Default)]
pub struct Nixpkgs {
/// Sorted list of packages in package_map
pub package_names: Vec<String>,
/// The ratchet values for all packages
pub package_map: HashMap<String, Package>,
}
impl Nixpkgs {
/// Validates the ratchet checks for Nixpkgs
pub fn compare(from: Self, to: Self) -> Validation<()> {
validation::sequence_(
// We only loop over the current attributes,
// we don't need to check ones that were removed
to.package_names.into_iter().map(|name| {
Package::compare(&name, from.package_map.get(&name), &to.package_map[&name])
}),
)
}
}
/// The ratchet value for a top-level package
pub struct Package {
/// The ratchet value for the check for non-auto-called empty arguments
pub manual_definition: RatchetState<ManualDefinition>,
/// The ratchet value for the check for new packages using pkgs/by-name
pub uses_by_name: RatchetState<UsesByName>,
}
impl Package {
/// Validates the ratchet checks for a top-level package
pub fn compare(name: &str, optional_from: Option<&Self>, to: &Self) -> Validation<()> {
validation::sequence_([
RatchetState::<ManualDefinition>::compare(
name,
optional_from.map(|x| &x.manual_definition),
&to.manual_definition,
),
RatchetState::<UsesByName>::compare(
name,
optional_from.map(|x| &x.uses_by_name),
&to.uses_by_name,
),
])
}
}
/// The ratchet state of a generic ratchet check.
pub enum RatchetState<Ratchet: ToNixpkgsProblem> {
/// The ratchet is loose, it can be tightened more.
/// In other words, this is the legacy state we're trying to move away from.
/// Introducing new instances is not allowed but previous instances will continue to be allowed.
/// The `Context` is context for error messages in case a new instance of this state is
/// introduced
Loose(Ratchet::ToContext),
/// The ratchet is tight, it can't be tightened any further.
/// This is either because we already use the latest state, or because the ratchet isn't
/// relevant.
Tight,
/// This ratchet can't be applied.
/// State transitions from/to NonApplicable are always allowed
NonApplicable,
}
/// A trait that can convert an attribute-specific error context into a NixpkgsProblem
pub trait ToNixpkgsProblem {
/// Context relating to the Nixpkgs that is being transitioned _to_
type ToContext;
/// How to convert an attribute-specific error context into a NixpkgsProblem
fn to_nixpkgs_problem(
name: &str,
optional_from: Option<()>,
to: &Self::ToContext,
) -> NixpkgsProblem;
}
impl<Context: ToNixpkgsProblem> RatchetState<Context> {
/// Compare the previous ratchet state of an attribute to the new state.
/// The previous state may be `None` in case the attribute is new.
fn compare(name: &str, optional_from: Option<&Self>, to: &Self) -> Validation<()> {
match (optional_from, to) {
// Loosening a ratchet is now allowed
(Some(RatchetState::Tight), RatchetState::Loose(loose_context)) => {
Context::to_nixpkgs_problem(name, Some(()), loose_context).into()
}
// Introducing a loose ratchet is also not allowed
(None, RatchetState::Loose(loose_context)) => {
Context::to_nixpkgs_problem(name, None, loose_context).into()
}
// Everything else is allowed, including:
// - Loose -> Loose (grandfathering policy for a loose ratchet)
// - -> Tight (always okay to keep or make the ratchet tight)
// - Anything involving NotApplicable, where we can't really make any good calls
_ => Success(()),
}
}
}
/// The ratchet to check whether a top-level attribute has/needs
/// a manual definition, e.g. in all-packages.nix.
///
/// This ratchet is only tight for attributes that:
/// - Are not defined in `pkgs/by-name`, and rely on a manual definition
/// - Are defined in `pkgs/by-name` without any manual definition,
/// (no custom argument overrides)
/// - Are defined with `pkgs/by-name` with a manual definition that can't be removed
/// because it provides custom argument overrides
///
/// In comparison, this ratchet is loose for attributes that:
/// - Are defined in `pkgs/by-name` with a manual definition
/// that doesn't have any custom argument overrides
pub enum ManualDefinition {}
impl ToNixpkgsProblem for ManualDefinition {
type ToContext = NixpkgsProblem;
fn to_nixpkgs_problem(
_name: &str,
_optional_from: Option<()>,
to: &Self::ToContext,
) -> NixpkgsProblem {
(*to).clone()
}
}
/// The ratchet value of an attribute
/// for the check that new packages use pkgs/by-name
///
/// This checks that all new package defined using callPackage must be defined via pkgs/by-name
/// It also checks that once a package uses pkgs/by-name, it can't switch back to all-packages.nix
pub enum UsesByName {}
impl ToNixpkgsProblem for UsesByName {
type ToContext = (CallPackageArgumentInfo, RelativePathBuf);
fn to_nixpkgs_problem(
name: &str,
optional_from: Option<()>,
(to, file): &Self::ToContext,
) -> NixpkgsProblem {
if let Some(()) = optional_from {
if to.empty_arg {
NixpkgsProblem::MovedOutOfByNameEmptyArg {
package_name: name.to_owned(),
call_package_path: to.relative_path.clone(),
file: file.to_owned(),
}
} else {
NixpkgsProblem::MovedOutOfByNameNonEmptyArg {
package_name: name.to_owned(),
call_package_path: to.relative_path.clone(),
file: file.to_owned(),
}
}
} else if to.empty_arg {
NixpkgsProblem::NewPackageNotUsingByNameEmptyArg {
package_name: name.to_owned(),
call_package_path: to.relative_path.clone(),
file: file.to_owned(),
}
} else {
NixpkgsProblem::NewPackageNotUsingByNameNonEmptyArg {
package_name: name.to_owned(),
call_package_path: to.relative_path.clone(),
file: file.to_owned(),
}
}
}
}

View File

@ -1,176 +0,0 @@
use crate::nixpkgs_problem::NixpkgsProblem;
use crate::utils;
use crate::validation::{self, ResultIteratorExt, Validation::Success};
use crate::NixFileStore;
use relative_path::RelativePath;
use anyhow::Context;
use rowan::ast::AstNode;
use std::ffi::OsStr;
use std::path::Path;
/// Check that every package directory in pkgs/by-name doesn't link to outside that directory.
/// Both symlinks and Nix path expressions are checked.
pub fn check_references(
nix_file_store: &mut NixFileStore,
relative_package_dir: &RelativePath,
absolute_package_dir: &Path,
) -> validation::Result<()> {
// The first subpath to check is the package directory itself, which we can represent as an
// empty path, since the absolute package directory gets prepended to this.
// We don't use `./.` to keep the error messages cleaner
// (there's no canonicalisation going on underneath)
let subpath = RelativePath::new("");
check_path(
nix_file_store,
relative_package_dir,
absolute_package_dir,
subpath,
)
.with_context(|| {
format!(
"While checking the references in package directory {}",
relative_package_dir
)
})
}
/// Checks for a specific path to not have references outside
///
/// The subpath is the relative path within the package directory we're currently checking.
/// A relative path so that the error messages don't get absolute paths (which are messy in CI).
/// The absolute package directory gets prepended before doing anything with it though.
fn check_path(
nix_file_store: &mut NixFileStore,
relative_package_dir: &RelativePath,
absolute_package_dir: &Path,
subpath: &RelativePath,
) -> validation::Result<()> {
let path = subpath.to_path(absolute_package_dir);
Ok(if path.is_symlink() {
// Check whether the symlink resolves to outside the package directory
match path.canonicalize() {
Ok(target) => {
// No need to handle the case of it being inside the directory, since we scan through the
// entire directory recursively anyways
if let Err(_prefix_error) = target.strip_prefix(absolute_package_dir) {
NixpkgsProblem::OutsideSymlink {
relative_package_dir: relative_package_dir.to_owned(),
subpath: subpath.to_owned(),
}
.into()
} else {
Success(())
}
}
Err(io_error) => NixpkgsProblem::UnresolvableSymlink {
relative_package_dir: relative_package_dir.to_owned(),
subpath: subpath.to_owned(),
io_error: io_error.to_string(),
}
.into(),
}
} else if path.is_dir() {
// Recursively check each entry
validation::sequence_(
utils::read_dir_sorted(&path)?
.into_iter()
.map(|entry| {
check_path(
nix_file_store,
relative_package_dir,
absolute_package_dir,
// TODO: The relative_path crate doesn't seem to support OsStr
&subpath.join(entry.file_name().to_string_lossy().to_string()),
)
})
.collect_vec()
.with_context(|| format!("Error while recursing into {}", subpath))?,
)
} else if path.is_file() {
// Only check Nix files
if let Some(ext) = path.extension() {
if ext == OsStr::new("nix") {
check_nix_file(
nix_file_store,
relative_package_dir,
absolute_package_dir,
subpath,
)
.with_context(|| format!("Error while checking Nix file {}", subpath))?
} else {
Success(())
}
} else {
Success(())
}
} else {
// This should never happen, git doesn't support other file types
anyhow::bail!("Unsupported file type for path {}", subpath);
})
}
/// Check whether a nix file contains path expression references pointing outside the package
/// directory
fn check_nix_file(
nix_file_store: &mut NixFileStore,
relative_package_dir: &RelativePath,
absolute_package_dir: &Path,
subpath: &RelativePath,
) -> validation::Result<()> {
let path = subpath.to_path(absolute_package_dir);
let nix_file = nix_file_store.get(&path)?;
Ok(validation::sequence_(
nix_file.syntax_root.syntax().descendants().map(|node| {
let text = node.text().to_string();
let line = nix_file.line_index.line(node.text_range().start().into());
// We're only interested in Path expressions
let Some(path) = rnix::ast::Path::cast(node) else {
return Success(());
};
use crate::nix_file::ResolvedPath;
match nix_file.static_resolve_path(path, absolute_package_dir) {
ResolvedPath::Interpolated => NixpkgsProblem::PathInterpolation {
relative_package_dir: relative_package_dir.to_owned(),
subpath: subpath.to_owned(),
line,
text,
}
.into(),
ResolvedPath::SearchPath => NixpkgsProblem::SearchPath {
relative_package_dir: relative_package_dir.to_owned(),
subpath: subpath.to_owned(),
line,
text,
}
.into(),
ResolvedPath::Outside => NixpkgsProblem::OutsidePathReference {
relative_package_dir: relative_package_dir.to_owned(),
subpath: subpath.to_owned(),
line,
text,
}
.into(),
ResolvedPath::Unresolvable(e) => NixpkgsProblem::UnresolvablePathReference {
relative_package_dir: relative_package_dir.to_owned(),
subpath: subpath.to_owned(),
line,
text,
io_error: e.to_string(),
}
.into(),
ResolvedPath::Within(..) => {
// No need to handle the case of it being inside the directory, since we scan through the
// entire directory recursively anyways
Success(())
}
}
}),
))
}

View File

@ -1,184 +0,0 @@
use crate::nixpkgs_problem::NixpkgsProblem;
use crate::references;
use crate::utils;
use crate::utils::{BASE_SUBPATH, PACKAGE_NIX_FILENAME};
use crate::validation::{self, ResultIteratorExt, Validation::Success};
use crate::NixFileStore;
use itertools::concat;
use lazy_static::lazy_static;
use regex::Regex;
use relative_path::RelativePathBuf;
use std::fs::DirEntry;
use std::path::Path;
lazy_static! {
static ref SHARD_NAME_REGEX: Regex = Regex::new(r"^[a-z0-9_-]{1,2}$").unwrap();
static ref PACKAGE_NAME_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9_-]+$").unwrap();
}
// Some utility functions for the basic structure
pub fn shard_for_package(package_name: &str) -> String {
package_name.to_lowercase().chars().take(2).collect()
}
pub fn relative_dir_for_shard(shard_name: &str) -> RelativePathBuf {
RelativePathBuf::from(format!("{BASE_SUBPATH}/{shard_name}"))
}
pub fn relative_dir_for_package(package_name: &str) -> RelativePathBuf {
relative_dir_for_shard(&shard_for_package(package_name)).join(package_name)
}
pub fn relative_file_for_package(package_name: &str) -> RelativePathBuf {
relative_dir_for_package(package_name).join(PACKAGE_NIX_FILENAME)
}
/// Check the structure of Nixpkgs, returning the attribute names that are defined in
/// `pkgs/by-name`
pub fn check_structure(
path: &Path,
nix_file_store: &mut NixFileStore,
) -> validation::Result<Vec<String>> {
let base_dir = path.join(BASE_SUBPATH);
let shard_results = utils::read_dir_sorted(&base_dir)?
.into_iter()
.map(|shard_entry| -> validation::Result<_> {
let shard_path = shard_entry.path();
let shard_name = shard_entry.file_name().to_string_lossy().into_owned();
let relative_shard_path = relative_dir_for_shard(&shard_name);
Ok(if shard_name == "README.md" {
// README.md is allowed to be a file and not checked
Success(vec![])
} else if !shard_path.is_dir() {
NixpkgsProblem::ShardNonDir {
relative_shard_path: relative_shard_path.clone(),
}
.into()
// we can't check for any other errors if it's a file, since there's no subdirectories to check
} else {
let shard_name_valid = SHARD_NAME_REGEX.is_match(&shard_name);
let result = if !shard_name_valid {
NixpkgsProblem::InvalidShardName {
relative_shard_path: relative_shard_path.clone(),
shard_name: shard_name.clone(),
}
.into()
} else {
Success(())
};
let entries = utils::read_dir_sorted(&shard_path)?;
let duplicate_results = entries
.iter()
.zip(entries.iter().skip(1))
.filter(|(l, r)| {
l.file_name().to_ascii_lowercase() == r.file_name().to_ascii_lowercase()
})
.map(|(l, r)| {
NixpkgsProblem::CaseSensitiveDuplicate {
relative_shard_path: relative_shard_path.clone(),
first: l.file_name(),
second: r.file_name(),
}
.into()
});
let result = result.and(validation::sequence_(duplicate_results));
let package_results = entries
.into_iter()
.map(|package_entry| {
check_package(
nix_file_store,
path,
&shard_name,
shard_name_valid,
package_entry,
)
})
.collect_vec()?;
result.and(validation::sequence(package_results))
})
})
.collect_vec()?;
// Combine the package names conatained within each shard into a longer list
Ok(validation::sequence(shard_results).map(concat))
}
fn check_package(
nix_file_store: &mut NixFileStore,
path: &Path,
shard_name: &str,
shard_name_valid: bool,
package_entry: DirEntry,
) -> validation::Result<String> {
let package_path = package_entry.path();
let package_name = package_entry.file_name().to_string_lossy().into_owned();
let relative_package_dir =
RelativePathBuf::from(format!("{BASE_SUBPATH}/{shard_name}/{package_name}"));
Ok(if !package_path.is_dir() {
NixpkgsProblem::PackageNonDir {
relative_package_dir: relative_package_dir.clone(),
}
.into()
} else {
let package_name_valid = PACKAGE_NAME_REGEX.is_match(&package_name);
let result = if !package_name_valid {
NixpkgsProblem::InvalidPackageName {
relative_package_dir: relative_package_dir.clone(),
package_name: package_name.clone(),
}
.into()
} else {
Success(())
};
let correct_relative_package_dir = relative_dir_for_package(&package_name);
let result = result.and(if relative_package_dir != correct_relative_package_dir {
// Only show this error if we have a valid shard and package name
// Because if one of those is wrong, you should fix that first
if shard_name_valid && package_name_valid {
NixpkgsProblem::IncorrectShard {
relative_package_dir: relative_package_dir.clone(),
correct_relative_package_dir: correct_relative_package_dir.clone(),
}
.into()
} else {
Success(())
}
} else {
Success(())
});
let package_nix_path = package_path.join(PACKAGE_NIX_FILENAME);
let result = result.and(if !package_nix_path.exists() {
NixpkgsProblem::PackageNixNonExistent {
relative_package_dir: relative_package_dir.clone(),
}
.into()
} else if package_nix_path.is_dir() {
NixpkgsProblem::PackageNixDir {
relative_package_dir: relative_package_dir.clone(),
}
.into()
} else {
Success(())
});
let result = result.and(references::check_references(
nix_file_store,
&relative_package_dir,
&relative_package_dir.to_path(path),
)?);
result.map(|_| package_name.clone())
})
}

View File

@ -1,95 +0,0 @@
use anyhow::Context;
use std::fs;
use std::io;
use std::path::Path;
pub const BASE_SUBPATH: &str = "pkgs/by-name";
pub const PACKAGE_NIX_FILENAME: &str = "package.nix";
/// Deterministic file listing so that tests are reproducible
pub fn read_dir_sorted(base_dir: &Path) -> anyhow::Result<Vec<fs::DirEntry>> {
let listing = base_dir
.read_dir()
.with_context(|| format!("Could not list directory {}", base_dir.display()))?;
let mut shard_entries = listing
.collect::<io::Result<Vec<_>>>()
.with_context(|| format!("Could not list directory {}", base_dir.display()))?;
shard_entries.sort_by_key(|entry| entry.file_name());
Ok(shard_entries)
}
/// A simple utility for calculating the line for a string offset.
/// This doesn't do any Unicode handling, though that probably doesn't matter
/// because newlines can't split up Unicode characters. Also this is only used
/// for error reporting
pub struct LineIndex {
/// Stores the indices of newlines
newlines: Vec<usize>,
}
impl LineIndex {
pub fn new(s: &str) -> LineIndex {
let mut newlines = vec![];
let mut index = 0;
// Iterates over all newline-split parts of the string, adding the index of the newline to
// the vec
for split in s.split_inclusive('\n') {
index += split.len();
newlines.push(index - 1);
}
LineIndex { newlines }
}
/// Returns the line number for a string index.
/// If the index points to a newline, returns the line number before the newline
pub fn line(&self, index: usize) -> usize {
match self.newlines.binary_search(&index) {
// +1 because lines are 1-indexed
Ok(x) => x + 1,
Err(x) => x + 1,
}
}
/// Returns the string index for a line and column.
pub fn fromlinecolumn(&self, line: usize, column: usize) -> usize {
// If it's the 1th line, the column is the index
if line == 1 {
// But columns are 1-indexed
column - 1
} else {
// For the nth line, we add the index of the (n-1)st newline to the column,
// and remove one more from the index since arrays are 0-indexed.
// Then add the 1-indexed column to get not the newline index itself,
// but rather the index of the position on the next line
self.newlines[line - 2] + column
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn line_index() {
let line_index = LineIndex::new("a\nbc\n\ndef\n");
let pairs = [
(0, 1, 1),
(1, 1, 2),
(2, 2, 1),
(3, 2, 2),
(4, 2, 3),
(5, 3, 1),
(6, 4, 1),
(7, 4, 2),
(8, 4, 3),
(9, 4, 4),
];
for (index, line, column) in pairs {
assert_eq!(line_index.line(index), line);
assert_eq!(line_index.fromlinecolumn(line, column), index);
}
}
}

View File

@ -1,111 +0,0 @@
use crate::nixpkgs_problem::NixpkgsProblem;
use itertools::concat;
use itertools::{
Either::{Left, Right},
Itertools,
};
use Validation::*;
/// The validation result of a check.
/// Instead of exiting at the first failure,
/// this type can accumulate multiple failures.
/// This can be achieved using the functions `and`, `sequence` and `sequence_`
///
/// This leans on https://hackage.haskell.org/package/validation
pub enum Validation<A> {
Failure(Vec<NixpkgsProblem>),
Success(A),
}
impl<A> From<NixpkgsProblem> for Validation<A> {
/// Create a `Validation<A>` from a single check problem
fn from(value: NixpkgsProblem) -> Self {
Failure(vec![value])
}
}
/// A type alias representing the result of a check, either:
/// - Err(anyhow::Error): A fatal failure, typically I/O errors.
/// Such failures are not caused by the files in Nixpkgs.
/// This hints at a bug in the code or a problem with the deployment.
/// - Ok(Failure(Vec<NixpkgsProblem>)): A non-fatal validation problem with the Nixpkgs files.
/// Further checks can be run even with this result type.
/// Such problems can be fixed by changing the Nixpkgs files.
/// - Ok(Success(A)): A successful (potentially intermediate) result with an arbitrary value.
/// No fatal errors have occurred and no validation problems have been found with Nixpkgs.
pub type Result<A> = anyhow::Result<Validation<A>>;
pub trait ResultIteratorExt<A, E>: Sized + Iterator<Item = std::result::Result<A, E>> {
fn collect_vec(self) -> std::result::Result<Vec<A>, E>;
}
impl<I, A, E> ResultIteratorExt<A, E> for I
where
I: Sized + Iterator<Item = std::result::Result<A, E>>,
{
/// A convenience version of `collect` specialised to a vector
fn collect_vec(self) -> std::result::Result<Vec<A>, E> {
self.collect()
}
}
impl<A> Validation<A> {
/// Map a `Validation<A>` to a `Validation<B>` by applying a function to the
/// potentially contained value in case of success.
pub fn map<B>(self, f: impl FnOnce(A) -> B) -> Validation<B> {
match self {
Failure(err) => Failure(err),
Success(value) => Success(f(value)),
}
}
/// Map a `Validation<A>` to a `Result<B>` by applying a function `A -> Result<B>`
/// only if there is a `Success` value
pub fn result_map<B>(self, f: impl FnOnce(A) -> Result<B>) -> Result<B> {
match self {
Failure(err) => Ok(Failure(err)),
Success(value) => f(value),
}
}
}
impl Validation<()> {
/// Combine two validations, both of which need to be successful for the return value to be successful.
/// The `NixpkgsProblem`s of both sides are returned concatenated.
pub fn and<A>(self, other: Validation<A>) -> Validation<A> {
match (self, other) {
(Success(_), Success(right_value)) => Success(right_value),
(Failure(errors), Success(_)) => Failure(errors),
(Success(_), Failure(errors)) => Failure(errors),
(Failure(errors_l), Failure(errors_r)) => Failure(concat([errors_l, errors_r])),
}
}
}
/// Combine many validations into a single one.
/// All given validations need to be successful in order for the returned validation to be successful,
/// in which case the returned validation value contains a `Vec` of each individual value.
/// Otherwise the `NixpkgsProblem`s of all validations are returned concatenated.
pub fn sequence<A>(check_results: impl IntoIterator<Item = Validation<A>>) -> Validation<Vec<A>> {
let (errors, values): (Vec<Vec<NixpkgsProblem>>, Vec<A>) = check_results
.into_iter()
.partition_map(|validation| match validation {
Failure(err) => Left(err),
Success(value) => Right(value),
});
// To combine the errors from the results we flatten all the error Vec's into a new Vec
// This is not very efficient, but doesn't matter because generally we should have no errors
let flattened_errors = errors.into_iter().concat();
if flattened_errors.is_empty() {
Success(values)
} else {
Failure(flattened_errors)
}
}
/// Like `sequence`, but without any containing value, for convenience
pub fn sequence_(validations: impl IntoIterator<Item = Validation<()>>) -> Validation<()> {
sequence(validations).map(|_| ())
}

View File

@ -1,3 +0,0 @@
self: super: {
baz = self.foo;
}

View File

@ -1,3 +0,0 @@
self: super: {
bar = self.foo;
}

View File

@ -1 +0,0 @@
import <test-nixpkgs> { root = ./.; }

View File

@ -1 +0,0 @@
Validated successfully

View File

@ -1,7 +0,0 @@
self: super: {
alt.callPackage = self.lib.callPackageWith {};
foo = self.alt.callPackage ({ }: self.someDrv) { };
}

View File

@ -1 +0,0 @@
import <test-nixpkgs> { root = ./.; }

View File

@ -1,9 +0,0 @@
- Because pkgs/by-name/fo/foo exists, the attribute `pkgs.foo` must be defined like
foo = callPackage ./pkgs/by-name/fo/foo/package.nix { /* ... */ };
However, in this PR, a different `callPackage` is used. See the definition in all-packages.nix:5:
foo = self.alt.callPackage ({ }: self.someDrv) { };
This PR introduces the problems listed above. Please fix them before merging, otherwise the base branch would break.

View File

@ -1 +0,0 @@
import <test-nixpkgs> { root = ./.; }

View File

@ -1 +0,0 @@
import <test-nixpkgs> { root = ./.; }

View File

@ -1 +0,0 @@
The base branch is broken, but this PR fixes it. Nice job!

View File

@ -1 +0,0 @@
import <test-nixpkgs> { root = ./.; }

Some files were not shown because too many files have changed in this diff Show More