diff --git a/.helix/languages.toml b/.helix/languages.toml new file mode 100644 index 0000000..94b3feb --- /dev/null +++ b/.helix/languages.toml @@ -0,0 +1,3 @@ +[[language]] +name = "nix" +formatter = { command = "nixfmt", args = ["--strict"] } diff --git a/flake.lock b/flake.lock index 3665d48..4bfb6cf 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1738703096, - "narHash": "sha256-1MABVDwNpAUrUDvyM6PlHlAB1eTWAX0eNYCzdsZ54NI=", + "lastModified": 1738797219, + "narHash": "sha256-KRwX9Z1XavpgeSDVM/THdFd6uH8rNm/6R+7kIbGa+2s=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "f7384aacd0ecd28681a99269ac0dff2c3a805d63", + "rev": "1da52dd49a127ad74486b135898da2cef8c62665", "type": "github" }, "original": { @@ -63,11 +63,11 @@ ] }, "locked": { - "lastModified": 1738070913, - "narHash": "sha256-j6jC12vCFsTGDmY2u1H12lMr62fnclNjuCtAdF1a4Nk=", + "lastModified": 1738680491, + "narHash": "sha256-8X7tR3kFGkE7WEF5EXVkt4apgaN85oHZdoTGutCFs6I=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "bebf27d00f7d10ba75332a0541ac43676985dea3", + "rev": "64dbb922d51a42c0ced6a7668ca008dded61c483", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 3f0e607..3d230c3 100644 --- a/flake.nix +++ b/flake.nix @@ -34,7 +34,10 @@ }; treefmt = treefmt-nix.lib.evalModule pkgs { # nixfmt is nixfmt-rfc-style - programs.nixfmt.enable = true; + programs.nixfmt = { + enable = true; + strict = true; + }; }; in { @@ -65,23 +68,20 @@ ); in pkgs.mkShell { - buildInputs = [ + inherit (prisma) env; + packages = [ pkgs.nodejs-18_x pkgs.pnpm pkgs.bun pkgs.stdenv.cc.cc.lib - prisma.package pkgs.nixfmt-rfc-style yarn-v1 yarn-berry ]; - env = prisma.env; }; } ) // { - lib = { - inherit prisma-factory; - }; + lib = { inherit prisma-factory; }; }; } diff --git a/fromCommit.nix b/fromCommit.nix new file mode 100644 index 0000000..0588fbc --- /dev/null +++ b/fromCommit.nix @@ -0,0 +1,136 @@ +{ + # pkgs + lib + utils, + lib, + stdenv, + openssl, + fetchurl, + zlib, + autoPatchelfHook, + + # info + system, + opensslVersion, + binaryTargetBySystem, + + # hashes + prisma-fmt-hash, + query-engine-hash, + libquery-engine-hash, + introspection-engine-hash, + schema-engine-hash, + migration-engine-hash, +}: +commit: +if builtins.stringLength commit != 40 then + throw "invalid commit: got ${commit}" +else + let + hostname = "binaries.prisma.sh"; + channel = "all_commits"; + binaryTarget = binaryTargetBySystem.${system}; + isDarwin = 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 = 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; + package = stdenv.mkDerivation { + pname = "prisma-bin"; + version = commit; + nativeBuildInputs = [ + zlib + openssl + stdenv.cc.cc.lib + ] ++ lib.optionals (!isDarwin) [ autoPatchelfHook ]; + phases = [ + "buildPhase" + "postFixupHooks" + ]; + buildPhase = '' + mkdir -p $out/bin + mkdir -p $out/lib + ${lib.concatStringsSep "\n" unzipCommands} + chmod +x $out/bin/* + ''; + }; + env = builtins.listToAttrs ( + builtins.map (file: { + name = file.variable; + value = "${package}/${file.path}"; + }) files + ); + shellHook = utils.toExportStyle env; + in + { + inherit env package shellHook; + } diff --git a/parsers/bun-lock.nix b/parsers/bun-lock.nix new file mode 100644 index 0000000..6a01e20 --- /dev/null +++ b/parsers/bun-lock.nix @@ -0,0 +1,30 @@ +{ utils }: +path: +let + lockfile = utils.fromJSONWithTrailingCommas ( + assert builtins.typeOf path == "path"; + builtins.readFile path + ); + bunLockParsers = { + # example: + # nu> open bun.lock | from json | get packages.@prisma/engines-version.0 + # @prisma/engines-version@5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e + "0" = bunLockParsers."1"; + "1" = + lock: + utils.afterLastDot ( + builtins.elemAt (lock."packages"."@prisma/engines-version" or (throw '' + nix-prisma-utils: lockfile parsing error: package @prisma/engines-version not found. + please make sure that you have @prisma/client installed. + '') + ) 0 + ); + }; + lockfileVersion = builtins.toString lockfile."lockfileVersion"; + parser = + bunLockParsers.${lockfileVersion} or (throw '' + nix-prisma-utils: Unsupported lockfile version: ${lockfileVersion} + nix-prisma-utils currently supports bun.lock version of 0 and 1. + ''); +in +parser lockfile diff --git a/parsers/default.nix b/parsers/default.nix new file mode 100644 index 0000000..adb9c44 --- /dev/null +++ b/parsers/default.nix @@ -0,0 +1,7 @@ +{ callPackage, utils }: +{ + npmLock = callPackage ./npm-lock.nix { }; + yarnLock = callPackage ./yarn-lock.nix { inherit utils; }; + pnpmLock = callPackage ./pnpm-lock.nix { }; + bunLock = callPackage ./bun-lock.nix { inherit utils; }; +} diff --git a/parsers/npm-lock.nix b/parsers/npm-lock.nix new file mode 100644 index 0000000..71041b0 --- /dev/null +++ b/parsers/npm-lock.nix @@ -0,0 +1,12 @@ +{ lib }: +path: +let + packageLock = builtins.fromJSON (builtins.readFile path); + version = + if builtins.hasAttr "dependencies" packageLock then + packageLock.dependencies.${"@prisma/engines-version"}.version + else + packageLock.packages.${"node_modules/@prisma/engines-version"}.version; + commit = lib.lists.last (lib.strings.splitString "." version); +in +commit diff --git a/parsers/pnpm-lock.nix b/parsers/pnpm-lock.nix new file mode 100644 index 0000000..2a00035 --- /dev/null +++ b/parsers/pnpm-lock.nix @@ -0,0 +1,49 @@ +# Type +# path -> string (commit) +{ lib }: +path: +let + pnpmLock = builtins.readFile path; + lockfileVersion = + if lib.strings.hasPrefix "lockfileVersion: 5" pnpmLock then + "5" + else if lib.strings.hasPrefix "lockfileVersion: '6" pnpmLock then + "6" + else if lib.strings.hasPrefix "lockfileVersion: '9" pnpmLock then + "9" + else + throw '' + nix-prisma-utils: unknown pnpm lockfile version. please report this to nix-prisma-utils with your lockfile. + ''; + pnpmLockParsers = { + # example line: + # /@prisma/engines-version/5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e: + "5" = + pnpmLock: + let + version = builtins.elemAt (builtins.split ":" (builtins.elemAt (builtins.split "@prisma/engines-version/" pnpmLock) 2)) 0; + in + lib.lists.last (lib.strings.splitString "." version); + + # example line: + # /@prisma/engines-version@5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e: + "6" = + pnpmLock: + let + version = builtins.elemAt (builtins.split ":" (builtins.elemAt (builtins.split "@prisma/engines-version@" pnpmLock) 2)) 0; + in + lib.lists.last (lib.strings.splitString "." version); + + # exmple line: + # '@prisma/engines-version@5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022': + "9" = + pnpmLock: + let + version = builtins.elemAt (builtins.split "'" (builtins.elemAt (builtins.split "@prisma/engines-version@" pnpmLock) 2)) 0; + in + lib.lists.last (lib.strings.splitString "." version); + }; + pnpmLockParser = pnpmLockParsers.${lockfileVersion}; + commit = pnpmLockParser pnpmLock; +in +commit diff --git a/parsers/yarn-lock.nix b/parsers/yarn-lock.nix new file mode 100644 index 0000000..3350a43 --- /dev/null +++ b/parsers/yarn-lock.nix @@ -0,0 +1,52 @@ +{ lib, utils }: +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. + '') + (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 (utils.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 (utils.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 +(parse lockfile) diff --git a/prisma.nix b/prisma.nix index 3b05641..36dd54d 100644 --- a/prisma.nix +++ b/prisma.nix @@ -18,40 +18,22 @@ }, }: let - 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); - # example: - # a.b123c.d.e12345 - # => e12345 - afterLastDot = text: lib.lists.last (lib.strings.splitString "." text); - - readYAML = pkgs.callPackage ./lib/readYAML.nix { }; - # polyfill: the function in nixpkgs is implemented on Dec 6, 2024. replace this with one from pkgs.lib after 24.11 reaches EOL. - concatMapAttrsStringSep = - let - inherit (pkgs) lib; - in - sep: f: attrs: - lib.concatStringsSep sep (lib.attrValues (lib.mapAttrs f attrs)); - + utils = pkgs.callPackage ./utils/default.nix { }; + parsers = pkgs.callPackage ./parsers/default.nix { inherit utils; }; + fromCommit = pkgs.callPackage ./fromCommit.nix { + inherit + utils + openssl + opensslVersion + introspection-engine-hash + migration-engine-hash + prisma-fmt-hash + query-engine-hash + libquery-engine-hash + schema-engine-hash + binaryTargetBySystem + ; + }; in pkgs.lib.warnIf (nixpkgs != null) '' @@ -60,324 +42,10 @@ pkgs.lib.warnIf (nixpkgs != null) if your code has `inherit nixpkgs;`, replace it with `pkgs = nixpkgs;`. if your code has `nixpkgs = pkgs;`, replace it with `pkgs = pkgs;` or `inherit pkgs;`. '' - rec { - fromCommit = - commit: - if builtins.stringLength commit != 40 then - throw "nvalid commit: got ${commit}" - else - let - hostname = "binaries.prisma.sh"; - channel = "all_commits"; - binaryTarget = binaryTargetBySystem.${pkgs.system}; - isDarwin = pkgs.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 = pkgs.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; - - mkEnv = - package: - builtins.listToAttrs ( - builtins.map (file: { - name = file.variable; - value = "${package}/${file.path}"; - }) files - ); - /** - This function converts attrset to bash export style. - return value contains leading and trailing newlines. - - # Example - ```nix - toExportStyle { foo = "bar"; baz = "abc"; } - => - '' - export foo="bar" - export baz="abc" - '' - ``` - - # Type - toExportStyle :: Attrset -> String - */ - toExportStyle = - attrset: - "\n" + (concatMapAttrsStringSep "\n" (name: value: "export ${name}=\"${value}\"") attrset) + "\n"; - in - rec { - package = pkgs.stdenv.mkDerivation { - pname = "prisma-bin"; - version = commit; - nativeBuildInputs = [ - pkgs.zlib - openssl - pkgs.stdenv.cc.cc.lib - ] ++ pkgs.lib.optionals (!isDarwin) [ pkgs.autoPatchelfHook ]; - phases = [ - "buildPhase" - "postFixupHooks" - ]; - buildPhase = '' - mkdir -p $out/bin - mkdir -p $out/lib - ${pkgs.lib.concatStringsSep "\n" unzipCommands} - chmod +x $out/bin/* - ''; - }; - env = mkEnv package; - shellHook = toExportStyle env; - }; - fromPnpmLock = - path: - let - textAfter = keyword: text: builtins.elemAt (builtins.split keyword text) 1; - textBefore = keyword: text: builtins.elemAt (builtins.split keyword text) 0; - parsePnpmLockVersion = - pnpmLock: - if pkgs.lib.strings.hasPrefix "lockfileVersion: 5" pnpmLock then - "5" - else if pkgs.lib.strings.hasPrefix "lockfileVersion: '6" pnpmLock then - "6" - else - "9"; - pnpmLockParsers = { - # example line: - # /@prisma/engines-version/5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e: - "5" = - pnpmLock: - let - version = builtins.elemAt (builtins.split ":" (builtins.elemAt (builtins.split ("@prisma/engines-version/") pnpmLock) 2)) 0; - in - pkgs.lib.lists.last (pkgs.lib.strings.splitString "." version); - - # example line: - # /@prisma/engines-version@5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e: - "6" = - pnpmLock: - let - version = builtins.elemAt (builtins.split ":" (builtins.elemAt (builtins.split ("@prisma/engines-version@") pnpmLock) 2)) 0; - in - pkgs.lib.lists.last (pkgs.lib.strings.splitString "." version); - - # exmple line: - # '@prisma/engines-version@5.15.0-29.12e25d8d06f6ea5a0252864dd9a03b1bb51f3022': - "9" = - pnpmLock: - let - version = builtins.elemAt (builtins.split "'" (builtins.elemAt (builtins.split ("@prisma/engines-version@") pnpmLock) 2)) 0; - in - pkgs.lib.lists.last (pkgs.lib.strings.splitString "." version); - }; - pnpmLock = builtins.readFile path; - pnpmLockVersion = parsePnpmLockVersion pnpmLock; - pnpmLockParser = pnpmLockParsers.${pnpmLockVersion}; - commit = pnpmLockParser pnpmLock; - in - fromCommit commit; - fromNpmLock = - path: - let - packageLock = builtins.fromJSON (builtins.readFile path); - version = - if builtins.hasAttr "dependencies" packageLock then - packageLock.dependencies.${"@prisma/engines-version"}.version - else - packageLock.packages.${"node_modules/@prisma/engines-version"}.version; - commit = pkgs.lib.lists.last (pkgs.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 - # HACK: nix doesn't support JSONC parsing, so currently doing - # 1. remove whitespace and newline - # 2. replace ",}" with "}" - # 3. replace ",]" with "]" - # to support JSON with trailing comma. - # Keep in mind that this removes all whitespaces / tab / newline in the key / value - # and doesn't support comments. - fromJSONWithTrailingComma = - jsonc: - builtins.fromJSON ( - builtins.replaceStrings - [ - ",}" - ",]" - ] - [ - "}" - "]" - ] - ( - builtins.replaceStrings - [ - " " - "\t" - "\n" - ] - [ - "" - "" - "" - ] - jsonc - ) - ); - bunLockParsers = { - # example: - # nu> open bun.lock | from json | get packages.@prisma/engines-version.0 - # @prisma/engines-version@5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e - "0" = bunLockParsers."1"; - "1" = - lock: - afterLastDot ( - builtins.elemAt (lock."packages"."@prisma/engines-version" or (throw '' - nix-prisma-utils: lockfile parsing error: package @prisma/engines-version not found. - please make sure that you have @prisma/client installed. - '') - ) 0 - ); - }; - lockfile = fromJSONWithTrailingComma ( - assert builtins.typeOf path == "path"; - builtins.readFile path - ); - lockfileVersion = builtins.toString lockfile."lockfileVersion"; - parse = - bunLockParsers.${lockfileVersion} or (throw '' - nix-prisma-utils: Unsupported lockfile version: ${lockfileVersion} - nix-prisma-utils currently supports bun.lock version of 0 and 1. - ''); - commit = parse lockfile; - in - fromCommit commit; + { + inherit fromCommit; + fromPnpmLock = path: fromCommit (parsers.pnpmLock path); + fromNpmLock = path: fromCommit (parsers.npmLock path); + fromYarnLock = path: fromCommit (parsers.yarnLock path); + fromBunLock = path: fromCommit (parsers.bunLock path); } diff --git a/readme.md b/readme.md index af7b979..819768c 100644 --- a/readme.md +++ b/readme.md @@ -27,6 +27,7 @@ With nix-prisma-utils it's the other way around. You can simply install prisma t inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; prisma-utils.url = "github:VanCoding/nix-prisma-utils"; + prisma-utils.inputs.nixpkgs.follows = "nixpkgs"; # force nix-prisma-utils to use same version of nixpkgs, to avoid package duplication. }; outputs = @@ -65,6 +66,7 @@ both yarn v1 and yarn-berry should work. inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; prisma-utils.url = "github:VanCoding/nix-prisma-utils"; + prisma-utils.inputs.nixpkgs.follows = "nixpkgs"; # force nix-prisma-utils to use same version of nixpkgs, to avoid package duplication. }; outputs = @@ -98,6 +100,7 @@ both yarn v1 and yarn-berry should work. inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; prisma-utils.url = "github:VanCoding/nix-prisma-utils"; + prisma-utils.inputs.nixpkgs.follows = "nixpkgs"; # force nix-prisma-utils to use same version of nixpkgs, to avoid package duplication. }; outputs = @@ -134,6 +137,7 @@ both yarn v1 and yarn-berry should work. inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; prisma-utils.url = "github:VanCoding/nix-prisma-utils"; + prisma-utils.inputs.nixpkgs.follows = "nixpkgs"; # force nix-prisma-utils to use same version of nixpkgs, to avoid package duplication. }; outputs = diff --git a/tests.nix b/tests.nix index fa3ff4d..3092258 100644 --- a/tests.nix +++ b/tests.nix @@ -50,7 +50,7 @@ let echo "testing npm" cd npm npm ci - ./node_modules/.bin/prisma generate + npm prisma generate ''; }; test-pnpm = @@ -67,7 +67,7 @@ let echo "testing pnpm" cd pnpm pnpm install - ./node_modules/.bin/prisma generate + pnpm prisma generate ''; }; test-bun = diff --git a/utils/default.nix b/utils/default.nix new file mode 100644 index 0000000..04805bf --- /dev/null +++ b/utils/default.nix @@ -0,0 +1,68 @@ +{ lib, callPackage }: +let + 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); + # example: + # a.b123c.d.e12345 + # => e12345 + afterLastDot = text: lib.lists.last (lib.strings.splitString "." text); + + # polyfill: the function in nixpkgs is implemented on Dec 6, 2024. replace this with one from pkgs.lib after 24.11 reaches EOL. + concatMapAttrsStringSep = + sep: f: attrs: + lib.concatStringsSep sep (lib.attrValues (lib.mapAttrs f attrs)); + + readYAML = callPackage ./readYAML.nix { }; + fromJSONWithTrailingCommas = callPackage ./fromJSONWithTrailingCommas.nix { }; + + /** + This function converts attrset to bash export style. + return value contains leading and trailing newlines. + + # Example + ```nix + toExportStyle { foo = "bar"; baz = "abc"; } + => + '' + export foo="bar" + export baz="abc" + '' + ``` + + # Type + toExportStyle :: Attrset -> String + */ + toExportStyle = + attrset: + "\n" + (concatMapAttrsStringSep "\n" (name: value: "export ${name}=\"${value}\"") attrset) + "\n"; +in +{ + inherit + lines + _splitMultiple + splitMultiple + splitMultipleAndFilterEmpty + afterLastDot + concatMapAttrsStringSep + readYAML + fromJSONWithTrailingCommas + toExportStyle + ; +} diff --git a/utils/fromJSONWithTrailingCommas.nix b/utils/fromJSONWithTrailingCommas.nix new file mode 100644 index 0000000..6fd24ea --- /dev/null +++ b/utils/fromJSONWithTrailingCommas.nix @@ -0,0 +1,14 @@ +# HACK: nix doesn't support JSONC parsing, so currently doing +# 1. remove whitespace and newline +# 2. replace ",}" with "}" +# 3. replace ",]" with "]" +# to support JSON with trailing comma. +# Keep in mind that this removes all whitespaces / tab / newline in the key / value +# and doesn't support comments. +{ }: +jsonc: +builtins.fromJSON ( + builtins.replaceStrings [ ",}" ",]" ] [ "}" "]" ] ( + builtins.replaceStrings [ " " "\t" "\n" ] [ "" "" "" ] jsonc + ) +) diff --git a/lib/readYAML.nix b/utils/readYAML.nix similarity index 100% rename from lib/readYAML.nix rename to utils/readYAML.nix