187 lines
5.6 KiB
Markdown
187 lines
5.6 KiB
Markdown
# Builds — Como gerar fc-uniao.exe, fc-alianca.exe, fc-ambos.exe
|
|
|
|
## Conceito
|
|
|
|
O mesmo código gera 3 binários diferentes. A diferença entre eles é apenas o valor da variável de ambiente `DOBRADO_LOJA` passado na hora da compilação Rust.
|
|
|
|
- **Build fixa (União ou Aliança):** o operador **não consegue trocar a loja** no formulário
|
|
- **Build livre (Ambós):** o operador escolhe entre União e Aliança no dropdown
|
|
|
|
---
|
|
|
|
## Mecanismo: `option_env!` em Rust
|
|
|
|
Em `src-tauri/src/plugins/app.rs`:
|
|
|
|
```rust
|
|
/// DOBRADO_LOJA é uma variável de ambiente lida em TEMPO DE COMPILAÇÃO.
|
|
/// Se não definida, retorna None.
|
|
pub const LOJA_FIXA: Option<&'static str> = option_env!("DOBRADO_LOJA");
|
|
```
|
|
|
|
O `option_env!` é uma macro built-in do Rust que avalia expressões const em tempo de compilação. Se `DOBRADO_LOJA` estiver definida como env var, `LOJA_FIXA` contém o valor. Se não, `None`.
|
|
|
|
### Por que compile-time?
|
|
|
|
Se fosse runtime (`std::env::var`), o valor estaría hardcoded no binário da mesma forma, mas compile-time é mais limpo porque o Rust elimina código morto (dead code elimination). Se `LOJA_FIXA` é `None`, o Rust pode optimizar o código de "loja fixa" para fora do binário final.
|
|
|
|
---
|
|
|
|
## Comportamento por build
|
|
|
|
| Build | `DOBRADO_LOJA` | Seletor loja | `set_loja` | `get_loja_fixa` |
|
|
|-------|----------------|-------------|-------------|-----------------|
|
|
| União | `Uniao` | **Escondido** | Bloqueado com erro | `"Uniao"` |
|
|
| Aliança | `Alianca` | **Escondido** | Bloqueado com erro | `"Alianca"` |
|
|
| Ambos | _(não definido)_ | Visível + funcional | Permitido | `null` |
|
|
|
|
---
|
|
|
|
## Como buildar (Linux → Windows cross-compile)
|
|
|
|
### Pré-requisitos
|
|
|
|
```bash
|
|
# Instalar target cross-compile
|
|
rustup target add x86_64-pc-windows-gnu
|
|
|
|
# Ou via apt (Ubuntu/Debian)
|
|
sudo apt install mingw-w64
|
|
```
|
|
|
|
### Comandos
|
|
|
|
```bash
|
|
cd src-tauri/
|
|
|
|
# ── UNIÃO ─────────────────────────────────────────────
|
|
DOBRADO_LOJA=Uniao \
|
|
cargo build --release --target x86_64-pc-windows-gnu
|
|
|
|
# Binário gerado:
|
|
# src-tauri/target/x86_64-pc-windows-gnu/release/fechamento-caixa.exe
|
|
|
|
# ── ALIANÇA ──────────────────────────────────────────
|
|
DOBRADO_LOJA=Alianca \
|
|
cargo build --release --target x86_64-pc-windows-gnu
|
|
|
|
# ── AMBOS ────────────────────────────────────────────
|
|
cargo build --release --target x86_64-pc-windows-gnu
|
|
# (sem DOBRADO_LOJA → loja livre)
|
|
```
|
|
|
|
### Local do binário
|
|
|
|
```
|
|
src-tauri/target/x86_64-pc-windows-gnu/release/fechamento-caixa.exe
|
|
```
|
|
|
|
Renomear para `fc-uniao.exe`, `fc-alianca.exe`, `fc-ambos.exe` antes de distribuir.
|
|
|
|
---
|
|
|
|
## O que acontece no frontend quando a loja é fixa
|
|
|
|
Em `src/index.html`, `DOMContentLoaded`:
|
|
|
|
```javascript
|
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
try {
|
|
const fixa = await window.__TAURI__.core.invoke('get_loja_fixa');
|
|
if (fixa) {
|
|
// Build fixa: esconde o <select id="f-loja">
|
|
const sel = document.getElementById('f-loja');
|
|
sel.style.display = 'none';
|
|
sel.disabled = true;
|
|
|
|
// Esconde o label "Loja"
|
|
const label = document.querySelector('.meta-label');
|
|
if (label && label.textContent.trim() === 'Loja') {
|
|
label.style.display = 'none';
|
|
}
|
|
|
|
estado.loja = fixa; // define sem precisar do select
|
|
}
|
|
} catch(e) {
|
|
console.warn('get_loja_fixa não disponível:', e);
|
|
}
|
|
// ... resto do init
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## O que acontece no Rust quando a loja é fixa
|
|
|
|
```rust
|
|
// set_loja retorna erro se a build tem loja fixa
|
|
#[tauri::command]
|
|
pub fn set_loja(state: State<'_, AppState>, loja: String) -> Result<(), String> {
|
|
if LOJA_FIXA.is_some() {
|
|
return Err("Loja fixa em tempo de build — não é possível trocar.".to_string());
|
|
}
|
|
state.config.lock().unwrap().loja = loja;
|
|
state.save()
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Testar localmente (dev mode)
|
|
|
|
```bash
|
|
cd src-tauri/
|
|
|
|
# Com loja fixa (dev)
|
|
DOBRADO_LOJA=Uniao cargo tauri dev
|
|
|
|
# Com loja livre (dev)
|
|
cargo tauri dev
|
|
```
|
|
|
|
---
|
|
|
|
## Criar release no Gitea
|
|
|
|
```bash
|
|
# 1. Buildar as 3 versões e copiar para /tmp/
|
|
cp src-tauri/target/x86_64-pc-windows-gnu/release/fechamento-caixa.exe /tmp/fc-uniao.exe
|
|
cp src-tauri/target/x86_64-pc-windows-gnu/release/fechamento-caixa.exe /tmp/fc-alianca.exe
|
|
cp src-tauri/target/x86_64-pc-windows-gnu/release/fechamento-caixa.exe /tmp/fc-ambos.exe
|
|
|
|
# 2. Criar releases via Gitea API
|
|
GITEA_TOKEN="seu_token_aqui"
|
|
REPO="filipe/fechamento-caixa"
|
|
|
|
for build in uniao alianca ambos; do
|
|
TAG="v2.0.0-${build}"
|
|
FILE="/tmp/fc-${build}.exe"
|
|
|
|
# Criar release
|
|
RESP=$(curl -s -H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"tag_name\":\"${TAG}\",\"name\":\"${TAG}\",\"body\":\"Build ${build}\"}" \
|
|
"https://git.ofrangao.com.br/api/v1/repos/${REPO}/releases")
|
|
ID=$(echo $RESP | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
|
|
|
# Upload asset
|
|
curl -s -H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H "Content-Type: application/octet-stream" \
|
|
--data-binary @${FILE} \
|
|
"https://git.ofrangao.com.br/api/v1/repos/${REPO}/releases/${ID}/assets?name=fc-${build}.exe"
|
|
done
|
|
```
|
|
|
|
---
|
|
|
|
## Arquivos que mudam entre builds
|
|
|
|
**Nenhum arquivo fonte muda.** O binário é identico exceto pelo valor de `LOJA_FIXA` hardcoded.
|
|
|
|
Para verificar o valor hardcoded no binário:
|
|
```bash
|
|
strings fc-uniao.exe | grep -E "Uniao|Alianca"
|
|
```
|
|
|
|
O binário `fc-uniao.exe` contém a string `Uniao` no lugar de `LOJA_FIXA`, enquanto `fc-ambos.exe` não contém nada (ou contém `None` ou não tem referência).
|