@@ -6,6 +6,7 @@ use std::path::{Path, PathBuf};
66use toml:: Value ;
77
88use crate :: jsonstructs_versionsdb:: JuliaupVersionDB ;
9+ use crate :: utils:: { print_juliaup_style, JuliaupMessageType } ;
910
1011// Constants matching Julia's base/loading.jl
1112// https://github.com/JuliaLang/julia/blob/dd80509227adbd525737244ebabc95ec5d634354/base/loading.jl#L625C1-L631C2
@@ -398,26 +399,12 @@ pub fn extract_version_from_project(project_file: PathBuf) -> Result<Option<Stri
398399
399400/// Find highest versioned manifest, preferring JuliaManifest over Manifest for same version
400401pub fn find_highest_versioned_manifest ( project_root : & Path ) -> Option < PathBuf > {
401- let Ok ( entries) = fs:: read_dir ( project_root) else {
402- return None ;
403- } ;
402+ let entries = fs:: read_dir ( project_root) . ok ( ) ?;
404403
405404 // Track highest version for both JuliaManifest and Manifest separately
406405 let mut highest_julia: Option < ( Version , PathBuf ) > = None ;
407406 let mut highest_manifest: Option < ( Version , PathBuf ) > = None ;
408407
409- // Helper to update highest version if new version is greater
410- let update_highest =
411- |highest : & mut Option < ( Version , PathBuf ) > , version : Version , path : PathBuf | match highest {
412- Some ( ( current_version, _) ) if version > * current_version => {
413- * highest = Some ( ( version, path) ) ;
414- }
415- None => {
416- * highest = Some ( ( version, path) ) ;
417- }
418- _ => { }
419- } ;
420-
421408 for entry in entries. flatten ( ) {
422409 let path = entry. path ( ) ;
423410 if let Some ( filename) = path. file_name ( ) . and_then ( |n| n. to_str ( ) ) {
@@ -438,20 +425,21 @@ pub fn find_highest_versioned_manifest(project_root: &Path) -> Option<PathBuf> {
438425 . and_then ( |s| s. strip_suffix ( ".toml" ) )
439426 . and_then ( parse_version_lenient)
440427 {
441- update_highest ( target, version, path) ;
428+ // Update highest if this version is greater or if none exists yet
429+ let should_update = match target {
430+ Some ( ( current_version, _) ) => version > * current_version,
431+ None => true ,
432+ } ;
433+ if should_update {
434+ * target = Some ( ( version, path) ) ;
435+ }
442436 }
443437 }
444438 }
445439
446440 // Return highest version, preferring JuliaManifest for same version
447441 match ( highest_julia, highest_manifest) {
448- ( Some ( ( jv, jpath) ) , Some ( ( mv, mpath) ) ) => {
449- if jv >= mv {
450- Some ( jpath)
451- } else {
452- Some ( mpath)
453- }
454- }
442+ ( Some ( ( jv, jpath) ) , Some ( ( mv, mpath) ) ) => Some ( if jv >= mv { jpath } else { mpath } ) ,
455443 ( Some ( ( _, jpath) ) , None ) => Some ( jpath) ,
456444 ( None , Some ( ( _, mpath) ) ) => Some ( mpath) ,
457445 ( None , None ) => None ,
@@ -509,12 +497,26 @@ pub fn parse_db_version(version: &str) -> Result<Version> {
509497 Version :: parse ( base) . with_context ( || format ! ( "Failed to parse version `{}`." , base) )
510498}
511499
512- pub fn max_available_version ( versions_db : & JuliaupVersionDB ) -> Result < Option < Version > > {
513- Ok ( versions_db
514- . available_versions
515- . keys ( )
516- . filter_map ( |key| parse_db_version ( key) . ok ( ) )
517- . max ( ) )
500+ fn versioned_nightly_channel ( major : u64 , minor : u64 ) -> String {
501+ format ! ( "{}.{}-nightly" , major, minor)
502+ }
503+
504+ impl JuliaupVersionDB {
505+ pub fn max_available_version ( & self ) -> Option < Version > {
506+ self . available_versions
507+ . keys ( )
508+ . filter_map ( |key| parse_db_version ( key) . ok ( ) )
509+ . max ( )
510+ }
511+
512+ /// Find the maximum version (including prerelease) for a given major.minor series
513+ pub fn max_version_for_minor ( & self , major : u64 , minor : u64 ) -> Option < Version > {
514+ self . available_channels
515+ . keys ( )
516+ . filter_map ( |key| parse_db_version ( key) . ok ( ) )
517+ . filter ( |version| version. major == major && version. minor == minor)
518+ . max ( )
519+ }
518520}
519521
520522pub fn resolve_auto_channel ( required : String , versions_db : & JuliaupVersionDB ) -> Result < String > {
@@ -535,29 +537,32 @@ pub fn resolve_auto_channel(required: String, versions_db: &JuliaupVersionDB) ->
535537 // Prereleases should use nightly channels because they represent development/testing versions
536538 if !required_version. pre . is_empty ( ) {
537539 // Check if a version-specific nightly channel exists (e.g., 1.12-nightly)
538- let versioned_nightly = format ! (
539- "{}.{}-nightly" ,
540- required_version. major, required_version. minor
541- ) ;
540+ let versioned_nightly =
541+ versioned_nightly_channel ( required_version. major , required_version. minor ) ;
542542
543543 if versions_db
544544 . available_channels
545545 . contains_key ( & versioned_nightly)
546546 {
547- eprintln ! (
548- "{} Manifest specifies prerelease Julia {}. Using {} channel." ,
549- console:: style( "Info:" ) . cyan( ) . bold( ) ,
550- required,
551- versioned_nightly
547+ print_juliaup_style (
548+ "Info" ,
549+ & format ! (
550+ "Manifest specifies prerelease Julia {}. Using {} channel." ,
551+ required, versioned_nightly
552+ ) ,
553+ JuliaupMessageType :: Progress ,
552554 ) ;
553555 return Ok ( versioned_nightly) ;
554556 }
555557
556558 // Fall back to main nightly channel
557- eprintln ! (
558- "{} Manifest specifies prerelease Julia {}. Using nightly channel." ,
559- console:: style( "Info:" ) . cyan( ) . bold( ) ,
560- required
559+ print_juliaup_style (
560+ "Info" ,
561+ & format ! (
562+ "Manifest specifies prerelease Julia {}. Using nightly channel." ,
563+ required
564+ ) ,
565+ JuliaupMessageType :: Progress ,
561566 ) ;
562567 return Ok ( "nightly" . to_string ( ) ) ;
563568 }
@@ -566,68 +571,72 @@ pub fn resolve_auto_channel(required: String, versions_db: &JuliaupVersionDB) ->
566571 // This handles both regular versions (e.g., 1.12.55 > 1.12.1) and prerelease versions
567572 // (e.g., 1.12.0-rc1 when only 1.11.x exists)
568573 let max_version_for_minor =
569- max_version_for_minor ( versions_db , required_version. major , required_version. minor ) ? ;
574+ versions_db . max_version_for_minor ( required_version. major , required_version. minor ) ;
570575
571576 if let Some ( max_minor_version) = & max_version_for_minor {
572577 if & required_version > max_minor_version {
573578 // The requested version is higher than any known version for this minor series
574- let channel = format ! (
575- "{}.{}-nightly" ,
576- required_version . major , required_version . minor
577- ) ;
578- eprintln ! (
579- "{} Manifest specifies Julia {} but the highest known version for {}.{} is {}. Using {} channel." ,
580- console :: style ( "Info:" ) . cyan ( ) . bold ( ) ,
581- required ,
582- required_version . major ,
583- required_version . minor ,
584- max_minor_version ,
585- channel
579+ let channel = versioned_nightly_channel ( required_version . major , required_version . minor ) ;
580+ print_juliaup_style (
581+ "Info" ,
582+ & format ! (
583+ "Manifest specifies Julia {} but the highest known version for {}.{} is {}. Using {} channel." ,
584+ required ,
585+ required_version . major ,
586+ required_version . minor ,
587+ max_minor_version ,
588+ channel
589+ ) ,
590+ JuliaupMessageType :: Progress ,
586591 ) ;
587592 return Ok ( channel) ;
588593 }
589594 }
590595
591596 // Check if requested version is higher than any known version overall
592597 // This handles the case where we have 1.12.x but request 1.13.0
593- let max_known_version = max_available_version ( versions_db ) ? ;
598+ let max_known_version = versions_db . max_available_version ( ) ;
594599 if let Some ( max_version) = & max_known_version {
595600 if & required_version > max_version {
596601 // Check if a version-specific nightly channel exists (e.g., 1.13-nightly)
597- let versioned_nightly = format ! (
598- "{}.{}-nightly" ,
599- required_version. major, required_version. minor
600- ) ;
602+ let versioned_nightly =
603+ versioned_nightly_channel ( required_version. major , required_version. minor ) ;
601604
602605 if versions_db
603606 . available_channels
604607 . contains_key ( & versioned_nightly)
605608 {
606- eprintln ! (
607- "{} Manifest specifies Julia {} but the highest known version is {}. Using {} channel." ,
608- console:: style( "Info:" ) . cyan( ) . bold( ) ,
609- required,
610- max_version,
611- versioned_nightly
609+ print_juliaup_style (
610+ "Info" ,
611+ & format ! (
612+ "Manifest specifies Julia {} but the highest known version is {}. Using {} channel." ,
613+ required, max_version, versioned_nightly
614+ ) ,
615+ JuliaupMessageType :: Progress ,
612616 ) ;
613617 return Ok ( versioned_nightly) ;
614618 }
615619
616620 // Fall back to main nightly channel
617- eprintln ! (
618- "{} Manifest specifies Julia {} but the highest known version is {}. Using nightly channel." ,
619- console:: style( "Info:" ) . cyan( ) . bold( ) ,
620- required,
621- max_version
621+ print_juliaup_style (
622+ "Info" ,
623+ & format ! (
624+ "Manifest specifies Julia {} but the highest known version is {}. Using nightly channel." ,
625+ required, max_version
626+ ) ,
627+ JuliaupMessageType :: Progress ,
622628 ) ;
623629 return Ok ( "nightly" . to_string ( ) ) ;
624630 }
625631 } else {
626632 // No versions in database at all, use nightly
627- eprintln ! (
628- "{} Manifest specifies Julia {} but no versions are known. Using nightly channel." ,
629- console:: style( "Info:" ) . cyan( ) . bold( ) ,
630- required
633+ print_juliaup_style (
634+ "Info" ,
635+ & format ! (
636+ "Manifest specifies Julia {} but no versions are known. Using nightly channel." ,
637+ required
638+ ) ,
639+ JuliaupMessageType :: Progress ,
631640 ) ;
632641 return Ok ( "nightly" . to_string ( ) ) ;
633642 }
@@ -638,35 +647,18 @@ pub fn resolve_auto_channel(required: String, versions_db: &JuliaupVersionDB) ->
638647 ) )
639648}
640649
641- /// Find the maximum version (including prerelease) for a given major.minor series
642- pub fn max_version_for_minor (
643- versions_db : & JuliaupVersionDB ,
644- major : u64 ,
645- minor : u64 ,
646- ) -> Result < Option < Version > > {
647- Ok ( versions_db
648- . available_channels
649- . keys ( )
650- . filter_map ( |key| parse_db_version ( key) . ok ( ) )
651- . filter ( |version| version. major == major && version. minor == minor)
652- . max ( ) )
653- }
654-
655650pub fn get_auto_channel (
656651 args : & [ String ] ,
657652 versions_db : & JuliaupVersionDB ,
658653 manifest_version_detect : bool ,
659- ) -> Option < String > {
654+ ) -> Result < Option < String > > {
660655 if !manifest_version_detect {
661- return None ;
656+ return Ok ( None ) ;
662657 }
663658
664- determine_project_version_spec ( args)
665- . and_then ( |opt_version| {
666- opt_version
667- . map ( |version| resolve_auto_channel ( version, versions_db) )
668- . transpose ( )
669- } )
670- . ok ( )
671- . flatten ( )
659+ if let Some ( required_version) = determine_project_version_spec ( args) ? {
660+ resolve_auto_channel ( required_version, versions_db) . map ( Some )
661+ } else {
662+ Ok ( None )
663+ }
672664}
0 commit comments