at master 157 lines 4.7 kB view raw
1# callPackage args 2{ 3 lib, 4 stdenv, 5 go, 6 xcaddy, 7 cacert, 8 git, 9 caddy, 10}: 11 12let 13 inherit (builtins) hashString; 14 inherit (lib) 15 assertMsg 16 concatMapStrings 17 elemAt 18 fakeHash 19 filter 20 hasInfix 21 length 22 lessThan 23 sort 24 toShellVar 25 ; 26in 27 28# pkgs.caddy.withPlugins args 29{ 30 plugins, 31 hash ? fakeHash, 32 doInstallCheck ? true, 33}: 34 35let 36 pluginsSorted = sort lessThan plugins; 37 pluginsList = concatMapStrings (plugin: "${plugin}-") pluginsSorted; 38 pluginsHash = hashString "md5" pluginsList; 39 pluginsWithoutVersion = filter (p: !hasInfix "@" p) pluginsSorted; 40in 41 42# eval barrier: user provided plugins must have tags 43# the go module must either be tagged in upstream repo 44# or user must provide commit sha or a pseudo-version number 45# https://go.dev/doc/modules/version-numbers#pseudo-version-number 46assert assertMsg ( 47 length pluginsWithoutVersion == 0 48) "Plugins must have tags present (e.g. ${elemAt pluginsWithoutVersion 0}@x.y.z)!"; 49 50caddy.overrideAttrs ( 51 finalAttrs: prevAttrs: { 52 vendorHash = null; 53 subPackages = [ "." ]; 54 55 src = stdenv.mkDerivation { 56 pname = "caddy-src-with-plugins-${pluginsHash}"; 57 version = finalAttrs.version; 58 59 nativeBuildInputs = [ 60 go 61 xcaddy 62 cacert 63 git 64 ]; 65 dontUnpack = true; 66 buildPhase = 67 let 68 withArgs = concatMapStrings (plugin: "--with ${plugin} ") pluginsSorted; 69 in 70 '' 71 export GOCACHE=$TMPDIR/go-cache 72 export GOPATH="$TMPDIR/go" 73 XCADDY_SKIP_BUILD=1 TMPDIR="$PWD" xcaddy build v${finalAttrs.version} ${withArgs} 74 (cd buildenv* && go mod vendor) 75 ''; 76 installPhase = '' 77 mv buildenv* $out 78 ''; 79 80 outputHashMode = "recursive"; 81 outputHash = hash; 82 outputHashAlgo = "sha256"; 83 }; 84 85 # xcaddy built output always uses pseudo-version number 86 # we enforce user provided plugins are present and have matching tags here 87 inherit doInstallCheck; 88 installCheckPhase = '' 89 runHook preInstallCheck 90 91 declare -A modules errors 92 ${toShellVar "notfound" pluginsSorted} 93 94 # put build info that we care about into `modules` list 95 while read -r kind module version _; do 96 case "$kind" in 97 'dep'|'=>') 98 modules[$module]=$version 99 ;; 100 *) 101 # we only care about 'dep' and '=>' directives for now 102 ;; 103 esac 104 done < <($out/bin/caddy build-info) 105 106 # compare build-time (Nix side) against runtime (Caddy side) 107 for spec in "''${notfound[@]}"; do 108 if [[ $spec == *=* ]]; then 109 # orig=repl_mod@repl_ver 110 orig=''${spec%%=*} 111 repl=''${spec#*=} 112 repl_mod=''${repl%@*} 113 repl_ver=''${repl#*@} 114 115 if [[ -z ''${modules[$orig]} ]]; then 116 errors[$spec]="plugin \"$spec\" with replacement not found in build info:\n reason: \"$orig\" missing" 117 elif [[ -z ''${modules[$repl_mod]} ]]; then 118 errors[$spec]="plugin \"$spec\" with replacement not found in build info:\n reason: \"$repl_mod\" missing" 119 elif [[ "''${modules[$repl_mod]}" != "$repl_ver" ]]; then 120 errors[$spec]="plugin \"$spec\" have incorrect tag:\n specified: \"$spec\"\n got: \"$orig=$repl_mod@''${modules[$repl_mod]}\"" 121 fi 122 else 123 # mod@ver 124 mod=''${spec%@*} 125 ver=''${spec#*@} 126 127 if [[ -z ''${modules[$mod]} ]]; then 128 errors[$spec]="plugin \"$spec\" not found in build info" 129 elif [[ "''${modules[$mod]}" != "$ver" ]]; then 130 errors[$spec]="plugin \"$spec\" have incorrect tag:\n specified: \"$spec\"\n got: \"$mod@''${modules[$mod]}\"" 131 fi 132 fi 133 done 134 135 # print errors if any 136 if [[ ''${#errors[@]} -gt 0 ]]; then 137 for spec in "''${!errors[@]}"; do 138 printf "Error: ''${errors[$spec]}\n" >&2 139 done 140 141 echo "Tips:" 142 echo "If:" 143 echo " - you are using module replacement (e.g. \`plugin1=plugin2@version\`)" 144 echo " - the provided Caddy plugin is under a repository's subdirectory, and \`go.{mod,sum}\` files are not in that subdirectory" 145 echo " - you have custom build logic or other advanced use cases" 146 echo "Please consider:" 147 echo " - set \`doInstallCheck = false\`" 148 echo " - write your own \`installCheckPhase\` and override the default script" 149 echo "If you are sure this error is caused by packaging, or by caddy/xcaddy, raise an issue with upstream or nixpkgs" 150 151 exit 1 152 fi 153 154 runHook postInstallCheck 155 ''; 156 } 157)