diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1166500..dfe9c39 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -101,6 +101,9 @@ The following `Key: value` pairs are recognized. - Fix memory leak in fdopen (bug 31840) - libio: Test for fdopen memory leak without SEEK_END ``` + If there are no `- ` lines, the changelog entry is automatically + word-wrapped. If `- ` lines are used, the line breaks found in the + trailer are preserved in the RPM `%changelog` section. * `RPM-Changelog-Stop`. Boolean. When `yes`, generation of changelog entries stops at this commit. Requires `Parent`. diff --git a/patch-git.lua b/patch-git.lua index f5f7637..04f201b 100644 --- a/patch-git.lua +++ b/patch-git.lua @@ -883,6 +883,22 @@ do assert(err == 'ticket reference without trailing number: bug') end +-- Append a line to the changelog table. It is prefixed with '- '. +-- Long lines are wrapped at word boundaries and indented. +local function append_to_rpm_changelog(line, result) + if #result == 0 then + result[1] = '-' + end + for word in string.gmatch(line, '%S+') do + if #result[#result] + #word > 76 then + result[#result + 1] = ' ' .. word + else + result[#result] = result[#result] .. ' ' .. word + end + end +end + + -- Extract the trailers from the passed commit message. Returns a -- single table where keys are derived from the trailer tags. -- On error, returns nil and an error message. @@ -928,7 +944,9 @@ do assert(not n and err == 'Patch-Git-Version does not contain a number') end - -- Validator for RPM-Changelog. + -- Validator for RPM-Changelog. It returns the changelog entries + -- as a table of lines. The lines start with '- ' or ' ', unless + -- they are empty. local function parse_rpm_changelog(tag, s) assert(string.sub(s, #s) == '\n') @@ -938,11 +956,11 @@ do end local lines = {} - for line in string.gmatch(s, '([^\n]+\n)') do + for line in string.gmatch(s, '([^\n]+)\n') do lines[#lines + 1] = line end -- Remove leading whitespace from the first line. - lines[1] = assert(string.match(lines[1], '^[ \t]*(.*\n)$')) + lines[1] = assert(string.match(lines[1], '^[ \t]*(.*)$')) if #lines == 1 then -- Nothing to do else @@ -964,22 +982,31 @@ do local result = {} if not string.match(lines[1], '^- ') then - -- This is not an itemized changelog entry. The loop below - -- appends to this entry. - result[1] = '' - end - for _, line in ipairs(lines) do - local tagged = string.match(line, '^-[ \t]+(.*)%s*\n') - if tagged then - -- New entry. - result[#result + 1] = tagged - else - local stripped = assert(string.match(line, '%s*(.*)%s*\n')) - local old = result[#result] - if old ~= '' then - old = old .. ' ' - end - result[#result] = old .. stripped + -- This is not an itemized changelog entry. Concatenate all + -- lines with word-wrapping. + for _, line in ipairs(lines) do + append_to_rpm_changelog(line, result) + end + else + local dashed = false + for lineno, line in ipairs(lines) do + if lineno > 1 and string.match(line, '^- ') then + dashed = true + end + end + + for lineno, line in ipairs(lines) do + if not string.match(line, '^- ') then + if string.match(line, '^%s*$') then + line = '' + elseif not dashed then + -- If there are no '- ' lines in the continuation + -- part, all lines need to be indented to line up + -- with with the '- ' from the first line. + line = ' ' .. line + end + end + result[lineno] = line end end return result @@ -989,35 +1016,33 @@ do local function prc(s) return parse_rpm_changelog('RPM-Changelog', s) end - local t, err -- Single-line changelog entry, not itemized. - t = assert(prc('Switch to patch-git\n')) - assert(#t == 1) - assert(t[1] == 'Switch to patch-git') + assert_eq(assert(prc('Switch to patch-git\n')), + {'- Switch to patch-git'}) -- Single-line changelog entry, itemized. - t = assert(prc(' - Switch to patch-git\n')) - assert(#t == 1) - assert(t[1] == 'Switch to patch-git') + assert_eq(assert(prc(' - Switch to patch-git\n')), + {'- Switch to patch-git'}) -- Multi-line changelog entry, not itemized. - t = assert(prc(' Switch to\n patch-git\n')) - assert(#t == 1) - assert(t[1] == 'Switch to patch-git') + assert_eq(assert(prc(' Switch to\n patch-git\n')), + {'- Switch to patch-git'}) -- Multi-line changelog entry, one item. - t = assert(prc('- Switch to\n patch-git\n')) - assert(#t == 1) - assert(t[1] == 'Switch to patch-git') + assert_eq(assert(prc('- Switch to\n patch-git\n')), + {'- Switch to', ' patch-git'}) -- Multi-line changelog entry, two items. - t = assert(prc( - '- Switch to\n patch-git\n' - .. ' - Additional patch-git\n fixes\n')) - assert(#t == 2, t[1]) - assert(t[1] == 'Switch to patch-git') - assert(t[2] == 'Additional patch-git fixes') + assert_eq(assert(prc([[- Switch to + patch-git + - Additional patch-git + fixes +]])), + {'- Switch to', + ' patch-git', + '- Additional patch-git', + ' fixes'}) end local function parse_rpm_release(tag, s) @@ -1453,7 +1478,9 @@ local function rpm_changelog_default(message, trailer) and tickets and #tickets > 0) then subject = subject .. ' (' .. table.concat(tickets, ', ') .. ')' end - return {subject} + local result = {} + append_to_rpm_changelog(subject, result) + return result end -- Tests for rpm_changelog_default. do @@ -1465,15 +1492,13 @@ do Resolves: RHEL-108475 ]]) - assert(#t == 1) - assert(t[1] == 'Remove memory leak in fdopen (RHEL-108475)', t[1]) + assert_eq(t, {'- Remove memory leak in fdopen (RHEL-108475)'}) t = rcd([[Remove memory leak in fdopen (RHEL-108475) Resolves: RHEL-108475 ]]) - assert(#t == 1) - assert(t[1] == 'Remove memory leak in fdopen (RHEL-108475)', t[1]) + assert_eq(t, {'- Remove memory leak in fdopen (RHEL-108475)'}) t = rcd([[Remove memory leak in fdopen (RHEL-108475) @@ -1489,9 +1514,73 @@ RPM-Changelog: - Remove memory leak in fdopen (bug 31840) - libio: Test for fdopen memory leak without SEEK_END ]]) - assert(#t == 2) - assert(t[1] == 'Remove memory leak in fdopen (bug 31840)') - assert(t[2] == 'libio: Test for fdopen memory leak without SEEK_END') + assert_eq(t, + {'- Remove memory leak in fdopen (bug 31840)', + '- libio: Test for fdopen memory leak without SEEK_END'}) + + t = rcd([[Do not wrap the cat + +Resolves: RHEL-108475 +RPM-Changelog: + - Do not wrap the cat! + /\_/\ + ( o.o ) + > ^ < + - Thank you. +]]) + assert_eq(t, + {'- Do not wrap the cat!', + [[ /\_/\]], + [[ ( o.o )]], + [[ > ^ <]], + '- Thank you.'}) + + t = rcd([[Do not wrap the cat + +Resolves: RHEL-108475 +RPM-Changelog: + - Do not wrap the cat! + /\_/\ + ( o.o ) + > ^ < + - Thank you. +]]) + assert_eq(t, + {'- Do not wrap the cat!', + [[ /\_/\]], + [[ ( o.o )]], + [[ > ^ <]], + '- Thank you.'}) + + t = rcd([[Do not wrap the cat + +Resolves: RHEL-108475 +RPM-Changelog: + - Do not wrap the cat! + /\_/\ + ( o.o ) + > ^ < +]]) + assert_eq(t, + {[[- Do not wrap the cat!]], + [[ /\_/\]], + [[ ( o.o )]], + [[ > ^ <]]}) + + -- Variant that has the dash on the RPM-Changelog line. + t = rcd([[Do not wrap the cat + +Resolves: RHEL-108475 +RPM-Changelog: - Do not wrap the cat! + /\_/\ + ( o.o ) + > ^ < +]]) + assert_eq(t, + {[[- Do not wrap the cat!]], + [[ /\_/\]], + [[ ( o.o )]], + [[ > ^ <]]}) end @@ -1770,9 +1859,8 @@ local function process_commits(changelog, changelog_after_commit) assert_commit(commit, target_cl and #target_cl > 0, 'first commit skips changelog and has an entry') - for i=1,#cl_entries do - target_cl[#target_cl + 1] = '- ' .. cl_entries[i] - end + table.move(cl_entries, 1, #cl_entries, + #target_cl + 1, target_cl) end end end