Skip to content

Commit

Permalink
feat: support yarn.lock
Browse files Browse the repository at this point in the history
  • Loading branch information
aster-void committed Feb 3, 2025
1 parent 897e2aa commit 06ffd2a
Show file tree
Hide file tree
Showing 13 changed files with 462 additions and 119 deletions.
24 changes: 23 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,29 @@
system:
let
nixpkgs = import pkgs { inherit system; };

yarn-v1 = nixpkgs.writeShellApplication {
name = "yarn-v1";
checkPhase = "";
runtimeInputs = [ nixpkgs.yarn ];
text = "yarn $@";
};
yarn-berry = nixpkgs.writeShellApplication {
name = "yarn-berry";
checkPhase = "";
runtimeInputs = [ nixpkgs.yarn-berry ];
text = "yarn $@";
};
in
{
packages = import ./tests.nix { inherit prisma-factory nixpkgs; };
packages = nixpkgs.callPackage ./tests.nix {
inherit
prisma-factory
nixpkgs
yarn-v1
yarn-berry
;
};
devShells.default =
let
prisma = (
Expand All @@ -34,6 +54,8 @@
nixpkgs.stdenv.cc.cc.lib
prisma.package
nixpkgs.nixfmt-rfc-style
yarn-v1
yarn-berry
];
shellHook = prisma.shellHook;
};
Expand Down
10 changes: 10 additions & 0 deletions lib/readYAML.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# converts path to yaml file -> Nix Object
{ runCommand, remarshal }:
path:
let
jsonOutputDrv = runCommand "from-yaml" {
nativeBuildInputs = [ remarshal ];
} "remarshal -if yaml -i \"${path}\" -of json -o \"$out\"";
in
# perf: importing from / reading a file in a derivation (IFD: Import From Derivation) is known to be slow.
builtins.fromJSON (builtins.readFile jsonOutputDrv)
304 changes: 192 additions & 112 deletions prisma.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,117 +15,145 @@
aarch64-darwin = "darwin-arm64";
},
}:
let
pkgs = nixpkgs; # remove this after renaming nixpkg -> pkgs
inherit (pkgs) lib;
lines = s: lib.strings.splitString "\n" s;

# example:
# splitMultiple ["|" "," "-"] "a-|b,c-d"
# -> ["a" "" "b" "c" "d"]
splitMultiple = delims: s: _splitMultiple delims [ s ];
# example:
# _splitMultiple ["|" "," "-"] ["a-|b,c-d"]
# -> ["a" "" "b" "c" "d"]
_splitMultiple =
delims: list:
if builtins.length delims == 0 then
list
else
let
splitStr = map (str: lib.strings.splitString (builtins.elemAt delims 0) str) list;
in
_splitMultiple (lib.drop 1 delims) (lib.lists.concatLists splitStr);
splitMultipleAndFilterEmpty = delims: s: builtins.filter (str: str != "") (splitMultiple delims s);
afterLastDot = text: nixpkgs.lib.lists.last (nixpkgs.lib.strings.splitString "." text);

