Project

General

Profile

« Previous | Next » 

Revision e7c425cc

Added by jahoti almost 2 years ago

Add command line options (inc. build artifacts)

Add extension packaging for Mozilla and some other treats

View differences:

build.sh
1 1
#!/bin/sh
2 2

  
3
# Copyright (C) 2021 Wojtek Kosior
3
# Copyright (C) 2021 jahoti <jahoti@tilde.team>
4 4
# Redistribution terms are gathered in the `copyright' file.
5 5

  
6
. ./shell_utils.sh
7

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

  
18
	EXPORTCODE="${EXPORTCODE}window.killtheweb.$2 = $2;$ENDL"
19

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

  
26
	map_set_instr EXPORTS $2 "$FILE"
27

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

  
35
translate_exports() {
36
    STATE="before_block"
37
    EXPORTCODE=''
38

  
39
    while read EXPORT_LINE; do
40
	handle_export_line $EXPORT_LINE || return 1
41
    done
42

  
43
    map_set_instr EXPORTCODES $FILEKEY "$EXPORTCODE"
44
}
45

  
46
add_exports() {
47
    FILE="$1"
48
    FILEKEY="$(sanitize "$FILE")"
49

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

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

  
63
	IMPORTCODE="${IMPORTCODE}const $2 = window.killtheweb.$2;$ENDL"
64

  
65
	IMPORTS="$IMPORTS $2"
66

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

  
74
translate_imports() {
75
    STATE="before_block"
76
    IMPORTCODE=''
77
    IMPORTS=''
78

  
79
    while read IMPORT_LINE; do
80
	handle_import_line $IMPORT_LINE || return 1
81
    done
82

  
83
    map_set_instr IMPORTCODES $FILEKEY "$IMPORTCODE"
84
    map_set_instr IMPORTS $FILEKEY "$IMPORTS"
85
}
86

  
87
add_imports() {
88
    FILE="$1"
89
    FILEKEY="$(sanitize "$FILE")"
90

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

  
94
compute_scripts_list_rec() {
95
    local FILE="$1"
96
    local FILEKEY=$(sanitize "$1")
97

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

  
107
    USED="$USED $FILEKEY"
108

  
109
    map_set FILESTATES $FILEKEY "processing"
110

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

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

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

  
134
    for FILEKEY in $USED; do
135
	map_set_instr USED $FILEKEY yes
136
    done
137
}
138

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

  
150
as_html_list() {
151
    while [ "x" != "x$1" ]; do
152
	echo -n '\\n'"    <script src=\"/$1\"></script>"
6
print_usage() {
7
    EXIT_STATUS=${1:-0}
8
    if [ "x$1" != x ]; then
153 9
	shift
154
    done
155
}
156

  
157
set_browser() {
158
    if [ "x$1" = "xmozilla" -o "x$1" = "xchromium" ]; then
159
	BROWSER="$1"
160
    else
161
	errcho "usage:  $0 mozilla|chromium"
162
	exit 1
10
	errcho "$@"
163 11
    fi
12
    
13
    errcho "usage:  $0 [OPTION]... BROWSER"
14
    errcho
15
    errcho "the -- preceding long forms is optional"
16
    errcho "browsers:"
17
    errcho "    -C, chromium:     build for Chromium and derivatives"
18
    errcho "    -M, mozilla:      build for Firefox and derivatives"
19
    errcho "options:"
20
    errcho "    -b, build [LOC]:  set file/directory to use for building"
21
    errcho "    -f, force:        delete the build directory if it exists"
22
    errcho "                      instead of throwing an error."
23
    errcho "    -h, help:         print usage information and exit"
24
    errcho "    -o, output [LOC]: set output file/directory"
25
    errcho "    -z, zip_ext:      pack the extension as a file"
26
    errcho "    -7, 7zip:         use the '7z' command instead of 'zip'"
27
    
28
    exit $EXIT_STATUS
164 29
}
165 30

  
166
main() {
167
    set_browser "$1"
168

  
169
    # placate importers of these, as they are exported by the yet-to-be-created exports_init.js
170
    EXPORTS__browser=exports_init.js
171
    EXPORTS__is_chrome=exports_init.js
172
    EXPORTS__is_mozilla=exports_init.js
173

  
174
    SCRIPTDIRS='background html common content'
175

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

  
178
    for SCRIPT in $SCRIPTS; do
179
	add_exports $SCRIPT
180
	add_imports $SCRIPT
181
    done
182

  
183
    eval "$(compute_scripts_list background/main.js || exit 1)"
184
    BGSCRIPTS="$(as_json_list $COMPUTED_SCRIPTS)"
185
    eval "$(compute_scripts_list content/main.js || exit 1)"
186
    CONTENTSCRIPTS="$(as_json_list $COMPUTED_SCRIPTS)"
187
    eval "$(compute_scripts_list html/display-panel.js || exit 1)"
188
    POPUPSCRIPTS="$(as_html_list $COMPUTED_SCRIPTS)"
189
    eval "$(compute_scripts_list html/options_main.js || exit 1)"
190
    OPTIONSSCRIPTS="$(as_html_list $COMPUTED_SCRIPTS)"
191

  
192
    BUILDDIR=build_$BROWSER
193
    rm -rf $BUILDDIR
194
    mkdir $BUILDDIR
195
    for DIR in $(find $SCRIPTDIRS -type d); do
196
	mkdir -p $BUILDDIR/$DIR
197
    done
198

  
199
    CHROMIUM_KEY=''
200
    GECKO_APPLICATIONS=''
201

  
202
    if [ "$BROWSER" = "chromium" ]; then
203
	CHROMIUM_KEY="$(dd if=/dev/urandom bs=32 count=1 2>/dev/null | base64)"
204
	CHROMIUM_KEY=$(echo chromium-key-dummy-file-$CHROMIUM_KEY | tr / -)
205
	touch $BUILDDIR/$CHROMIUM_KEY
206

  
207
	CHROMIUM_KEY="\n\
208
	// WARNING!!!\n\
209
	// EACH USER SHOULD REPLACE DUMMY FILE's VALUE WITH A UNIQUE ONE!!!\n\
210
	// OTHERWISE, SECURITY CAN BE TRIVIALLY COMPROMISED!\n\
211
	// Only relevant to users of chrome-based browsers.\n\
212
	// Users of Firefox forks are safe.\n\
213
	\"$CHROMIUM_KEY\"\
214
"
215
    else
216
	GECKO_APPLICATIONS="\n\
217
    \"applications\": {\n\
218
	\"gecko\": {\n\
219
	    \"id\": \"{6fe13369-88e9-440f-b837-5012fb3bedec}\",\n\
220
	    \"strict_min_version\": \"60.0\"\n\
221
	}\n\
222
    },"
223
    fi
224

  
225
    sed "\
226
s^_GECKO_APPLICATIONS_^$GECKO_APPLICATIONS^
227
s^_CHROMIUM_KEY_^$CHROMIUM_KEY^
228
s^_BGSCRIPTS_^$BGSCRIPTS^
229
s^_CONTENTSCRIPTS_^$CONTENTSCRIPTS^" \
230
	< manifest.json > $BUILDDIR/manifest.json
231

  
232
    ./process_html_file.sh html/display-panel.html |
233
	sed "s^_POPUPSCRIPTS_^$POPUPSCRIPTS^" \
234
	    > $BUILDDIR/html/display-panel.html
235

  
236
    ./process_html_file.sh html/options.html |
237
	sed "s^_OPTIONSSCRIPTS_^$OPTIONSSCRIPTS^" \
238
	    > $BUILDDIR/html/options.html
239

  
240
    for FILE in $SCRIPTS; do
241
	FILEKEY=$(sanitize "$FILE")
242
	if [ "xyes" != "x$(map_get USED $FILEKEY)" ]; then
243
	    errcho "WARNING! $FILE not used"
244
	else
245
	    (echo "\
246
\"use strict\";
247

  
248
({fun: (function() {
249
$(map_get IMPORTCODES $FILEKEY)
250

  
251
";
252

  
253
# A hack to insert the contents of default_settings.json at the appropriate location in background/main.js
254
if [ "$FILE" = "background/main.js" ]; then
255
    # Uses an internal sed expression to escape and indent the JSON file for use in the external sed expression
256
    sed 's/^        `DEFAULT SETTINGS`$/'"$(sed -E 's/([\\\&\/])/\\\1/g; s/^/        /; s/$/\\/' < default_settings.json) "/g < "$FILE"
257
else
258
    cat $FILE
31
. ./lib_build.sh
32

  
33
BROWSER=''
34
BUILDDIR=''
35
MAKEZIP=0
36
FORCE=0
37
ZIP_COMMAND='zip -r'
38

  
39
while [ "x$1" != x ]; do
40
    case "$1" in
41
	-C | chromium | --chromium) BROWSER=chromium;;
42
	-M | mozilla | --mozilla)   BROWSER=mozilla;;
43
	-b | output | --build)      BUILDDIR="$2"
44
	                            shift;;
45
	-f | force | --force)       FORCE=1;;
46
	-h | help | --help)         print_usage;;
47
	-o | output | --output)     OUTPUT="$2"
48
	                            shift;;
49
	-z | zip_ext | --zip_ext)   MAKEZIP=1;;
