pthbs

Packaging Through Hashed Build Scripts
git clone https://ccx.te2000.cz/git/pthbs
Log | Files | Refs | Submodules | README

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"