@@ -9,7 +9,7 @@ use pubgrub::{DerivationTree, Derived, External, Map, Range, ReportFormatter, Te
99use rustc_hash:: FxHashMap ;
1010
1111use uv_configuration:: IndexStrategy ;
12- use uv_distribution_types:: { Index , IndexLocations , IndexUrl } ;
12+ use uv_distribution_types:: { Index , IndexCapabilities , IndexLocations , IndexUrl } ;
1313use uv_normalize:: PackageName ;
1414use uv_pep440:: Version ;
1515
@@ -505,6 +505,7 @@ impl PubGrubReportFormatter<'_> {
505505 derivation_tree : & ErrorTree ,
506506 selector : & CandidateSelector ,
507507 index_locations : & IndexLocations ,
508+ index_capabilities : & IndexCapabilities ,
508509 available_indexes : & FxHashMap < PackageName , BTreeSet < IndexUrl > > ,
509510 unavailable_packages : & FxHashMap < PackageName , UnavailablePackage > ,
510511 incomplete_packages : & FxHashMap < PackageName , BTreeMap < Version , IncompletePackage > > ,
@@ -540,6 +541,7 @@ impl PubGrubReportFormatter<'_> {
540541 set,
541542 selector,
542543 index_locations,
544+ index_capabilities,
543545 available_indexes,
544546 unavailable_packages,
545547 incomplete_packages,
@@ -589,6 +591,7 @@ impl PubGrubReportFormatter<'_> {
589591 & derived. cause1 ,
590592 selector,
591593 index_locations,
594+ index_capabilities,
592595 available_indexes,
593596 unavailable_packages,
594597 incomplete_packages,
@@ -602,6 +605,7 @@ impl PubGrubReportFormatter<'_> {
602605 & derived. cause2 ,
603606 selector,
604607 index_locations,
608+ index_capabilities,
605609 available_indexes,
606610 unavailable_packages,
607611 incomplete_packages,
@@ -621,6 +625,7 @@ impl PubGrubReportFormatter<'_> {
621625 set : & Range < Version > ,
622626 selector : & CandidateSelector ,
623627 index_locations : & IndexLocations ,
628+ index_capabilities : & IndexCapabilities ,
624629 available_indexes : & FxHashMap < PackageName , BTreeSet < IndexUrl > > ,
625630 unavailable_packages : & FxHashMap < PackageName , UnavailablePackage > ,
626631 incomplete_packages : & FxHashMap < PackageName , BTreeMap < Version , IncompletePackage > > ,
@@ -721,6 +726,20 @@ impl PubGrubReportFormatter<'_> {
721726 }
722727 }
723728 }
729+
730+ // Add hints due to an index returning an unauthorized response.
731+ for index in index_locations. indexes ( ) {
732+ if index_capabilities. unauthorized ( & index. url ) {
733+ hints. insert ( PubGrubHint :: UnauthorizedIndex {
734+ index : index. url . clone ( ) ,
735+ } ) ;
736+ }
737+ if index_capabilities. forbidden ( & index. url ) {
738+ hints. insert ( PubGrubHint :: ForbiddenIndex {
739+ index : index. url . clone ( ) ,
740+ } ) ;
741+ }
742+ }
724743 }
725744
726745 fn prerelease_available_hint (
@@ -873,6 +892,10 @@ pub(crate) enum PubGrubHint {
873892 // excluded from `PartialEq` and `Hash`
874893 next_index : IndexUrl ,
875894 } ,
895+ /// An index returned an Unauthorized (401) response.
896+ UnauthorizedIndex { index : IndexUrl } ,
897+ /// An index returned a Forbidden (403) response.
898+ ForbiddenIndex { index : IndexUrl } ,
876899}
877900
878901/// This private enum mirrors [`PubGrubHint`] but only includes fields that should be
@@ -921,6 +944,12 @@ enum PubGrubHintCore {
921944 UncheckedIndex {
922945 package : PubGrubPackage ,
923946 } ,
947+ UnauthorizedIndex {
948+ index : IndexUrl ,
949+ } ,
950+ ForbiddenIndex {
951+ index : IndexUrl ,
952+ } ,
924953}
925954
926955impl From < PubGrubHint > for PubGrubHintCore {
@@ -974,6 +1003,8 @@ impl From<PubGrubHint> for PubGrubHintCore {
9741003 workspace,
9751004 } ,
9761005 PubGrubHint :: UncheckedIndex { package, .. } => Self :: UncheckedIndex { package } ,
1006+ PubGrubHint :: UnauthorizedIndex { index } => Self :: UnauthorizedIndex { index } ,
1007+ PubGrubHint :: ForbiddenIndex { index } => Self :: ForbiddenIndex { index } ,
9771008 }
9781009 }
9791010}
@@ -1214,6 +1245,26 @@ impl std::fmt::Display for PubGrubHint {
12141245 "--index-strategy unsafe-best-match" . green( ) ,
12151246 )
12161247 }
1248+ Self :: UnauthorizedIndex { index } => {
1249+ write ! (
1250+ f,
1251+ "{}{} An index URL ({}) could not be queried due to a lack of valid authentication credentials ({})." ,
1252+ "hint" . bold( ) . cyan( ) ,
1253+ ":" . bold( ) ,
1254+ index. redacted( ) . cyan( ) ,
1255+ "401 Unauthorized" . bold( ) . red( ) ,
1256+ )
1257+ }
1258+ Self :: ForbiddenIndex { index } => {
1259+ write ! (
1260+ f,
1261+ "{}{} An index URL ({}) could not be queried due to a lack of valid authentication credentials ({})." ,
1262+ "hint" . bold( ) . cyan( ) ,
1263+ ":" . bold( ) ,
1264+ index. redacted( ) . cyan( ) ,
1265+ "403 Forbidden" . bold( ) . red( ) ,
1266+ )
1267+ }
12171268 }
12181269 }
12191270}
0 commit comments