@@ -98,6 +98,43 @@ export class Cargo {
98
98
return artifacts [ 0 ] . fileName ;
99
99
}
100
100
101
+ async crates ( ) : Promise < Crate [ ] > {
102
+ const pathToCargo = await cargoPath ( ) ;
103
+ return await new Promise ( ( resolve , reject ) => {
104
+ const crates : Crate [ ] = [ ] ;
105
+
106
+ const cargo = cp . spawn ( pathToCargo , [ 'tree' , '--prefix' , 'none' ] , {
107
+ stdio : [ 'ignore' , 'pipe' , 'pipe' ] ,
108
+ cwd : this . rootFolder
109
+ } ) ;
110
+ const rl = readline . createInterface ( { input : cargo . stdout } ) ;
111
+ rl . on ( 'line' , line => {
112
+ const match = line . match ( TREE_LINE_PATTERN ) ;
113
+ if ( match ) {
114
+ const name = match [ 1 ] ;
115
+ const version = match [ 2 ] ;
116
+ const extraInfo = match [ 3 ] ;
117
+ // ignore duplicates '(*)' and path dependencies
118
+ if ( this . shouldIgnore ( extraInfo ) ) {
119
+ return ;
120
+ }
121
+ crates . push ( { name, version } ) ;
122
+ }
123
+ } ) ;
124
+ cargo . on ( 'exit' , ( exitCode , _ ) => {
125
+ if ( exitCode === 0 )
126
+ resolve ( crates ) ;
127
+ else
128
+ reject ( new Error ( `exit code: ${ exitCode } .` ) ) ;
129
+ } ) ;
130
+
131
+ } ) ;
132
+ }
133
+
134
+ private shouldIgnore ( extraInfo : string ) : boolean {
135
+ return extraInfo !== undefined && ( extraInfo === '*' || path . isAbsolute ( extraInfo ) ) ;
136
+ }
137
+
101
138
private async runCargo (
102
139
cargoArgs : string [ ] ,
103
140
onStdoutJson : ( obj : any ) => void ,
@@ -129,6 +166,58 @@ export class Cargo {
129
166
}
130
167
}
131
168
169
+ export async function activeToolchain ( ) : Promise < string > {
170
+ const pathToRustup = await rustupPath ( ) ;
171
+ return await new Promise ( ( resolve , reject ) => {
172
+ const execution = cp . spawn ( pathToRustup , [ 'show' , 'active-toolchain' ] , {
173
+ stdio : [ 'ignore' , 'pipe' , 'pipe' ] ,
174
+ cwd : os . homedir ( )
175
+ } ) ;
176
+ const rl = readline . createInterface ( { input : execution . stdout } ) ;
177
+
178
+ let currToolchain : string | undefined = undefined ;
179
+ rl . on ( 'line' , line => {
180
+ const match = line . match ( TOOLCHAIN_PATTERN ) ;
181
+ if ( match ) {
182
+ currToolchain = match [ 1 ] ;
183
+ }
184
+ } ) ;
185
+ execution . on ( 'exit' , ( exitCode , _ ) => {
186
+ if ( exitCode === 0 && currToolchain )
187
+ resolve ( currToolchain ) ;
188
+ else
189
+ reject ( new Error ( `exit code: ${ exitCode } .` ) ) ;
190
+ } ) ;
191
+
192
+ } ) ;
193
+ }
194
+
195
+ export async function rustVersion ( ) : Promise < string > {
196
+ const pathToRustup = await rustupPath ( ) ;
197
+ return await new Promise ( ( resolve , reject ) => {
198
+ const execution = cp . spawn ( pathToRustup , [ 'show' , 'active-toolchain' ] , {
199
+ stdio : [ 'ignore' , 'pipe' , 'pipe' ] ,
200
+ cwd : os . homedir ( )
201
+ } ) ;
202
+ const rl = readline . createInterface ( { input : execution . stdout } ) ;
203
+
204
+ let currToolchain : string | undefined = undefined ;
205
+ rl . on ( 'line' , line => {
206
+ const match = line . match ( TOOLCHAIN_PATTERN ) ;
207
+ if ( match ) {
208
+ currToolchain = match [ 1 ] ;
209
+ }
210
+ } ) ;
211
+ execution . on ( 'exit' , ( exitCode , _ ) => {
212
+ if ( exitCode === 1 && currToolchain )
213
+ resolve ( currToolchain ) ;
214
+ else
215
+ reject ( new Error ( `exit code: ${ exitCode } .` ) ) ;
216
+ } ) ;
217
+
218
+ } ) ;
219
+ }
220
+
132
221
/** Mirrors `project_model::sysroot::discover_sysroot_dir()` implementation*/
133
222
export async function getSysroot ( dir : string ) : Promise < string > {
134
223
const rustcPath = await getPathForExecutable ( "rustc" ) ;
@@ -147,6 +236,16 @@ export async function getRustcId(dir: string): Promise<string> {
147
236
return rx . exec ( data ) ! [ 1 ] ;
148
237
}
149
238
239
+ export async function getRustcVersion ( dir : string ) : Promise < string > {
240
+ const rustcPath = await getPathForExecutable ( "rustc" ) ;
241
+
242
+ // do not memoize the result because the toolchain may change between runs
243
+ const data = await execute ( `${ rustcPath } -V` , { cwd : dir } ) ;
244
+ const rx = / ( \d \. \d + \. \d + ) / ;
245
+
246
+ return rx . exec ( data ) ! [ 1 ] ;
247
+ }
248
+
150
249
/** Mirrors `toolchain::cargo()` implementation */
151
250
export function cargoPath ( ) : Promise < string > {
152
251
return getPathForExecutable ( "cargo" ) ;
0 commit comments