diff --git a/ci/eval/compare/maintainers.nix b/ci/eval/compare/maintainers.nix index 1d83ecfd4258..8c594b9532df 100644 --- a/ci/eval/compare/maintainers.nix +++ b/ci/eval/compare/maintainers.nix @@ -6,6 +6,11 @@ # - pkgs/by-name//* is linked to pkgs. # - The file position of various attributes of pkgs. # - Explicitly specified file positions in derivations +# +# Test with +# nix-instantiate --eval --strict --json test.nix -A result | jq +# +# Empty list as an output means success { # Files that were changed # Type: ListOf (Nixpkgs-root-relative path) diff --git a/ci/eval/compare/test.nix b/ci/eval/compare/test.nix new file mode 100644 index 000000000000..323d71d87680 --- /dev/null +++ b/ci/eval/compare/test.nix @@ -0,0 +1,228 @@ +{ + pkgs ? import ../../.. { + config = { }; + overlays = [ ]; + }, + lib ? pkgs.lib, +}: +let + fun = import ./maintainers.nix; + + mockPkgs = + { + packages ? [ ], + modules ? [ ], + githubTeams ? true, + }: + lib.updateManyAttrsByPath + (lib.imap0 (i: p: { + path = p; + update = _: { + meta.maintainersPosition.file = lib.concatStringsSep "/" p; + meta.nonTeamMaintainers = [ { githubId = i; } ]; + meta.teams = + if githubTeams then [ { githubId = i + 100; } ] else [ { members = [ { githubId = i + 100; } ]; } ]; + }; + }) packages) + { + nixos = + { }: + { + config.meta.maintainers = lib.listToAttrs ( + lib.imap0 (i: m: lib.nameValuePair m [ { githubId = i; } ]) modules + ); + config.meta.teams = lib.listToAttrs ( + lib.imap0 ( + i: m: + lib.nameValuePair m ( + if githubTeams then [ { githubId = i + 100; } ] else [ { members = [ { githubId = i + 100; } ]; } ] + ) + ) modules + ); + }; + }; + + tests = { + testEmpty = { + expr = fun { + pkgs = mockPkgs { }; + inherit lib; + changedFiles = [ ]; + affectedAttrPaths = [ ]; + }; + expected = { + packages = [ ]; + teams = { }; + users = { }; + }; + }; + testNonExistentAffected = { + expr = fun { + pkgs = mockPkgs { }; + inherit lib; + changedFiles = [ "a" ]; + affectedAttrPaths = [ [ "b" ] ]; + }; + expected = { + packages = [ ]; + teams = { }; + users = { }; + }; + }; + testIrrelevantAffected = { + expr = fun { + pkgs = mockPkgs { + packages = [ [ "b" ] ]; + }; + inherit lib; + changedFiles = [ "a" ]; + affectedAttrPaths = [ [ "b" ] ]; + }; + expected = { + packages = [ ]; + teams = { }; + users = { }; + }; + }; + testRelevantAffected = { + expr = fun { + pkgs = mockPkgs { + packages = [ [ "b" ] ]; + }; + inherit lib; + # Also tests that subpaths work + changedFiles = [ "b/c" ]; + affectedAttrPaths = [ [ "b" ] ]; + }; + expected = { + packages = [ [ "b" ] ]; + teams."100" = [ + { attrPath = [ "b" ]; } + ]; + users."0" = [ + { attrPath = [ "b" ]; } + ]; + }; + }; + testRelevantAffectedNonGitHub = { + expr = fun { + pkgs = mockPkgs { + packages = [ [ "b" ] ]; + githubTeams = false; + }; + inherit lib; + changedFiles = [ "b/c" ]; + affectedAttrPaths = [ [ "b" ] ]; + }; + expected = { + packages = [ [ "b" ] ]; + teams = { }; + users."0" = [ + { attrPath = [ "b" ]; } + ]; + users."100" = [ + { attrPath = [ "b" ]; } + ]; + }; + }; + testByNameChanged = { + expr = fun { + pkgs = mockPkgs { + packages = [ [ "hello" ] ]; + }; + inherit lib; + changedFiles = [ "pkgs/by-name/he/hello/sources.json" ]; + affectedAttrPaths = [ ]; + }; + expected = { + packages = [ [ "hello" ] ]; + teams."100" = [ + { attrPath = [ "hello" ]; } + ]; + users."0" = [ + { attrPath = [ "hello" ]; } + ]; + }; + }; + testByNameReadmeChanged = { + expr = fun { + pkgs = mockPkgs { + packages = [ [ "hello" ] ]; + }; + inherit lib; + changedFiles = [ "pkgs/by-name/README.md" ]; + affectedAttrPaths = [ ]; + }; + expected = { + packages = [ ]; + teams = { }; + users = { }; + }; + }; + testNoDuplicates = { + expr = fun { + pkgs = mockPkgs { + packages = [ [ "hello" ] ]; + }; + inherit lib; + changedFiles = [ + "hello" + "pkgs/by-name/he/hello/sources.json" + ]; + affectedAttrPaths = [ [ "hello" ] ]; + }; + expected = { + packages = [ [ "hello" ] ]; + teams."100" = [ + { attrPath = [ "hello" ]; } + ]; + users."0" = [ + { attrPath = [ "hello" ]; } + ]; + }; + }; + testModuleMaintainers = { + expr = fun { + pkgs = mockPkgs { + modules = [ "a" ]; + }; + inherit lib; + changedFiles = [ "a" ]; + affectedAttrPaths = [ ]; + }; + expected = { + packages = [ ]; + teams."100" = [ + { file = "a"; } + ]; + users."0" = [ + { file = "a"; } + ]; + }; + }; + testModuleMaintainersNonGithub = { + expr = fun { + pkgs = mockPkgs { + modules = [ "a" ]; + githubTeams = false; + }; + inherit lib; + changedFiles = [ "a" ]; + affectedAttrPaths = [ ]; + }; + expected = { + packages = [ ]; + teams = { }; + users."100" = [ + { file = "a"; } + ]; + users."0" = [ + { file = "a"; } + ]; + }; + }; + }; +in +{ + result = lib.runTests tests; +}