summaryrefslogtreecommitdiff
path: root/bash/SOURCES.bash
blob: 2f06c68335ae2bb7eaefcda2514e8199a7608bcd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/bin/bash
source()
{
	if	[[ $1 != */* ]] &&
	    	(
			command -v base64_embedded_source__"$1" >/dev/null ||
			[ -f src/"$1" ]
		)
	then
		rewrite_self \
			"$1" \
			src/"$1" \
			base64_embedded_source__"$1" \
			"${@:2}"
	else
		builtin source "$@"
	fi
}

denominate_function()
{
	declare -n func_name="$1"
	local func_output_b64encoded output_hash
	read -r -d '' \
		func_output_b64encoded \
		< <(base64) || [ "$func_output_b64encoded" ]
	read output_hash _ \
		< <(base64 -d <<< "$func_output_b64encoded" | sha256sum)
	[ ${#output_hash} = 64 ] || return
	func_name=SHA256_${output_hash:0:32}
	source <(cat <<END
${func_name} ()
{
base64 -d <<.
${func_output_b64encoded}
.
}
END
)
}

rewrite_self()
{
	declare -n do_rewrite=do_rewrite${RANDOM}
	do_rewrite=

	if	! command -v "$3" >/dev/null
	then
		[ -f "$2" ] || return
		if	[ -w "$0" ]
		then
			do_rewrite=$(mktemp) || return
			builtin source \
				<(stdin_to_function "$3" < "$2" |
				tee "$do_rewrite") || return
		else
			builtin source \
				<(stdin_to_function "$3" < "$2") || return
		fi
		command -v "$3" >/dev/null || return
	fi

	builtin source <("$3") "${@:4}" || return

	[ "$do_rewrite" ] || return 0

	if	sed \
		-i~"$(date -Ins)" \
		-e "1 { r ${do_rewrite}"$'\n'" }" \
		"$0"
	then
		local r=0
	else
		local r=$?
	fi
	rm "$do_rewrite"
	return $r
}

stdin_to_function()
{
	cat <<.
${1}()
{
	base64 -d <<.
$(base64 && echo .)
}
.
}

print_test_script_for_SOURCES.bash()
{
	cat <<.
#!/bin/bash
source SOURCES.bash
source SOURCES.bash
source rpc.bash
r()
{
	: base64_embedded_source__SOURCES.bash
	: base64_embedded_source__rpc.bash
	: base64_embedded_source__dependencies.bash
	source SOURCES.bash
	source rpc.bash
	BASH_RPC_REMOTE_DEST=localhost remote_run_function uptime
}
BASH_RPC_REMOTE_DEST=localhost \\
	remote_run_function \\
		r
.
}

setup_test_dir()
{
	(
		set -e
		mkdir -p test_SOURCES.bash
		cd test_SOURCES.bash
		mkdir -p src
		ln -sf -t src \
			../../SOURCES.bash \
			../../src/{rpc,dependencies}.bash
		print_test_script_for_SOURCES.bash > test-SOURCES.bash
	)
}

run_test()
{
	(
		set -ex
		cd test_SOURCES.bash
		PATH=$PWD/src:$PATH bash test-SOURCES.bash || true
		PATH=$PWD/src:$PATH bash test-SOURCES.bash
	)
}

bootstrap_SOURCES.bash()
{
	setup_test_dir && run_test
}

[ "$0" = 'bootstrap_SOURCES.bash' ] && bootstrap_SOURCES.bash