#!/usr/bin/env bash # Monta os jogos do John Morris (github.com/johnmorrisdotca, MIT, (c) 2026 John Morris) para o FredyGames: # # src/FredGames.Bundler/Builds/build-johnmorris-games.sh # pacotes: toranpu sugoroku domino tenka jarajara kumimoji houseki jirai karakuri kazu tsunagi suido tobiishi meikyuu # # Cada pacote traz o seu scripts/site.mjs, que gera a vitrine do GitHub Pages em site/. Aqui: tarball do commit # (sha256 conferido) -> TypeScript 5.9.3 do npm (o do pnpm-lock de todos eles; integridade sha512 conferida; so ele e # preciso, o site.mjs nao usa mais nada) -> tsc --noCheck -> scripts/site.mjs -> johnmorris/postprocess.mjs, que tira o # cabecalho/rodape da "familia" (links para GitHub, npm, itsutsu.com, spxis.github.io e os outros pacotes), a referencia da # API, o construtor de embeds e os blocos de vitrine para desenvolvedores, poe uma CSP (nada sai do site) e troca o que # cita jogo comercial (ver REPL no postprocess). O Tenka tambem precisa do korokoro e do toranpu do npm (devDependencies # dele, versoes e sha512 do pnpm-lock). Saida: artifacts/build/jm--/-dist.tar.gz (pasta dist/, tar # deterministico). Dois builds seguidos dao os mesmos bytes. Precisa do Node (artifacts/tools/node-v24.21.0) e de rede. set -euo pipefail pkg="${1:?uso: build-johnmorris-games.sh }" case "$pkg" in toranpu) COMMIT=550d3bb9fe8130768203bddb18be59aca8dcef74; SHA256=6231a7aaf462e46e6fff0c2785420b6085f0d90b9452241d2161940ffcf251c8; CREDITS="docs/credits.md" ;; sugoroku) COMMIT=a7cb501e94bbf00c00c62a21703d0edef226b99d; SHA256=e99341c9fa4e3c9a713520a1079d49744c12bf782abe748cd98ae5d93095599a; CREDITS="" ;; domino) COMMIT=9754058f40001d1045fe939e3b2a48ba506ebfcf; SHA256=2c612bf62809224bf4df25cf6158cf86390c45cf10afab0612a8bd3c2f75fbf4; CREDITS="CREDITS.md" ;; tenka) COMMIT=70748215b724cce1bbb8ac6e8f89e9f5effda013; SHA256=17ec20e7db60803ea3bfde7e88e203bfdbe0769bd024d81426f2dce3f948ca27; CREDITS="" ;; jarajara) COMMIT=191efdc8580ca186f2da04425b36aff162717e34; SHA256=39e6ee61cc8159cb7a8c7c6a0fafe2ca5cb230fdd8435878e844f359f12ca341; CREDITS="CREDITS.md" ;; kumimoji) COMMIT=68375b05b5febd7a281a303a3089db0a12d6fd25; SHA256=54ce582772f6dcbbf78d13cbff8f99f9bedc7ca4558dcde49d725f9e336712b8; CREDITS="" ;; houseki) COMMIT=df2217069098ec0b45aa8def3a8624548bae6d7b; SHA256=fbcb18afc201686fd4d9297f66f793df684de71760d97ebe96161971d0bdbde0; CREDITS="" ;; jirai) COMMIT=11ec52a46969259cb9eaae64f78a87c427eee957; SHA256=de77d64b70a45bf56a39091023506ea4e5ab2c41fa62ed27ab19795b7dffc1d1; CREDITS="" ;; karakuri) COMMIT=e61c584343b87ced29b5db20b27bdfbc4c0977ee; SHA256=b18cd65f72e04fd0eeca0f36857577059c86d43cd11e54132f013389bec5fc03; CREDITS="" ;; kazu) COMMIT=7034ddc2081b4a7f628b2b968fe940a5f0db3134; SHA256=ee8f03b70a108b76c28b4305e3d162c3d53e6eee398c9545d3eb59d1053d078d; CREDITS="" ;; tsunagi) COMMIT=54fde2e0ac0b1b750d3b442da519646ccec5ac65; SHA256=035c2bb8096e3bab3857a247f0eb452fc3ee08150ca4fe369c8bc30c03ebcdf0; CREDITS="" ;; suido) COMMIT=f055ccaf41abade60291a4041caa07951ee46d7d; SHA256=dda31af9ae1bb697530854de797306aa95b42ffb2d4047a4e83cb806dbdcb1d7; CREDITS="" ;; tobiishi) COMMIT=f772f8c01bfb11c3534818fb88edec95d8a08d65; SHA256=767f89f218a7683102253909a7218d392396d0e03524c4cae5a6fa7da1600328; CREDITS="" ;; meikyuu) COMMIT=38c952a4ae56f3e5a49cda73b7254c3f21e03410; SHA256=88c59a007e3c64a3d1421737d69e5ee24fc67f9bdc40361dc9d98820470e67e0; CREDITS="" ;; *) echo "pacote desconhecido: $pkg" >&2; exit 1 ;; esac TS_VERSION=5.9.3 TS_SHA512="jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==" here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$here" rev-parse --show-toplevel 2>/dev/null || pwd)" out="$root/artifacts/build/jm-${pkg}-${COMMIT:0:7}" cache="$root/artifacts/build/cache" nodedir="$root/artifacts/tools/node-v24.21.0/bin" [ -x "$nodedir/node" ] || { echo "Precisa do Node em $nodedir." >&2; exit 1; } mkdir -p "$cache" # npm_fetch : baixa para o cache e confere a integridade do npm. npm_fetch() { local file="$cache/$1" [ -f "$file" ] || curl -fsSL --retry 5 --max-time 180 "$2" -o "$file.partial" && { [ -f "$file" ] || mv "$file.partial" "$file"; } [ "$(openssl dgst -sha512 -binary "$file" | base64 | tr -d '\n')" = "$3" ] || { echo "sha512 de $1 nao confere" >&2; exit 1; } } tarball="$cache/johnmorris-$pkg-${COMMIT:0:7}.tar.gz" if [ ! -f "$tarball" ]; then curl -fsSL --retry 5 --max-time 180 "https://github.com/johnmorrisdotca/$pkg/archive/$COMMIT.tar.gz" -o "$tarball.partial" && mv "$tarball.partial" "$tarball" fi echo "$SHA256 $tarball" | shasum -a 256 -c - rm -rf "$out" mkdir -p "$out/tree" tar -xzf "$tarball" -C "$out/tree" --strip-components 1 cd "$out/tree" npm_fetch "typescript-$TS_VERSION.tgz" "https://registry.npmjs.org/typescript/-/typescript-$TS_VERSION.tgz" "$TS_SHA512" mkdir -p node_modules/typescript tar -xzf "$cache/typescript-$TS_VERSION.tgz" -C node_modules/typescript --strip-components 1 extra_credits=() if [ "$pkg" = tenka ]; then npm_fetch korokoro-1.15.0.tgz https://registry.npmjs.org/@johnmorrisdotca/korokoro/-/korokoro-1.15.0.tgz \ "KYXuEkIOVcBQ6FsQ0fU6FErAbc2CwFHQk3FE8rpNYD/ASG7f6A/BYLtqCJGv14r3ADL/rBipPUNQNTbLUpNWFg==" npm_fetch toranpu-2.14.0.tgz https://registry.npmjs.org/@johnmorrisdotca/toranpu/-/toranpu-2.14.0.tgz \ "AT4YVYIM3lcaA63/gz7BR/h+EanIXSmR+ztFc/XTREQ8TijqaZ6SXTWWe1vWSEfFEDvgDNhW6k+G6MZxG67KLQ==" for p in korokoro toranpu; do mkdir -p "node_modules/@johnmorrisdotca/$p" tar -xzf "$cache/$p-"*.tgz -C "node_modules/@johnmorrisdotca/$p" --strip-components 1 done fi export PATH="$nodedir:/usr/bin:/bin" node node_modules/typescript/bin/tsc -p tsconfig.json --noCheck node scripts/site.mjs >/dev/null node "$here/johnmorris/postprocess.mjs" "$PWD/site" "$pkg" # Licencas e creditos que acompanham o jogo. cp LICENSE site/LICENSE if [ -n "$CREDITS" ]; then mkdir -p site/credits cp "$CREDITS" "site/credits/$(basename "$CREDITS")" fi if [ "$pkg" = kumimoji ]; then # O NOTICE.md diz que o aviso completo do SCOWL (com os direitos das listas de que ele e feito) acompanha as listas. scowl="$cache/scowl-2020.12.07-Copyright" [ -f "$scowl" ] || curl -fsSL --retry 5 --max-time 60 https://raw.githubusercontent.com/en-wl/wordlist/rel-2020.12.07/scowl/Copyright -o "$scowl" echo "283326a422e29c510e2ba6805518c418ce3c35ed1fadc3eec83d2da4f6c5a055 $scowl" | shasum -a 256 -c - mkdir -p site/credits cp "$scowl" site/credits/SCOWL-Copyright.txt fi if [ "$pkg" = tenka ]; then mkdir -p site/credits cp node_modules/@johnmorrisdotca/korokoro/LICENSE site/credits/korokoro-LICENSE cp node_modules/@johnmorrisdotca/korokoro/SOUNDS.md site/credits/korokoro-SOUNDS.md cp node_modules/@johnmorrisdotca/toranpu/LICENSE site/credits/toranpu-LICENSE cp node_modules/@johnmorrisdotca/toranpu/docs/credits.md site/credits/toranpu-credits.md fi # site/ vira dist/ num tar.gz deterministico (datas fixas, ordem fixa, sem dono). mv site "$out/dist" cd "$out" rm -rf tree find dist -exec touch -t 202611020000 {} + 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 > "$pkg-dist.tar.gz" rm -f files.txt rm -rf dist ls -l "$out/$pkg-dist.tar.gz" shasum -a 256 "$out/$pkg-dist.tar.gz"