From d7f7e36cbbcf2003ea9d03adec93a7060c44c5e3 Mon Sep 17 00:00:00 2001 From: Matt Glaman Date: Wed, 3 Sep 2025 11:47:59 -0500 Subject: [PATCH] Copy over CommitParser --- src/Cli/Command/Maintainer/ReleaseNotes.php | 39 ++++++---------- src/Cli/CommitParser.php | 51 +++++++++++++++++++++ 2 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 src/Cli/CommitParser.php diff --git a/src/Cli/Command/Maintainer/ReleaseNotes.php b/src/Cli/Command/Maintainer/ReleaseNotes.php index 1e4badc..508e9b6 100644 --- a/src/Cli/Command/Maintainer/ReleaseNotes.php +++ b/src/Cli/Command/Maintainer/ReleaseNotes.php @@ -2,9 +2,11 @@ namespace mglaman\DrupalOrgCli\Command\Maintainer; +use CzProject\GitPhp\Commit; use CzProject\GitPhp\Git; use CzProject\GitPhp\GitRepository; use mglaman\DrupalOrgCli\Command\Command; +use mglaman\DrupalOrgCli\CommitParser; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -114,36 +116,25 @@ protected function execute( return 1; } - $gitLog = $this->runProcess([ - 'git', - 'log', - '-s', - '--pretty=format:%s', - "$ref1..$ref2", - ]); - if ($gitLog->getExitCode() !== 0) { - var_export($gitLog->getErrorOutput()); - $this->stdOut->writeln('Error getting commit log'); - return 1; - } + $commits = array_map( + fn($hash) => $this->repository->getCommit($hash), + $this->repository->execute('log', '--pretty=format:%H', "$ref1..$ref2") + ); $format = $this->stdIn->getOption('format'); - $changes = array_filter(explode(PHP_EOL, trim($gitLog->getOutput()))); - $processedChanges = []; - foreach ($changes as $change) { - $nidsMatches = []; - preg_match('/#(\d+)/S', $change, $nidsMatches); + foreach ($commits as $commit) { + $nid = CommitParser::getNid($commit->getSubject()); - if (isset($nidsMatches[1]) && !isset($this->nids[$nidsMatches[1]])) { - $this->nids[$nidsMatches[1]] = $nidsMatches[1]; - $issue = $this->client->getNode($nidsMatches[1]); + if ($nid !== null) { + $this->nids[$nid] = $nid; + $issue = $this->client->getNode($nid); // There should always be an issue category, but if not default to `Task.` $issueCategory = $issue->get('field_issue_category') ?? 'Task'; $issueCategoryLabel = $this->categoryLabelMap[$issueCategory]; - $processedChanges[$issueCategoryLabel][$nidsMatches[1]] = $this->formatLine( - $change, + $processedChanges[$issueCategoryLabel][$nid] = $this->formatLine( + $commit, $format ); } @@ -280,9 +271,9 @@ protected function formatUsername(string $user, string $format): string return sprintf($replacement, $userAlias, $user); } - protected function formatLine(string $value, string $format): string + protected function formatLine(Commit $commit, string $format): string { - $value = preg_replace('/^(Patch |- |Issue ){0,3}/', '', $value); + $value = preg_replace('/^(Patch |- |Issue ){0,3}/', '', $commit->getSubject()); $baseUrl = 'https://www.drupal.org/node/$1'; diff --git a/src/Cli/CommitParser.php b/src/Cli/CommitParser.php new file mode 100644 index 0000000..c519465 --- /dev/null +++ b/src/Cli/CommitParser.php @@ -0,0 +1,51 @@ +title); + $from_message = self::extractUsernamesFromString($commit->message); + $usernames = array_merge($from_title, $from_message); + + $usernames = array_values(array_unique($usernames)); + if ($sort) { + sort($usernames); + } + + return $usernames; + } + + private static function extractUsernamesFromString(string $message): array { + $usernames = []; + // The classic "by" line in a commit title. + $matches = []; + if (preg_match('/by ([^:]+):/S', $message, $matches) === 1) { + foreach (explode(',', $matches[1]) as $user) { + $usernames[] = trim($user); + } + } + + if (preg_match_all('/^(?:By|Authored-by|Co-authored-by): ([^<]+)(?: <[^>]+>)?$/mi', $message, $matches)) { + foreach ($matches[1] as $user) { + $usernames[] = trim($user); + } + } + return $usernames; + } + + public static function getNid(string $title): ?string { + $matches = []; + // Drupal.org commits should have "Issue #{nid}". + if (preg_match('/#(\d+)/S', $title, $matches) === 1) { + return $matches[1]; + } + // But maybe they forgot the leading "#" on the issue ID. + if (preg_match('/([0-9]{4,})/S', $title, $matches) === 1) { + return $matches[1]; + } + return null; + } + +}