pthbs

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

pthbs-makegen (5582B)


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