/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 2 0 . ĠZ ac ĠS we ers Ċ Ġ* Ċ Ġ* Ġ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 Ġdev . z acs we ers . catch up . gradle Ċ Ċ import Ġcom . android . build . gradle . App Extension Ċ import Ġcom . android . build . gradle . internal . tasks . factory . depends On Ċ import Ġcom . squareup . mos hi . Json Writer Ċ import Ġok io . buffer Ċ import Ġok io . sink Ċ import Ġorg . gradle . api . Default Task Ċ import Ġorg . gradle . api . Plugin Ċ import Ġorg . gradle . api . Project Ċ import Ġorg . gradle . api . artifacts . Artifact View Ċ import Ġorg . gradle . api . artifacts . Configuration Ċ import Ġorg . gradle . api . artifacts . component . Module Component Identifier Ċ import Ġorg . gradle . api . artifacts . result . Resolved Artifact Result Ċ import Ġorg . gradle . api . attributes . Attribute Ċ import Ġorg . gradle . api . file . Configurable File Collection Ċ import Ġorg . gradle . api . file . Regular File Property Ċ import Ġorg . gradle . api . internal . artifacts . Default Module Identifier Ċ import Ġorg . gradle . api . tasks . Classpath Ċ import Ġorg . gradle . api . tasks . Internal Ċ import Ġorg . gradle . api . tasks . OutputFile Ċ import Ġorg . gradle . api . tasks . Task Action Ċ import Ġorg . gradle . internal . component . external . model . Default Module Component Identifier Ċ import Ġorg . gradle . kotlin . dsl . findBy Type Ċ import Ġorg . gradle . kotlin . dsl . register Ċ import Ġorg . gradle . maven . Maven Module Ċ import Ġorg . gradle . maven . Maven P om Artifact Ċ import Ġorg . w 3 c . dom . Document Ċ import Ġorg . w 3 c . dom . Node Ċ import Ġorg . w 3 c . dom . NodeList Ċ import Ġjava . io . File Ċ import Ġjava . util . Locale Ċ import Ġjavax . xml . parsers . Document BuilderFactory Ċ Ċ private Ġconst Ġval ĠTAG Ġ= Ġ" License s Json Generator " Ċ Ċ class ĠLicense s Json Generator Plugin Ġ: ĠPlugin < Project > Ġ{ ĊĠ Ġoverride Ġfun Ġapply ( project : ĠProject ) Ġ{ ĊĠĠĠ Ġproject . extensions . findBy Type < App Extension >() !!. application Variants . configure Each Ġ{ ĊĠĠĠĠĠ Ġif Ġ( build Type . name Ġ== Ġ" release ") Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlicenses Task Ġ= Ġproject . tasks . register < License s Json Generator >(" generate License s Json ") Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġgroup Ġ= Ġ" licenses " ĊĠĠĠĠĠĠĠĠĠ Ġartifact Files . from ( runtime Configuration . artifact View (). artifacts . artifact Files ) ĊĠĠĠĠĠĠĠĠĠ Ġconfiguration Ġ= Ġruntime Configuration ĊĊĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO Ġshould Ġwe Ġjust Ġgenerate Ġthis Ġinto Ġan Ġintermediate Ġand Ġnot Ġcheck Ġit Ġin ? ĊĠĠĠĠĠĠĠĠĠ Ġjson File . set ( project . file (" src / main / assets / generated _ licenses . json ")) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠMake Ġthe Ġrelease Ġassemble Ġtask Ġdepend Ġon Ġthis Ġto Ġbe Ġsafe ĊĠĠĠĠĠĠĠ Ġproject . tasks . named (" assemble ${ name . capitalize ( Locale . US )} ") ĊĠĠĠĠĠĠĠĠĠ Ġ. depends On ( licenses Task ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠConfiguration . artifact View (): ĠArtifact View Ġ{ ĊĠĠĠ Ġreturn Ġincoming . artifact View Ġ{ ĊĠĠĠĠĠ Ġattributes Ġ{ ĊĠĠĠĠĠĠĠ Ġattribute ( Attribute . of (" artifact Type ", ĠString :: class . java ), Ġ" android - classes ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ abstract Ġclass ĠLicense s Json Generator Ġ: ĠDefault Task () Ġ{ ĊĠ Ġ/** ĊĠĠ Ġ* ĠThis Ġis Ġthe Ġ" official " Ġinput Ġfor Ġw iring Ġtask Ġdependencies Ġcorrectly , Ġbut Ġis Ġotherwise ĊĠĠ Ġ* Ġunused . ĠSee Ġ[ configuration ]. ĊĠĠ Ġ*/ ĊĠ Ġ@ get : Classpath ĊĠ Ġabstract Ġval Ġartifact Files : ĠConfigur able File Collection ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠThis Ġis Ġwhat Ġthe Ġtask Ġactually Ġuses Ġas Ġits Ġinput . ĊĠĠ Ġ*/ ĊĠ Ġ@ get : Internal ĊĠ Ġlateinit Ġvar Ġconfiguration : ĠConfiguration ĊĊĠ Ġ@ get : OutputFile ĊĠ Ġabstract Ġval Ġjson File : ĠRegular File Property ĊĊĠ Ġ@ Task Action ĊĠ Ġfun Ġgenerate File () Ġ{ ĊĠĠĠ Ġval Ġcomponent Ids Ġ= Ġconfiguration . incoming . resolution Result . all Dependencies . map Ġ{ Ġit . from . id Ġ} ĊĠĠĠĠĠ Ġ. filter Is Instance < Module Component Identifier >() ĊĊĠĠĠ Ġval Ġgithub Details Ġ= Ġfetch Components ( component Ids ) ĊĠĠĠĠĠ Ġ. map Ġ{ Ġit . substring After (". com /") Ġ} ĊĠĠĠĠĠ Ġ. map Ġ{ Ġrepo Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġ( owner , Ġname ) Ġ= Ġrepo . split ("/") ĊĠĠĠĠĠĠĠ Ġowner Ġto Ġname ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ. distinct () ĊĊĠĠĠ ĠJson Writer . of ( json File . get (). as File . sink (). buffer ()). use Ġ{ Ġwriter Ġ-> ĊĠĠĠĠĠ Ġwriter . begin Array () ĊĠĠĠĠĠ Ġgithub Details . sorted By Ġ{ Ġit . toString (). toLowerCase ( Locale . US ) Ġ} ĊĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġ( owner , Ġname ) Ġ-> ĊĠĠĠĠĠĠĠĠĠ Ġwriter . begin Object () ĊĠĠĠĠĠĠĠĠĠ Ġwriter . name (" owner ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. value ( owner ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. name (" name ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. value ( name ) ĊĠĠĠĠĠĠĠĠĠ Ġwriter . end Object () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġwriter . end Array () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġfetch Components ( component Ids : ĠList < Module Component Identifier >): ĠSequence < String > Ġ{ ĊĠĠĠ Ġreturn Ġproject . dependencies . create Artifact Resolution Query () ĊĠĠĠĠĠ Ġ. for Components ( component Ids ) ĊĠĠĠĠĠ Ġ. with Artifacts ( Maven Module :: class . java , ĠMaven P om Artifact :: class . java ) ĊĠĠĠĠĠ Ġ. execute () ĊĠĠĠĠĠ Ġ. resolved Components ĊĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠ Ġ. flatMap Ġ{ Ġcomponent Ġ-> ĊĠĠĠĠĠĠĠ Ġcomponent . get Artifacts ( Maven P om Artifact :: class . java ) ĊĠĠĠĠĠĠĠĠĠ Ġ. filter Is Instance < Resolved Artifact Result >() ĊĠĠĠĠĠĠĠĠĠ Ġ. on Each Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug ("$ TAG : ĠPO M Ġfile Ġfor Ġ${ component . id }: Ġ${ it . file }") ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġresult Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpom File Ġ= Ġresult . file ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpom File . read Github Projects From P om () Ġ?: Ġrun Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġcomponent . id Ġas ĠModule Component Identifier ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgroup Ġ= Ġid . group ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsequence Of ( known Mapping ( group )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ. filter NotNull () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠFile . read Github Projects From P om (): ĠSequence < String >? Ġ{ ĊĠĠĠ Ġval Ġdocument Ġ= ĠDocument BuilderFactory . newInstance (). new Document Builder (). parse ( absolute Path ) ĊĠĠĠ Ġdocument . parse Sc m ()?. let Ġ{ Ġreturn Ġsequence Of ( it ) Ġ} ĊĊĠĠĠ Ġ// ĠIf Ġthere 's Ġa Ġparent Ġtag , Ġtry Ġto Ġfetch Ġthat Ġinstead ĊĠĠĠ Ġval Ġparent Ġ= Ġdocument . getElementsByTagName (" parent "). as Sequence (). first OrNull () Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġval Ġparent Nodes Ġ= Ġparent . childNodes . as Sequence () ĊĠĠĠĠĠ Ġ. associate By Ġ{ Ġit . nodeName Ġ} ĊĊĠĠĠ Ġval ĠgroupId Ġ= Ġparent Nodes [" groupId "] ?. textContent Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġval Ġartifact Id Ġ= Ġparent Nodes [" artifactId "] ?. textContent Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġval Ġversion Ġ= Ġparent Nodes [" version "] ?. textContent Ġ?: Ġreturn Ġnull ĊĊĠĠĠ Ġval Ġcomponent Ġ= ĠDefault Module Component Identifier ĊĠĠĠĠĠ Ġ. new Id ( Default Module Identifier . new Id ( groupId , Ġartifact Id ), Ġversion ) ĊĊĠĠĠ Ġlogger . debug ("$ TAG : ĠFetch ing Ġparent Ġ$ component ") ĊĊĠĠĠ Ġreturn Ġfetch Components ( listOf ( component )) ĊĠĠĠĠĠ Ġ. on Each Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . debug ("$ TAG : ĠResolved Ġparent Ġversion Ġfor Ġ'$ component ': Ġ$ it ") ĊĠĠĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠDocument . parse Sc m (): ĠString ? Ġ{ ĊĠĠĠ Ġval Ġsc m Ġ= Ġget Elements By TagName (" scm "). as Sequence (). first OrNull () Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġval Ġurl Ġ= Ġsc m . childNodes . as Sequence () ĊĠĠĠĠĠ Ġ. filter Ġ{ Ġit . textContent . contains (" github . com ") Ġ} ĊĠĠĠĠĠ Ġ. first OrNull ()?. textContent ĊĠĠĠ Ġreturn Ġurl ?. substring After (" github . com ") ĊĠĠĠĠĠ Ġ? . remove Prefix ("/") ĊĠĠĠĠĠ Ġ? . remove Prefix (": ") ĊĠĠĠĠĠ Ġ? . remove Suffix (". git ") ĊĠĠĠĠĠ Ġ? . remove Suffix ("/ issues ") ĊĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġknown Mapping ( group : ĠString ): ĠString ? Ġ{ ĊĠ Ġif Ġ( group . startsWith (" android x .") Ġ|| Ġgroup . startsWith (" com . google . android . gms ")) Ġ{ ĊĠĠĠ Ġ// ĠThese Ġare Ġhandled Ġvia Ġlicenses _ mixins . json ĊĠĠĠ Ġreturn Ġnull ĊĠ Ġ} ĊĠ Ġreturn Ġwhen Ġ( group ) Ġ{ ĊĠĠĠ Ġ" com . google . firebase " Ġ-> Ġ" firebase / firebase - android - sdk " ĊĠĠĠ Ġelse Ġ-> Ġerror (" Unrecognized Ġgroup ! Ġ$ group ") ĊĠ Ġ} Ċ } Ċ Ċ /* Ċ Ġ* ĠBelow Ġbits Ġborrow ed Ġfrom Ġhttps :// github . com / k ro pp / gradle - plugin - thanks . Ċ Ġ*/ Ċ Ċ private Ġfun ĠNode List . as Sequence () Ġ= ĠNode List Sequence ( this ) Ċ Ċ private Ġclass ĠNode List Sequence ( private Ġval Ġnodes : ĠNode List ) Ġ: ĠSequence < Node > Ġ{ ĊĠ Ġoverride Ġfun Ġiterator () Ġ= ĠNode List Iterator ( nodes ) Ċ } Ċ Ċ private Ġclass ĠNode List Iterator ( private Ġval Ġnodes : ĠNode List ) Ġ: ĠIterator < Node > Ġ{ ĊĠ Ġprivate Ġvar Ġi Ġ= Ġ 0 ĊĠ Ġoverride Ġfun Ġhas Next () Ġ= Ġnodes . length Ġ> Ġi ĊĠ Ġoverride Ġfun Ġnext (): ĠNode Ġ= Ġnodes . item ( i ++) Ċ } Ċ