pthbs-makegen (5308B)
1 #!/bin/sh 2 if test -n "$pthbs_xtrace"; then set -x; fi 3 bsh=$(sha256sum $1) || exit $? 4 bsh=${bsh%% *} 5 if test -z "$pthbs_workdir"; then 6 printf '%s\n' >&2 "$0: fatal: pthbs_workdir env var undefined or empty" 7 exit 100 8 fi 9 if test -z "$pthbs_cache"; then 10 printf '%s\n' >&2 "$0: fatal: pthbs_cache env var undefined or empty" 11 exit 100 12 fi 13 if test -z "$pthbs_indexdir"; then 14 printf '%s\n' >&2 "$0: fatal: pthbs_indexdir env var undefined or empty" 15 exit 100 16 fi 17 workdir=$pthbs_workdir/builddir.$$ 18 script=$(realpath "$1") 19 20 pthbs_package=${1##*/} 21 pthbs_package=${pthbs_package%%:*}.$bsh 22 23 exec env \ 24 workdir="$workdir" \ 25 script="$script" \ 26 scriptname="${script##*/}" \ 27 bsh="$bsh" \ 28 package="$pthbs_package" \ 29 makedir="$pthbs_cache/make" \ 30 awk -v single_quote="'" ' 31 BEGIN { 32 downloadlist_path=ENVIRON["pthbs_indexdir"]"/downloadlist.sha256" 33 filelist_path=ENVIRON["pthbs_indexdir"]"/filelist.sha256" 34 printf "DBG: reading downloadlist: %s\n", downloadlist_path >"/dev/stderr" 35 while(getline <downloadlist_path) { 36 downloadable_hashes["sha256",$1] = 1 37 } 38 close(downloadlist_path) 39 40 printf "DBG: reading filelist: %s\n", filelist_path >"/dev/stderr" 41 while(getline <filelist_path) { 42 linkable_hashes["sha256",$1] = 1 43 } 44 close(filelist_path) 45 46 settings["sandbox"] = 1 47 settings["set_path"] = 1 48 dep_count = 0 49 env_count = 0 50 is_envfile = ENVIRON["script"] ~ /\.environment$/ 51 if(is_envfile) { 52 envname = substr(ENVIRON["scriptname"], 1, length(ENVIRON["scriptname"])-12) 53 } 54 FS=":" 55 } 56 57 function q(s) { # quote string for sh 58 gsub(single_quote, single_quote "\\" single_quote single_quote, s) 59 return single_quote s single_quote 60 } 61 62 function fatal(msg) { 63 printf "FATAL: pthbs-makegen: %s %s:%d: \"%s\"\n", msg, FILENAME, FNR, $0 >"/dev/stderr" 64 exit 1 65 } 66 67 function have_file(hash_type, file_hash) { 68 if(((hash_type, file_hash) in linkable_hashes)) { 69 deps[++dep_count] = "$(cache)/link/file-"hash_type"/.local" 70 return 71 } 72 if(((hash_type, file_hash) in downloadable_hashes)) { 73 deps[++dep_count] = "$(cache)/make/file."hash_type"."file_hash".downloaded" 74 return 75 } 76 fatal("Could not determine source for file "hash_type":"file_hash) 77 } 78 function have_git_commit(commit_id) { 79 deps[++dep_count] = "$(cache)/link/git-commit-sha1/.local" 80 } 81 82 function have_envdep(package) { 83 if(match(package, "[.][0-9a-f]{64}$") == 0) { 84 fatal("invalid syntax for @sha256:") 85 } 86 env[++env_count] = package 87 package_hash = substr(package, 64, RSTART+1) 88 envdep[env_count] = "$(versions)/"package"/.install-links" 89 } 90 91 function make_envfile( n, envfile, envhash) { 92 if(!env_count) { 93 fatal("environment is empty") 94 } 95 envfile = ENVIRON["makedir"] "/package.sha256."ENVIRON["bsh"]".env" 96 for(n=1; n<=env_count; n++) { 97 print env[n] >envfile 98 } 99 close(envfile) 100 if(("pthbs-getenvhash "q(envfile) | getline) < 1) { 101 fatal("Error getting envhash from "q(envfile)) 102 } 103 envhash=$0 104 if(match(envhash, "^[0-9a-f]{64}$") == 0) { 105 fatal("received invalid envhash: "q(envhash)) 106 } 107 deps[++dep_count] = "$(versions)/env."envhash"/.pthbs-env" 108 printf "ifndef %s\n", "env_"envhash"_defined" 109 printf "%s:", "$(versions)/env."envhash"/.pthbs-env" 110 for(n=1; n<=env_count; n++) { 111 printf " %s", envdep[n] 112 } 113 printf "\n\t@%s", "printf "q("Creating environment for %s => %s\\n")" "q(FILENAME)" "q("$(versions)/env."envhash) 114 printf "\n\t%s", "if test -e "q("$(versions)/env."envhash)"; then rm -r "q("$(versions)/env."envhash)"; fi" 115 printf "\n\t%s", "mkdir -p "q("$(versions)/env."envhash"/env") 116 for(n=1; n<=env_count; n++) { 117 printf "\n\t%s", "pthbs-link "q("$(versions)/"env[n])" "q("$(versions)/env."envhash) 118 } 119 printf "\n\t%s", "pthbs-enter-gen "q("$(versions)/env."envhash) 120 printf "\n\t%s\n\n", "sort -u <"q(envfile)" >"q("$@") 121 printf "%s\n", "env_"envhash"_defined="ENVIRON["scriptname"] 122 printf "%s\n", "endif" 123 return envhash 124 } 125 /^#!/ { next } 126 /^#\+/ { 127 if($0 == "#+*") { 128 settings["sandbox"] = 0 129 } else { 130 have_envdep(substr($0, 3)) 131 } 132 next 133 } 134 /^#@/ && !is_envfile { 135 if($1 == "#@git") { 136 have_git_commit($2) 137 } else if($1 == "#@pragma") { 138 if($2 == "nosandbox") { 139 settings["sandbox"] = 0 140 } else if($2 == "nopath") { 141 settings["set_path"] = 0 142 } else { 143 fatal("unrecognized @pragma:") 144 } 145 next 146 } else if($1 == "#@sha256") { 147 if(match($0, "^#@sha256:[0-9a-f]+:") == 0) { 148 fatal("invalid syntax for @sha256:") 149 } 150 have_file("sha256", $2) 151 } else if($1 == "#@untar") { 152 if(match($0, "^#@untar:[^:]*:sha256:[0-9a-f]+:") == 0) { 153 fatal("invalid syntax for @untar:") 154 } 155 have_file("sha256", $4) 156 } else { 157 fatal("unrecognized @command:") 158 } 159 next 160 } 161 /^$/ && !is_envfile { 162 if(env_count) { 163 make_envfile() 164 } 165 printf "%s", "$(versions)/"ENVIRON["package"]"/.install-links:" 166 for(n=1; n<=dep_count; n++) { 167 printf " %s", deps[n] 168 } 169 printf "\n\t%s\n", "if test -f "q("$@")"; then touch "q("$@")"; else pthbs-build "q(ENVIRON["script"])"; fi" 170 has_body = 1 171 exit 0 172 } 173 { 174 fatal("unexpected line") 175 } 176 END{ 177 if(!is_envfile){ 178 if(has_body) { exit 0 } 179 fatal("no build script present") 180 } 181 env_installdir = "$(versions)/env." make_envfile() 182 printf "%s: %s %s\n", ENVIRON["scriptname"], env_installdir"/.pthbs-env", "$(cache)/namedenv/.exists" 183 printf "\t%s\n\n", "pthbs-namedenv "q(env_installdir)" "q(envname) 184 printf ".PHONY: %s\n", ENVIRON["scriptname"] 185 } 186 ' "$script"