diff --git a/lib/meta.nix b/lib/meta.nix index 2e817c42327d..1a43016d27c4 100644 --- a/lib/meta.nix +++ b/lib/meta.nix @@ -3,6 +3,11 @@ { lib }: +let + inherit (lib) matchAttrs any all; + inherit (builtins) isString; + +in rec { @@ -83,14 +88,21 @@ rec { We can inject these into a pattern for the whole of a structured platform, and then match that. */ - platformMatch = platform: elem: let - pattern = - if builtins.isString elem - then { system = elem; } - else if elem?parsed - then elem - else { parsed = elem; }; - in lib.matchAttrs pattern platform; + platformMatch = platform: elem: ( + # Check with simple string comparison if elem was a string. + # + # The majority of comparisons done with this function will be against meta.platforms + # which contains a simple platform string. + # + # Avoiding an attrset allocation results in significant performance gains (~2-30) across the board in OfBorg + # because this is a hot path for nixpkgs. + if isString elem then platform ? system && elem == platform.system + else matchAttrs ( + # Normalize platform attrset. + if elem ? parsed then elem + else { parsed = elem; } + ) platform + ); /* Check if a package is available on a given platform. @@ -102,8 +114,8 @@ rec { 2. None of `meta.badPlatforms` pattern matches the given platform. */ availableOn = platform: pkg: - ((!pkg?meta.platforms) || lib.any (platformMatch platform) pkg.meta.platforms) && - lib.all (elem: !platformMatch platform elem) (pkg.meta.badPlatforms or []); + ((!pkg?meta.platforms) || any (platformMatch platform) pkg.meta.platforms) && + all (elem: !platformMatch platform elem) (pkg.meta.badPlatforms or []); /* Get the corresponding attribute in lib.licenses from the SPDX ID. diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 06cb5e763e2c..8f4a37149d92 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -1948,4 +1948,24 @@ runTests { testGetExe'FailureSecondArg = testingThrow ( getExe' { type = "derivation"; } "dir/executable" ); + + testPlatformMatch = { + expr = meta.platformMatch { system = "x86_64-linux"; } "x86_64-linux"; + expected = true; + }; + + testPlatformMatchAttrs = { + expr = meta.platformMatch (systems.elaborate "x86_64-linux") (systems.elaborate "x86_64-linux").parsed; + expected = true; + }; + + testPlatformMatchNoMatch = { + expr = meta.platformMatch { system = "x86_64-darwin"; } "x86_64-linux"; + expected = false; + }; + + testPlatformMatchMissingSystem = { + expr = meta.platformMatch { } "x86_64-linux"; + expected = false; + }; }