readYAML = pkgs.callPackage ./lib/readYAML.nix { };
in
rec {
fromCommit =
commit:
let
hostname = "binaries.prisma.sh";
channel = "all_commits";
binaryTarget = binaryTargetBySystem.${nixpkgs.system};
isDarwin = nixpkgs.lib.strings.hasPrefix "darwin" binaryTarget;
target = if isDarwin then binaryTarget else "${binaryTarget}-openssl-${opensslVersion}";
baseUrl = "https://${hostname}/${channel}";
files =
[
{
name = "prisma-fmt";
hash = prisma-fmt-hash;
path = "bin/prisma-fmt";
variable = "PRISMA_FMT_BINARY";
}
{
name = "query-engine";
hash = query-engine-hash;
path = "bin/query-engine";
variable = "PRISMA_QUERY_ENGINE_BINARY";
}
{
name = if isDarwin then "libquery_engine.dylib.node" else "libquery_engine.so.node";
hash = libquery-engine-hash;
path = "lib/libquery_engine.node";
variable = "PRISMA_QUERY_ENGINE_LIBRARY";
if builtins.stringLength commit != 40 then
throw "nvalid commit: got ${commit}"
else
let
hostname = "binaries.prisma.sh";
channel = "all_commits";
binaryTarget = binaryTargetBySystem.${nixpkgs.system};
isDarwin = nixpkgs.lib.strings.hasPrefix "darwin" binaryTarget;
target = if isDarwin then binaryTarget else "${binaryTarget}-openssl-${opensslVersion}";
baseUrl = "https://${hostname}/${channel}";
files =
[
{
name = "prisma-fmt";
hash = prisma-fmt-hash;
path = "bin/prisma-fmt";
variable = "PRISMA_FMT_BINARY";
}
{
name = "query-engine";
hash = query-engine-hash;
path = "bin/query-engine";
variable = "PRISMA_QUERY_ENGINE_BINARY";
}
{
name = if isDarwin then "libquery_engine.dylib.node" else "libquery_engine.so.node";
hash = libquery-engine-hash;
path = "lib/libquery_engine.node";
variable = "PRISMA_QUERY_ENGINE_LIBRARY";
}
]
++ (
if introspection-engine-hash == null then
[ ]
else
[
{
name = "introspection-engine";
hash = introspection-engine-hash;
path = "bin/introspection-engine";
variable = "PRISMA_INTROSPECTION_ENGINE_BINARY";
}
]
)
++ (
if migration-engine-hash == null then
[ ]
else
[
{
name = "migration-engine";
hash = migration-engine-hash;
path = "bin/migration-engine";
variable = "PRISMA_MIGRATION_ENGINE_BINARY";
}
]
)
++ (
if schema-engine-hash == null then
[ ]
else
[
{
name = "schema-engine";
hash = schema-engine-hash;
path = "bin/schema-engine";
variable = "PRISMA_SCHEMA_ENGINE_BINARY";
}
]
);
downloadedFiles = builtins.map (
file:
file
// {
file = nixpkgs.fetchurl {
name = "${baseUrl}/${commit}/${target}/${file.name}.gz";
url = "${baseUrl}/${commit}/${target}/${file.name}.gz";
hash = file.hash;
};
}
]
++ (
if introspection-engine-hash == null then
[ ]
else
[
{
name = "introspection-engine";
hash = introspection-engine-hash;
path = "bin/introspection-engine";
variable = "PRISMA_INTROSPECTION_ENGINE_BINARY";
}
]
)
++ (
if migration-engine-hash == null then
[ ]
else
[
{
name = "migration-engine";
hash = migration-engine-hash;
path = "bin/migration-engine";
variable = "PRISMA_MIGRATION_ENGINE_BINARY";
}
]
)
++ (
if schema-engine-hash == null then
[ ]
else
[
{
name = "schema-engine";
hash = schema-engine-hash;
path = "bin/schema-engine";
variable = "PRISMA_SCHEMA_ENGINE_BINARY";
}
]
);
downloadedFiles = builtins.map (
file:
file
// {
file = nixpkgs.fetchurl {
name = "${baseUrl}/${commit}/${target}/${file.name}.gz";
url = "${baseUrl}/${commit}/${target}/${file.name}.gz";
hash = file.hash;
};
}
) files;
unzipCommands = builtins.map (file: "gunzip -c ${file.file} > $out/${file.path}") downloadedFiles;
exportCommands =
package: builtins.map (file: "export ${file.variable}=${package}/${file.path}") files;
in
rec {
package = nixpkgs.stdenv.mkDerivation {
pname = "prisma-bin";
version = commit;
nativeBuildInputs = [
nixpkgs.zlib
openssl
nixpkgs.stdenv.cc.cc.lib
] ++ nixpkgs.lib.optionals (!isDarwin) [ nixpkgs.autoPatchelfHook ];
phases = [
"buildPhase"
"postFixupHooks"
];
buildPhase = ''
mkdir -p $out/bin
mkdir -p $out/lib
${nixpkgs.lib.concatStringsSep "\n" unzipCommands}
chmod +x $out/bin/*
'';
) files;
unzipCommands = builtins.map (file: "gunzip -c ${file.file} > $out/${file.path}") downloadedFiles;
exportCommands =
package: builtins.map (file: "export ${file.variable}=${package}/${file.path}") files;
in
rec {
package = nixpkgs.stdenv.mkDerivation {
pname = "prisma-bin";
version = commit;
nativeBuildInputs = [
nixpkgs.zlib
openssl
nixpkgs.stdenv.cc.cc.lib
] ++ nixpkgs.lib.optionals (!isDarwin) [ nixpkgs.autoPatchelfHook ];
phases = [
"buildPhase"
"postFixupHooks"
];
buildPhase = ''
mkdir -p $out/bin
mkdir -p $out/lib
${nixpkgs.lib.concatStringsSep "\n" unzipCommands}
chmod +x $out/bin/*
'';
};
shellHook = nixpkgs.lib.concatStringsSep "\n" (exportCommands package);
};
shellHook = nixpkgs.lib.concatStringsSep "\n" (exportCommands package);
};
# example:
# a.b123c.d.e12345
# => e12345
afterLastDot = text: nixpkgs.lib.lists.last (nixpkgs.lib.strings.splitString "." text);
fromPnpmLock =
path:
let
Expand All @@ -145,9 +173,7 @@ rec {
"5" =
pnpmLock:
let
version = builtins.elemAt (builtins.split ":" (
builtins.elemAt (builtins.split ("@prisma/engines-version/") pnpmLock) 2
)) 0;
version = builtins.elemAt (builtins.split ":" (builtins.elemAt (builtins.split ("@prisma/engines-version/") pnpmLock) 2)) 0;
in
nixpkgs.lib.lists.last (nixpkgs.lib.strings.splitString "." version);

Expand All @@ -156,9 +182,7 @@ rec {
"6" =
pnpmLock:
let
version = builtins.elemAt (builtins.split ":" (
builtins.elemAt (builtins.split ("@prisma/engines-version@") pnpmLock) 2
)) 0;
version = builtins.elemAt (builtins.split ":" (builtins.elemAt (builtins.split ("@prisma/engines-version@") pnpmLock) 2)) 0;
in
nixpkgs.lib.lists.last (nixpkgs.lib.strings.splitString "." version);

Expand All @@ -167,9 +191,7 @@ rec {
"9" =
pnpmLock:
let
version = builtins.elemAt (builtins.split "'" (
builtins.elemAt (builtins.split ("@prisma/engines-version@") pnpmLock) 2
)) 0;
version = builtins.elemAt (builtins.split "'" (builtins.elemAt (builtins.split ("@prisma/engines-version@") pnpmLock) 2)) 0;
in
nixpkgs.lib.lists.last (nixpkgs.lib.strings.splitString "." version);
};
Expand All @@ -191,6 +213,64 @@ rec {
commit = nixpkgs.lib.lists.last (nixpkgs.lib.strings.splitString "." version);
in
fromCommit commit;
fromYarnLock =
path:
let
# find this line from yarn.lock:
# "@prisma/engines-version@npm:6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0":
yarnLockParser1 =
file:
let
versionLine =
lib.lists.findFirst
(line: builtins.length (lib.strings.splitString "@prisma/engines-version" line) >= 2)
# else
(throw ''
nix-prisma-utils/yarnLockParser1: package @prisma/engines-version not found in lockfile ${path} .
please make sure you have installed `@prisma/client`.
if you have already installed `@prisma/client` and still see this, please report this to nix-prisma-utils.
'')
(lines file);
# "@prisma/engines-version@npm:6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0":
# -> ["@prisma/engines-version@npm" "6" "3" "0-17" "acc0b9dd43eb689cbd20c9470515d719db10d0b0"]
# -> acc0b9dd43eb689cbd20c9470515d719db10d0b0
version = lib.lists.last (
splitMultipleAndFilterEmpty [
"\""
":"
"."
] versionLine
);
in
version;
isYarnLockV1 =
file:
lib.lists.any (line: lib.strings.trim line == "# yarn lockfile v1") (
lib.strings.splitString "\n" file
);
# example line:
# "@prisma/engines-version@6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0":
yarnV1LockParser = yarnLockParser1;
# example line:
# "@prisma/engines-version@npm:6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0":
yarnBerryLockParsers = {
"8" = yarnLockParser1;
};

lockfile = builtins.readFile path;
parse =
if isYarnLockV1 lockfile then
yarnV1LockParser
else
let
lockfileVersion = builtins.toString (readYAML path).__metadata.version;
in
yarnBerryLockParsers.${lockfileVersion} or (throw ''
nix-prisma-utils: unknown lockfile version ${lockfileVersion}.
please report this to nix-prisma-utils with your lockfile.
'');
in
fromCommit (parse lockfile);
fromBunLock =
path:
let
Expand Down
Loading

0 comments on commit 06ffd2a

Please sign in to comment.