Files
Pulse/Xmake/Actions/CheckFiles.lua
2025-01-26 12:55:13 +01:00

188 lines
4.1 KiB
Lua

task("check-files")
set_menu({
usage = "xmake check-files [options]",
description = "Check every file for consistency (can fix some errors)",
options =
{
{'f', "fix", "k", nil, "Attempt to automatically fix files." }
}
})
on_run(function()
import("core.base.option")
local file_lines = {}
local updated_files = {}
local function GetFile(file_path)
file_path = path.translate(file_path)
local lines = file_lines[file_path]
if not lines then
lines = table.to_array(io.lines(file_path))
if not lines then
os.raise("failed to open " .. file_path)
end
file_lines[file_path] = lines
end
return lines
end
local function UpdateFile(file_path, lines)
file_path = path.translate(file_path)
if lines then
file_lines[file_path] = lines
end
updated_files[file_path] = true
end
local checks = {}
-- Remove empty lines at the beginning of files
table.insert(checks, {
Name = "empty lines",
Check = function()
local files = table.join(
os.files("Sources/**.h"),
os.files("Sources/**.inl"),
os.files("Sources/**.c"),
os.files("Sources/**.cpp")
)
local fixes = {}
for _, file_path in pairs(files) do
local lines = GetFile(file_path)
for i = 1, #lines do
if not lines[i]:match("^%s*$") then
if i ~= 1 then
print(file_path .. " starts with empty lines")
table.insert(fixes, {
File = file_path,
Func = function(lines)
for j = 1, i - 1 do
table.remove(lines, 1)
end
UpdateFile(file_path, lines)
end
})
end
break
end
end
end
return fixes
end
})
-- Check copyright date and format
table.insert(checks, {
Name = "copyright",
Check = function()
local files = table.join(
os.files("Sources/**.h"),
os.files("Sources/**.inl"),
os.files("Sources/**.c"),
os.files("Sources/**.cpp")
)
local current_year = os.date("%Y")
local fixes = {}
-- Headers
for _, file_path in pairs(files) do
local lines = GetFile(file_path)
local has_copyright
local should_fix = false
local year, authors = lines[1]:match("^// Copyright %(C%) (Y?E?A?R?%d*) kanel$")
has_copyright = year ~= nil
if has_copyright then
if year ~= current_year then
print(file_path .. ": copyright year error")
sould_fix = true
end
if lines[2] ~= "// This file is part of \"Pulse\"" then
print(file_path .. ": copyright project error")
sould_fix = true
end
if lines[3] ~= "// For conditions of distribution and use, see copyright notice in LICENSE" then
print(file_path .. ": copyright file reference error")
sould_fix = true
end
else
print(file_path .. ": copyright not found")
sould_fix = true
end
if sould_fix then
table.insert(fixes, {
File = file_path,
Func = function(lines)
local copyright_lines = {
"// Copyright (C) " .. current_year .. " kanel",
"// This file is part of \"Pulse\"",
"// For conditions of distribution and use, see copyright notice in LICENSE"
}
if has_copyright then
for i, line in ipairs(copyright_lines) do
lines[i] = line
end
else
for i, line in ipairs(copyright_lines) do
table.insert(lines, i, line)
end
table.insert(lines, #copyright_lines + 1, "")
end
return lines
end
})
end
::skip::
end
return fixes
end
})
local sould_fix = option.get("fix") or false
for _, check in pairs(checks) do
print("Running " .. check.Name .. " check...")
local fixes = {}
table.join2(fixes, check.Check())
if sould_fix then
for _, fix in pairs(fixes) do
print("Fixing " .. fix.File)
UpdateFile(fix.File, fix.Func(assert(file_lines[fix.File])))
end
end
end
for file_path, _ in pairs(updated_files) do
local lines = assert(file_lines[file_path])
if lines[#lines] ~= "" then
table.insert(lines, "")
end
print("Saving changes to " .. file_path)
io.writefile(file_path, table.concat(lines, "\n"))
end
end)