/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 1 7 - 2 0 1 8 ĠHERE ĠEurope ĠB . V . Ċ Ġ* Ċ Ġ* Ġ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 . Ċ Ġ* Ċ Ġ* ĠSPDX - License - Identifier : ĠApache - 2 . 0 Ċ Ġ* ĠLicense - Filename : ĠLICENSE Ċ Ġ*/ Ċ Ċ package Ġcom . here . ort . scanner Ċ Ċ import Ġch . fr ank el . slf 4 k .* Ċ Ċ import Ġcom . be ust . j command er . I String Converter Ċ import Ġcom . be ust . j command er . J Command er Ċ import Ġcom . be ust . j command er . Parameter Ċ import Ġcom . be ust . j command er . Parameter Exception Ċ Ċ import Ġcom . here . ort . model . Analyzer Result Ċ import Ġcom . here . ort . model . Output Format Ċ import Ġcom . here . ort . model . Package Ċ import Ġcom . here . ort . model . Project Ċ import Ġcom . here . ort . model . Scope Ċ import Ġcom . here . ort . scanner . sc anners . Scan Code Ċ import Ġcom . here . ort . utils . PARAMETER _ ORDER _ HELP Ċ import Ġcom . here . ort . utils . PARAMETER _ ORDER _ LOG GING Ċ import Ġcom . here . ort . utils . PARAMETER _ ORDER _ M AND AT ORY Ċ import Ġcom . here . ort . utils . PARAMETER _ ORDER _ OPTIONAL Ċ import Ġcom . here . ort . utils . collect Messages Ċ import Ġcom . here . ort . utils . json Mapper Ċ import Ġcom . here . ort . utils . log Ċ import Ġcom . here . ort . utils . yaml Mapper Ċ Ċ import Ġjava . io . File Ċ import Ġjava . util . Sorted Set Ċ Ċ import Ġkotlin . system . exit Process Ċ Ċ @ Suppress (" unused ") Ġ// ĠThe Ġclass Ġis Ġonly Ġused Ġto Ġserialize Ġdata . Ċ class ĠScan Summary ( ĊĠĠĠĠĠĠĠ Ġval Ġpkg Summary : ĠPackage Summary , ĊĠĠĠĠĠĠĠ Ġval Ġcache Stats : ĠCache Statistics , ĊĠĠĠĠĠĠĠ Ġval Ġscanned Scopes : ĠSorted Set < String >, ĊĠĠĠĠĠĠĠ Ġval Ġignored Scopes : ĠSorted Set < String > Ċ ) Ċ Ċ type alias ĠPackage Summary Ġ= ĠMutable Map < String , ĠSummary Entry > Ċ Ċ class ĠSummary Entry ( ĊĠĠĠĠĠĠĠ Ġval Ġscopes : ĠSorted Set < String > Ġ= Ġsorted Set Of (), ĊĠĠĠĠĠĠĠ Ġval Ġdeclared License s : ĠSorted Set < String > Ġ= Ġsorted Set Of (), ĊĠĠĠĠĠĠĠ Ġval Ġdetected License s : ĠSorted Set < String > Ġ= Ġsorted Set Of (), ĊĠĠĠĠĠĠĠ Ġval Ġerrors : ĠMutable List < String > Ġ= Ġmutable ListOf () Ċ ) Ċ Ċ /** Ċ Ġ* ĠThe Ġmain Ġentry Ġpoint Ġof Ġthe Ġapplication . Ċ Ġ*/ Ċ object ĠMain Ġ{ ĊĠĠĠ Ġconst Ġval ĠTO OL _ NAME Ġ= Ġ" scanner " ĊĠĠĠ Ġconst Ġval ĠHTTP _ CACHE _ PATH Ġ= Ġ"$ TOOL _ NAME / cache / http " ĊĊĠĠĠ Ġprivate Ġclass ĠOutput Format Converter Ġ: ĠI String Converter < Output Format > Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġconvert ( name : ĠString ): ĠOutput Format Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠOutput Format . valueOf ( name . toUpperCase ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalArgumentException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( com . here . ort . utils . printStackTrace ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠParameter Exception (" Summary Ġformats Ġmust Ġbe Ġcontained Ġin Ġ${ Output Format . ALL }. ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠScanner Converter Ġ: ĠI String Converter < Scanner > Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġconvert ( scanner Name : ĠString ): ĠScanner Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : ĠConsider Ġallowing Ġto Ġenable Ġmultiple Ġsc anners Ġ( and Ġpotentially Ġrunning Ġthem Ġin Ġparallel ). ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠScanner . ALL . find Ġ{ Ġit . java Class . simple Name . toUpperCase () Ġ== Ġscanner Name . toUpperCase () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠParameter Exception (" The Ġscanner Ġmust Ġbe Ġone Ġof Ġ${ Scanner . ALL }. ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" The Ġdependencies Ġanalysis Ġfile Ġto Ġuse . ĠSource Ġcode Ġwill Ġbe Ġdownloaded Ġautomatically Ġif Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" needed . ĠThis Ġparameter Ġand Ġ-- input - path Ġare Ġmut ually Ġexclusive .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- dependencies - file ", Ġ"- d "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ OPTIONAL ) ĊĠĠĠ Ġprivate Ġvar Ġdependencies File : ĠFile ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" The Ġinput Ġdirectory Ġor Ġfile Ġto Ġscan . ĠThis Ġparameter Ġand Ġ-- dependencies - file Ġare Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" mut ually Ġexclusive .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- input - path ", Ġ"- i "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ OPTIONAL ) ĊĠĠĠ Ġprivate Ġvar Ġinput Path : ĠFile ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" The Ġlist Ġof Ġscopes Ġthat Ġshall Ġbe Ġscanned . ĠWorks Ġonly Ġwith Ġthe Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"-- dependencies - file Ġparameter . ĠIf Ġempty , Ġall Ġscopes Ġare Ġscanned .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- scopes "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ OPTIONAL ) ĊĠĠĠ Ġprivate Ġvar Ġscopes To Scan Ġ= ĠlistOf < String >() ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" The Ġoutput Ġdirectory Ġto Ġstore Ġthe Ġscan Ġresults Ġin .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- output - dir ", Ġ"- o "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequired Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ M AND AT ORY ) ĊĠĠĠ Ġ@ Suppress (" Late init Usage ") ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġoutput Dir : ĠFile ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" The Ġoutput Ġdirectory Ġfor Ġdownloaded Ġsource Ġcode . ĠDefaults Ġto Ġ< output - dir >/ downloads .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- download - dir "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ OPTIONAL ) ĊĠĠĠ Ġprivate Ġvar Ġdownload Dir : ĠFile ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" The Ġscanner Ġto Ġuse .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- scanner ", Ġ"- s "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconverter Ġ= ĠScanner Converter :: class , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ OPTIONAL ) ĊĠĠĠ Ġprivate Ġvar Ġscanner : ĠScanner Ġ= ĠScan Code ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" The Ġpath Ġto Ġthe Ġconfiguration Ġfile .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- config ", Ġ"- c "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ OPTIONAL ) ĊĠĠĠ Ġ@ Suppress (" Late init Usage ") ĊĠĠĠ Ġprivate Ġvar Ġconfig File : ĠFile ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" The Ġlist Ġof Ġfile Ġformats Ġfor Ġthe Ġsummary Ġfiles .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- summary - format ", Ġ"- f "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconverter Ġ= ĠOutput Format Converter :: class , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ OPTIONAL ) ĊĠĠĠ Ġprivate Ġvar Ġsummary Formats Ġ= ĠlistOf ( Output Format . YAML ) ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" Enable Ġinfo Ġlogging .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- info "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ LOG GING ) ĊĠĠĠ Ġprivate Ġvar Ġinfo Ġ= Ġfalse ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" Enable Ġdebug Ġlogging Ġand Ġkeep Ġany Ġtemporary Ġfiles .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- debug "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ LOG GING ) ĊĠĠĠ Ġprivate Ġvar Ġdebug Ġ= Ġfalse ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" Print Ġout Ġthe Ġstack trace Ġfor Ġall Ġexceptions .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- stack trace "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ LOG GING ) ĊĠĠĠ Ġprivate Ġvar Ġstack trace Ġ= Ġfalse ĊĊĠĠĠ Ġ@ Parameter ( description Ġ= Ġ" Display Ġthe Ġcommand Ġline Ġhelp .", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnames Ġ= Ġ[" -- help ", Ġ"- h "], ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhelp Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorder Ġ= ĠPARAMETER _ ORDER _ HELP ) ĊĠĠĠ Ġprivate Ġvar Ġhelp Ġ= Ġfalse ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġentry Ġpoint Ġfor Ġthe Ġapplication . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġargs ĠThe Ġlist Ġof Ġapplication Ġarguments . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġfun Ġmain ( args : ĠArray < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġjc Ġ= ĠJ Command er ( this ) ĊĠĠĠĠĠĠĠ Ġjc . parse (* args ) ĊĠĠĠĠĠĠĠ Ġjc . program Name Ġ= ĠTO OL _ NAME ĊĊĠĠĠĠĠĠĠ Ġif Ġ( info ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . level Ġ= Ġch . qos . log back . classic . Level . INFO ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( debug ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . level Ġ= Ġch . qos . log back . classic . Level . DEBUG ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( help ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġjc . usage () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexit Process ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠMake Ġthe Ġparameter Ġglobally Ġavailable . ĊĠĠĠĠĠĠĠ Ġcom . here . ort . utils . printStackTrace Ġ= Ġstack trace ĊĊĠĠĠĠĠĠĠ Ġif Ġ(( dependencies File Ġ!= Ġnull ) Ġ== Ġ( input Path Ġ!= Ġnull )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Either Ġ-- dependencies - file Ġor Ġ-- input - path Ġmust Ġbe Ġspecified .") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġrequire (! output Dir . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" The Ġoutput Ġdirectory Ġ'${ output Dir . absolute Path }' Ġmust Ġnot Ġexist Ġyet ." ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġdownload Dir ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire (! it . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" The Ġdownload Ġdirectory Ġ'${ it . absolute Path }' Ġmust Ġnot Ġexist Ġyet ." ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( configFile Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠScan Results Cache . configure ( yaml Mapper . read Tree ( configFile )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprintln (" Using Ġscanner Ġ'$ scanner '. ") ĊĊĠĠĠĠĠĠĠ Ġval Ġpkg Summary : ĠPackage Summary Ġ= Ġmutable Map Of () ĊĊĠĠĠĠĠĠĠ Ġval Ġincluded Scopes : ĠSorted Set < Scope > Ġ= Ġsorted Set Of () ĊĠĠĠĠĠĠĠ Ġval Ġexcluded Scopes : ĠSorted Set < Scope > Ġ= Ġsorted Set Of () ĊĊĠĠĠĠĠĠĠ Ġdependencies File ?. let Ġ{ Ġdependencies File Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( dependencies File . isFile ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Provided Ġpath Ġis Ġnot Ġa Ġfile : Ġ${ dependencies File . absolute Path }" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmapper Ġ= Ġwhen Ġ( dependencies File . extension ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOutput Format . JSON . file Extension Ġ-> Ġjson Mapper ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOutput Format . YAML . file Extension Ġ-> Ġyaml Mapper ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" Provided Ġinput Ġfile Ġis Ġneither ĠJSON Ġnor ĠYAML .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġanalyzer Result Ġ= Ġmapper . readValue ( dependencies File , ĠAnalyzer Result :: class . java ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAdd Ġthe Ġproject Ġitself Ġalso Ġas Ġa Ġ" package " Ġto Ġscan . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpackages Ġ= Ġmutable ListOf ( analyzer Result . project . to Package ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scopes To Scan . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Limit ing Ġscan Ġto Ġscopes Ġ$ scopes To Scan ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġanalyzer Result . project . scopes . partition Ġ{ Ġscopes To Scan . contains ( it . name ) Ġ}. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġincluded Scopes . addAll ( it . first ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexcluded Scopes . addAll ( it . second ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( included Scopes . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpackages . addAll ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġanalyzer Result . packages . filter Ġ{ Ġpkg Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġincluded Scopes . any Ġ{ Ġscope Ġ-> Ġscope . contains ( pkg ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" No Ġscopes Ġfound Ġfor Ġgiven Ġscopes Ġ$ scopes To Scan .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġincluded Scopes . addAll ( analyzer Result . project . scopes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpackages . addAll ( analyzer Result . packages ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresults Ġ= Ġscanner . scan ( packages , Ġoutput Dir , Ġdownload Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresults . forEach Ġ{ Ġpkg , Ġresult Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= ĠSummary Entry ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscopes Ġ= Ġfind Scopes For Package ( pkg , Ġanalyzer Result . project ). to Sorted Set (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdeclared License s Ġ= Ġpkg . declared License s , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetected License s Ġ= Ġresult . licenses , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerrors Ġ= Ġresult . errors . to Mutable List () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpkg Summary [ pkg . id . toString ()] Ġ= Ġentry ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Declared Ġlicenses Ġfor Ġ'${ pkg . id } ': Ġ${ entry . declared License s . join ToString () }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Detected Ġlicenses Ġfor Ġ'${ pkg . id } ': Ġ${ entry . detected License s . join ToString () }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġinput Path ?. let Ġ{ Ġinput Path Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( input Path . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Provided Ġpath Ġdoes Ġnot Ġexist : Ġ${ input Path . absolute Path }" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlocal Scanner Ġ= Ġscanner Ġas ? ĠLocal Scanner ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( local Scanner Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Sc anning Ġpath Ġ'${ input Path . absolute Path }' ...") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġlocal Scanner . scan ( input Path , Ġoutput Dir ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Detected Ġlicenses Ġfor Ġpath Ġ'${ input Path . absolute Path } ': Ġ${ result . licenses . join ToString () }") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSummary Entry ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdetected License s Ġ= Ġresult . licenses , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerrors Ġ= Ġresult . errors . to Mutable List () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠScan Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( com . here . ort . utils . printStackTrace ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error Ġ{ Ġ" Could Ġnot Ġscan Ġpath Ġ'${ input Path . absolute Path } ': Ġ${ e . message }" Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSummary Entry ( errors Ġ= Ġe . collect Messages (). to Mutable List ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpkg Summary [ input Path . absolute Path ] Ġ= Ġentry ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" To Ġscan Ġlocal Ġfiles Ġthe Ġchosen Ġscanner Ġmust Ġbe Ġa Ġlocal Ġscanner .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġscanned Scopes Ġ= Ġincluded Scopes . map Ġ{ Ġit . name Ġ}. to Sorted Set () ĊĠĠĠĠĠĠĠ Ġval Ġignored Scopes Ġ= Ġexcluded Scopes . map Ġ{ Ġit . name Ġ}. to Sorted Set () ĊĠĠĠĠĠĠĠ Ġwrite Summary ( output Dir , ĠScan Summary ( pkg Summary , ĠScan Results Cache . stats , Ġscanned Scopes , Ġignored Scopes )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Scopes For Package ( pkg : ĠPackage , Ġproject : ĠProject ) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġproject . scopes . filter Ġ{ Ġit . contains ( pkg ) Ġ}. map Ġ{ Ġit . name Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġwrite Summary ( output Directory : ĠFile , Ġscan Summary : ĠScan Summary ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsummary Formats . forEach Ġ{ Ġformat Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsummary File Ġ= ĠFile ( output Directory , Ġ" scan - summary .${ format . file Extension }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmapper Ġ= Ġwhen Ġ( format ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOutput Format . JSON Ġ-> Ġjson Mapper ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOutput Format . YAML Ġ-> Ġyaml Mapper ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Writing Ġscan Ġsummary Ġto Ġ${ summary File . absolute Path }. ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmapper . writer WithDefault PrettyPrinter (). writeValue ( summary File , Ġscan Summary ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