Project

General

Profile

Download (7.35 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / build.sh @ 96068ada

1
#!/bin/sh
2

    
3
# Copyright (C) 2021 Wojtek Kosior
4
# Redistribution terms are gathered in the `copyright' file.
5

    
6
handle_export_line() {
7
    if [ "x$1" = "xEXPORTS_START" ]; then
8
	if [ "$STATE" = "before_block" ]; then
9
	    STATE="in_block"
10
	fi
11
    elif [ "x$1" = "xEXPORT" ]; then
12
	if [ "$STATE" != "in_block" ]; then
13
	    return
14
	fi
15

    
16
	EXPORTCODE="${EXPORTCODE}window.killtheweb.$2 = $2;$ENDL"
17

    
18
	PREVIOUS_FILE="$(map_get EXPORTS $2)"
19
	if [ "x$PREVIOUS_FILE" != "x" ]; then
20
	    errcho "export $2 present in both $PREVIOUS_FILE and $FILE"
21
	    return 1
22
	fi
23

    
24
	map_set_instr EXPORTS $2 "$FILE"
25

    
26
    elif [ "x$1" = "xEXPORTS_END" ]; then
27
	if [ "$STATE" = "in_block" ]; then
28
	    STATE="after_block"
29
	fi
30
    fi
31
}
32

    
33
translate_exports() {
34
    STATE="before_block"
35
    EXPORTCODE=''
36

    
37
    while read EXPORT_LINE; do
38
	handle_export_line $EXPORT_LINE || return 1
39
    done
40

    
41
    map_set_instr EXPORTCODES $FILEKEY "$EXPORTCODE"
42
}
43

    
44
add_exports() {
45
    FILE="$1"
46
    FILEKEY="$(sanitize "$FILE")"
47

    
48
    eval "$(grep -o 'EXPORT.\+' "$1" | translate_exports || exit 1)"
49
}
50

    
51
handle_import_line() {
52
    if [ "x$1" = "xIMPORTS_START" ]; then
53
	if [ "$STATE" = "before_block" ]; then
54
	    STATE="in_block"
55
	fi
56
    elif [ "x$1" = "xIMPORT" ]; then
57
	if [ "$STATE" != "in_block" ]; then
58
	    return
59
	fi
60

    
61
	IMPORTCODE="${IMPORTCODE}const $2 = window.killtheweb.$2;$ENDL"
62

    
63
	IMPORTS="$IMPORTS $2"
64

    
65
    elif [ "x$1" = "xIMPORTS_END" ]; then
66
	if [ "$STATE" = "in_block" ]; then
67
	    STATE="after_block"
68
	fi
69
    fi
70
}
71

    
72
translate_imports() {
73
    STATE="before_block"
74
    IMPORTCODE=''
75
    IMPORTS=''
76

    
77
    while read IMPORT_LINE; do
78
	handle_import_line $IMPORT_LINE || return 1
79
    done
80

    
81
    map_set_instr IMPORTCODES $FILEKEY "$IMPORTCODE"
82
    map_set_instr IMPORTS $FILEKEY "$IMPORTS"
83
}
84

    
85
add_imports() {
86
    FILE="$1"
87
    FILEKEY="$(sanitize "$FILE")"
88

    
89
    eval "$(grep -o 'IMPORT.\+' "$1" | translate_imports || exit 1)"
90
}
91

    
92
compute_scripts_list_rec() {
93
    local FILE="$1"
94
    local FILEKEY=$(sanitize "$1")
95

    
96
    local FILESTATE="$(map_get FILESTATES $FILEKEY)"
97
    if [ "xprocessed" = "x$FILESTATE" ]; then
98
	return
99
    fi
100
    if [ "xprocessing" = "x$FILESTATE" ]; then
101
	errcho "import loop on $FILE"
102
	return 1
103
    fi
104

    
105
    USED="$USED $FILEKEY"
106

    
107
    map_set FILESTATES $FILEKEY "processing"
108

    
109
    local IMPORT
110
    for IMPORT in $(map_get IMPORTS $FILEKEY); do
111
	NEXT_FILE="$(map_get EXPORTS $IMPORT)"
112
	if [ "x" = "x$NEXT_FILE" ]; then
113
	    errcho "nothing exports $IMPORT, required by $FILE"
114
	    return 1
115
	fi
116
	if ! compute_scripts_list_rec "$NEXT_FILE"; then
117
	    errcho "when satisfying $IMPORT for $FILE"
118
	    return 1
119
	fi
120
    done
121

    
122
    [ "x$FILE" = "xexports_init.js" ] || echo $FILE # exports_init.js is hardcoded to load first; the entire export system depends on it
123
    map_set FILESTATES $FILEKEY "processed"
124
}
125

    
126
compute_scripts_list() {
127
    USED=''
128
    echo COMPUTED_SCRIPTS=\"exports_init.js
129
    compute_scripts_list_rec "$1"
130
    echo \"
131

    
132
    for FILEKEY in $USED; do
133
	map_set_instr USED $FILEKEY yes
134
    done
135
}
136

    
137
as_json_list() {
138
    while true; do
139
	if [ "x" = "x$2" ]; then
140
	    echo -n '\\n'"\t\t\"$1\""'\\n\t'
141
	    return
142
	fi
143
	echo -n '\\n'"\t\t\"$1\","
144
	shift
145
    done
146
}
147

    
148
as_html_list() {
149
    while [ "x" != "x$1" ]; do
150
	echo -n '\\n'"    <script src=\"/$1\"></script>"
151
	shift
152
    done
153
}
154

    
155
build_main() {
156
    # placate importers of these, as they are exported by the yet-to-be-created exports_init.js
157
    EXPORTS__browser=exports_init.js
158
    EXPORTS__is_chrome=exports_init.js
159
    EXPORTS__is_mozilla=exports_init.js
160

    
161
    SCRIPTDIRS='background html common content'
162

    
163
    SCRIPTS=$(find $SCRIPTDIRS -name '[^.#]*.js')
164

    
165
    for SCRIPT in $SCRIPTS; do
166
	add_exports $SCRIPT
167
	add_imports $SCRIPT
168
    done
169

    
170
    eval "$(compute_scripts_list background/main.js || exit 1)"
171
    BGSCRIPTS="$(as_json_list $COMPUTED_SCRIPTS)"
172
    eval "$(compute_scripts_list content/main.js || exit 1)"
173
    CONTENTSCRIPTS="$(as_json_list $COMPUTED_SCRIPTS)"
174
    eval "$(compute_scripts_list html/display-panel.js || exit 1)"
175
    POPUPSCRIPTS="$(as_html_list $COMPUTED_SCRIPTS)"
176
    eval "$(compute_scripts_list html/options_main.js || exit 1)"
177
    OPTIONSSCRIPTS="$(as_html_list $COMPUTED_SCRIPTS)"
178

    
179
    for DIR in $(find $SCRIPTDIRS -type d); do
180
	mkdir -p "$BUILDDIR"/$DIR
181
    done
182

    
183
    CHROMIUM_UPDATE_URL=''
184
    GECKO_APPLICATIONS=''
185

    
186
    if [ "x$UPDATE_URL" != x ]; then
187
	UPDATE_URL=",\n    \"update_url\": \"$UPDATE_URL\""
188
    fi
189

    
190
    if [ "$BROWSER" = "chromium" ]; then
191
	CHROMIUM_UPDATE_URL="$UPDATE_URL"
192
    else
193
	GECKO_APPLICATIONS="\n\
194
    \"applications\": {\n\
195
	\"gecko\": {\n\
196
	    \"id\": \"{6fe13369-88e9-440f-b837-5012fb3bedec}\",\n\
197
	    \"strict_min_version\": \"60.0\"$UPDATE_URL\n\
198
	}\n\
199
    },"
