Siddarth Kumar ce69df19ac
apply patches with patch files (#19451)
fixes #19449

In this commit we change the way patches are applied.
We no longer have to write patches in a patch phase like we used to, we can now place individual changes in a patch file inside the `patches` directory and they will be automatically applied.

Because of this change we can get rid of forks and instead have those changes in patch files.

To generate a patch file this make command can be used `make patch-file`
This will open an interactive shell which will allow you to specify which file you want to patch and then wait till you make those changes and generate a patch for it.

```
make patch-file
Configuring Nix shell for target 'default'...
Enter the path of the file to patch: ./node_modules/is-glob/index.js
File to patch: ./node_modules/is-glob/index.js
Temporary directory created: /tmp/tmp-status-mobile-40bc588fa/tmp.xrXarXoTPZ
Original file copied to temporary directory.
Please make the necessary changes to the file: ./node_modules/is-glob/index.js
Press any key when you are done with the changes...
Generating patch file...
Patch file created at /Users/siddarthkumar/code/status-im/PR/status-mobile/patches/index.js.patch
Info: Please execute 'make run-clojure' to test if the patch file works as expected.
```

- Android
- iOS
2024-04-08 21:06:41 +05:30

73 lines
2.1 KiB
Nix

# This derivation patches Node.js dependencies by
# taking the result of yarn2nix and symlinking what is fine,
# and copying and modifying what needs to be adjusted.
{ stdenv, deps, nodejs, patchMavenSources }:
let
patchesDir = ./../../../patches;
patches = builtins.attrNames (builtins.readDir patchesDir);
in
stdenv.mkDerivation {
name = "${deps.nodejs.name}-patched";
phases = [
"unpackPhase"
"patchGradlePhase"
"patchNodeLibsPhase"
"installPhase"
];
# First symlink all modules as is
# WARNING: Metro has issues when dealing with symlinks!
unpackPhase = ''
mkdir -p ./node_modules/
for module in $(ls ${deps.nodejs}/node_modules); do
ln -s ${deps.nodejs}/node_modules/$module ./node_modules/
done
cp -r ${deps.nodejs}/node_modules/.bin ./node_modules/
'';
# Patch build.gradle files in 'react-native-*' dependencies to replace
# maven and google central repositories with our own local directories.
# This prevents the builder from downloading Maven artifacts
patchGradlePhase = ''
gradleConfigs=$(
find -L ./node_modules \
-name build.gradle -or \
-name build.gradle.kts -or \
-name settings.gradle -or \
-name settings.gradle.kts
)
for modBuildGradle in $gradleConfigs; do
relativeToNode=''${modBuildGradle#*node_modules/}
moduleName=''${relativeToNode%%/*}
if [[ -L ./node_modules/$moduleName ]]; then
unlink ./node_modules/$moduleName
cp -r ${deps.nodejs}/node_modules/$moduleName ./node_modules/
chmod u+w -R ./node_modules/$moduleName
fi
${patchMavenSources} $modBuildGradle
done
'';
installPhase = ''
mkdir -p $out
cp -R node_modules $out/
'';
patchNodeLibsPhase = ''
for patch in ${toString patches}; do
patch -p1 < ${patchesDir}/$patch
done
'';
# The ELF types are incompatible with the host platform, so let's not even try
# TODO: Use Android NDK to strip binaries manually
dontPatchELF = true;
dontStripHost = true;
# Take whole sources into consideration when calculating sha
outputHashMode = "recursive";
outputHashAlgo = "sha256";
}