/* Ċ Ġ* ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠMIT Ġlicense Ġthat Ġcan Ġbe Ċ Ġ* Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ Ġ*/ Ċ Ċ package Ġorg . rust . cargo . toolchain Ċ Ċ import Ġcom . google . common . annotations . Visible ForTesting Ċ import Ġcom . intellij . openapi . util . System Info Ċ import Ġcom . intellij . openapi . util . io . File Util Ċ import Ġcom . intellij . openapi . vfs . Local FileSystem Ċ import Ġcom . intellij . openapi . vfs . Virtual File Ċ import Ġcom . intellij . openapi ext . is UnitTest Mode Ċ import Ġcom . intellij . util . text . Sem Ver Ċ import Ġorg . rust . openapi ext .* Ċ import Ġjava . io . File Ċ import Ġjava . nio . file . Files Ċ import Ġjava . nio . file . Path Ċ import Ġjava . time . LocalDate Ċ import Ġjava . time . format . DateTime ParseException Ċ Ċ data Ġclass ĠRust Tool chain ( val Ġlocation : ĠPath ) Ġ{ ĊĊĠĠĠ Ġfun Ġlooks Like Valid Tool chain (): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠ Ġhas Executable ( C ARG O ) Ġ&& Ġhas Executable ( R UST C ) ĊĊĠĠĠ Ġfun Ġquery Versions (): ĠVersion Info Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! is UnitTest Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Is Background Thread () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠVersion Info ( scrape Rust c Version ( path To Executable ( R UST C ))) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Sys root ( project Directory : ĠPath ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! is UnitTest Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Is Background Thread () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġtimeout Ms Ġ= Ġ 1 0 0 0 0 ĊĠĠĠĠĠĠĠ Ġval Ġoutput Ġ= ĠGeneral CommandLine ( path To Executable ( R UST C )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. with Charset ( Charsets . UTF _ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. with Work Directory ( project Directory ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. with Parameters ("-- print ", Ġ" sys root ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. execute ( timeout Ms ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( output ?. is Success Ġ== Ġtrue ) Ġoutput . stdout . trim () Ġelse Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Std lib From Sys root ( project Directory : ĠPath ): ĠVirtual File ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsys root Ġ= Ġget Sys root ( project Directory ) Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġfs Ġ= ĠLocal FileSystem . getInstance () ĊĠĠĠĠĠĠĠ Ġreturn Ġfs . refresh And Find File By Path ( File Util . join ( sys root , Ġ" lib / rust lib / src / rust / src ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Cfg Options ( project Directory : ĠPath ): ĠList < String >? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtimeout Ms Ġ= Ġ 1 0 0 0 0 ĊĠĠĠĠĠĠĠ Ġval Ġoutput Ġ= ĠGeneral CommandLine ( path To Executable ( R UST C )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. with Charset ( Charsets . UTF _ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. with Work Directory ( project Directory ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. with Parameters ("-- print ", Ġ" cfg ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. execute ( timeout Ms ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( output ?. is Success Ġ== Ġtrue ) Ġoutput . stdout Lines Ġelse Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġraw Cargo (): ĠC argo Ġ= ĠC argo ( path To Executable ( C ARG O )) ĊĊĠĠĠ Ġfun Ġcargo Or Wrapper ( cargo Project Directory : ĠPath ?): ĠC argo Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġhas X argo Tom l Ġ= Ġcargo Project Directory ?. resolve ( X ARG O _ TO ML )?. let Ġ{ ĠFiles . is Regular File ( it ) Ġ} Ġ== Ġtrue ĊĠĠĠĠĠĠĠ Ġval Ġcargo Wrapper Ġ= Ġif Ġ( has X argo Tom l Ġ&& Ġhas Executable ( X ARG O )) ĠX ARG O Ġelse ĠC ARG O ĊĠĠĠĠĠĠĠ Ġreturn ĠC argo ( path To Executable ( cargo Wrapper )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġrust up ( cargo Project Directory : ĠPath ): ĠRust up ? Ġ= ĊĠĠĠĠĠĠĠ Ġif Ġ( is Rust up Available ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRust up ( this , Ġpath To Executable ( R UST UP ), Ġcargo Project Directory ) ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĊĠĠĠ Ġfun Ġrust fmt (): ĠRust fmt Ġ= ĠRust fmt ( path To Executable ( R UST FMT )) ĊĊĠĠĠ Ġfun Ġgr cov (): ĠGr cov ? Ġ= Ġif Ġ( has Executable ( GR CO V )) ĠGr cov ( path To Executable ( GR CO V )) Ġelse Ġnull ĊĊĠĠĠ Ġfun Ġe vc xr (): ĠE vc xr ? Ġ= Ġif Ġ( has Executable ( E VC XR )) ĠE vc xr ( path To Executable ( E VC XR )) Ġelse Ġnull ĊĊĠĠĠ Ġval Ġis Rust up Available : ĠBoolean Ġget () Ġ= Ġhas Executable ( R UST UP ) ĊĊĠĠĠ Ġval Ġpresent able Location : ĠString Ġ= Ġpath To Executable ( C ARG O ). toString () ĊĊĠĠĠ Ġprivate Ġfun Ġpath To Executable ( tool Name : ĠString ): ĠPath Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġexe Name Ġ= Ġif Ġ( System Info . is Windows ) Ġ"$ tool Name . exe " Ġelse Ġtool Name ĊĠĠĠĠĠĠĠ Ġreturn Ġlocation . resolve ( exe Name ). to AbsolutePath () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhas Executable ( exec : ĠString ): ĠBoolean Ġ= ĊĠĠĠĠĠĠĠ ĠFiles . is Executable ( path To Executable ( exec )) ĊĊĠĠĠ Ġdata Ġclass ĠVersion Info ( ĊĠĠĠĠĠĠĠ Ġval Ġrustc : ĠRust c Version ? ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠR UST C Ġ= Ġ" rustc " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠR UST FMT Ġ= Ġ" rust fmt " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠC ARG O Ġ= Ġ" cargo " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠR UST UP Ġ= Ġ" rust up " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠX ARG O Ġ= Ġ" x argo " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠGR CO V Ġ= Ġ" gr cov " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠE VC XR Ġ= Ġ" e vc xr " ĊĊĠĠĠĠĠĠĠ Ġconst Ġval ĠC ARG O _ TO ML Ġ= Ġ" Cargo . toml " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠC ARG O _ LOCK Ġ= Ġ" Cargo . lock " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠX ARG O _ TO ML Ġ= Ġ" X argo . toml " ĊĊĠĠĠĠĠĠĠ Ġfun Ġsuggest (): ĠRust Tool chain ? Ġ= ĠSuggest ions . all (). map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcandidate Ġ= ĠRust Tool chain ( it . to Path (). to AbsolutePath ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( candidate . look s Like Valid Tool chain ()) Ġcandidate Ġelse Ġnull ĊĠĠĠĠĠĠĠ Ġ}. first OrNull () ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠRust c Version ( ĊĠĠĠ Ġval Ġsemver : ĠSem Ver , ĊĠĠĠ Ġval Ġhost : ĠString , ĊĠĠĠ Ġval Ġchannel : ĠRust Channel , ĊĠĠĠ Ġval Ġcommit Hash : ĠString ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġcommit Date : ĠLocalDate ? Ġ= Ġnull Ċ ) Ċ Ċ private Ġfun Ġsc rape Rust c Version ( rustc : ĠPath ): ĠRust c Version ? Ġ{ ĊĠĠĠ Ġval Ġlines Ġ= ĠGeneral CommandLine ( rustc ) ĊĠĠĠĠĠĠĠ Ġ. with Parameters ("-- version ", Ġ"-- verbose ") ĊĠĠĠĠĠĠĠ Ġ. execute () ĊĠĠĠĠĠĠĠ Ġ? . stdout Lines ĊĠĠĠĠĠĠĠ Ġ?: Ġreturn Ġnull ĊĊĠĠĠ Ġreturn Ġparse Rust c Version ( lines ) Ċ } Ċ Ċ @ Visible ForTesting Ċ fun Ġparse Rust c Version ( lines : ĠList < String >): ĠRust c Version ? Ġ{ ĊĠĠĠ Ġ// ĠWe Ġwant Ġto Ġparse Ġfollowing ĊĠĠĠ Ġ// ĊĠĠĠ Ġ// Ġ Ġ``` ĊĠĠĠ Ġ// Ġ Ġrustc Ġ 1 . 8 . 0 - beta . 1 Ġ( fac bf dd 7 1 Ġ 2 0 1 6 - 0 3 - 0 2 ) ĊĠĠĠ Ġ// Ġ Ġbinary : Ġrustc ĊĠĠĠ Ġ// Ġ Ġcommit - hash : Ġfac bf dd 7 1 cb 6 ed 0 aea eb 0 6 b 6 b 8 4 2 8 f 3 3 3 de 4 0 7 2 b ĊĠĠĠ Ġ// Ġ Ġcommit - date : Ġ 2 0 1 6 - 0 3 - 0 2 ĊĠĠĠ Ġ// Ġ Ġhost : Ġx 8 6 _ 6 4 - unknown - linux - gnu ĊĠĠĠ Ġ// Ġ Ġrelease : Ġ 1 . 8 . 0 - beta . 1 ĊĠĠĠ Ġ// Ġ Ġ``` ĊĠĠĠ Ġval Ġrelease Re Ġ= Ġ""" release : Ġ(\ d +\ .\ d +\ .\ d + )( .* ) """. to Regex () ĊĠĠĠ Ġval Ġhost Re Ġ= Ġ" host : Ġ( .* ) ". to Regex () ĊĠĠĠ Ġval Ġcommit Hash Re Ġ= Ġ" commit - hash : Ġ([ A - Fa - f 0 - 9 ]{ 4 0 }) ". to Regex () ĊĠĠĠ Ġval Ġcommit Date Re Ġ= Ġ""" commit - date : Ġ(\ d { 4 }- \ d { 2 }- \ d { 2 }) """. to Regex () ĊĠĠĠ Ġval Ġfind Ġ= Ġ{ Ġre : ĠRegex Ġ-> Ġlines . map NotNull Ġ{ Ġre . match Ent ire ( it ) Ġ}. first OrNull () Ġ} ĊĊĠĠĠ Ġval Ġrelease Match Ġ= Ġfind ( release Re ) Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġval Ġhost Text Ġ= Ġfind ( host Re )?. groups ?. get ( 1 )?. value Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġval Ġversion Text Ġ= Ġrelease Match . groups [ 1 ]?. value Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġval Ġcommit Hash Ġ= Ġfind ( commit Hash Re )?. groups ?. get ( 1 )?. value ĊĠĠĠ Ġval Ġcommit Date Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġfind ( commit Date Re )?. groups ?. get ( 1 )?. value ?. let ( LocalDate :: parse ) ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠDateTime ParseException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġsem Ver Ġ= ĠSem Ver . parse FromText ( version Text ) Ġ?: Ġreturn Ġnull ĊĠĠĠ Ġval Ġrelease Suffix Ġ= Ġrelease Match . groups [ 2 ]?. value . or Empty () ĊĠĠĠ Ġval Ġchannel Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġrelease Suffix . isEmpty () Ġ-> ĠRust Channel . ST ABLE ĊĠĠĠĠĠĠĠ Ġrelease Suffix . startsWith ("- beta ") Ġ-> ĠRust Channel . B ETA ĊĠĠĠĠĠĠĠ Ġrelease Suffix . startsWith ("- nightly ") Ġ-> ĠRust Channel . N IGHT LY ĊĠĠĠĠĠĠĠ Ġrelease Suffix . startsWith ("- dev ") Ġ-> ĠRust Channel . DEV ĊĠĠĠĠĠĠĠ Ġelse Ġ-> ĠRust Channel . DEFAULT ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠRust c Version ( sem Ver , Ġhost Text , Ġchannel , Ġcommit Hash , Ġcommit Date ) Ċ } Ċ Ċ private Ġobject ĠSuggest ions Ġ{ ĊĠĠĠ Ġfun Ġall () Ġ= Ġsequence Of ( ĊĠĠĠĠĠĠĠ Ġfrom Rust up (), ĊĠĠĠĠĠĠĠ Ġfrom Path (), ĊĠĠĠĠĠĠĠ Ġfor Mac (), ĊĠĠĠĠĠĠĠ Ġfor Unix (), ĊĠĠĠĠĠĠĠ Ġfor Windows () ĊĠĠĠ Ġ). flatten () ĊĊĠĠĠ Ġprivate Ġfun Ġfrom Rust up (): ĠSequence < File > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfile Ġ= ĠFile ( File Util . expand User Home (" ~/. cargo / bin ")) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( file . isDirectory ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsequence Of ( file ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġempty Sequence () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfrom Path (): ĠSequence < File > Ġ= ĠSystem . getenv (" PATH "). or Empty () ĊĠĠĠĠĠĠĠ Ġ. split ( File . path Separator ) ĊĠĠĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġ! it . isEmpty () Ġ} ĊĠĠĠĠĠĠĠ Ġ. map (:: File ) ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . isDirectory Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfor Unix (): ĠSequence < File > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! System Info . is Unix ) Ġreturn Ġempty Sequence () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsequence Of ( File ("/ usr / local / bin ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfor Mac (): ĠSequence < File > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! System Info . is Mac ) Ġreturn Ġempty Sequence () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsequence Of ( File ("/ usr / local / Cell ar / rust / bin ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfor Windows (): ĠSequence < File > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! System Info . is Windows ) Ġreturn Ġempty Sequence () ĊĠĠĠĠĠĠĠ Ġval Ġfrom Home Ġ= ĠFile ( System . getProperty (" user . home ") Ġ?: Ġ"", Ġ". cargo / bin ") ĊĊĠĠĠĠĠĠĠ Ġval Ġprogram Files Ġ= ĠFile ( System . getenv (" Program Files ") Ġ?: Ġ"") ĊĠĠĠĠĠĠĠ Ġval Ġfrom Program Files Ġ= Ġif Ġ(! program Files . exists () Ġ|| Ġ! program Files . isDirectory ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġempty Sequence () ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprogram Files . list Files Ġ{ Ġfile Ġ-> Ġfile . isDirectory Ġ}. as Sequence () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . name Without Extension . toLowerCase (). startsWith (" rust ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠFile ( it , Ġ" bin ") Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsequence Of ( from Home ) Ġ+ Ġfrom Program Files ĊĠĠĠ Ġ} Ċ } Ċ