59 lines
2.8 KiB
Text
59 lines
2.8 KiB
Text
|
|
// 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<std::string> 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<LintFinding> 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<std::filesystem::path> 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);
|
||
|
|
}
|