@@ -35,6 +35,8 @@ const PUBLIC_NODE_VERSION_INDEX: &'static str = "https://nodejs.org/dist/index.j
3535/// URL of the index of available Yarn versions on the public git repository.
3636const PUBLIC_YARN_VERSION_INDEX : & ' static str =
3737 "https://github.com/notion-cli/yarn-releases/raw/master/index.json" ;
38+ /// URL of the latest Yarn version on the public yarnpkg.com
39+ const PUBLIC_YARN_LATEST_VERSION : & ' static str = "https://yarnpkg.com/latest-version" ;
3840
3941/// Lazily loaded tool catalog.
4042pub struct LazyCatalog {
@@ -278,51 +280,7 @@ impl RegistryFetchError {
278280
279281impl Resolve < NodeDistro > for NodeCollection {
280282 fn resolve_public ( & self , matching : & VersionReq ) -> Fallible < NodeDistro > {
281- let index: Index = match read_cached_opt ( ) . unknown ( ) ? {
282- Some ( serial) => serial,
283- None => {
284- let spinner = progress_spinner ( & format ! (
285- "Fetching public registry: {}" ,
286- PUBLIC_NODE_VERSION_INDEX
287- ) ) ;
288- let mut response: reqwest:: Response = reqwest:: get ( PUBLIC_NODE_VERSION_INDEX )
289- . with_context ( RegistryFetchError :: from_error) ?;
290- let response_text: String = response. text ( ) . unknown ( ) ?;
291- let cached: NamedTempFile = NamedTempFile :: new ( ) . unknown ( ) ?;
292-
293- // Block to borrow cached for cached_file.
294- {
295- let mut cached_file: & File = cached. as_file ( ) ;
296- cached_file. write ( response_text. as_bytes ( ) ) . unknown ( ) ?;
297- }
298-
299- cached. persist ( path:: node_index_file ( ) ?) . unknown ( ) ?;
300-
301- let expiry: NamedTempFile = NamedTempFile :: new ( ) . unknown ( ) ?;
302-
303- // Block to borrow expiry for expiry_file.
304- {
305- let mut expiry_file: & File = expiry. as_file ( ) ;
306-
307- if let Some ( expires_header) = response. headers ( ) . get :: < Expires > ( ) {
308- write ! ( expiry_file, "{}" , expires_header) . unknown ( ) ?;
309- } else {
310- let expiry_date =
311- SystemTime :: now ( ) + Duration :: from_secs ( max_age ( & response) . into ( ) ) ;
312-
313- write ! ( expiry_file, "{}" , HttpDate :: from( expiry_date) ) . unknown ( ) ?;
314- }
315- }
316-
317- expiry. persist ( path:: node_index_expiry_file ( ) ?) . unknown ( ) ?;
318-
319- let serial: serial:: index:: Index =
320- serde_json:: de:: from_str ( & response_text) . unknown ( ) ?;
321-
322- spinner. finish_and_clear ( ) ;
323- serial
324- }
325- } . into_index ( ) ?;
283+ let index: Index = resolve_node_versions ( ) ?. into_index ( ) ?;
326284
327285 let version = index. entries . iter ( )
328286 . rev ( )
@@ -433,3 +391,76 @@ fn max_age(response: &reqwest::Response) -> u32 {
433391 // Default to four hours.
434392 4 * 60 * 60
435393}
394+
395+ fn resolve_node_versions ( ) -> Result < serial:: index:: Index , NotionError > {
396+ match read_cached_opt ( ) . unknown ( ) ? {
397+ Some ( serial) => Ok ( serial) ,
398+ None => {
399+ let spinner = progress_spinner ( & format ! (
400+ "Fetching public registry: {}" ,
401+ PUBLIC_NODE_VERSION_INDEX
402+ ) ) ;
403+ let mut response: reqwest:: Response = reqwest:: get ( PUBLIC_NODE_VERSION_INDEX )
404+ . with_context ( RegistryFetchError :: from_error) ?;
405+ let response_text: String = response. text ( ) . unknown ( ) ?;
406+ let cached: NamedTempFile = NamedTempFile :: new ( ) . unknown ( ) ?;
407+
408+ // Block to borrow cached for cached_file.
409+ {
410+ let mut cached_file: & File = cached. as_file ( ) ;
411+ cached_file. write ( response_text. as_bytes ( ) ) . unknown ( ) ?;
412+ }
413+
414+ cached. persist ( path:: node_index_file ( ) ?) . unknown ( ) ?;
415+
416+ let expiry: NamedTempFile = NamedTempFile :: new ( ) . unknown ( ) ?;
417+
418+ // Block to borrow expiry for expiry_file.
419+ {
420+ let mut expiry_file: & File = expiry. as_file ( ) ;
421+
422+ if let Some ( expires_header) = response. headers ( ) . get :: < Expires > ( ) {
423+ write ! ( expiry_file, "{}" , expires_header) . unknown ( ) ?;
424+ } else {
425+ let expiry_date =
426+ SystemTime :: now ( ) + Duration :: from_secs ( max_age ( & response) . into ( ) ) ;
427+
428+ write ! ( expiry_file, "{}" , HttpDate :: from( expiry_date) ) . unknown ( ) ?;
429+ }
430+ }
431+
432+ expiry. persist ( path:: node_index_expiry_file ( ) ?) . unknown ( ) ?;
433+
434+ let serial: serial:: index:: Index =
435+ serde_json:: de:: from_str ( & response_text) . unknown ( ) ?;
436+
437+ spinner. finish_and_clear ( ) ;
438+ Ok ( serial)
439+ }
440+ }
441+ }
442+
443+ pub fn parse_node_version ( src : String ) -> Fallible < String > {
444+ let mut version: String = src;
445+ if version == "latest" {
446+ let index = resolve_node_versions ( ) ?. into_index ( ) ?;
447+ let mut latest_version: Version = index. entries . keys ( ) . next ( ) . unwrap ( ) . clone ( ) ;
448+ for key in index. entries . keys ( ) {
449+ if key > & latest_version {
450+ latest_version = key. clone ( ) ;
451+ }
452+ } ;
453+ version = latest_version. to_string ( ) ;
454+ }
455+ Ok ( version)
456+ }
457+
458+ pub fn parse_yarn_version ( src : String ) -> Fallible < String > {
459+ let mut version: String = src;
460+ if version == "latest" {
461+ let mut response: reqwest:: Response = reqwest:: get ( PUBLIC_YARN_LATEST_VERSION )
462+ . with_context ( RegistryFetchError :: from_error) ?;
463+ version = response. text ( ) . unknown ( ) ?;
464+ }
465+ Ok ( version)
466+ }
0 commit comments