/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 ĠThe ĠB azel ĠAuthors . ĠAll Ġrights Ġreserved . Ċ Ġ* Ċ Ġ* Ġ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 Ġio . bazel . kotlin . builder . tasks . jvm Ċ Ċ import Ġcom . google . common . truth . Truth . assertThat Ċ import Ġio . bazel . kotlin . builder . Kotlin Jvm Test Builder Ċ import Ġio . bazel . kotlin . builder . tasks . Invocation Worker Ċ import Ġio . bazel . kotlin . builder . tasks . Kotlin Builder . Companion . Java Builder Flags Ċ import Ġio . bazel . kotlin . builder . tasks . Kotlin Builder . Companion . Kotlin Builder Flags Ċ import Ġio . bazel . kotlin . builder . tasks . Worker IO Ċ import Ġio . bazel . kotlin . builder . utils . Flag Ċ import Ġio . bazel . kotlin . model . Compilation Task Info Ċ import Ġio . bazel . kotlin . model . Platform Ċ import Ġio . bazel . kotlin . model . Rule Kind Ċ import Ġorg . junit . Test Ċ import Ġorg . junit . runner . RunWith Ċ import Ġorg . junit . runners . JUnit 4 Ċ import Ġjava . io . ByteArray OutputStream Ċ import Ġjava . io . File Ċ import Ġjava . nio . charset . StandardCharsets Ċ import Ġjava . nio . file . Files Ċ import Ġjava . nio . file . Path Ċ import Ġjava . util . zip . Zip Entry Ċ import Ġjava . util . zip . Zip File Ċ import Ġkotlin . streams . toList Ċ Ċ @ RunWith ( JUnit 4 :: class ) Ċ class ĠKotlin Worker Test Ġ{ ĊĊĠ Ġprivate Ġval Ġwr k Dir Ġ= ĠFiles . create Temp Directory (" Kotlin Builder Environment Test ") ĊĊĠ Ġclass ĠSource Builder ( private Ġval Ġout : ĠByteArrayOutputStream Ġ= ĠByteArrayOutputStream ()) Ġ{ ĊĠĠĠ Ġval Ġln Ġ= Ġ"\ n ". toByteArray ( StandardCharsets . UTF _ 8 ) ĊĠĠĠ Ġfun Ġl ( l : ĠString ) Ġ{ ĊĠĠĠĠĠ Ġout . write ( l . toByteArray ( StandardCharsets . UTF _ 8 )) ĊĠĠĠĠĠ Ġout . write ( ln ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġbytes (): ĠByteArray Ġ{ ĊĠĠĠĠĠ Ġreturn Ġout . toByteArray () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġsrc ( path : ĠString , Ġwrite Lines : Ġ( Source Builder . () Ġ-> ĠUnit )): ĠPath Ġ{ ĊĠĠĠ Ġval Ġsrc Path Ġ= ĠFiles . create Directories ( wrk Dir . resolve (" src ")). resolve ( path ) ĊĠĠĠ Ġval Ġb Ġ= ĠSource Builder () ĊĠĠĠ Ġb . write Lines () ĊĠĠĠ ĠFiles . write ( src Path , Ġb . bytes ()) ĊĊĠĠĠ Ġrequire ( Files . read All Lines ( src Path ). isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġ" failed Ġto Ġwrite Ġ$ src Path " ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġsrc Path ĊĠ Ġ} ĊĊĠ Ġclass ĠArgs Builder ( val Ġargs : ĠMutable Map < Flag , ĠMutable List < String >> Ġ= Ġmutable Map Of ()) Ġ{ ĊĠĠĠ Ġfun Ġflag ( flag : ĠFlag , Ġvalue : ĠString ) Ġ{ ĊĠĠĠĠĠ Ġargs [ flag ] Ġ= Ġ( args [ flag ] Ġ?: Ġmutable ListOf ()). also Ġ{ ĊĠĠĠĠĠĠĠ Ġit . add ( value ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġflag ( flag : ĠFlag , Ġp : ĠPath ) Ġ{ ĊĠĠĠĠĠ Ġflag ( flag , Ġp . toString ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġcp ( flag : ĠFlag , Ġvalue : ĠString ) Ġ{ ĊĠĠĠĠĠ Ġargs [ flag ] Ġ= Ġmutable ListOf ( ĊĠĠĠĠĠĠĠ Ġ( args [ flag ] Ġ?: Ġmutable ListOf ()). also Ġ{ Ġit . add ( value ) Ġ}. join ToString ( File . path Separator )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove ( flag : ĠFlag ) Ġ{ ĊĠĠĠĠĠ Ġargs . remove ( flag ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsource ( src : ĠPath ) Ġ{ ĊĠĠĠĠĠ Ġflag ( Java Builder Flags . SOURCES , Ġsrc . toString ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġlist (): ĠList < String > Ġ{ ĊĠĠĠĠĠ Ġreturn Ġargs . flatMap Ġ{ Ġentry Ġ-> ĊĠĠĠĠĠĠĠ Ġentry . value . flatMap Ġ{ Ġvalue Ġ-> ĊĠĠĠĠĠĠĠĠĠ ĠlistOf ( entry . key . flag , Ġvalue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġargs ( ĊĠĠĠ Ġinfo : ĠCompilation Task Info , ĊĠĠĠ Ġinit : ĠArgs Builder . () Ġ-> ĠUnit ĊĠ Ġ) Ġ= Ġwith ( Args Builder ()) Ġ{ ĊĠĠĠ Ġflag ( Java Builder Flags . TARGET _ LABEL , Ġinfo . label ) ĊĠĠĠ Ġflag ( Kotlin Builder Flags . MODULE _ NAME , Ġinfo . moduleName ) ĊĠĠĠ Ġflag ( Kotlin Builder Flags . API _ VERSION , Ġinfo . toolchain Info . common . apiVersion ) ĊĠĠĠ Ġflag ( Kotlin Builder Flags . LANGUAGE _ VERSION , Ġinfo . toolchain Info . common . language Version ) ĊĠĠĠ Ġflag ( Java Builder Flags . RULE _ KIND , Ġ" kt _${ info . platform . name }_${ info . rule Kind . name }") ĊĠĠĠ Ġflag ( Java Builder Flags . CLASS DIR , Ġ" kt _ classes ") ĊĠĠĠ Ġflag ( Kotlin Builder Flags . GENERATED _ CLASS DIR , Ġ" generated _ classes ") ĊĠĠĠ Ġflag ( Java Builder Flags . TEMP DIR , Ġ" tmp ") ĊĠĠĠ Ġflag ( Java Builder Flags . SOURCE GEN _ DIR , Ġ" generated _ sources ") ĊĠĠĠ Ġflag ( Kotlin Builder Flags . STRICT _ K OT LIN _ DEPS , Ġ" off ") ĊĠĠĠ Ġcp ( Java Builder Flags . CLAS SPATH , ĠKotlin Jvm Test Builder . K OT LIN _ STD LIB . single Compile Jar ()) ĊĠĠĠ Ġcp ( Java Builder Flags . DIRECT _ DEPEND ENCI ES , Ġ"") ĊĠĠĠ Ġinfo . pas sthrough Flags List . forEach Ġ{ Ġpf Ġ-> ĊĠĠĠĠĠ Ġflag ( Kotlin Builder Flags . PAS ST H ROUGH _ FLAGS , Ġpf ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġflag ( Kotlin Builder Flags . DEBUG , Ġinfo . debug List . join ToString ("," )) ĊĠĠĠ Ġflag ( Kotlin Builder Flags . JVM _ TARGET , Ġinfo . toolchain Info . jvm . jvm Target ) ĊĠĠĠ Ġinit () ĊĠĠĠ Ġlist () ĊĠ Ġ} ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġ` abi Ġgeneration `() Ġ{ ĊĊĠĠĠ Ġval Ġbuilder Ġ= ĠKotlin Jvm Test Builder . component (). kotlin Builder () ĊĊĠĠĠ Ġval Ġone Ġ= Ġsrc (" One . kt ") Ġ{ ĊĠĠĠĠĠ Ġl (" package Ġh arry . nil sson ") ĊĠĠĠĠĠ Ġl ("") ĊĠĠĠĠĠ Ġl (" class ĠOne Ġ: ĠZero (), ĠIm ag inary Ġ{ ") ĊĠĠĠĠĠ Ġl (" Ġ Ġoverride Ġval Ġi : Boolean Ġ= Ġfalse ") ĊĠĠĠĠĠ Ġl (" Ġ Ġoverride Ġfun Ġis The Lon eli est Number (): String Ġ{ ") ĊĠĠĠĠĠ Ġl (" ĠĠĠĠ Ġreturn Ġ\" that Ġyou 'll Ġever Ġdo \" ") ĊĠĠĠĠĠ Ġl (" Ġ Ġ} ") ĊĠĠĠĠĠ Ġl (" }") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġzero Ġ= Ġsrc (" Zero . kt ") Ġ{ ĊĠĠĠĠĠ Ġl (" package Ġh arry . nil sson ") ĊĠĠĠĠĠ Ġl ("") ĊĠĠĠĠĠ Ġl (" abstract Ġclass ĠZero Ġ{ ") ĊĠĠĠĠĠ Ġl (" Ġ Ġabstract Ġfun Ġis The Lon eli est Number (): String ") ĊĠĠĠĠĠ Ġl (" }") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġimag inary Ġ= Ġsrc (" Imag inary . kt ") Ġ{ ĊĠĠĠĠĠ Ġl (" package Ġh arry . nil sson ") ĊĠĠĠĠĠ Ġl ("") ĊĠĠĠĠĠ Ġl (" interface ĠIm ag inary Ġ{ ") ĊĠĠĠĠĠ Ġl (" Ġ Ġval Ġi : ĠBoolean Ġget () Ġ= Ġtrue ") ĊĠĠĠĠĠ Ġl (" }") ĊĠĠĠ Ġ} ĊĊĠĠĠ ĠWorker IO . open (). use Ġ{ Ġio Ġ-> ĊĠĠĠĠĠ Ġval Ġworker Ġ= ĠInvocation Worker ( io , Ġbuilder ) ĊĊĠĠĠĠĠ Ġval Ġabi Jar Ġ= Ġout (" abi . jar ") ĊĠĠĠĠĠ Ġval Ġoutput Jar Ġ= Ġout (" output . jar ") ĊĊĠĠĠĠĠ ĠassertThat ( ĊĠĠĠĠĠĠĠ Ġworker . run ( ĊĠĠĠĠĠĠĠĠĠ Ġargs ( compilation Task Info ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflag ( Kotlin Builder Flags . ABI _ JAR , Ġabi Jar ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflag ( Java Builder Flags . OUTPUT , Ġoutput Jar ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflag ( Kotlin Builder Flags . BUILD _ K OT LIN , Ġ" true ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflag ( Java Builder Flags . BUILD _ JAVA , Ġ" false ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflag ( Kotlin Builder Flags . OUTPUT _ J DEPS , Ġ" out . j deps ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsource ( one ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsource ( zero ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsource ( imag inary ) ĊĠĠĠĠĠĠĠĠĠ Ġ})). isEqualTo ( 0 ) ĊĊĠĠĠĠĠ Ġassert Jar Classes ( abi Jar ). contains Exactly ( ĊĠĠĠĠĠĠĠ Ġ" h arry / nil sson / Imag inary \$ Default Imp ls . class ", ĊĠĠĠĠĠĠĠ Ġ" h arry / nil sson / Imag inary . class ", ĊĠĠĠĠĠĠĠ Ġ" h arry / nil sson / One . class ", ĊĠĠĠĠĠĠĠ Ġ" h arry / nil sson / Zero . class " ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġassert Jar Classes ( jar : ĠPath ) Ġ= ĠassertThat ( ĊĠĠĠ ĠZip File ( jar . to File ()) ĊĠĠĠĠĠ Ġ. stream () ĊĠĠĠĠĠ Ġ. map ( Zip Entry :: getName ) ĊĠĠĠĠĠ Ġ. filter Ġ{ Ġit . endsWith (". class ") Ġ} ĊĠĠĠĠĠ Ġ. toList () ĊĠ Ġ) ĊĊĠ Ġ@ Test ĊĠ Ġfun Ġ` output Ġdirectories Ġare Ġdifferent Ġfor Ġinv ocations `() Ġ{ ĊĊĠĠĠ Ġval Ġbuilder Ġ= ĠKotlin Jvm Test Builder . component (). kotlin Builder () ĊĊĠĠĠ Ġval Ġone Ġ= Ġsrc (" One . kt ") Ġ{ ĊĠĠĠĠĠ Ġl (" package Ġh arry . nil sson ") ĊĠĠĠĠĠ Ġl ("") ĊĠĠĠĠĠ Ġl (" class ĠOne Ġ{ ") ĊĠĠĠĠĠ Ġl (" Ġ Ġfun Ġis The Lon eli est Number (): String Ġ{ ") ĊĠĠĠĠĠ Ġl (" ĠĠĠĠ Ġreturn Ġ\" that Ġyou 'll Ġever Ġdo \" ") ĊĠĠĠĠĠ Ġl (" Ġ Ġ} ") ĊĠĠĠĠĠ Ġl (" }") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġtwo Ġ= Ġsrc (" Two . kt ") Ġ{ ĊĠĠĠĠĠ Ġl (" package Ġh arry . nil sson ") ĊĠĠĠĠĠ Ġl (" class ĠTwo Ġ{ ") ĊĠĠĠĠĠ Ġl (" Ġ Ġfun Ġcan Be As Bad As One (): String Ġ{ ") ĊĠĠĠĠĠ Ġl (" ĠĠĠĠ Ġreturn Ġ\" it Ġis Ġthe Ġlon eli est Ġnumber Ġsince Ġthe Ġnumber Ġone \" ") ĊĠĠĠĠĠ Ġl (" Ġ Ġ} ") ĊĠĠĠĠĠ Ġl (" }") ĊĠĠĠ Ġ} ĊĊĠĠĠ ĠWorker IO . open (). use Ġ{ Ġio Ġ-> ĊĠĠĠĠĠ Ġval Ġworker Ġ= ĠInvocation Worker ( io , Ġbuilder ) ĊĊĠĠĠĠĠ Ġval Ġjar One Ġ= Ġout (" one . jar ") ĊĠĠĠĠĠ ĠassertThat ( worker . run ( args ( compilation Task Info ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsource ( one ) ĊĠĠĠĠĠĠĠ Ġflag ( Java Builder Flags . OUTPUT , Ġjar One . toString ()) ĊĠĠĠĠĠĠĠ Ġflag ( Kotlin Builder Flags . OUTPUT _ SRC JAR , Ġ"$ jar One . src jar ") ĊĠĠĠĠĠĠĠ Ġflag ( Kotlin Builder Flags . OUTPUT _ J DEPS , Ġ" out . j deps ") ĊĠĠĠĠĠĠĠ Ġflag ( Kotlin Builder Flags . BUILD _ K OT LIN , Ġ" true ") ĊĠĠĠĠĠĠĠ Ġflag ( Java Builder Flags . BUILD _ JAVA , Ġ" false ") ĊĠĠĠĠĠ Ġ})). isEqualTo ( 0 ) ĊĊĠĠĠĠĠ ĠassertThat ( ĊĠĠĠĠĠĠĠ ĠZip File ( jar One . to File ()) ĊĠĠĠĠĠĠĠĠĠ Ġ. stream () ĊĠĠĠĠĠĠĠĠĠ Ġ. map ( Zip Entry :: getName ) ĊĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . endsWith (". class ") Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ. toList () ĊĠĠĠĠĠ Ġ). contains Exactly (" h arry / nil sson / One . class ") ĊĊĠĠĠĠĠ Ġval Ġjar Two Ġ= Ġout (" two . jar ") ĊĠĠĠĠĠ ĠassertThat ( worker . run ( args ( compilation Task Info ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsource ( two ) ĊĠĠĠĠĠĠĠ Ġflag ( Java Builder Flags . OUTPUT , Ġjar Two . toString ()) ĊĠĠĠĠĠĠĠ Ġflag ( Kotlin Builder Flags . OUTPUT _ SRC JAR , Ġ"$ jar Two . src jar ") ĊĠĠĠĠĠĠĠ Ġflag ( Kotlin Builder Flags . OUTPUT _ J DEPS , Ġ" out . j deps ") ĊĠĠĠĠĠĠĠ Ġflag ( Kotlin Builder Flags . BUILD _ K OT LIN , Ġ" true ") ĊĠĠĠĠĠĠĠ Ġflag ( Java Builder Flags . BUILD _ JAVA , Ġ" false ") ĊĠĠĠĠĠ Ġ})). isEqualTo ( 0 ) ĊĊĠĠĠĠĠ ĠassertThat ( ĊĠĠĠĠĠĠĠ ĠZip File ( jar Two . to File ()) ĊĠĠĠĠĠĠĠĠĠ Ġ. stream () ĊĠĠĠĠĠĠĠĠĠ Ġ. map ( Zip Entry :: getName ) ĊĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . endsWith (". class ") Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ. toList () ĊĠĠĠĠĠ Ġ). contains Exactly (" h arry / nil sson / Two . class ") ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġout ( name : ĠString ): ĠPath Ġ{ ĊĠĠĠ Ġreturn ĠFiles . create Directories ( wrk Dir . resolve (" out ")). resolve ( name ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġval Ġcompilation Task Info : ĠCompilation Task Info ĊĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠ Ġreturn Ġwith ( Compilation Task Info . newBuilder ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġlabel Ġ= Ġ"// sing ing / nil sson : one " ĊĠĠĠĠĠĠĠ ĠmoduleName Ġ= Ġ" h arry . nil sson " ĊĠĠĠĠĠĠĠ Ġplatform Ġ= ĠPlatform . JVM ĊĠĠĠĠĠĠĠ Ġrule Kind Ġ= ĠRule Kind . LIBRARY ĊĠĠĠĠĠĠĠ Ġtoolchain Info Ġ= Ġwith ( toolchain Info Builder ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġcommon Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcommon Builder . set ApiVersion (" 1 . 3 "). set Cor outines (" enabled "). set Language Version (" 1 . 3 ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠ Ġj vm Ġ= Ġj vm Builder . set Jvm Target (" 1 . 8 "). build () ĊĠĠĠĠĠĠĠĠĠ Ġbuild () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġbuild () ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