// SPDX-License-Identifier: LGPL-3.0-only // SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts® module; #include "Crafter.Build-Api.h" export module Crafter.Build:Lint; import std; import :Clang; export namespace Crafter { enum class LintMode { // `lint`: diagnose only; transform output becomes would-reformat // findings. Never writes. The default. Report, // `format --check`: dry run; record the files that would change. Check, // `format`: rewrite changed files in place. Apply, }; struct RunLintOptions { // Rule-name globs ('*', '?'); empty = every registered rule. std::vector globs; // Enumerate matching rule names without running them. bool listOnly = false; LintMode mode = LintMode::Report; // Absolute path of the loaded project.cpp. It is linted too, and its // parent directory is the project root that decides which dependency // Configurations contribute rules/files (GitProject / cache-dir deps // are foreign code and skipped). Empty => fall back to cfg.path. std::filesystem::path projectFile; }; struct LintSummary { std::vector findings; // sorted by (file, line); filled in every mode // Apply: files rewritten on disk. Report/Check: files a transform // would change. The `format` verb's exit code keys off this in Check // mode; formatting files in Apply mode is success. std::vector changedFiles; std::size_t filesLinted = 0; std::size_t rulesRun = 0; // rules remaining after glob filter std::size_t errors = 0; // rule exceptions + write failures bool noRulesDefined = false; // project registered no rules at all // Host-side only (like TestSummary::AllPassed), safe as in-class inline. bool Clean() const { return findings.empty() && !noRulesDefined; } }; // Run the project's lint rules over its own sources: module interfaces // (+ partitions), implementations, cFiles, cuda, shaders, declared tests' // sources, and project.cpp itself — for the root Configuration plus every // transitive dependency whose path lies inside the project root. Rules // run in registration order per file, each seeing the previous rule's // transform output; a rule that throws is reverted and surfaced as a // finding + error. Only Apply mode writes to disk, and only files whose // final content differs from the original. Prints per-mode output: // findings compiler-style (Report), would-change paths (Check), or // formatted paths (Apply), plus a summary line. CRAFTER_API LintSummary RunLint(Configuration& projectCfg, const RunLintOptions& opts); }