aboutsummaryrefslogtreecommitdiff
path: root/scripts/lintcommit.lua
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lintcommit.lua')
-rw-r--r--scripts/lintcommit.lua76
1 files changed, 44 insertions, 32 deletions
diff --git a/scripts/lintcommit.lua b/scripts/lintcommit.lua
index d2c8601c25..96f6304247 100644
--- a/scripts/lintcommit.lua
+++ b/scripts/lintcommit.lua
@@ -16,7 +16,7 @@ local _trace = false
-- Print message
local function p(s)
vim.cmd('set verbose=1')
- vim.api.nvim_echo({{s, ''}}, false, {})
+ vim.api.nvim_echo({ { s, '' } }, false, {})
vim.cmd('set verbose=0')
end
@@ -25,7 +25,7 @@ end
-- Prints `cmd` if `trace` is enabled.
local function run(cmd, or_die)
if _trace then
- p('run: '..vim.inspect(cmd))
+ p('run: ' .. vim.inspect(cmd))
end
local rv = vim.trim(vim.fn.system(cmd)) or ''
if vim.v.shell_error ~= 0 then
@@ -43,14 +43,14 @@ end
local function validate_commit(commit_message)
-- Return nil if the commit message starts with "fixup" as it signifies it's
-- a work in progress and shouldn't be linted yet.
- if vim.startswith(commit_message, "fixup") then
+ if vim.startswith(commit_message, 'fixup') then
return nil
end
- local commit_split = vim.split(commit_message, ":", {plain = true})
+ local commit_split = vim.split(commit_message, ':', { plain = true })
-- Return nil if the type is vim-patch since most of the normal rules don't
-- apply.
- if commit_split[1] == "vim-patch" then
+ if commit_split[1] == 'vim-patch' then
return nil
end
@@ -74,35 +74,41 @@ local function validate_commit(commit_message)
if after_idx > vim.tbl_count(commit_split) then
return [[Commit message does not include colons.]]
end
- local after_colon = commit_split[after_idx]
+ local after_colon = ''
+ while after_idx <= vim.tbl_count(commit_split) do
+ after_colon = after_colon .. commit_split[after_idx]
+ after_idx = after_idx + 1
+ end
-- Check if commit introduces a breaking change.
- if vim.endswith(before_colon, "!") then
+ if vim.endswith(before_colon, '!') then
before_colon = before_colon:sub(1, -2)
end
-- Check if type is correct
- local type = vim.split(before_colon, "(", {plain = true})[1]
- local allowed_types = {'build', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'test', 'vim-patch'}
+ local type = vim.split(before_colon, '(', { plain = true })[1]
+ local allowed_types =
+ { 'build', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'test', 'vim-patch' }
if not vim.tbl_contains(allowed_types, type) then
return string.format(
[[Invalid commit type "%s". Allowed types are:
%s.
If none of these seem appropriate then use "fix"]],
type,
- vim.inspect(allowed_types))
+ vim.inspect(allowed_types)
+ )
end
-- Check if scope is appropriate
- if before_colon:match("%(") then
- local scope = vim.trim(commit_message:match("%((.-)%)"))
+ if before_colon:match('%(') then
+ local scope = vim.trim(commit_message:match('%((.-)%)'))
if scope == '' then
return [[Scope can't be empty]]
end
- if vim.startswith(scope, "nvim_") then
- return [[Scope should be "api" instead of "nvim_..."]]
+ if vim.startswith(scope, 'nvim_') then
+ return [[Scope should be "api" instead of "nvim_..."]]
end
local alternative_scope = {
@@ -119,17 +125,17 @@ local function validate_commit(commit_message)
end
-- Check that description doesn't end with a period
- if vim.endswith(after_colon, ".") then
+ if vim.endswith(after_colon, '.') then
return [[Description ends with a period (".").]]
end
-- Check that description starts with a whitespace.
- if after_colon:sub(1,1) ~= " " then
+ if after_colon:sub(1, 1) ~= ' ' then
return [[There should be a whitespace after the colon.]]
end
-- Check that description doesn't start with multiple whitespaces.
- if after_colon:sub(1,2) == " " then
+ if after_colon:sub(1, 2) == ' ' then
return [[There should only be one whitespace after the colon.]]
end
@@ -139,7 +145,7 @@ local function validate_commit(commit_message)
end
-- Check that description isn't just whitespaces
- if vim.trim(after_colon) == "" then
+ if vim.trim(after_colon) == '' then
return [[Description shouldn't be empty.]]
end
@@ -150,25 +156,25 @@ end
function M.main(opt)
_trace = not opt or not not opt.trace
- local branch = run({'git', 'rev-parse', '--abbrev-ref', 'HEAD'}, true)
+ local branch = run({ 'git', 'rev-parse', '--abbrev-ref', 'HEAD' }, true)
-- TODO(justinmk): check $GITHUB_REF
- local ancestor = run({'git', 'merge-base', 'origin/master', branch})
+ local ancestor = run({ 'git', 'merge-base', 'origin/master', branch })
if not ancestor then
- ancestor = run({'git', 'merge-base', 'upstream/master', branch})
+ ancestor = run({ 'git', 'merge-base', 'upstream/master', branch })
end
- local commits_str = run({'git', 'rev-list', ancestor..'..'..branch}, true)
+ local commits_str = run({ 'git', 'rev-list', ancestor .. '..' .. branch }, true)
assert(commits_str)
local commits = {} --- @type string[]
- for substring in commits_str:gmatch("%S+") do
- table.insert(commits, substring)
+ for substring in commits_str:gmatch('%S+') do
+ table.insert(commits, substring)
end
local failed = 0
for _, commit_id in ipairs(commits) do
- local msg = run({'git', 'show', '-s', '--format=%s' , commit_id})
+ local msg = run({ 'git', 'show', '-s', '--format=%s', commit_id })
if vim.v.shell_error ~= 0 then
- p('Invalid commit-id: '..commit_id..'"')
+ p('Invalid commit-id: ' .. commit_id .. '"')
else
local invalid_msg = validate_commit(msg)
if invalid_msg then
@@ -179,20 +185,22 @@ function M.main(opt)
p('\n')
end
- p(string.format([[
+ p(string.format(
+ [[
Invalid commit message: "%s"
Commit: %s
%s
]],
msg,
commit_id,
- invalid_msg))
+ invalid_msg
+ ))
end
end
end
if failed > 0 then
- p([[
+ p([[
See also:
https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md#commit-messages
@@ -239,11 +247,14 @@ function M._test()
['refactor(): empty scope'] = false,
['ci( ): whitespace as scope'] = false,
['ci: period at end of sentence.'] = false,
+ ['ci: period: at end of sentence.'] = false,
['ci: Capitalized first word'] = false,
['ci: UPPER_CASE First Word'] = true,
['unknown: using unknown type'] = false,
['feat: foo:bar'] = true,
+ ['feat: :foo:bar'] = true,
['feat(something): foo:bar'] = true,
+ ['feat(something): :foo:bar'] = true,
['feat(:grep): read from pipe'] = true,
['feat(:grep/:make): read from pipe'] = true,
['feat(:grep): foo:bar'] = true,
@@ -252,7 +263,7 @@ function M._test()
['feat(:grep/:make)'] = false,
['feat(:grep'] = false,
['feat(:grep/:make'] = false,
- ['ci: you\'re saying this commit message just goes on and on and on and on and on and on for way too long?'] = false,
+ ["ci: you're saying this commit message just goes on and on and on and on and on and on for way too long?"] = false,
}
local failed = 0
@@ -260,14 +271,15 @@ function M._test()
local is_valid = (nil == validate_commit(message))
if is_valid ~= expected then
failed = failed + 1
- p(string.format('[ FAIL ]: expected=%s, got=%s\n input: "%s"', expected, is_valid, message))
+ p(
+ string.format('[ FAIL ]: expected=%s, got=%s\n input: "%s"', expected, is_valid, message)
+ )
end
end
if failed > 0 then
os.exit(1)
end
-
end
--- @class LintcommitOptions