mirror of
https://github.com/apricote/releaser-pleaser.git
synced 2026-01-13 21:21:03 +00:00
Fixes a bug where commits with messages that do not strictly conform to conventional commits spec would be ignored. This could easily happen while parsing footers like "Closes #xx" which would start the footer section, while continuing with the body afterwards. This solution has two downsides: - these warnings are not surfaced to the user. - If a `BREAKING CHANGE` footer exists after the parsing issue it is ignored Co-authored-by: jo <ljonas@riseup.net>
72 lines
2.1 KiB
Go
72 lines
2.1 KiB
Go
package conventionalcommits
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"strings"
|
|
|
|
"github.com/leodido/go-conventionalcommits"
|
|
"github.com/leodido/go-conventionalcommits/parser"
|
|
|
|
"github.com/apricote/releaser-pleaser/internal/commitparser"
|
|
"github.com/apricote/releaser-pleaser/internal/git"
|
|
)
|
|
|
|
type Parser struct {
|
|
machine conventionalcommits.Machine
|
|
logger *slog.Logger
|
|
}
|
|
|
|
func NewParser(logger *slog.Logger) *Parser {
|
|
parserMachine := parser.NewMachine(
|
|
parser.WithBestEffort(),
|
|
parser.WithTypes(conventionalcommits.TypesConventional),
|
|
)
|
|
|
|
return &Parser{
|
|
machine: parserMachine,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
func (c *Parser) Analyze(commits []git.Commit) ([]commitparser.AnalyzedCommit, error) {
|
|
analyzedCommits := make([]commitparser.AnalyzedCommit, 0, len(commits))
|
|
|
|
for _, commit := range commits {
|
|
msg, err := c.machine.Parse([]byte(strings.TrimSpace(commit.Message)))
|
|
if err != nil {
|
|
if msg == nil {
|
|
c.logger.Warn("failed to parse message of commit, skipping", "commit.hash", commit.Hash, "err", err)
|
|
continue
|
|
}
|
|
|
|
c.logger.Warn("failed to parse message of commit fully, trying to use as much as possible", "commit.hash", commit.Hash, "err", err)
|
|
}
|
|
|
|
conventionalCommit, ok := msg.(*conventionalcommits.ConventionalCommit)
|
|
if !ok {
|
|
return nil, fmt.Errorf("unable to get ConventionalCommit from parser result: %T", msg)
|
|
}
|
|
|
|
if conventionalCommit.Type == "" {
|
|
// Parsing broke before getting the type, can not use the commit
|
|
c.logger.Warn("commit type was not parsed, skipping", "commit.hash", commit.Hash, "err", err)
|
|
continue
|
|
}
|
|
|
|
commitVersionBump := conventionalCommit.VersionBump(conventionalcommits.DefaultStrategy)
|
|
if commitVersionBump > conventionalcommits.UnknownVersion {
|
|
// We only care about releasable commits
|
|
analyzedCommits = append(analyzedCommits, commitparser.AnalyzedCommit{
|
|
Commit: commit,
|
|
Type: conventionalCommit.Type,
|
|
Description: conventionalCommit.Description,
|
|
Scope: conventionalCommit.Scope,
|
|
BreakingChange: conventionalCommit.IsBreakingChange(),
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
return analyzedCommits, nil
|
|
}
|