prettier: Use `wrapProgram` for plugins (#442463)

Changed files
+127 -2
pkgs
by-name
pr
prettier
+127 -2
pkgs/by-name/pr/prettier/package.nix
···
{
fetchFromGitHub,
lib,
···
stdenv,
versionCheckHook,
yarn-berry,
}:
stdenv.mkDerivation (finalAttrs: {
pname = "prettier";
version = "3.6.2";
···
makeBinaryWrapper "${lib.getExe nodejs}" "$out/bin/prettier" \
--add-flags "$out/bin/prettier.cjs"
-
runHook postInstall
'';
···
homepage = "https://prettier.io/";
license = lib.licenses.mit;
mainProgram = "prettier";
-
maintainers = with lib.maintainers; [ l0b0 ];
};
})
···
+
/**
+
# Example
+
+
Prettier with plugins and Vim Home Manager configuration
+
+
```nix
+
pkgs.prettier.override {
+
plugins = with pkgs.nodePackages; [
+
prettier-plugin-toml
+
# ...
+
];
+
}
+
```
+
*/
{
fetchFromGitHub,
lib,
···
stdenv,
versionCheckHook,
yarn-berry,
+
plugins ? [ ],
}:
+
let
+
/**
+
# Example
+
+
```nix
+
exportRelativePathOf (builtins.fromJSON "./package.json")
+
=>
+
lib/node_modules/prettier-plugin-toml/./lib/index.cjs
+
```
+
+
# Type
+
+
```
+
exportRelativePathOf :: AttrSet => String
+
```
+
+
# Arguments
+
+
packageJsonAttrs
+
: Attribute set with shape similar to `package.json` file
+
*/
+
## Blame NodeJS
+
exportRelativePathOf =
+
let
+
nodeExportAttrAddresses = [
+
[ "main" ]
+
[
+
"exports"
+
"."
+
"default"
+
]
+
[
+
"exports"
+
"."
+
]
+
[
+
"exports"
+
"default"
+
]
+
[ "exports" ]
+
];
+
+
recAttrByPath =
+
addresses: default: attrs:
+
if builtins.length addresses == 0 then
+
default
+
else
+
let
+
addressNext = builtins.head addresses;
+
addressesRemaning = lib.lists.drop 1 addresses;
+
in
+
lib.attrByPath addressNext (recAttrByPath addressesRemaning default attrs) attrs;
+
in
+
packageJsonAttrs:
+
recAttrByPath nodeExportAttrAddresses (builtins.head (
+
lib.attrByPath [ "prettier" "plugins" ] [ "null" ] packageJsonAttrs
+
)) packageJsonAttrs;
+
+
/**
+
# Example
+
+
```nix
+
nodeEntryPointOf pkgs.nodePackages.prettier-plugin-toml
+
=>
+
/nix/store/<NAR_HASH>-prettier-plugin-toml-<VERSION>/lib/node_modules/prettier-plugin-toml/./lib/index.cjs
+
```
+
+
# Type
+
+
```
+
nodeEntryPointOf :: AttrSet => String
+
```
+
+
# Arguments
+
+
plugin
+
: Attribute set with `.packageName` and `.outPath` defined
+
*/
+
nodeEntryPointOf =
+
plugin:
+
let
+
pluginDir = "${plugin.outPath}/lib/node_modules/${plugin.packageName}";
+
+
packageJsonAttrs = builtins.fromJSON (builtins.readFile "${pluginDir}/package.json");
+
+
exportPath = exportRelativePathOf packageJsonAttrs;
+
+
pathAbsoluteNaive = "${pluginDir}/${exportPath}";
+
pathAbsoluteFallback = "${pluginDir}/${exportPath}.js";
+
in
+
if builtins.pathExists pathAbsoluteNaive then
+
pathAbsoluteNaive
+
else if builtins.pathExists pathAbsoluteFallback then
+
pathAbsoluteFallback
+
else
+
lib.warn ''
+
${plugin.packageName}: error context, tried finding entry point under;
+
pathAbsoluteNaive -> ${pathAbsoluteNaive}
+
pathAbsoluteFallback -> ${pathAbsoluteFallback}
+
'' throw ''${plugin.packageName}: does not provide parse-able entry point'';
+
in
stdenv.mkDerivation (finalAttrs: {
pname = "prettier";
version = "3.6.2";
···
makeBinaryWrapper "${lib.getExe nodejs}" "$out/bin/prettier" \
--add-flags "$out/bin/prettier.cjs"
+
''
+
+ lib.optionalString (builtins.length plugins > 0) ''
+
wrapProgram $out/bin/prettier --add-flags "${
+
builtins.concatStringsSep " " (lib.map (plugin: "--plugin=${nodeEntryPointOf plugin}") plugins)
+
}";
+
''
+
+ ''
runHook postInstall
'';
···
homepage = "https://prettier.io/";
license = lib.licenses.mit;
mainProgram = "prettier";
+
maintainers = with lib.maintainers; [
+
l0b0
+
S0AndS0
+
];
};
})