50
	-7 | 7zip | --7zip)         ZIP_COMMAND='7z a';;
51
	*)                          print_usage 2 Unrecognized option "'$1'.";;
52
    esac
53
    shift
54
done
55

  
56
if [ "x$BROWSER" = x ]; then
57
    print_usage 1 No browser was specified.
259 58
fi
260 59

  
261
echo "
262

  
263
$(map_get EXPORTCODES $FILEKEY)
264
})}).fun();") > $BUILDDIR/$FILE
265
	fi
266
    done
267

  
268
    if [ "$BROWSER" = "chromium" ]; then
269
	cat > $BUILDDIR/exports_init.js <<EOF
270
window.killtheweb={is_chrome: true, browser: window.chrome};
271
EOF
60
BUILDDIR="${BUILDDIR:-build_$BROWSER}"
61
if [ -e "$BUILDDIR" ]; then
62
    if [ $FORCE = 0 ]; then
63
	errcho "Build directory '$BUILDDIR' exists."
64
	exit 3
272 65
    else
273
	cat > $BUILDDIR/exports_init.js <<EOF
274
/* Polyfill for IceCat 60. */
275
String.prototype.matchAll = String.prototype.matchAll || function(regex) {
276
    if (regex.flags.search("g") === -1)
277
        throw new TypeError("String.prototype.matchAll called with a non-global RegExp argument");
278

  
279
    for (const matches = [];;) {
280
        if (matches[matches.push(regex.exec(this)) - 1] === null)
281
	    return matches.splice(0, matches.length - 1);
282
    }
283
}
284

  
285
window.killtheweb={is_mozilla: true, browser: this.browser};
286
EOF
66
	rm -rf "$BUILDDIR"
