1010use Symfony \Component \Console \Input \InputArgument ;
1111use Symfony \Component \Console \Input \InputOption ;
1212use Symfony \Component \Console \Helper \ProgressBar ;
13+
1314# TODO
1415#use Cache\Adapter\Redis\RedisCachePool;
1516
1617class GenerateChangelogCommand extends Command
1718{
18- const ORG_NAME = 'nextcloud ' ;
19- const REPO_SERVER = 'server ' ;
19+ public const ORG_NAME = 'nextcloud ' ;
20+ public const REPO_SERVER = 'server ' ;
2021
2122 private $ skipLabels = [];
2223 private bool $ skipDrafts ;
@@ -61,7 +62,7 @@ protected function cleanTitle($title)
6162 $ title = preg_replace ('!(\[|\()(stable)? ?\d\d(\]|\))?\W*!i ' , '' , $ title );
6263 $ title = preg_replace ('!^\[security\]!i ' , '' , $ title );
6364 $ title = trim ($ title );
64- return strtoupper ( substr ( $ title, 0 , 1 )) . substr ( $ title , 1 );
65+ return ucfirst ( $ title );
6566 }
6667
6768 protected function processPR ($ repoName , $ pr )
@@ -75,6 +76,8 @@ protected function processPR($repoName, $pr)
7576 'repoName ' => $ repoName ,
7677 'number ' => $ pr ['number ' ],
7778 'title ' => $ title ,
79+ 'mergeable ' => $ pr ['mergeable ' ] ?? '' ,
80+ 'reviewDecision ' => $ pr ['reviewDecision ' ] ?? '' ,
7881 ];
7982
8083 if (isset ($ pr ['assignees ' ]['nodes ' ])
@@ -101,7 +104,7 @@ protected function shouldPRBeSkipped(array $pr, $noBots = false)
101104 }
102105 if (isset ($ pr ['labels ' ], $ pr ['labels ' ]['nodes ' ])) {
103106 foreach ($ pr ['labels ' ]['nodes ' ] as $ label ) {
104- if (in_array ($ label ['id ' ], $ this ->skipLabels , false ) || in_array (strtolower ($ label ['name ' ]), $ this ->skipLabels , false ) ) {
107+ if (in_array ($ label ['id ' ], $ this ->skipLabels , false ) || in_array (strtolower ($ label ['name ' ]), $ this ->skipLabels , false )) {
105108 return true ;
106109 }
107110 }
@@ -155,21 +158,22 @@ protected function getReposToIterate($head = 'master')
155158 $ repos = $ paginator ->fetchAll ($ organizationApi , 'repositories ' , $ parameters );
156159
157160 // Filter out archived and disabled repos
158- $ results = array_filter ($ repos , function ($ repo ): bool {
161+ $ results = array_filter ($ repos , function ($ repo ): bool {
159162 return $ repo ['archived ' ] === false
160163 && $ repo ['disabled ' ] === false ;
161164 });
162165
163166 // Return repos names
164- $ orgRepositories = array_map (fn ($ repo ): string => $ repo ['name ' ], $ results );
167+ $ orgRepositories = array_map (fn ($ repo ): string => $ repo ['name ' ], $ results );
165168 } catch (\Exception $ e ) {
166169 throw new Exception ('Unable to fetch the github repositories list: ' . $ e ->getMessage ());
167170 }
168171
169172 return [...$ reposToIterate , ...array_intersect ($ orgRepositories , $ shippedApps )];
170173 }
171174
172- protected function authenticateGithubClient (\Github \Client $ client ) {
175+ protected function authenticateGithubClient (\Github \Client $ client )
176+ {
173177 if (!file_exists (__DIR__ . '/../credentials.json ' )) {
174178 throw new Exception ('Credentials file is missing - please provide your credentials in credentials.json in the root folder. ' );
175179 }
@@ -319,7 +323,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
319323 if ($ head === 'master ' ) {
320324 $ info = $ repo ->show (self ::ORG_NAME , $ repoName );
321325 $ effectiveHead = $ info ['default_branch ' ];
322- } else if ($ base === 'master ' ) {
326+ } elseif ($ base === 'master ' ) {
323327 $ info = $ repo ->show (self ::ORG_NAME , $ repoName );
324328 $ effectiveBase = $ info ['default_branch ' ];
325329 }
@@ -348,15 +352,15 @@ protected function execute(InputInterface $input, OutputInterface $output)
348352 foreach ($ commits as $ commit ) {
349353 $ login = $ commit ['author ' ]['login ' ] ?? $ commit ['committer ' ]['login ' ] ?? $ commit ['commit ' ]['author ' ]['name ' ];
350354 $ fullMessage = $ commit ['commit ' ]['message ' ];
351- list ($ firstLine ,) = explode ("\n" , $ fullMessage , 2 );
355+ list ($ firstLine , ) = explode ("\n" , $ fullMessage , 2 );
352356 if (substr ($ firstLine , 0 , 20 ) === 'Merge pull request # ' ) {
353357 if ($ noBots && (str_contains ($ login , '[bot] ' ) || str_contains ($ login , 'nextcloud- ' ))) {
354358 // ignore this bot-created commit
355359 continue ;
356360 }
357-
361+
358362 $ firstLine = substr ($ firstLine , 20 );
359- list ($ number ,) = explode (" " , $ firstLine , 2 );
363+ list ($ number , ) = explode (" " , $ firstLine , 2 );
360364 $ pullRequests [] = $ number ;
361365 }
362366 }
@@ -376,6 +380,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
376380 nodes {
377381 number
378382 title
383+ mergeable
384+ reviewDecision
379385 author {
380386 login
381387 }
@@ -589,7 +595,7 @@ function ($a, $b) {
589595 if ($ this ->isAuthorBot ($ author )) {
590596 $ author = '(generated) ' ;
591597 }
592-
598+
593599 // If backportbot, let's see if we have someone assigned
594600 if (str_contains ($ author , 'backport ' )
595601 && array_key_exists ('assignee ' , $ data )) {
@@ -600,12 +606,28 @@ function ($a, $b) {
600606 $ output ->writeln ("* $ author " );
601607 $ prevAuthor = $ author ;
602608 }
609+
610+ $ status = '' ;
611+ if ($ data ['mergeable ' ] === 'CONFLICTING ' ) {
612+ $ status = ' ⚠ ' ;
613+ }
614+ if ($ data ['reviewDecision ' ] === 'APPROVED ' ) {
615+ $ status = ' ✅ ' ;
616+ } elseif ($ data ['reviewDecision ' ] === 'CHANGES_REQUESTED ' ) {
617+ $ status = ' 🔁 ' ;
618+ }
619+
603620 if ($ repoName === self ::REPO_SERVER ) {
604- $ output ->writeln (" * [ ] # $ number " );
605- } else {
606- $ output ->writeln (" * [ ] $ orgName/ $ repoName# $ number " );
621+ $ output ->writeln (" * # $ number$ status " );
622+ } else {
623+ $ output ->writeln (" * $ orgName/ $ repoName# $ number$ status " );
607624 }
608625 }
626+
627+ $ output ->writeln ('--- ' );
628+ $ output ->writeln ('- ⚠: conflicts detected ' );
629+ $ output ->writeln ('- ✅: approved ' );
630+ $ output ->writeln ('- 🔁: changes requested ' );
609631 }
610632 break ;
611633 }
@@ -615,16 +637,18 @@ function ($a, $b) {
615637 #$client->removeCache();
616638 }
617639
618- function escapeMarkdown (string $ text ): string {
640+ public function escapeMarkdown (string $ text ): string
641+ {
619642 // Escape characters that break markdown
620643 $ escapeChars = ['* ' , '_ ' , '~ ' , '` ' , '[ ' , '] ' , '( ' , ') ' , '# ' , '+ ' , '- ' , '! ' , '| ' ];
621644 foreach ($ escapeChars as $ char ) {
622645 $ text = str_replace ($ char , '\\' . $ char , $ text );
623646 }
624647 return $ text ;
625648 }
626-
627- function groupPRsByRepo ($ prs ) {
649+
650+ public function groupPRsByRepo ($ prs )
651+ {
628652 $ grouped = [];
629653 foreach ($ prs as $ pr ) {
630654 $ repo = $ pr ['repoName ' ];
0 commit comments