Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at domenkozar-patch-1 80 lines 2.6 kB view raw
1# This function downloads and normalizes a patch/diff file. 2# This is primarily useful for dynamically generated patches, 3# such as GitHub's or cgit's, where the non-significant content parts 4# often change with updating of git or cgit. 5# stripLen acts as the -p parameter when applying a patch. 6 7{ lib, fetchurl, patchutils }: 8 9{ relative ? null 10, stripLen ? 0 11, extraPrefix ? null 12, excludes ? [] 13, includes ? [] 14, revert ? false 15, postFetch ? "" 16, ... 17}@args: 18let 19 args' = if relative != null then { 20 stripLen = 1 + lib.length (lib.splitString "/" relative) + stripLen; 21 extraPrefix = if extraPrefix != null then extraPrefix else ""; 22 } else { 23 inherit stripLen extraPrefix; 24 }; 25in let 26 inherit (args') stripLen extraPrefix; 27in 28lib.throwIfNot (excludes == [] || includes == []) 29 "fetchpatch: cannot use excludes and includes simultaneously" 30fetchurl ({ 31 postFetch = '' 32 tmpfile="$TMPDIR/patch" 33 34 if [ ! -s "$out" ]; then 35 echo "error: Fetched patch file '$out' is empty!" 1>&2 36 exit 1 37 fi 38 39 "${patchutils}/bin/lsdiff" \ 40 ${lib.optionalString (relative != null) "-p1 -i ${lib.escapeShellArg relative}/'*'"} \ 41 "$out" \ 42 | sort -u | sed -e 's/[*?]/\\&/g' \ 43 | xargs -I{} \ 44 "${patchutils}/bin/filterdiff" \ 45 --include={} \ 46 --strip=${toString stripLen} \ 47 ${lib.optionalString (extraPrefix != null) '' 48 --addoldprefix=a/${lib.escapeShellArg extraPrefix} \ 49 --addnewprefix=b/${lib.escapeShellArg extraPrefix} \ 50 ''} \ 51 --clean "$out" > "$tmpfile" 52 53 if [ ! -s "$tmpfile" ]; then 54 echo "error: Normalized patch '$tmpfile' is empty (while the fetched file was not)!" 1>&2 55 echo "Did you maybe fetch a HTML representation of a patch instead of a raw patch?" 1>&2 56 echo "Fetched file was:" 1>&2 57 cat "$out" 1>&2 58 exit 1 59 fi 60 61 ${patchutils}/bin/filterdiff \ 62 -p1 \ 63 ${builtins.toString (builtins.map (x: "-x ${lib.escapeShellArg x}") excludes)} \ 64 ${builtins.toString (builtins.map (x: "-i ${lib.escapeShellArg x}") includes)} \ 65 "$tmpfile" > "$out" 66 67 if [ ! -s "$out" ]; then 68 echo "error: Filtered patch '$out' is empty (while the original patch file was not)!" 1>&2 69 echo "Check your includes and excludes." 1>&2 70 echo "Normalized patch file was:" 1>&2 71 cat "$tmpfile" 1>&2 72 exit 1 73 fi 74 '' + lib.optionalString revert '' 75 ${patchutils}/bin/interdiff "$out" /dev/null > "$tmpfile" 76 mv "$tmpfile" "$out" 77 '' + postFetch; 78} // builtins.removeAttrs args [ 79 "relative" "stripLen" "extraPrefix" "excludes" "includes" "revert" "postFetch" 80])