Repository navigation
refactor(discover): port the discover module to Zig - #107
Merged
Merged
Conversation
…mpat_fs discover.c carried its own Windows code: a wide-char stat, a stat that skips reparse points, and _fullpath in place of realpath. They move unchanged into compat_fs as cbm_stat_utf8, cbm_stat_no_follow and cbm_canonical_path, so discover.c no longer needs win_utf8.h or platform #ifdefs for them. This prepares the Zig port of discover: the Zig code can call one function on every platform, and the Windows code stays in C. Signed-off-by: ata-sesli <atasesli@protonmail.com>
gitignore.zig, userconfig.zig and language.zig replace their C files and implement the same discover.h and userconfig.h declarations; the comptime export check compares each with its header. - gitignore: glob matching, parsing and the atomic merge are unchanged. cbm_gitignore_match_result stays a non-header export for discover.c, and the merge test hook stays an exported variable. - userconfig: extra_extensions parsing still goes through yyjson with the same flags, so duplicate keys and the project-over-global dedup behave as before. - language: the extension, filename, compound-extension, interpreter and name tables keep their entries and order; the tier switch, shebang probe and .m/.cls/.frm disambiguation are ported as written. generate-lang-code.py now prints language.zig table rows. Signed-off-by: ata-sesli <atasesli@protonmail.com>
discover.zig replaces discover.c, so src/discover/ has no C left. It implements the walk part of discover.h with the same exports, checked against the header at comptime. Ported as written: the skip, suffix, filename, fast-pattern and ignored-JSON lists (entry for entry); core.excludesFile and XDG lookup; the gitignore link chain with nested files, info/exclude and the enclosing-repository ancestors; tracked-file sets from git ls-files; cache-tree pruning; the growable walk stack; the degraded flag; and the CBM_DISCOVER_TEST_FAIL_PHASE/_NTH fault injection. Paths keep the fixed 4 KiB buffers with snprintf truncation, and the file and excluded arrays stay on the C allocator for cbm_discover_free and cbm_discover_free_excluded. One deviation: when the excluded_strdup fault fires, the copied string is now freed instead of leaked. cbm_gitignore_match_result was exported only for discover.c; it is now the plain Zig function gitignore.matchResult. The license-gate ignore entry for the license-filename list moves to discover.zig. Signed-off-by: ata-sesli <atasesli@protonmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This moves the file-discovery module (
src/discover/) from C to Zig, following the same approach as the earlier git, simhash and watcher port: the C headers (discover.h,userconfig.h) stay the interface, and the Zig files export the samecbm_*functions. No caller changes. After this PR,src/discover/has no.cfiles.Discovery should behave exactly as before: the same files are found, the same directories are skipped, and
.gitignore,.git/info/exclude,.cbmignoreand the global excludes file are applied the same way.Commits
Each commit builds and passes the full test suite on its own.
refactor(foundation): move discover's stat and realpath helpers to compat_fs(C only). Moves the platform-specific file helpers out ofdiscover.cunchanged, ascbm_stat_utf8,cbm_stat_no_followandcbm_canonical_pathinfoundation/compat_fs.{h,c}. On Windows they use_wstat64, skip reparse points and call_fullpath; on POSIX they usestat/lstat/realpath. This keeps the Windows#ifdefcode in C, so the Zig walk calls one helper on every platform.refactor(discover): port gitignore, userconfig and language to Zig. Replacesgitignore.c,userconfig.candlanguage.cwith.zigcounterparts.userconfig.zigparses JSON through the same yyjson calls as before, so duplicate keys and parse errors are handled the same way.scripts/generate-lang-code.pynow prints Zig table rows.refactor(discover): port the directory walk to Zig. Replacesdiscover.cwithdiscover.zig. The port covers:CBM_DISCOVER_TEST_FAIL_PHASE/_NTHfault-injection hooks.It keeps the C version's fixed buffers and truncation behaviour. Arrays and strings returned to C use the C allocator, so
cbm_discover_freeandcbm_discover_free_excludedwork unchanged.Build wiring:
build.zigandMakefile.cbmdrop the C sources and list the Zig files inCBM_ZIG_SRCS.src/cbm_zig.zigrunscheckExportson the new modules, so a signature that drifts from its C header fails the build.scripts/license-policy.jsonandCONTRIBUTING.mdpoint at the new file names.Differences from the C code
cbm_gitignore_match_resultis no longer exported. No header declared it;discover.cdeclared it locally.discover.zignow calls the matcher through a Zig import.cbm_gitignore_merge_dup_hook_for_testis kept as an exported variable. It is a test hook.excluded_strdupfault path: when that injected fault fires, the Zig code frees the copied string. The C code leaked it. This only runs under fault injection.#ifdef. The Zig code keeps the same guard asif (!is_windows).Verification
CBM_TEST_TIERS=all(all language tiers on), macOS arm64: 6,447 passed onmain(7484e7e) and 6,447 passed after each of the three commits.mainand this branch each indexed the same repositories, each into its own cache. Theindex_repositoryresponse (status, excluded dirs and counts), the sortedFilepaths and the node counts per label were identical in every case. The repositories were:a scratch fixture that covers:
.gitignorefiles, including re-included files;.git/info/excludeand.cbmignore;core.excludesFilefrom~/.gitconfigand from the XDG config dir;.git(exercising enclosing-repository lookup);It was indexed in
full,fastandmoderatemodes.this repository's source tree and a larger external repository, each in
fullandfastmodes.main's C sources and from the Zig sources (extensions, filenames, compound extensions, language names, tiers, user-config language names, skip dirs, suffixes, filenames, patterns, ignored JSON files) and compared them in order. All 14 were identical.libcbm_zig.asucceeded for x86_64 and aarch64 Linux (gnu), x86_64 Windows (gnu) and aarch64 macOS, and the discover exports were present in each archive.discover.h. The build failed withcbm_discover_free: parameter 1 is c_int in Zig but c_long in its C header. The change was then reverted.zig fmt --check,git diff --checkandtests/test_github_workflows.shall pass.Limits
src/discover/discover.c. They are intests/repro/*.c,src/pipeline/pass_pkgmap.cand one line ofdiscover.h. They are left as they are to keep this diff focused on the port.