GitNexus/gitnexus/test/helpers/optional-grammar.ts
Gergő Magyar c5c4fbe43c
fix(zig): vendor tree-sitter-zig so npm i -g no longer warns on peers (#3180)
* fix(zig): vendor tree-sitter-zig so npm i -g no longer warns on peers

Published overrides do not apply to dependents, so the Zig optionalDependency
kept warning that tree-sitter@0.21.1 does not satisfy peerOptional ^0.22.1.
Load it from vendor/ like Dart/Kotlin/Swift instead.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(ci): add zig parse snippet to prebuild validate

The six zig prebuild jobs failed at "Validate the .node loads and parses"
because snippets[GRAMMAR] was undefined and tree-sitter threw
"Input must be a function".

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore: drop Unreleased changelog note from the Zig vendor PR

CHANGELOG.md is owned by the release process, not individual PRs.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33949409205

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33949616521

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33949829377

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33950025077

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33950220655

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33950400275

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33950607933

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33950882912

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33951170483

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33951386477

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33951624305

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33951813452

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33951998309

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33952225172

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33952524393

* fix(ci): stop native prebuild rebuild loops

PR path filters and source checks see the cumulative diff, so generated binaries kept rebuilding the original source change. Skip output-only synchronize events using their exact before/head range, failing closed when Git cannot compare it. Exercise the workflow against real commit histories, including multi-commit source pushes and merge-ref drift.

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33953226606

* fix: address Zig PR review feedback (#3180)

Check for the vendored package without loading its native binding so a
broken installed Zig grammar fails the parsing test instead of skipping.
Match the optional child descriptor in the Zig metadata declaration and
include Zig in the two optional/vendored grammar comments.

Validation: 159 targeted tests, TypeScript, metadata type fixture, and
formatting passed. Injected native-load failure now fails instead of
skipping; explicit Zig opt-out still skips.

* chore(vendor): rebuild native prebuilds (tree-sitter-zig)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/33956342308

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: gitnexus-release-bot[bot] <gitnexus-release-bot[bot]@users.noreply.github.com>
2026-09-05 10:35:33 +01:00

81 lines
4 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { SupportedLanguages } from 'gitnexus-shared';
import { isLanguageAvailable } from '../../src/core/tree-sitter/parser-loader.js';
/**
* Grammars that ship as an npm `optionalDependency` or a vendored prebuild are
* absent on platforms without a build for them, so the suites that need them
* skip by contract. That contract has a hole: a language whose grammar never
* installs *anywhere in CI* merges with every one of its suites reported
* green-by-skip, and its native parser path is never executed once.
*
* `GITNEXUS_REQUIRE_<LANG>=1` closes it. A job that sets it declares "this
* platform has a prebuild, so the grammar MUST be here" and a missing grammar
* becomes a hard failure instead of a skip — the same contract
* `GITNEXUS_REQUIRE_FTS` gives the FTS suites (test/helpers/fts-availability.ts).
* Local and prebuild-less runs leave the variable unset and keep skipping.
*
* Add a language here only once at least one *required* CI job runs on a
* platform its grammar publishes a prebuild for; otherwise the gate would fail
* a job it cannot satisfy.
*/
export const OPTIONAL_GRAMMAR_ENV: Readonly<Partial<Record<string, string>>> = {
// Vendored tree-sitter-zig ships prebuilds for the CI matrix OS/arch
// tuples (linux-arm64 is rebuilt by the GitNexus prebuild workflow;
// ubuntu/windows/macos latest in required jobs have a committed binary).
[SupportedLanguages.Zig]: 'GITNEXUS_REQUIRE_ZIG',
} satisfies Partial<Record<SupportedLanguages, string>>;
/**
* True when CI declared this grammar mandatory on the current runner.
*
* Keyed by GRAMMAR key, not by `SupportedLanguages`: the registry the ABI
* load-smoke walks (`listGrammarSources()`) yields one row per `SOURCES` entry,
* which includes variants such as `typescript:tsx` that are not enum members.
* Widening the parameter is what keeps that call honest — narrowing the key
* with a cast would claim every grammar row is a language, which is false.
* `satisfies` above still pins every key WE write to a real language.
*/
export const isOptionalGrammarRequired = (grammarKey: string): boolean => {
const envVar = OPTIONAL_GRAMMAR_ENV[grammarKey];
return envVar !== undefined && process.env[envVar] === '1';
};
export interface OptionalGrammarGate {
readonly language: SupportedLanguages;
/** The grammar loaded on this machine. */
readonly available: boolean;
/** CI declared it mandatory here (see {@link OPTIONAL_GRAMMAR_ENV}). */
readonly required: boolean;
/** Pass to `describe.skipIf` — suites still skip when the grammar is absent. */
readonly skip: boolean;
}
export const optionalGrammarGate = (language: SupportedLanguages): OptionalGrammarGate => {
const available = isLanguageAvailable(language);
return { language, available, required: isOptionalGrammarRequired(language), skip: !available };
};
/**
* Register the presence assertion for `gate`. Call it once per language, from
* the suite file that owns that language's coverage.
*
* Deliberately a separate assertion rather than flipping the suites themselves
* from skip to fail: a skipped suite reports success, so the only thing that
* can turn "Zig never ran" into a red job is a test that *fails* when the
* grammar is missing. It is inert (skipped) wherever the grammar is genuinely
* optional, which is what keeps local runs on a prebuild-less platform usable.
*/
export const describeGrammarPresence = (gate: OptionalGrammarGate): void => {
const envVar = OPTIONAL_GRAMMAR_ENV[gate.language] ?? '<unregistered>';
describe.skipIf(!gate.required)(`${gate.language} grammar presence (${envVar}=1)`, () => {
it('the optional grammar is installed, so no suite below is green-by-skip', () => {
expect(
gate.available,
`${envVar}=1 declares the ${gate.language} grammar mandatory on this runner, but it did ` +
`not load — every ${gate.language} suite would have skipped and the job would still be ` +
`green. Install the grammar on this platform or drop ${envVar} from the job.`,
).toBe(true);
});
});
};