Skip to content

fix: v3.5.1 — gerador lê as specs atuais, enum negativo (#39), deprecations (#36) e gate de php -l - #42

Open
andrenfe wants to merge 8 commits into
masterfrom
fix/v3.5.1
Open

andrenfe wants to merge 8 commits into
masterfrom
fix/v3.5.1

Conversation

@andrenfe

Copy link
Copy Markdown
Member

Descrição

Correções do gerador e da base que destravam a atualização das specs às APIs atuais. O resync das specs vem num PR seguinte; este PR não altera openapi/.

Diagnóstico de origem: um ensaio de resync com as specs atuais do nfe/docs parou em três pontos. O gerador não lia 3 specs de NF-e, um enum gerado de CT-e dava erro fatal (#39) e um teste dependia do DNS da máquina.

Corrigido

  • Fatal error na v3.5.0: enum gerado com case duplicado (ConsultaCteV2/DFe_NetCore_Domain_Enums_EntityStatus) #39: enum de CT-e com case duplicado. ConsultaCteV2\DFe_NetCore_Domain_Enums_EntityStatus declarava Value_1 duas vezes (para 1 e -1) e dava erro fatal ao carregar, em php -l e com --classmap-authoritative. Valores negativos agora viram Value_MinusN, seguindo o padrão Value_<n>. O gerador passa a falhar, citando spec, schema e valores, quando dois valores geram o mesmo nome de case ou o mesmo valor de backing.
  • DTOs gerados de ConsultaNfeDistribuicaoV1 emitem Deprecated em PHP 8.2 (parâmetro opcional antes de obrigatório) #36: deprecations em 3 DTOs de ConsultaNfeDistribuicaoV1. Os DTOs declaravam parâmetro opcional antes de obrigatório. O gerador não emite mais esse default, que já era inalcançável. A ordem dos parâmetros e o tipo ?string não mudam.
  • Specs atuais da fonte com string entre aspas e continuação na coluna 0. nf-produto-v2, nf-produto-v3 e product-invoice-rtc-v1 passaram a ter esse formato. PyYAML e js-yaml aceitam, mas o symfony/yaml recusava, e o composer generate não rodava.
    • Decisão: reindentar essas linhas no carregamento, só quando o parser recusa o arquivo como está. O valor lido não muda: nas 3 specs, o documento é idêntico ao do PyYAML. O resumo do composer generate informa quantas linhas foram reindentadas.
    • Descartado: trocar o parser, porque o libyaml usa tipos do YAML 1.1 e exige extensão PECL no CI.
    • Descartado: normalizar no sync, porque as specs vendoradas divergiriam da fonte.
  • Teste de FailurePhase independente de DNS. O teste supunha que .invalid nunca resolve e falhava em rede com DNS curinga. Agora força conexão recusada numa porta livre de 127.0.0.1.

Adicionado

  • Gate composer lint (scripts/lint.sh): php -l com E_ALL em todo src/, falhando em erro ou deprecation. Roda como job próprio no CI (PHP 8.2) e no verify da release. Pega o que o lint do gerador (token_get_all) deixava passar.

Removido

  • Arquivo VERSION da raiz. Era resto da linha v2, dizia 3.4.1 e nada no repositório o lia. A versão vem só de Nfe\Version::CURRENT.

Versão

  • Version::CURRENT sobe para 3.5.1 e o CHANGELOG ganha a seção [3.5.1] — 2026-10-17.
  • A tag v3.5.1 fica para depois do merge.

Tipo de mudança

  • fix
  • feat
  • docs
  • chore/ci

Arquivos gerados alterados: 4

Todos explicados: 1 pela #39 (o enum) e 3 pela #36 (os 4 parâmetros que geravam deprecation).

Validação (Docker)

Compatibilidade

Sem quebra:

  • O case renomeado pertencia a um enum que nunca carregou.
  • A remoção do default não muda comportamento, verificado em 8.2, 8.3 e 8.4.
  • O gerador fica em scripts/, fora do pacote distribuído.

Fora deste PR

  • Resync das specs com o nfe/docs.
  • Issue no nfe/docs sobre as continuações em coluna 0. A tabela markdown dos eventos de autoridade vira uma linha só, porque dentro de aspas a quebra simples vira espaço; o certo é usar bloco |.
  • Teste que volte a cobrir a falha de DNS (errno 6).

Closes #39
Closes #36

O teste de FailurePhase supunha que o TLD .invalid nunca resolve. Em rede
com DNS curinga o host resolve e o teste falha. Agora ele reserva uma porta
efêmera livre em 127.0.0.1, libera e conecta no IP literal: a conexão é
recusada (CURLE_COULDNT_CONNECT, errno 7) de forma determinística e offline,
e a classificação continua sendo ConnectionNotEstablished.
O lint do gerador usa token_get_all, que só verifica sintaxe e deixa passar
erros de compilação, como case de enum duplicado (#39), e deprecations de
assinatura (#36). O novo scripts/lint.sh roda `php -l` com E_ALL em cada
arquivo de src/ e reprova qualquer saída diferente de "No syntax errors".

Entra como job próprio no CI (PHP 8.2), como passo do verify da release e
como `composer lint` / `make lint`. Nesta revisão o gate ainda falha:
1 fatal (#39) e 4 deprecations (#36), corrigidos nos commits seguintes.
As specs atuais de NF-e v2, v3 e RTC de produto (texto "Indisponível no
momento" dos eventos de autoridade) trazem descriptions entre aspas com
linhas de continuação na coluna 0. PyYAML e js-yaml aceitam; o symfony/yaml
recusa com "Malformed inline YAML string", porque o YAML 1.2 exige que essas
linhas fiquem indentadas além do nó pai.

O SpecLoader agora tenta o parse do arquivo como está e, só se o
symfony/yaml recusar, tenta uma segunda vez depois de reindentar as linhas
de continuação de escalares entre aspas que estejam na coluna da chave ou à
esquerda dela (YamlNormalizer). Dentro de string entre aspas, o espaço
inicial da continuação não é conteúdo, então o valor lido não muda. Blocos
| e >, comentários e strings que fecham na mesma linha não são tocados.
Spec que já era lida não passa pelo normalizador, e o hash do cabeçalho
continua sendo o dos bytes em disco.

O resumo do `composer generate` informa quantas linhas foram reindentadas
por spec, para o reparo nunca ficar silencioso e o caso ser reportado ao
time de docs. Nas 3 specs atuais da fonte, o documento lido é idêntico ao
do PyYAML.
… em colisão (#39)

O gerador descartava o sinal ao nomear o case: 1 e -1 viravam Value_1, e
ConsultaCteV2\DFe_NetCore_Domain_Enums_EntityStatus dava erro fatal
("Cannot redefine class constant") no carregamento, em `php -l` e em
--classmap-authoritative.

Valores numéricos negativos agora recebem o prefixo Value_Minus (-1 vira
Value_Minus1), seguindo o padrão Value_<n> já usado nos positivos. O único
valor negativo nas specs vendoradas é esse -1, então nenhum outro case muda
de nome.

O EnumCompiler passa a recusar, com erro que cita spec, schema e valores,
dois valores que gerem o mesmo nome de case ou o mesmo valor de backing,
em vez de emitir um enum que não compila.

Regerado a partir das specs vendoradas: só o enum do #39 muda.
…atório (#36)

Propriedade obrigatória e nullable vira `?T $x = null` entre as
obrigatórias. Quando uma obrigatória não nullable vem depois, o PHP 8.1+
emite "Optional parameter declared before required parameter is implicitly
treated as a required parameter". Isso acontecia em 3 DTOs de
ConsultaNfeDistribuicaoV1 (Sucessonarequisio, Sucessonarequisio2 e
Sucessonarequisio6).

O SchemaCompiler agora remove o `= null` de todo parâmetro declarado antes
de outro sem default. A ordem dos parâmetros não muda (quem chama
posicionalmente não quebra) e o tipo `?T` continua. O default já era
inalcançável: omitir o argumento, inclusive por nome, já lançava
ArgumentCountError, e a Reflection já o tratava como não opcional (conferido
em PHP 8.2, 8.3 e 8.4).

Regerado a partir das specs vendoradas: só esses 3 arquivos mudam, nos 4
parâmetros apontados pelas deprecations.
VERSION estava em 3.4.1 enquanto src/Version.php e o Packagist dizem 3.5.0.
Nada no repositório lê esse arquivo: scripts/release.sh só atualiza
src/Version.php e o release.yml confere a tag contra src/Version.php. Como
não está em export-ignore, ele vai no dist do Composer com valor defasado.
Por ora só alinha; a remoção fica para decisão do mantenedor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant