#!/usr/bin/env bash # Compila a versao offline do Blockly Games (google/blockly-games, Apache-2.0) no commit 5d2ff6f, para a pagina # "Block Coding Games": oito jogos de programacao em blocos (Puzzle, Maze, Bird, Turtle, Movie, Music, Pond Tutor e # Pond). E o "make offline" do Makefile do autor, sem Java, svn e wget e com tudo pinado por sha256: # - as dependencias que o Makefile baixa sem versao (ace-builds, blockly-for-BG, SoundJS, JS-Interpreter, Babel) # vem de tarballs de commit/versao fixos (datas proximas a do commit do jogo, maio de 2024); # - o Closure Compiler e o binario nativo do npm (google-closure-compiler-macos 20240317.0.0, x86_64, roda pelo # Rosetta 2), a mesma versao do compiler.jar da epoca; o compress.py chama o binario no lugar de "java -jar"; # - python3 no lugar de python (mesmos scripts do autor). # # Mudancas nossas, todas em block-coding-games/block-coding-games-fredygames.patch (aplicado ao tarball do jogo): # - nome "Block Coding Games" no lugar de "Blockly Games" (titulos, mensagem Games.name, noscript) e a entrada com # texto no lugar do logotipo, sem o link para about.html (que e uma pagina do Google com links e Analytics); # - boot.js: so os idiomas en e pt-br, sem cookie de idioma e sem o redirecionamento para blockly.games; # - Maze sem o Pegman: so as skins Astro e Panda; as duas fotos de fundo (uma "usada com permissao" so para o site # original, outra "CC licensed for reuse" sem dizer qual CC) viram cor lisa; o marcador de chegada (o pino do # Google Maps) e o icone da entrada (que mostra o Pegman) sao trocados por desenhos nossos (make-icons.py); # - compress.py usa o compilador nativo e nao gera o uncompressed.js. # Fora isso o build tira as paginas e arquivos do servidor (galeria, admin, about, storage, errorReporter, yaml, py), o # fonte de cada jogo (src/), os idiomas que nao sao en/pt-br e os links de ajuda (HELPURL) das mensagens, que abririam # a Wikipedia e o GitHub. # # src/FredGames.Bundler/Builds/build-block-coding-games.sh # # Saida: artifacts/build/block-coding-games-5d2ff6f/{block-coding-games-5d2ff6f-dist.tar.gz,licenses.txt}; o tar.gz tem # que sair igual em dois builds. set -euo pipefail COMMIT=5d2ff6f39207f7ed31e3d11ba1de277c85efe4c2 SHA256=7f2133efc6355ca7d79b58979b2a90a05cb8f6b1e358564b49557a39df38a170 ACE=655c20ab3243bf0603dadbb3905e73ebbdb633cd ACE_SHA256=0b0da7261998aa5a24d882b951c1015980bd5f742eea572c01d8cb4572378fd0 BFB=837051b5466457a8f4e956b95bff334d95c26b85 BFB_SHA256=31dae62528e6e5d10e2dbc4937fe0a15f78795b49721ae14909f23f9093eec8d SOUNDJS=5213ac5696142bcba216ef10bef3105e5be1d4ef SOUNDJS_SHA256=e0847910f3b6596c6bc3011bdd25d91637216823089459e92f842d67907cd3c8 JSI=9c31dcb6bbd210feee8f505b32f9a957eada2c3b JSI_SHA256=b7bfd2f1a4b97d3cbca625ec0dc7ec39954f68da296bf0c8c171299581bd9d4b BABEL=7.14.8 BABEL_SHA256=b25fa848afe3d3afb9009084bd9ae6ffb1b13d98ffe1dc35a8dbf7cbd17d38af CC=20240317.0.0 CC_SHA256=7207ef4e20a77fafa27ca8fd2c3dddadaf746f83952cba4016443393a75c4f68 MARKER_SHA256=4d82f3dd08b6ac8676f43d383909b05628e78e04f47e2c1790d64378f2ddc8fb ICON_SHA256=1d110b2394a001d5bf81e3bebdef19da97c07a5b8a09c500ce9f47f369d70931 here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$here" rev-parse --show-toplevel 2>/dev/null || pwd)" out="$root/artifacts/build/block-coding-games-${COMMIT:0:7}" cache="$root/artifacts/build/cache" cctool="$root/artifacts/tools/closure-compiler-$CC" mkdir -p "$cache" fetch() { if [ ! -f "$cache/$2" ]; then curl -fsSL --retry 4 "$1" -o "$cache/$2.partial" && mv "$cache/$2.partial" "$cache/$2" fi echo "$3 $cache/$2" | shasum -a 256 -c - } fetch "https://github.com/google/blockly-games/archive/$COMMIT.tar.gz" "blockly-games-${COMMIT:0:7}.tar.gz" "$SHA256" fetch "https://github.com/ajaxorg/ace-builds/archive/$ACE.tar.gz" "ace-builds-${ACE:0:7}.tar.gz" "$ACE_SHA256" fetch "https://github.com/NeilFraser/blockly-for-BG/archive/$BFB.tar.gz" "blockly-for-BG-${BFB:0:7}.tar.gz" "$BFB_SHA256" fetch "https://github.com/CreateJS/SoundJS/archive/$SOUNDJS.tar.gz" "SoundJS-${SOUNDJS:0:7}.tar.gz" "$SOUNDJS_SHA256" fetch "https://github.com/NeilFraser/JS-Interpreter/archive/$JSI.tar.gz" "JS-Interpreter-${JSI:0:7}.tar.gz" "$JSI_SHA256" fetch "https://registry.npmjs.org/@babel/standalone/-/standalone-$BABEL.tgz" "babel-standalone-$BABEL.tgz" "$BABEL_SHA256" fetch "https://registry.npmjs.org/google-closure-compiler-macos/-/google-closure-compiler-macos-$CC.tgz" "google-closure-compiler-macos-$CC.tgz" "$CC_SHA256" if [ ! -x "$cctool/compiler" ]; then mkdir -p "$cctool.tmp" && tar -xzf "$cache/google-closure-compiler-macos-$CC.tgz" -C "$cctool.tmp" --strip-components 1 mv "$cctool.tmp" "$cctool" fi [ "$("$cctool/compiler" --version | sed -n 's/^Version: v//p')" = "${CC%%.*}" ] || { echo "Closure Compiler $CC esperado" >&2; exit 1; } echo "$MARKER_SHA256 $here/block-coding-games/maze-marker.png" | shasum -a 256 -c - echo "$ICON_SHA256 $here/block-coding-games/maze-icon.png" | shasum -a 256 -c - rm -rf "$out" mkdir -p "$out/tree" "$out/x" tar -xzf "$cache/blockly-games-${COMMIT:0:7}.tar.gz" -C "$out/tree" --strip-components 1 --exclude='*/archive' cd "$out/tree" patch -s -p1 < "$here/block-coding-games/block-coding-games-fredygames.patch" # Dependencias de terceiros (o alvo "deps" do Makefile, com versoes fixas). t=appengine/third-party mkdir -p $t/ace $t/blockly $t/SoundJS $t/JS-Interpreter untar() { mkdir -p "$out/x/$2" && tar -xzf "$cache/$1" -C "$out/x/$2" --strip-components 1; } untar "ace-builds-${ACE:0:7}.tar.gz" ace untar "blockly-for-BG-${BFB:0:7}.tar.gz" bfb untar "SoundJS-${SOUNDJS:0:7}.tar.gz" soundjs untar "JS-Interpreter-${JSI:0:7}.tar.gz" jsi untar "babel-standalone-$BABEL.tgz" babel cp "$out/x/babel/babel.min.js" $t/ cp -R "$out/x/ace/src-min-noconflict/." $t/ace/ cp -R "$out/x/bfb/." $t/blockly/ cp -R "$out/x/soundjs/lib/." $t/SoundJS/ cp -R "$out/x/jsi/." $t/JS-Interpreter/ cp third-party/base.js $t/ cp -R third-party/soundfonts $t/ export CLOSURE_COMPILER="$cctool/compiler" # O Music precisa mexer na pilha do interpretador: SIMPLE_OPTIMIZATIONS (como no Makefile). "$CLOSURE_COMPILER" --language_out ECMASCRIPT5 --language_in ECMASCRIPT5 \ --js $t/JS-Interpreter/acorn.js --js $t/JS-Interpreter/interpreter.js \ --js_output_file $t/JS-Interpreter/compressed.js # Mensagens (alvo "common"), sem os links de ajuda, que abririam sites de terceiros. python3 -I build/messages_to_json.py > "$out/messages.log" 2>&1 python3 -I build/json_to_js.py >> "$out/messages.log" 2>&1 python3 -I - <<'PY' import re n = 0 for lang in ('en', 'pt-br'): p = 'appengine/generated/msg/%s.js' % lang s = open(p, encoding='utf-8').read() s, k = re.subn(r'^((?:BlocklyMsg\["[A-Z_]*HELPURL"\]|BlocklyGamesMsg\["[A-Za-z.0-9]*HelpUrl"\]) = )"[^"]*";', r'\1"";', s, flags=re.M) n += k open(p, 'w', encoding='utf-8').write(s) assert n > 100, n PY for game in index puzzle maze bird turtle movie music pond/tutor pond/duck; do python3 -I build/compress.py "$game" >> "$out/compress.log" 2>&1 || { tail -20 "$out/compress.log"; exit 1; } done # O alvo "offline": so o que a pagina precisa no navegador. d="$out/dist" mkdir -p "$d" cp -R appengine/. "$d/" cd "$d" rm -f ./*.yaml ./*.py ./*.sh ./about.html ./admin.html ./apple-touch-icon.png ./favicon.ico ./robots.txt rm -rf gallery gallery_api gallery.html generated rm -rf ./src ./*/src ./*/*/src rm -f ./*/generated/uncompressed.js ./*/*/generated/uncompressed.js rm -f index/title.png index/title-beta.png index/title.svg pond/crobots.txt common/stripes.svg rm -rf pond/battle rm -f third-party/base.js third-party/soundfonts/README.txt # Pegman, fotos de fundo do Maze e imagens trocadas rm -f maze/pegman.png maze/tiles_pegman.png maze/fail_pegman.mp3 maze/fail_pegman.ogg maze/bg_astro.jpg maze/bg_panda.jpg cp "$here/block-coding-games/maze-marker.png" maze/marker.png cp "$here/block-coding-games/maze-icon.png" index/maze.png # So en e pt-br for f in */generated/msg/*.js */*/generated/msg/*.js; do case "$(basename "$f" .js)" in en|pt-br) ;; *) rm -f "$f" ;; esac done # Terceiros: so o que roda mkdir -p "$out/keep" mv third-party/ace/{ace.js,mode-javascript.js,theme-chrome.js,worker-javascript.js,ext-language_tools.js} "$out/keep/" rm -rf third-party/ace/* mv "$out/keep/"* third-party/ace/ mv third-party/SoundJS/soundjs.min.js "$out/keep/" rm -rf third-party/SoundJS/* mv "$out/keep/soundjs.min.js" third-party/SoundJS/ mv third-party/blockly/media "$out/keep/media" rm -rf third-party/blockly/* mv "$out/keep/media" third-party/blockly/media mv third-party/JS-Interpreter/compressed.js "$out/keep/" rm -rf third-party/JS-Interpreter/* third-party/JS-Interpreter/.gitignore mv "$out/keep/compressed.js" third-party/JS-Interpreter/ find . -name '.DS_Store' -delete cd "$out/tree" # Nada pode citar o Pegman nem pedir coisas de fora. if grep -rqiE "pegman_|fail_pegman|tiles_pegman|bg_panda|bg_astro|google-analytics|googletagmanager|fonts\.googleapis|gstatic" "$d" --include='*.js' --include='*.html' --include='*.css'; then echo "o build ainda cita Pegman, fotos removidas ou servico externo" >&2 grep -rliE "pegman_|fail_pegman|tiles_pegman|bg_panda|bg_astro|google-analytics|googletagmanager|fonts\.googleapis|gstatic" "$d" >&2 || true exit 1 fi { echo "== Blockly Games (LICENSE do repositorio, Apache License 2.0; sem arquivo NOTICE)" cat LICENSE echo echo "== Blockly (blockly-for-BG, $BFB): Apache-2.0, Copyright Google LLC e Massachusetts Institute of Technology (cabecalhos dos arquivos); texto igual ao acima" echo echo "== JS-Interpreter ($JSI), Neil Fraser: Apache-2.0 (texto abaixo); acorn.js, de Marijn Haverbeke, MIT" cat "$out/x/jsi/LICENSE" echo echo "== Ace (ace-builds $ACE)" cat "$out/x/ace/LICENSE" echo echo "== SoundJS ($SOUNDJS)" cat "$out/x/soundjs/LICENSE.txt" echo echo "== Babel standalone $BABEL" cat "$out/x/babel/LICENSE" echo echo "== Soundfonts (third-party/soundfonts/README.txt do repositorio)" cat third-party/soundfonts/README.txt } > "$out/licenses.txt" find "$d" -exec touch -t 202611040000 {} + ( cd "$out" && find dist -type f | LC_ALL=C sort > files.txt \ && COPYFILE_DISABLE=1 tar --format=ustar --uid 0 --gid 0 --uname root --gname root -n -cf - -T files.txt \ | gzip -n -9 > "block-coding-games-${COMMIT:0:7}-dist.tar.gz" && rm files.txt ) du -sh "$d" cd "$out" && rm -rf tree x keep ls -l "$out/block-coding-games-${COMMIT:0:7}-dist.tar.gz" shasum -a 256 "$out/block-coding-games-${COMMIT:0:7}-dist.tar.gz" "$out/licenses.txt"