/* Ċ Ġ* ĠCopyright Ġ 2 0 1 8 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġandroidx . build . git client Ċ Ċ import Ġandroidx . build . re le as en otes . get Bug an izer Link Ċ import Ġandroidx . build . re le as en otes . get Change Id AO SP Link Ċ import Ġorg . gradle . api . logging . Logger Ċ import Ġjava . io . File Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ interface ĠGit Client Ġ{ ĊĠĠĠ Ġfun Ġfind Changed Files Since ( ĊĠĠĠĠĠĠĠ Ġsha : ĠString , ĊĠĠĠĠĠĠĠ Ġtop : ĠString Ġ= Ġ" HEAD ", ĊĠĠĠĠĠĠĠ Ġinclude Un committed : ĠBoolean Ġ= Ġfalse ĊĠĠĠ Ġ): ĠList < String > ĊĠĠĠ Ġfun Ġfind Previous Submitted Change (): ĠString ? ĊĊĠĠĠ Ġfun Ġget Git Log ( ĊĠĠĠĠĠĠĠ Ġgit Commit Range : ĠGit Commit Range , ĊĠĠĠĠĠĠĠ Ġkeep Merge s : ĠBoolean , ĊĠĠĠĠĠĠĠ Ġfull Project Dir : ĠFile ĊĠĠĠ Ġ): ĠList < Commit > ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAb straction Ġfor Ġrunning Ġexecution Ġcommands Ġfor Ġtest ability ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinterface ĠCommand Runner Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠExec utes Ġthe Ġgiven Ġshell Ġcommand Ġand Ġreturns Ġthe Ġstdout Ġas Ġa Ġstring . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġexecute ( command : ĠString ): ĠString ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠExec utes Ġthe Ġgiven Ġshell Ġcommand Ġand Ġreturns Ġthe Ġstdout Ġby Ġlines . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġexecute And Parse ( command : ĠString ): ĠList < String > ĊĠĠĠ Ġ} Ċ } Ċ /** Ċ Ġ* ĠA Ġsimple Ġgit Ġclient Ġthat Ġuses Ġsystem Ġprocess Ġcommands Ġto Ġcommunicate Ġwith Ġthe Ġgit Ġsetup Ġin Ġthe Ċ Ġ* Ġgiven Ġworking Ġdirectory . Ċ Ġ*/ Ċ class ĠGit Client Impl ( ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġroot Ġlocation Ġfor Ġgit ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġworking Dir : ĠFile , ĊĠĠĠ Ġprivate Ġval Ġlogger : ĠLogger ?, ĊĠĠĠ Ġprivate Ġval Ġcommand Runner : ĠGit Client . Command Runner Ġ= ĠReal Command Runner ( ĊĠĠĠĠĠĠĠ Ġworking Dir Ġ= Ġworking Dir , ĊĠĠĠĠĠĠĠ Ġlogger Ġ= Ġlogger ĊĠĠĠ Ġ) Ċ ) Ġ: ĠGit Client Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġgit Root : ĠFile Ġ= Ġfind Git Dir In Parent File path ( working Dir ) Ġ?: Ġworking Dir ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠFinds Ġchanged Ġfile Ġpaths Ġsince Ġthe Ġgiven Ġsha ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġfind Changed Files Since ( ĊĠĠĠĠĠĠĠ Ġsha : ĠString , ĊĠĠĠĠĠĠĠ Ġtop : ĠString , ĊĠĠĠĠĠĠĠ Ġinclude Un committed : ĠBoolean ĊĠĠĠ Ġ): ĠList < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġuse Ġthis Ġif Ġwe Ġdon 't Ġwant Ġlocal Ġchanges ĊĠĠĠĠĠĠĠ Ġreturn Ġcommand Runner . execute And Parse ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( include Un committed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ CHANGED _ FILES _ CMD _ PREFIX ĠHEAD .. $ sha " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ CHANGED _ FILES _ CMD _ PREFIX Ġ$ top Ġ$ sha " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġchecks Ġthe Ġhistory Ġto Ġfind Ġthe Ġfirst Ġmerge ĠCL . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġfind Previous Submitted Change (): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġcommand Runner . execute And Parse ( PREVIOUS _ SUBMIT TED _ CMD ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. first OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . split (" Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . first OrNull () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Git Dir In Parent File path ( filepath : ĠFile ): ĠFile ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcur Directory : ĠFile Ġ= Ġfilepath ĊĠĠĠĠĠĠĠ Ġwhile Ġ( cur Directory . path Ġ!= Ġ"/") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( File ("$ cur Directory /. git "). exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcur Directory ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcur Directory Ġ= Ġcur Directory . parent File ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Commit Log String ( ĊĠĠĠĠĠĠĠ Ġcommit Log String : ĠString , ĊĠĠĠĠĠĠĠ Ġcommit Start Delimiter : ĠString , ĊĠĠĠĠĠĠĠ Ġcommit SH AD elim iter : ĠString , ĊĠĠĠĠĠĠĠ Ġsubject Delimiter : ĠString , ĊĠĠĠĠĠĠĠ Ġauthor Email Delimiter : ĠString , ĊĠĠĠĠĠĠĠ Ġlocal Project Dir : ĠString ĊĠĠĠ Ġ): ĠList < Commit > Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠSplit Ġcommits Ġstring Ġout Ġinto Ġindividual Ġcommits Ġ( note : Ġthis Ġremoves Ġthe Ġdeli min ter ) ĊĠĠĠĠĠĠĠ Ġval Ġgit Log String List : ĠList < String >? Ġ= Ġcommit Log String . split ( commit Start Delimiter ) ĊĠĠĠĠĠĠĠ Ġvar Ġcommit Log : ĠMutable List < Commit > Ġ= Ġmutable ListOf () ĊĠĠĠĠĠĠĠ Ġgit Log String List ?. filter Ġ{ Ġgit Commit Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgit Commit . trim () Ġ!= Ġ"" ĊĠĠĠĠĠĠĠ Ġ} ?. forEach Ġ{ Ġgit Commit Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommit Log . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCommit ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgit Commit , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Project Dir , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcommit SH AD elim iter Ġ= Ġcommit SH AD elim iter , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubject Delimiter Ġ= Ġsubject Delimiter , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġauthor Email Delimiter Ġ= Ġauthor Email Delimiter ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcommit Log . toList () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠConverts Ġa Ġdiff Ġlog Ġcommand Ġinto Ġa Ġ[ List < Commit >] ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġgit Commit Range Ġthe Ġ[ Git Commit Range ] Ġthat Ġdefines Ġthe Ġparameters Ġof Ġthe Ġgit Ġlog Ġcommand ĊĠĠĠĠ Ġ* Ġ@ param Ġkeep Merge s Ġboolean Ġfor Ġwhether Ġor Ġnot Ġto Ġadd Ġmerge s Ġto Ġthe Ġreturn Ġ[ List < Commit > ]. ĊĠĠĠĠ Ġ* Ġ@ param Ġfull Project Dir Ġa Ġ[ File ] Ġobject Ġthat Ġrepresents Ġthe Ġfull Ġproject Ġdirectory . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġget Git Log ( ĊĠĠĠĠĠĠĠ Ġgit Commit Range : ĠGit Commit Range , ĊĠĠĠĠĠĠĠ Ġkeep Merge s : ĠBoolean , ĊĠĠĠĠĠĠĠ Ġfull Project Dir : ĠFile ĊĠĠĠ Ġ): ĠList < Commit > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcommit Start Delimiter : ĠString Ġ= Ġ"_ Commit Start " ĊĠĠĠĠĠĠĠ Ġval Ġcommit SH AD elim iter : ĠString Ġ= Ġ"_ Commit SHA :" ĊĠĠĠĠĠĠĠ Ġval Ġsubject Delimiter : ĠString Ġ= Ġ"_ Subject :" ĊĠĠĠĠĠĠĠ Ġval Ġauthor Email Delimiter : ĠString Ġ= Ġ"_ Author :" ĊĠĠĠĠĠĠĠ Ġval Ġdate Delimiter : ĠString Ġ= Ġ"_ Date :" ĊĠĠĠĠĠĠĠ Ġval Ġbody Delimiter : ĠString Ġ= Ġ"_ Body :" ĊĠĠĠĠĠĠĠ Ġval Ġlocal Project Dir : ĠString Ġ= Ġfull Project Dir . relative To ( git Root ). toString () ĊĠĠĠĠĠĠĠ Ġval Ġrelative Project Dir : ĠString Ġ= Ġfull Project Dir . relative To ( working Dir ). toString () ĊĊĠĠĠĠĠĠĠ Ġvar Ġgit Log Options : ĠString Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"-- pretty = format :$ commit Start Delimiter % n " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ commit SH AD elim iter % H % n " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ author Email Delimiter % ae % n " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ date Delimiter % ad % n " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ subject Delimiter % s % n " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ body Delimiter % b " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! keep Merge s ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġ-- no - mer ges " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġgit Log Cmd : ĠString ĊĠĠĠĠĠĠĠ Ġif Ġ( git Commit Range . from Exclusive Ġ!= Ġ"") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgit Log Cmd Ġ= Ġ"$ GIT _ LOG _ CMD _ PREFIX Ġ$ git Log Options Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ git Commit Range . from Exclusive } .. ${ git Commit Range . until Inclusive }" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġ-- Ġ./ $ relative Project Dir " ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgit Log Cmd Ġ= Ġ"$ GIT _ LOG _ CMD _ PREFIX Ġ$ git Log Options Ġ${ git Commit Range . until Inclusive } Ġ- n Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ git Commit Range . n } Ġ-- Ġ./ $ relative Project Dir " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġgit Log String : ĠString Ġ= Ġcommand Runner . execute ( git Log Cmd ) ĊĠĠĠĠĠĠĠ Ġval Ġcommits Ġ= Ġparse Commit Log String ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgit Log String , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommit Start Delimiter , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommit SH AD elim iter , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsubject Delimiter , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġauthor Email Delimiter , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlocal Project Dir ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġif Ġ( commits . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠProbably Ġan Ġerror ; Ġlog Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger ?. warn ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" No Ġgit Ġcommits Ġfound ! ĠR an Ġthis Ġcommand : Ġ'" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgit Log Cmd Ġ+ Ġ"' Ġand Ġreceived Ġthis Ġoutput : Ġ'" Ġ+ Ġgit Log String Ġ+ Ġ"'" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcommits ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠReal Command Runner ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġworking Dir : ĠFile , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġlogger : ĠLogger ? ĊĠĠĠ Ġ) Ġ: ĠGit Client . Command Runner Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġexecute ( command : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparts Ġ= Ġcommand . split ("\\ s ". to Regex ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger ?. info (" running Ġcommand Ġ$ command Ġin Ġ$ working Dir ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġproc Ġ= ĠProcess Builder (* parts . to Typed Array ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. directory ( working Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. redirect Output ( Process Builder . Redirect . PIPE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. redirect Error ( Process Builder . Redirect . PIPE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. start () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRead Ġoutput , Ġwaiting Ġfor Ġprocess Ġto Ġfinish , Ġas Ġneeded ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstdout Ġ= Ġproc ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. inputStream ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. buffered Reader () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. read Text () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstderr Ġ= Ġproc ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. error Stream ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. buffered Reader () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. read Text () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġstdout Ġ+ Ġstderr ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwait Ġpotentially Ġa Ġlittle Ġbit Ġlonger Ġin Ġcase ĠGit Ġwas Ġwaiting Ġfor Ġus Ġto ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġread Ġits Ġresponse Ġbefore Ġit Ġexited ĊĠĠĠĠĠĠĠĠĠĠĠ Ġproc . waitFor ( 1 0 , ĠTimeUnit . SECONDS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stderr Ġ!= Ġ"") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger ?. error (" Response : Ġ$ message ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger ?. info (" Response : Ġ$ message ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( proc . exit Value () Ġ== Ġ 0 ) Ġ{ Ġ" Non zero Ġexit Ġvalue Ġrunning Ġgit Ġcommand ." Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġstdout ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġexecute And Parse ( command : ĠString ): ĠList < String > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġexecute ( command ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. split ( System . line Separator ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Not Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . isEmpty () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresponse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠPRE V IOUS _ SUBMIT TED _ CMD Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" git Ġlog Ġ- 1 Ġ-- mer ges Ġ-- on eline Ġ-- invert - grep Ġ-- author = android - build - server " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠCH ANG ED _ FILES _ CMD _ PREFIX Ġ= Ġ" git Ġdiff Ġ-- name - only " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠGIT _ LOG _ CMD _ PREFIX Ġ= Ġ" git Ġlog Ġ-- name - only " ĊĠĠĠ Ġ} Ċ } Ċ Ċ enum Ġclass ĠCommit Type Ġ{ ĊĠĠĠ ĠNEW _ FEATURE , ĠAPI _ CHANGE , ĠBUG _ FIX , ĠEXTER NAL _ CONTRIBUT ION ; ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġget Title ( commit Type : ĠCommit Type ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( commit Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠNEW _ FEATURE Ġ-> Ġ" New ĠFeatures " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAPI _ CHANGE Ġ-> Ġ" API ĠChanges " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBUG _ FIX Ġ-> Ġ" Bug ĠFixes " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠEXTER NAL _ CONTRIBUT ION Ġ-> Ġ" External ĠCont ribution " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠDefines Ġthe Ġparameters Ġfor Ġa Ġgit Ġlog Ġcommand Ċ Ġ* Ċ Ġ* Ġ@ property Ġfrom Exclusive Ġthe Ġoldest ĠSHA Ġat Ġwhich Ġthe Ġgit Ġlog Ġstarts . ĠSet Ġto Ġan Ġempty Ġstring Ġto Ġuse Ċ Ġ* Ġ[ n ] Ċ Ġ* Ġ@ property Ġuntil Inclusive Ġthe Ġlatest ĠSHA Ġincluded Ġin Ġthe Ġgit Ġlog . Ġ ĠDefaults Ġto ĠHEAD Ċ Ġ* Ġ@ property Ġn Ġa Ġcount Ġof Ġhow Ġmany Ġcommits Ġto Ġgo Ġback Ġto . Ġ ĠOnly Ġused Ġwhen Ġ[ from Exclusive ] Ġis Ġan Ċ Ġ* Ġempty Ġstring Ċ Ġ*/ Ċ data Ġclass ĠGit Commit Range ( ĊĠĠĠ Ġval Ġfrom Exclusive : ĠString Ġ= Ġ"", ĊĠĠĠ Ġval Ġuntil Inclusive : ĠString Ġ= Ġ" HEAD ", ĊĠĠĠ Ġval Ġn : ĠInt Ġ= Ġ 0 Ċ ) Ċ Ċ /** Ċ Ġ* ĠClass Ġimplementation Ġof Ġa Ġgit Ġcommit . Ġ ĠIt Ġuses Ġthe Ġinput Ġde limiters Ġto Ġparse Ġthe Ġcommit Ċ Ġ* Ċ Ġ* Ġ@ property Ġgit Commit Ġa Ġstring Ġrepresentation Ġof Ġa Ġgit Ġcommit Ċ Ġ* Ġ@ property Ġproject Dir Ġthe Ġproject Ġdirectory Ġfor Ġwhich Ġto Ġparse Ġfile Ġpaths Ġfrom Ġa Ġcommit Ċ Ġ* Ġ@ property Ġcommit SH AD elim iter Ġthe Ġterm Ġto Ġuse Ġto Ġsearch Ġfor Ġthe Ġcommit ĠSHA Ċ Ġ* Ġ@ property Ġsubject Delimiter Ġthe Ġterm Ġto Ġuse Ġto Ġsearch Ġfor Ġthe Ġsubject Ġ( aka Ġcommit Ġsummary ) Ċ Ġ* Ġ@ property Ġchange Id Delimiter Ġthe Ġterm Ġto Ġuse Ġto Ġsearch Ġfor Ġthe Ġchange - id Ġin Ġthe Ġbody Ġof Ġthe Ġcommit Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠ Ġmessage Ċ Ġ* Ġ@ property Ġauthor Email Delimiter Ġthe Ġterm Ġto Ġuse Ġto Ġsearch Ġfor Ġthe Ġauthor Ġemail Ċ Ġ*/ Ċ data Ġclass ĠCommit ( ĊĠĠĠ Ġval Ġgit Commit : ĠString , ĊĠĠĠ Ġval Ġproject Dir : ĠString , ĊĠĠĠ Ġprivate Ġval Ġcommit SH AD elim iter : ĠString Ġ= Ġ"_ Commit SHA :", ĊĠĠĠ Ġprivate Ġval Ġsubject Delimiter : ĠString Ġ= Ġ"_ Subject :", ĊĠĠĠ Ġprivate Ġval Ġauthor Email Delimiter : ĠString Ġ= Ġ"_ Author :" Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġchange Id Delimiter : ĠString Ġ= Ġ" Change - Id :" ĊĠĠĠ Ġvar Ġbugs : ĠMutable List < Int > Ġ= Ġmutable ListOf () ĊĠĠĠ Ġvar Ġfiles : ĠMutable List < String > Ġ= Ġmutable ListOf () ĊĠĠĠ Ġvar Ġsha : ĠString Ġ= Ġ"" ĊĠĠĠ Ġvar Ġauthor Email : ĠString Ġ= Ġ"" ĊĠĠĠ Ġvar Ġchange Id : ĠString Ġ= Ġ"" ĊĠĠĠ Ġvar Ġsummary : ĠString Ġ= Ġ"" ĊĠĠĠ Ġvar Ġtype : ĠCommit Type Ġ= ĠCommit Type . BUG _ FIX ĊĠĠĠ Ġvar Ġrelease Note : ĠString Ġ= Ġ"" ĊĠĠĠ Ġprivate Ġval Ġrelease Note Delimit ers : ĠList < String > Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠ Ġ" Rel note :" ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlisted Commit : ĠList < String > Ġ= Ġgit Commit . split ('\ n ') ĊĠĠĠĠĠĠĠ Ġlisted Commit . filter Ġ{ Ġline Ġ-> Ġline . trim () Ġ!= Ġ"" Ġ}. forEach Ġ{ Ġline Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Commit Line ( line ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġprocess Commit Line ( line : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( commit SH AD elim iter Ġin Ġline ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget SHA From Git Line ( line ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( subject Delimiter Ġin Ġline ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Summary ( line ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( change Id Delimiter Ġin Ġline ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Change Id From Git Line ( line ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( author Email Delimiter Ġin Ġline ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Author Email From Git Line ( line ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ(" Bug :" Ġin Ġline Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" b /" Ġin Ġline Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" bug :" Ġin Ġline Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Fixes :" Ġin Ġline Ġ|| ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" fixes Ġb /" Ġin Ġline ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Bugs From Git Line ( line ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġrelease Note Delimit ers . forEach Ġ{ Ġdelimiter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( delimiter Ġin Ġline ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Release Notes From Git Line ( line , Ġgit Commit ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( project Dir . trim ('/') Ġin Ġline ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠgetFile From Git Line ( line ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis External Author Email ( author Email : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ!( author Email . contains ("@ google . com ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠParses ĠSH As Ġfrom Ġgit Ġcommit Ġline , Ġwith Ġthe Ġformat : ĊĠĠĠĠ Ġ* Ġ[ Commit . commit SH AD elim iter ] Ġ< commit SHA > ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget SHA From Git Line ( line : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsha Ġ= Ġline . substring After ( commit SH AD elim iter ). trim () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠParses Ġsubject Ġfrom Ġgit Ġcommit Ġline , Ġwith Ġthe Ġformat : ĊĠĠĠĠ Ġ* Ġ[ Commit . subject Delimiter ]< commit Ġsubject > ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Summary ( line : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsummary Ġ= Ġline . substring After ( subject Delimiter ). trim () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠParses Ġcommit ĠChange - Id Ġlines , Ġwith Ġthe Ġformat : ĊĠĠĠĠ Ġ* Ġ` commit . change Id Delimiter ` Ġ< change Id > ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Change Id From Git Line ( line : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġchange Id Ġ= Ġline . substring After ( change Id Delimiter ). trim () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠParses Ġcommit Ġauthor Ġlines , Ġwith Ġthe Ġformat : ĊĠĠĠĠ Ġ* Ġ[ Commit . author Email Delimiter ] email @ google . com ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Author Email From Git Line ( line : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġauthor Email Ġ= Ġline . substring After ( author Email Delimiter ). trim () ĊĠĠĠĠĠĠĠ Ġif Ġ( is External Author Email ( author Email )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtype Ġ= ĠCommit Type . EXTERNAL _ CONTRIBUT ION ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠParses Ġfilepath Ġto Ġget Ġchanged Ġfiles Ġfrom Ġcommit , Ġwith Ġthe Ġformat : ĊĠĠĠĠ Ġ* Ġ{ project _ directory }/{ filepath } ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun ĠgetFile From Git Line ( filepath : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfiles . add ( filepath . trim ()) ĊĠĠĠĠĠĠĠ Ġif Ġ( filepath . contains (" current . txt ") Ġ&& Ġtype Ġ!= ĠCommit Type . EXTERNAL _ CONTRIBUT ION ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtype Ġ= ĠCommit Type . API _ CHANGE ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ ĠParses Ġbugs Ġfrom Ġa Ġgit Ġcommit Ġmessage Ġline ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Bugs From Git Line ( line : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġformatted Line Ġ= Ġline . replace (" b /", Ġ" Ġ") ĊĠĠĠĠĠĠĠ Ġformatted Line Ġ= Ġformatted Line . replace (" :", Ġ" Ġ") ĊĠĠĠĠĠĠĠ Ġformatted Line Ġ= Ġformatted Line . replace (",", Ġ" Ġ") ĊĠĠĠĠĠĠĠ Ġvar Ġwords : ĠList < String > Ġ= Ġformatted Line . split (' Ġ') ĊĠĠĠĠĠĠĠ Ġwords . forEach Ġ{ Ġword Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġpossible Bug : ĠInt ? Ġ= Ġword . toInt OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( possible Bug Ġ!= Ġnull Ġ&& Ġpossible Bug Ġ> Ġ 1 0 0 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbugs . add ( possible Bug ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReads Ġin Ġthe Ġrelease Ġnotes Ġfield Ġfrom Ġthe Ġgit Ġcommit Ġmessage Ġline ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThey Ġcan Ġhave Ġa Ġcouple Ġvalid Ġformats : ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ` Release Ġnotes : ĠThis Ġis Ġa Ġone - line Ġrelease Ġnote ` ĊĠĠĠĠ Ġ* Ġ` Release ĠNotes : Ġ" This Ġis Ġa Ġmulti - line Ġrelease Ġnote . Ġ ĠThis Ġaccounts Ġfor Ġthe Ġuse Ġcase Ġwhere ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthe Ġcommit Ġcannot Ġbe Ġexplained Ġin Ġone Ġline " ĊĠĠĠĠ Ġ* Ġ` release Ġnotes : Ġ" This Ġis Ġa Ġone - line Ġrelease Ġnote . Ġ ĠThe Ġquotes Ġcan Ġbe Ġused Ġthis Ġway Ġtoo "` ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Release Notes From Git Line ( line : ĠString , Ġgit Commit : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ/* ĠAccount Ġfor Ġthe Ġuse Ġof Ġquotes Ġin Ġa Ġrelease Ġnote Ġline ĊĠĠĠĠĠĠĠĠ Ġ* ĠNo Ġquotes Ġin Ġthe ĠRelease ĠNote Ġline Ġmeans Ġit 's Ġa Ġone - line Ġrelease Ġnote ĊĠĠĠĠĠĠĠĠ Ġ* ĠIf Ġthere Ġare Ġquotes , Ġassume Ġit 's Ġa Ġmulti - line Ġrelease Ġnote ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġvar Ġquote Count In Rel Note Line : ĠInt Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġline . forEach Ġ{ Ġcharacter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( character Ġ== Ġ'" ') Ġ{ Ġquote Count In Rel Note Line ++ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( quote Count In Rel Note Line Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget One Line Release Notes From Git Line ( line ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrelease Note Delimit ers . forEach Ġ{ Ġdelimiter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( delimiter Ġin Ġline ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFind Ġthe Ġstarting Ġquote Ġof Ġthe Ġrelease Ġnotes Ġquote Ġblock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġrelease Note StartIndex Ġ= Ġgit Commit . lastIndexOf ( delimiter ) Ġ+ Ġdelimiter . length ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrelease Note StartIndex Ġ= Ġgit Commit . indexOf (' "', Ġrelease Note StartIndex ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMove Ġto Ġthe Ġcharacter Ġafter Ġthe Ġfirst Ġquote ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( git Commit [ release Note StartIndex ] Ġ== Ġ'" ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrelease Note StartIndex ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFind Ġthe Ġending Ġquote Ġof Ġthe Ġrelease Ġnotes Ġquote Ġblock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġrelease Note End Index Ġ= Ġrelease Note StartIndex Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrelease Note End Index Ġ= Ġgit Commit . indexOf (' "', Ġrelease Note End Index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthere Ġis Ġno Ġclosing Ġquote , Ġjust Ġuse Ġthe Ġfirst Ġline ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( release Note End Index Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget One Line Release Notes From Git Line ( line ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrelease Note Ġ= Ġgit Commit . substring ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠstartIndex Ġ= Ġrelease Note StartIndex , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġend Index Ġ= Ġrelease Note End Index ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ). trim () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget One Line Release Notes From Git Line ( line : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrelease Note Delimit ers . forEach Ġ{ Ġdelimiter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( delimiter Ġin Ġline ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrelease Note Ġ= Ġline . substring After ( delimiter ). trim (' Ġ', Ġ'" ') ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Release Note String (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġrelease Note String : ĠString Ġ= Ġrelease Note ĊĠĠĠĠĠĠĠ Ġrelease Note String Ġ+= Ġ" Ġ${ get Change Id AO SP Link ( change Id )}" ĊĠĠĠĠĠĠĠ Ġbugs . forEach Ġ{ Ġbug Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrelease Note String Ġ+= Ġ" Ġ${ get Bug an izer Link ( bug )}" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġrelease Note String ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcommit String : ĠString Ġ= Ġsummary ĊĠĠĠĠĠĠĠ Ġcommit String Ġ+= Ġ" Ġ${ get Change Id AO SP Link ( change Id )}" ĊĠĠĠĠĠĠĠ Ġbugs . forEach Ġ{ Ġbug Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommit String Ġ+= Ġ" Ġ${ get Bug an izer Link ( bug )}" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcommit String ĊĠĠĠ Ġ} Ċ } Ċ