O Fim dos Erros Silenciosos de Localização em Apps .NET - Conheça o resx-lint
"Impeça erros de localização silenciosos em apps .NET. O resx-lint valida chaves .resx em XAML e C#, corrige erros automaticamente e integra-se ao seu pipeline de build."
resx-lint é uma ferramenta global .NET que valida chaves de localização .resx em seus arquivos de origem XAML e C#. Ele detecta chaves ausentes antes que cheguem à produção, corrige automaticamente problemas comuns e integra-se diretamente ao seu pipeline de build para que os erros apareçam inline no Visual Studio, Rider e em qualquer saída de CI.
Funcionalidades
- Análise estática — verifica
{maui:Translate Key}no XAML eAppResources.Keyno C# e reporta chaves ausentes como erros de build - Correções automáticas — remove chaves duplicadas, adiciona propriedades ausentes no
Designer.cse preenche automaticamente entradas de idioma órfãs - Erros nativos do MSBuild — emite o formato
file(line): error TRANS001: ...para que o VS/Rider mostrem sublinhados ondulados (squiggles) inline com links clicáveis - Sugestões de chaves semelhantes — quando uma chave está ausente, sugere as correspondências mais próximas para ajudar a identificar erros de digitação rapidamente
- Modo
--what-if— visualize cada alteração sem tocar em nenhum arquivo - Amigável para CI —
--fail-on-warningseleva avisos a erros para pipelines mais rigorosos - Zero dependências — executável único e independente, sem necessidade de pacotes NuGet extras
Instalação
Global (desenvolvimento local)
dotnet tool install --global ResxLint
Por repositório (recomendado para equipes e CI)
dotnet new tool-manifest # cria .config/dotnet-tools.json — versione este arquivo
dotnet tool install ResxLint
Novos desenvolvedores e agentes de CI executam apenas uma vez:
dotnet tool restore
Uso
resx-lint --project-dir <dir> --resx-file <path> [options]
| Opção | Descrição |
|---|---|
--project-dir <dir> |
Raiz do projeto (onde os arquivos .xaml e .cs residem) |
--resx-file <path> |
Caminho para o arquivo .resx base (ex: Resources/AppResources.resx) |
--what-if |
Visualiza todas as alterações sem gravar nenhum arquivo |
--fail-on-warnings |
Trata TRANS006 e TRANS007 como erros fatais |
--quiet |
Suprime mensagens ✓ OK e ℹ INFO — mostra apenas problemas |
--help |
Mostra a ajuda e sai |
Integração com MSBuild
Adicione este target ao seu .csproj para validar em cada build.
O trecho abaixo verifica se o resx-lint está instalado antes de executá-lo e emite uma mensagem de erro clara e acionável se não estiver — em vez do erro críptico exited with code 9009 que você obteria de outra forma:
<Target Name="ValidateTranslationKeys" BeforeTargets="BeforeBuild">
<!-- Erro amigável se o resx-lint não estiver instalado -->
<Exec Command="resx-lint --help"
ConsoleToMSBuild="true"
IgnoreExitCode="true"
StandardOutputImportance="low"
StandardErrorImportance="low">
<Output TaskParameter="ExitCode" PropertyName="_ResxLintExitCode" />
</Exec>
<Error
Condition="'$(_ResxLintExitCode)' == '9009' OR '$(_ResxLintExitCode)' == '127'"
Text="resx-lint is not installed. Run: dotnet tool install --global ResxLint | Docs: https://github.com/CW-Software-Apps/resx-lint" />
<!-- Executar validação -->
<Exec
Command="resx-lint --project-dir "$(MSBuildProjectDirectory)" --resx-file "$(MSBuildProjectDirectory)\Resources\AppResources.resx""
ConsoleToMSBuild="true"
IgnoreExitCode="false" />
</Target>
Se a ferramenta estiver faltando, o build para com:
error : resx-lint is not installed. Run: dotnet tool install --global ResxLint
Docs: https://github.com/CW-Software-Apps/resx-lint
Para o modo estrito (avisos tornam-se erros), adicione --fail-on-warnings ao comando Exec.
Integração CI/CD
GitHub Actions
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.x'
- name: Restore tools
run: dotnet tool restore # lê .config/dotnet-tools.json
- name: Validate translations
run: resx-lint --project-dir . --resx-file Resources/AppResources.resx --fail-on-warnings
Docker / Coolify / Auto-hospedado
Se o seu CI/CD faz o build via Docker (ex: Coolify na Hostinger), instale a ferramenta em seu Dockerfile e execute-a antes do dotnet publish:
# Instalar resx-lint
RUN dotnet tool install --global ResxLint
ENV PATH="${PATH}:/root/.dotnet/tools"
# Copiar fontes
COPY [".", "/src/app"]
# ✅ Validar traduções — falha o build Docker se chaves estiverem ausentes
RUN resx-lint \
--project-dir /src/app \
--resx-file /src/YourLibrary/Resources/AppResources.resx
# Build
RUN dotnet publish MyApp.csproj -f net10.0-android -c Release
A ferramenta sai com o código 3 em erros fatais, o que faz com que o build Docker falhe e interrompa a implantação do Coolify antes que um build quebrado chegue à produção.
Códigos de Diagnóstico
| Código | Gravidade | Descrição | Ação |
|---|---|---|---|
TRANS001 |
❌ Fatal | Chave usada em {maui:Translate Key} (XAML) não encontrada no .resx base |
Corrigir manualmente |
TRANS002 |
🔧 Auto-fix | Chave duplicada encontrada em um arquivo .resx |
Ocorrências extras removidas |
TRANS003 |
🔧 Auto-fix | Chave no .resx base não tem propriedade correspondente no Designer.cs |
Propriedade adicionada automaticamente |
TRANS004 |
❌ Fatal | Chave acessada como AppResources.Key (C#) não encontrada no .resx base |
Corrigir manualmente |
TRANS005 |
🔧 Auto-fix | Chave existe em um arquivo de idioma, mas não no .resx base |
Adicionada ao base com o marcador [TRADUZIR] |
TRANS006 |
⚠️ Aviso | Chave no .resx base não tem tradução em um ou mais arquivos de idioma |
Adicionar tradução ou elevar com --fail-on-warnings |
TRANS007 |
⚠️ Aviso | O valor no .resx base está vazio ou é um marcador como [TRADUZIR] |
Tradução pendente |
TRANS008 |
ℹ️ Info | O valor é idêntico ao idioma base em um arquivo traduzido | Pode ser intencional (nomes próprios, números, etc.) |
Erros fatais (TRANS001, TRANS004) interrompem o build imediatamente. Correções automáticas (TRANS002, TRANS003, TRANS005) modificam arquivos e retornam o código de saída 1 para que o MSBuild reinicie o build para revalidar.
Códigos de Saída
| Código | Significado |
|---|---|
0 |
Tudo OK — nenhum problema encontrado |
1 |
Correções automáticas foram aplicadas — reinicie o build para revalidar |
2 |
Parâmetros inválidos |
3 |
Erros fatais encontrados (TRANS001 ou TRANS004) |
Exemplo de Saída
═══ 4/6 Validando uso de XAML ({maui:Translate}) ═══
Views/HomePage.xaml(42) : error TRANS001 : Translation key 'WelcomeTitel' not found in AppResources.resx. Similar keys: 'WelcomeTitle'.
──────────────────────────────────────────────────────────────
RESUMO — resx-lint
──────────────────────────────────────────────────────────────
.resx base : Resources\AppResources.resx
Chaves no base : 312
Idiomas : 2 (AppResources.en-US.resx, AppResources.es-ES.resx)
Auto-fixes aplicados: 0
Avisos : 0
Erros fatais : 1
──────────────────────────────────────────────────────────────
✖ Build cancelado: 1 erro(s) fatal(is). Corrija as chaves ausentes e recompile.
Requisitos
- .NET 10 SDK ou posterior
Licença
MIT © CW Software
