package Ġcom . github . ps x paul . task Ċ Ċ import Ġcom . github . ps x paul . Fork Task Termination Service Ċ import Ġcom . github . ps x paul . stream . InputStream Pipe Ċ import Ġcom . github . ps x paul . stream . OutputStream Logger Ċ import Ġcom . github . ps x paul . util . waitFor Port Open Ċ import Ġorg . gradle . api . Default Task Ċ import Ġorg . gradle . api . Gradle Exception Ċ import Ġorg . gradle . api . Task Ċ import Ġorg . gradle . api . file . Regular File Property Ċ import Ġorg . gradle . api . model . ObjectFactory Ċ import Ġorg . gradle . api . provider . Property Ċ import Ġorg . gradle . api . tasks .* Ċ import Ġorg . gradle . process . Process Fork Options Ċ import Ġjava . io . File Ċ import Ġjava . io . File OutputStream Ċ import Ġjava . io . OutputStream Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġkotlin . reflect .* Ċ import Ġkotlin . reflect . full .* Ċ import Ġkotlin . reflect . jvm .* Ċ import Ġjava . util . stream . Stream Ċ Ċ /** Ċ Ġ* ĠAn Ġabstract Ġtask Ġthat Ġwill Ġlaunch Ġan Ġexecutable Ġas Ġa Ġbackground Ġprocess , Ġoptionally Ċ Ġ* Ġwaiting Ġuntil Ġa Ġspecific Ġport Ġis Ġopened . ĠThe Ġtask Ġwill Ġalso Ġstop Ġthe Ġprocess Ġif Ġgiven Ċ Ġ* Ġa Ġstop After Ġor Ġjoin Task Ċ Ġ* Ċ Ġ* Ġ@ see ĠExec Fork Ċ Ġ* Ġ@ see ĠJava Exec Fork Ċ Ġ* Ġ@ see ĠProcess Fork Options Ċ Ġ* Ċ Ġ* Ġ@ param Ġargs Ġthe Ġarguments Ġto Ġgive Ġthe Ġexecutable Ċ Ġ* Ġ@ param Ġstandard Output Ġthe Ġname Ġof Ġthe Ġfile Ġto Ġwrite Ġthe Ġprocess 's Ġstandard Ġoutput Ġto Ċ Ġ* Ġ@ param Ġerror Output Ġthe Ġname Ġof Ġthe Ġfile Ġto Ġwrite Ġthe Ġprocess 's Ġerror Ġoutput Ġto Ċ Ġ* Ġ@ param ĠwaitFor Port Ġif Ġspecified , Ġblock Ġthe Ġtask Ġfrom Ġcomplet ing Ġuntil Ġthe Ġgiven Ġport Ġis Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopen Ġlocally Ċ Ġ* Ġ@ param Ġtimeout Ġthe Ġlength Ġof Ġtime Ġin Ġseconds Ġthat Ġthe Ġtask Ġwill Ġwait Ġfor Ġthe Ġport Ġto Ġbe Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbe Ġopened , Ġbefore Ġfailing Ċ Ġ* Ġ@ param Ġstop After Ġif Ġspecified , Ġthis Ġtask Ġwill Ġstop Ġthe Ġrunning Ġprocess Ġafter Ġthe Ġstop After Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtask Ġhas Ġbeen Ġcompleted Ċ Ġ*/ Ċ abstract Ġclass ĠAbstract Exec Fork ( object Factory : ĠObject Factory ) Ġ: ĠDefault Task (), ĠProcess Fork Options Ġ{ ĊĊĠĠĠ Ġ@ Input ĊĠĠĠ Ġabstract Ġoverride Ġfun Ġget Environment (): ĠMutable Map < String , ĠAny > ĊĊĠĠĠ Ġ@ Input ĊĠĠĠ Ġabstract Ġoverride Ġfun Ġget Executable (): ĠString ? ĊĊĠĠĠ Ġ@ Input ĊĠĠĠ Ġvar Ġargs : ĠMutable List < CharSequence > Ġ= Ġmutable ListOf () ĊĊĠĠĠ Ġ@ Input Directory ĊĠĠĠ Ġabstract Ġoverride Ġfun Ġget Working Dir (): ĠFile ĊĊĠĠĠ Ġ@ OutputFile ĊĠĠĠ Ġ@ Optional ĊĠĠĠ Ġval Ġstandard Output : ĠRegular File Property Ġ= Ġobject Factory . file Property () ĊĊĠĠĠ Ġ@ OutputFile ĊĠĠĠ Ġ@ Optional ĊĠĠĠ Ġval Ġerror Output : ĠRegular File Property Ġ= Ġobject Factory . file Property () ĊĊĠĠĠ Ġ@ Input ĊĠĠĠ Ġ@ Optional ĊĠĠĠ Ġvar ĠwaitFor Port : ĠInt ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Input ĊĠĠĠ Ġ@ Optional ĊĠĠĠ Ġvar ĠwaitFor Output : ĠString ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Input ĊĠĠĠ Ġ@ Optional ĊĠĠĠ Ġvar ĠwaitFor Error : ĠString ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Input ĊĠĠĠ Ġvar Ġforce Kill : ĠBoolean Ġ= Ġfalse ĊĊĠĠĠ Ġ@ Input ĊĠĠĠ Ġvar Ġkill Desc endants : ĠBoolean Ġ= Ġtrue ĊĊĠĠĠ Ġ@ Internal ĊĠĠĠ Ġvar Ġprocess : ĠProcess ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Input ĊĠĠĠ Ġvar Ġtimeout : ĠLong Ġ= Ġ 6 0 ĊĊĠĠĠ Ġ@ Internal ĊĠĠĠ Ġvar Ġstop After : ĠTask Provider < Task >? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġset ( stop After Value : ĠTask Provider < Task > ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( stop After Value Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( field Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠGradle Exception (" Cannot Ġre assign Ġstop After ! ĠWas Ġset Ġto Ġ${ field !!. name } Ġalready Ġwhen Ġattempting Ġto Ġset Ġto Ġ${ stop After Value . name }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjoin Task Ġ= Ġproject . tasks . register ( create Name For ( this ), ĠExec Join :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . fork Task Ġ= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info (" Adding Ġ{} Ġas Ġa Ġfinal izing Ġtask Ġto Ġ{}", Ġjoin Task . name , Ġstop After Value . name ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstop After Value . configure Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . final ized By ( join Task ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġstop After Value ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠIt Ġshould Ġbe ĠProperty < Fork Task Termination Service > Ġbut Ġbecause Ġof Ġa Ġbug Ġin ĠGradle ĊĠĠĠ Ġ// Ġwe Ġhave Ġto Ġuse Ġa Ġmore Ġgeneric Ġtype , Ġsee Ġhttps :// github . com / gradle / gradle / issues / 1 7 5 5 9 ĊĠĠĠ Ġ// ĠThis Ġcan Ġbe Ġrepro duced Ġin Ġthe Ġspring _ boot Ġsample Ġproject ĊĠĠĠ Ġ@ Internal ĊĠĠĠ Ġ@ Suppress (" PLATFORM _ CLASS _ MAP PED _ TO _ K OT LIN ") ĊĠĠĠ Ġval Ġfork Task Termination Service : ĠProperty < in ĠObject > Ġ= Ġobject Factory . property ( Object :: class . java ) ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠThe Ġexec Ġfork Ġtask Ġshould Ġbe Ġexecuted Ġin Ġany Ġcase Ġif Ġnot Ġmanually Ġspecified Ġotherwise . ĊĠĠĠĠĠĠĠ Ġ// ĠBy Ġdefault , Ġthis Ġis Ġthe Ġcase Ġas Ġthe Ġtask Ġhas Ġonly Ġinputs Ġdefined , Ġbut Ġe . g . Ġj aco co Ġatt aches Ġa Ġj vm Ġargument ĊĠĠĠĠĠĠĠ Ġ// Ġprovider , Ġwhich Ġin Ġturn Ġcontribut es Ġan Ġoutput Ġproperty , Ġwhich Ġcauses Ġthe Ġtask Ġto Ġbe Ġconsidered Ġup - to - date . ĊĠĠĠĠĠĠĠ Ġoutputs . up ToDate When Ġ{ Ġfalse Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Task Action ĊĠĠĠ Ġopen Ġfun Ġexec () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġprocess Builder : ĠProcess Builder Ġ= ĠProcess Builder ( get Process Args ()) ĊĠĠĠĠĠĠĠ Ġredirect Streams ( process Builder ) ĊĊĠĠĠĠĠĠĠ Ġval Ġprocess Working Dir : ĠFile Ġ= Ġworking Dir ĊĠĠĠĠĠĠĠ Ġprocess Working Dir . mkdir s () ĊĠĠĠĠĠĠĠ Ġprocess Builder . directory ( process Working Dir ) ĊĊĠĠĠĠĠĠĠ Ġenvironment . forEach Ġ{ Ġprocess Builder . environment ()[ it . key ] Ġ= Ġit . value . toString () Ġ} ĊĊĠĠĠĠĠĠĠ Ġlogger . info (" running Ġprocess : Ġ{}", Ġprocess Builder . command (). join ToString ( separator Ġ= Ġ" Ġ")) ĊĊĠĠĠĠĠĠĠ Ġthis . process Ġ= Ġprocess Builder . start () ĊĠĠĠĠĠĠĠ Ġinstall Pip es And Wait ( this . process !! ) ĊĊĠĠĠĠĠĠĠ Ġval ĠwaitFor Port Val : ĠInt ? Ġ= ĠwaitFor Port ĊĠĠĠĠĠĠĠ Ġif Ġ( waitFor Port Val Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠwaitFor Port Open ( waitFor Port Val , Ġtimeout , ĠTimeUnit . SECONDS , Ġprocess !! ) ĊĊĠĠĠĠĠĠĠ Ġval Ġtask : ĠAbstract Exec Fork Ġ= Ġthis ĊĠĠĠĠĠĠĠ ĠRuntime . get Runtime (). add Shutdown Hook ( object Ġ: ĠThread () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġrun () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtask . stop () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġ( fork Task Termination Service . get () Ġas ĠFork Task Termination Service ). add Abstract Exec Fork Task ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Input ĊĠĠĠ Ġabstract Ġfun Ġget Process Args (): ĠList < String >? ĊĊĠĠĠ Ġprivate Ġfun Ġinstall Pip es And Wait ( process : ĠProcess ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġprocess Out : ĠOutputStream Ġ= Ġif Ġ( standard Output . isPresent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstandard Output . as File . get (). parent File . mkdir s () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFileOutputStream ( standard Output . as File . get ()) ĊĠĠĠĠĠĠĠ Ġ} Ġelse ĠOutputStream Logger ( logger ) ĊĠĠĠĠĠĠĠ Ġval Ġout Pipe : ĠInputStream Pipe Ġ= ĠInputStream Pipe ( process . inputStream , Ġprocess Out , ĠwaitFor Output ) ĊĠĠĠĠĠĠĠ Ġif Ġ( error Output . isPresent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror Output . as File . get (). parent File . mkdir s () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġerr Pipe : ĠInputStream Pipe Ġ= ĠInputStream Pipe ( process . error Stream , ĠFileOutputStream ( error Output . as File . get ()), ĠwaitFor Error ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerr Pipe . waitFor Pattern ( timeout , ĠTimeUnit . SECONDS ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġout Pipe . waitFor Pattern ( timeout , ĠTimeUnit . SECONDS ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġredirect Streams ( process Builder : ĠProcess Builder ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! error Output . isPresent ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Builder . redirect Error Stream ( true ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠStop Ġthe Ġprocess Ġthat Ġthis Ġtask Ġhas Ġspawn ed ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( kill Desc endants ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstop Desc endants () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn (" Failed Ġto Ġstop Ġdesc endants ", Ġe ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġstop Root Process () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstop Root Process () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġprocess : ĠProcess Ġ= Ġprocess Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġif Ġ( process . is Alive Ġ&& Ġ! force Kill ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocess . destroy () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocess . waitFor ( 1 5 , ĠTimeUnit . SECONDS ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( process . is Alive ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocess . destroy For c ibly (). waitFor ( 1 5 , ĠTimeUnit . SECONDS ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstop Desc endants () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġprocess : ĠProcess Ġ= Ġprocess Ġ?: Ġreturn ĊĠĠĠĠĠĠĠ Ġif Ġ(! process . is Alive ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġto Handle Ġ= Ġprocess :: class . member Functions . single OrNull Ġ{ Ġit . name Ġ== Ġ" to Handle " Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( to Handle Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error (" Could Ġnot Ġload ĠProcess . to Handle (). ĠThe Ġkill Desc endants Ġflag Ġrequires ĠJava Ġ 9 +. ĠPlease Ġset Ġkill Desc endants = false , Ġor Ġupgrade Ġto ĠJava Ġ 9 + .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ// Ġnot Ġsupported , Ġpre Ġjava Ġ 9 ? ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġto Handle . is Accessible Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġval Ġhandle Ġ= Ġto Handle . call ( process ) ĊĠĠĠĠĠĠĠ Ġif Ġ( handle Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn (" Could Ġnot Ġget Ġprocess Ġhandle . ĠProcess Ġdesc endants Ġmay Ġnot Ġbe Ġstopped .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġdesc endants Ġ= Ġhandle :: class . member Functions . single Ġ{ Ġit . name Ġ== Ġ" desc endants " Ġ} ĊĠĠĠĠĠĠĠ Ġdesc endants . is Accessible Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġval Ġchildren : ĠStream < *> Ġ= Ġdesc endants . call ( handle ) Ġas ĠStream <* >; ĊĠĠĠĠĠĠĠ Ġval Ġdestroy Ġ= Ġhandle :: class . member Functions . single Ġ{ Ġit . name Ġ== Ġif Ġ( force Kill ) Ġ" destroy For c ibly " Ġelse Ġ" destroy " Ġ} ĊĠĠĠĠĠĠĠ Ġdestroy . is Accessible Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġchildren . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdestroy . call ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Deprecated (" Use Ġa Ġtask Ġprovider Ġinstead Ġof Ġa Ġconcrete ĠTask Ġinstance ", ĠReplace With (" stop After Ġ= Ġtasks . named (': my Task ') ")) ĊĠĠĠ Ġfun Ġset Stop After ( task : ĠTask ) Ġ{ ĊĠĠĠĠĠĠĠ Ġstop After Ġ= Ġtask . project . tasks . named ( task . name ) ĊĠĠĠ Ġ} Ċ } Ċ