287 67
    fi
68
fi
288 69

  
289
    cp -r copyright licenses/ $BUILDDIR
290
    cp html/*.css $BUILDDIR/html
291
    mkdir $BUILDDIR/icons
292
    cp icons/*.png $BUILDDIR/icons
70
if [ "x$OUTPUT" = x ]; then
71
    case "$MAKEZIP$BROWSER" in
72
	0*)        OUTPUT=build_$BROWSER;;
73
	1chromium) OUTPUT=build.crx;;
74
	1mozilla)  OUTPUT=build.xpi;;
75
    esac
76
fi
293 77

  
294
    if [ "$BROWSER" = "chromium" ]; then
295
	for MOZILLA_FILE in $(find $BUILDDIR -name "MOZILLA_*"); do
296
	    echo > "$MOZILLA_FILE"
297
	done
298
    fi
299
    if [ "$BROWSER" = "mozilla" ]; then
300
	for CHROMIUM_FILE in $(find $BUILDDIR -name "CHROMIUM_*"); do
301
	    echo > "$CHROMIUM_FILE"
302
	done
303
    fi
304
}
78
if [ -e "$OUTPUT" ]; then
79
    errcho "Output location '$OUTPUT' exists."
80
    exit 3
81
fi
305 82

  
306
main "$@"
83
mkdir "$BUILDDIR"
84
main
85
if [ $MAKEZIP = 1 ]; then
86
    make_zip
87
    mv "$BUILDDIR"/build.zip "$OUTPUT"
88
    rm -rf "$BUILDDIR"
89
elif [ "$BUILDDIR" != "$OUTPUT" ]; then
90
    mv "$BUILDDIR" "$OUTPUT"
91
fi

Also available in: Unified diff