200
    fi
201

    
202
    sed "\
203
s^_GECKO_APPLICATIONS_^$GECKO_APPLICATIONS^
204
s^_CHROMIUM_UPDATE_URL_^$CHROMIUM_UPDATE_URL^
205
s^_BGSCRIPTS_^$BGSCRIPTS^
206
s^_CONTENTSCRIPTS_^$CONTENTSCRIPTS^" \
207
	< manifest.json > "$BUILDDIR"/manifest.json
208

    
209
    ./process_html_file.sh html/display-panel.html |
210
	sed "s^_POPUPSCRIPTS_^$POPUPSCRIPTS^" \
211
	    > "$BUILDDIR"/html/display-panel.html
212

    
213
    ./process_html_file.sh html/options.html |
214
	sed "s^_OPTIONSSCRIPTS_^$OPTIONSSCRIPTS^" \
215
	    > "$BUILDDIR"/html/options.html
216

    
217
    for FILE in $SCRIPTS; do
218
	FILEKEY=$(sanitize "$FILE")
219
	if [ "xyes" != "x$(map_get USED $FILEKEY)" ]; then
220
	    errcho "WARNING! $FILE not used"
221
	else
222
	    (echo "\
223
\"use strict\";
224

    
225
({fun: (function() {
226
$(map_get IMPORTCODES $FILEKEY)
227

    
228
";
229

    
230
# A hack to insert the contents of default_settings.json at the appropriate location in background/main.js
231
if [ "$FILE" = "background/main.js" ]; then
232
    # Uses an internal sed expression to escape and indent the JSON file for use in the external sed expression
233
    sed 's/^        `DEFAULT SETTINGS`$/'"$(sed -E 's/([\\\&\/])/\\\1/g; s/^/        /; s/$/\\/' < default_settings.json) "/g < "$FILE"
234
else
235
    cat $FILE
236
fi
237

    
238
echo "
239

    
240
$(map_get EXPORTCODES $FILEKEY)
241
})}).fun();") > "$BUILDDIR"/$FILE
242
	fi
243
    done
244

    
245
    if [ "$BROWSER" = "chromium" ]; then
246
	cat > "$BUILDDIR"/exports_init.js <<EOF
247
window.killtheweb={is_chrome: true, browser: window.chrome};
248
EOF
249
    else
250
	cat > "$BUILDDIR"/exports_init.js <<EOF
251
/* Polyfill for IceCat 60. */
252
String.prototype.matchAll = String.prototype.matchAll || function(regex) {
253
    if (regex.flags.search("g") === -1)
254
        throw new TypeError("String.prototype.matchAll called with a non-global RegExp argument");
255

    
256
    for (const matches = [];;) {
257
        if (matches[matches.push(regex.exec(this)) - 1] === null)
258
	    return matches.splice(0, matches.length - 1);
259
    }
260
}
261

    
262
window.killtheweb={is_mozilla: true, browser: this.browser};
263
EOF
264
    fi
265

    
266
    cp -r copyright licenses/ "$BUILDDIR"
267
    cp dummy "$BUILDDIR"
268
    cp html/*.css "$BUILDDIR"/html
269
    mkdir "$BUILDDIR"/icons
270
    cp icons/*.png "$BUILDDIR"/icons
271

    
272
    if [ "$BROWSER" = "chromium" ]; then
273
	for MOZILLA_FILE in $(find "$BUILDDIR" -name "MOZILLA_*"); do
274
	    echo > "$MOZILLA_FILE"
275
	done
276
    fi
277
    if [ "$BROWSER" = "mozilla" ]; then
278
	for CHROMIUM_FILE in $(find "$BUILDDIR" -name "CHROMIUM_*"); do
279
	    echo > "$CHROMIUM_FILE"
280
	done
281
    fi
282
}
283

    
284
main() {
285
    if [ "x$1" = "xmozilla" -o "x$1" = "xchromium" ]; then
286
	BROWSER=$1
287
    else
288
	errcho "usage:  $0 mozilla|chromium [source directory] [update url]"
289
	exit 1
290
    fi
291

    
292
    SRCDIR="${2:-.}"
293
    if [ -d "$SRCDIR" ]; then
294
	BUILDDIR="$(realpath $BROWSER-unpacked)"
295
	rm -rf "$BUILDDIR"
296
	mkdir "$BUILDDIR"
297
	cd "$SRCDIR"
298
    else
299
	errcho "usage:  $0 mozilla|chromium [source directory] [update url]"
300
	exit 2
301
    fi
302

    
303
    UPDATE_URL="$3"
304

    
305
    . ./shell_utils.sh
306
    build_main
307
}
308

    
309
main "$@"
(3-3/13)