Files
neovim/src/lint.zig
Chinmay Dalal d2acc69644 build(zig): add formatc and lintc steps
problem: build.zig does not have formatc and lintc steps
solution: add formatc and lintc step to build.zig
2026-06-17 01:03:55 -04:00

161 lines
5.8 KiB
Zig

const std = @import("std");
const gen = @import("gen/gen_steps.zig");
pub fn lintSources(
b: *std.Build,
nvim_sources: std.ArrayList(gen.SourceItem),
nvim_headers: std.ArrayList([]u8),
) !std.ArrayList([]const u8) {
var lint_sources: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 0);
for (nvim_sources.items) |source| {
try lint_sources.append(b.allocator, b.fmt("src/nvim/{s}", .{source.name}));
}
for (nvim_headers.items) |header| {
try lint_sources.append(b.allocator, b.fmt("src/nvim/{s}", .{header}));
}
try lint_sources.append(b.allocator, "src/tee/tee.c");
try lint_sources.append(b.allocator, "src/xxd/xxd.c");
return lint_sources;
}
pub fn addSteps(
b: *std.Build,
target: std.Build.ResolvedTarget,
cdb_step: *std.Build.Step,
nvim_exe_install: *std.Build.Step.InstallArtifact,
nvim_sources: std.ArrayList(gen.SourceItem),
nvim_headers: std.ArrayList([]u8),
ci_build: bool,
) !void {
const lintc = b.step("lintc", "Lint C source");
var lint_sources = try lintSources(b, nvim_sources, nvim_headers);
defer lint_sources.deinit(b.allocator);
const lintc_uncrustify = addLintcUncrustifyStep(b, lint_sources);
lintc.dependOn(lintc_uncrustify);
const lintc_clint = addLintcClintStep(b, nvim_exe_install, lint_sources, ci_build);
lintc.dependOn(lintc_clint);
const lintc_clang_tidy = try addLintcClangtidyStep(b, cdb_step, nvim_exe_install, target, lint_sources);
lintc.dependOn(lintc_clang_tidy);
try addFormatcStep(b, lint_sources);
}
fn addLintcUncrustifyStep(
b: *std.Build,
lint_sources: std.ArrayList([]const u8),
) *std.Build.Step {
const lintc_uncrustify = b.step("lintc-uncrustify", "Check formatting of C source with uncrustify");
const uncrustify = b.dependency("uncrustify", .{
.target = b.graph.host,
.optimize = .ReleaseFast,
});
const uncrustify_exe = uncrustify.artifact("uncrustify");
for (lint_sources.items) |file| {
const run = b.addRunArtifact(uncrustify_exe);
run.addArgs(&.{ "-c", "src/uncrustify.cfg", "-q", "--check" });
run.addFileArg(b.path(file));
run.expectExitCode(0);
lintc_uncrustify.dependOn(&run.step);
}
return lintc_uncrustify;
}
fn addLintcClangtidyStep(
b: *std.Build,
cdb_step: *std.Build.Step,
nvim_exe_install: *std.Build.Step.InstallArtifact,
target: std.Build.ResolvedTarget,
lint_sources: std.ArrayList([]const u8),
) !*std.Build.Step {
const lintc_clang_tidy = b.step("lintc-clang-tidy", "Lint C source with clang-tidy");
var exclusions: std.ArrayList([]const u8) = try .initCapacity(b.allocator, 0);
defer exclusions.deinit(b.allocator);
try exclusions.appendSlice(b.allocator, &.{
"src/nvim/eval/typval_encode.c.h",
"src/nvim/api/ui_events.in.h",
"src/xxd/xxd.c",
});
if (target.result.os.tag == .windows) {
try exclusions.appendSlice(b.allocator, &.{
"src/nvim/os/pty_proc_unix.h",
"src/nvim/os/unix_defs.h",
});
} else {
try exclusions.appendSlice(b.allocator, &.{
"src/nvim/os/win_defs.h",
"src/nvim/os/pty_proc_win.h",
"src/nvim/os/pty_conpty_win.h",
"src/nvim/os/os_win_console.h",
});
}
outer: for (lint_sources.items) |file| {
for (exclusions.items) |exclusion| {
if (std.mem.eql(u8, exclusion, file)) continue :outer;
}
const run = b.addSystemCommand(&.{"clang-tidy"});
run.step.dependOn(cdb_step);
run.step.dependOn(&nvim_exe_install.step);
run.addFileArg(b.path(file));
run.addArg("--quiet");
run.expectStdOutEqual("");
lintc_clang_tidy.dependOn(&run.step);
}
return lintc_clang_tidy;
}
fn addLintcClintStep(
b: *std.Build,
// use InstallArtifact instead of nvim_exe so that cache is not busted
// for every file to be linted
nvim_exe_install: *std.Build.Step.InstallArtifact,
lint_sources: std.ArrayList([]const u8),
ci_build: bool,
) *std.Build.Step {
const lintc_clint = b.step("lintc-clint", "Lint C source with clint");
const exclusions = [_][]const u8{ "src/nvim/tui/terminfo_defs.h", "src/xxd/xxd.c" };
const nvim_path = b.getInstallPath(.bin, nvim_exe_install.artifact.out_filename);
outer: for (lint_sources.items) |file| {
for (exclusions) |exclusion| {
if (std.mem.endsWith(u8, file, exclusion)) continue :outer;
}
const run = b.addSystemCommand(&.{nvim_path});
run.step.dependOn(&nvim_exe_install.step);
run.addArgs(&.{ "-u", "NONE", "-l" });
run.addFileArg(b.path("src/clint.lua"));
if (ci_build) {
run.addArg("--output=gh_action");
} else {
run.addArg("--output=vs7");
}
run.addFileArg(b.path(file));
run.expectStdOutEqual("");
lintc_clint.dependOn(&run.step);
}
return lintc_clint;
}
fn addFormatcStep(
b: *std.Build,
lint_sources: std.ArrayList([]const u8),
) !void {
const formatc = b.step("formatc", "Format C source with uncrustify");
const uncrustify = b.dependency("uncrustify", .{
.target = b.graph.host,
.optimize = .ReleaseFast,
});
const uncrustify_exe = uncrustify.artifact("uncrustify");
const update = b.addUpdateSourceFiles();
for (lint_sources.items) |file| {
const run = b.addRunArtifact(uncrustify_exe);
run.addArgs(&.{ "-c", "src/uncrustify.cfg", "-f" });
run.addFileArg(b.path(file));
run.addArg("-o");
const output_name = try std.mem.replaceOwned(u8, b.allocator, file, "/", "-");
const output = run.addOutputFileArg(output_name);
update.addCopyFileToSource(output, file);
}
formatc.dependOn(&update.step);
}