#!/usr/bin/env bash # Compila o PicReact (nonograma com puzzles aleatorios e editor proprio, GPL-3.0, bgonp; React 18 + wouter + Vite 4) a partir do # commit 0be1cfd de github.com/bgonp/picreact, com o "npm ci" do package-lock.json do autor (hashes de integridade do npm) e # "vite build --base=./", com o Node 24.21.0 de artifacts/tools. # # Mudancas, todas feitas aqui (cada uma falha se o texto esperado nao existir): # - rotas por hash (wouter com um hook de #/rota, a receita da propria documentacao do wouter 2): o jogo roda numa pasta/iframe e # nao na raiz de um dominio; # - sai o botao de compartilhar (montava um link com o endereco da pagina e copiava ou chamava navigator.share; num iframe o # endereco nao serve) e o texto que o menciona; # - o rodape perde os links para o GitHub do autor e o "How to play": fica o credito e o nome da licenca. # O jogo nao tem imagem, som nem fonte web (so fontes do sistema) e nao faz requisicoes. # # src/FredGames.Bundler/Builds/build-picreact.sh # # Saida: artifacts/build/picreact-0be1cfd/picreact-0be1cfd-site.tar.gz (pasta site/); dois builds seguidos dao os mesmos bytes. set -euo pipefail COMMIT=0be1cfd8db7c35104b400394e52b76c66d9b35fc SHA256=534e878a96a4ba2c6bcf24f3c502c53e2d071219a188b83da7837f403a32aae8 NODE=24.21.0 here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$here" rev-parse --show-toplevel 2>/dev/null || pwd)" slug=picreact out="$root/artifacts/build/$slug-${COMMIT:0:7}" cache="$root/artifacts/build/cache" nodebin="$root/artifacts/tools/node-v$NODE/bin" [ -x "$nodebin/node" ] && [ "$("$nodebin/node" -v)" = "v$NODE" ] || { echo "Precisa do Node $NODE em $nodebin." >&2; exit 1; } export PATH="$nodebin:/usr/bin:/bin" mkdir -p "$cache" tarball="$cache/$slug-${COMMIT:0:7}.tar.gz" [ -f "$tarball" ] || curl -fsSL --retry 4 "https://github.com/bgonp/picreact/archive/$COMMIT.tar.gz" -o "$tarball" 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" python3 -I - <<'PY' def edit(path, fn): s = open(path, encoding="utf-8").read() n = fn(s) assert n != s, path open(path, "w", encoding="utf-8", newline="").write(n) def rep(s, old, new): assert s.count(old) == 1, old return s.replace(old, new) def main(s): s = rep(s, "import { FC } from 'react'\n", "import { FC, useCallback, useEffect, useState } from 'react'\nimport { Router as WouterRouter } from 'wouter'\n") s = rep(s, "const Main: FC = () => (\n