diff --git a/docs/default.nix b/docs/default.nix index 19498ebd..bbb94d88 100644 --- a/docs/default.nix +++ b/docs/default.nix @@ -9,6 +9,56 @@ let pkgs = import ./pkgs.nix { inherit system nixpkgs; }; inherit (pkgs) lib; + # A stub pkgs instance used while evaluating the nixvim modules for the docs + # If any non-meta attr is accessed, the eval will throw + noPkgs = + let + # Known suffixes for package sets + suffixes = [ + "Plugins" + "Packages" + ]; + + # Predicate for whether an attr name looks like a package set + # Determines whether stubPackage should recurse + isPackageSet = name: builtins.any (lib.flip lib.strings.hasSuffix name) suffixes; + + # Need to retain `meta.homepage` if present + stubPackage = + prefix: name: package: + let + loc = prefix ++ [ name ]; + in + if isPackageSet name then + lib.mapAttrs (stubPackage loc) package + else + lib.mapAttrs (_: throwAccessError loc) package + // lib.optionalAttrs (package ? meta) { inherit (package) meta; }; + + throwAccessError = + loc: + throw "Attempted to access `${ + lib.concatStringsSep "." ([ "pkgs" ] ++ loc) + }` while rendering the docs."; + in + lib.fix ( + self: + lib.mapAttrs (stubPackage [ ]) pkgs + // { + pkgs = self; + # The following pkgs attrs are required to eval nixvim, even for the docs: + inherit (pkgs) + _type + stdenv + stdenvNoCC + symlinkJoin + runCommand + runCommandLocal + writeShellApplication + ; + } + ); + nixvimPath = toString ./..; gitHubDeclaration = user: repo: branch: subpath: { @@ -37,7 +87,7 @@ let modules = [ { isDocs = true; - nixpkgs.pkgs = pkgs; + _module.args.pkgs = lib.mkForce noPkgs; } ]; }; diff --git a/tests/default.nix b/tests/default.nix index 15266faa..d2a3ff6b 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -44,7 +44,6 @@ in nixpkgs-module = callTest ./nixpkgs-module.nix { }; plugins-by-name = callTest ./plugins-by-name.nix { }; generated = callTest ./generated.nix { }; - package-options = callTest ./package-options.nix { }; lsp-all-servers = callTest ./lsp-servers.nix { }; } # Expose some tests from the docs as flake-checks too diff --git a/tests/package-options.nix b/tests/package-options.nix deleted file mode 100644 index 7af30250..00000000 --- a/tests/package-options.nix +++ /dev/null @@ -1,94 +0,0 @@ -# This test ensures "package" options use a "literalExpression" in their defaultText -# I.e. it validates `lib.mkPackageOption` was used to build the package options. -{ - nixvimConfiguration, - lib, - runCommandLocal, -}: -let - inherit (builtins) - filter - head - map - match - ; - inherit (lib.strings) concatMapStringsSep removePrefix removeSuffix; - inherit (lib.attrsets) isDerivation; - inherit (lib.options) - isOption - renderOptionValue - showOption - ; - - # This doesn't collect any submodule sub-options, - # but that's fine since most of our "package" options are in the top level module eval - options = lib.collect isOption nixvimConfiguration.options; - - # All visible non-sub options that default to a derivation - drvOptions = filter ( - { - default ? null, - visible ? true, - internal ? false, - ... - }: - let - # Some options have defaults that throw when evaluated - default' = (builtins.tryEval default).value; - in - visible && !internal && isDerivation default' - ) options; - - # Bad options do not use `literalExpression` in their `defaultText`, - # or have a `defaultText` that doesn't start with "pkgs." - badOptions = filter ( - opt: - opt.defaultText._type or null != "literalExpression" - || match ''pkgs[.].*'' (opt.defaultText.text or "") == null - ) drvOptions; -in -runCommandLocal "validate-package-options" - { - # Use structuredAttrs to avoid "Argument List Too Long" errors - # and get proper bash array support. - __structuredAttrs = true; - - # Passthroughs for debugging purposes - passthru = { - inherit nixvimConfiguration drvOptions badOptions; - }; - - # Error strings to print - errors = - let - # A little hack to get the flake's source in the nix store - # We will use this to make the option declaration sources more readable - src = removeSuffix "modules/top-level/output.nix" ( - head nixvimConfiguration.options.package.declarations - ); - in - map ( - opt: - let - # The default, as rendered in documentation. Will always be a literalExpression. - default = builtins.addErrorContext "while evaluating the default text for `${showOption opt.loc}`" ( - renderOptionValue (opt.defaultText or opt.default) - ); - in - '' - - ${showOption opt.loc} (${default.text}), declared in: - ${concatMapStringsSep "\n" (file: " - ${removePrefix src file}") opt.declarations} - '' - ) badOptions; - } - '' - if [ -n "$errors" ]; then - echo "Found ''${#errors[@]} errors:" - for err in "''${errors[@]}"; do - echo "$err" - done - echo "(''${#errors[@]} options with errors)" - exit 1 - fi - touch $out - ''