@@ -24,7 +24,7 @@ public async Task<bool> DownloadAsync(Uri uri, string outputFile)
2424 try
2525 {
2626 using var xa = XRefArchive . Open ( outputFile , XRefArchiveMode . Create ) ;
27- await DownloadCoreAsync ( uri , xa , true ) ;
27+ await DownloadCoreAsync ( uri , xa ) ;
2828 }
2929 catch ( Exception ex )
3030 {
@@ -36,88 +36,42 @@ public async Task<bool> DownloadAsync(Uri uri, string outputFile)
3636 }
3737 }
3838
39- private async Task < string > DownloadCoreAsync ( Uri uri , XRefArchive xa , bool isMajor )
39+ private async Task < string > DownloadCoreAsync ( Uri uri , XRefArchive xa )
4040 {
4141 IXRefContainer container ;
4242 container = await _downloader . DownloadAsync ( uri ) ;
4343 if ( container is not XRefMap map )
4444 {
45- // not support download an xref archive, or reference to an xref archive
45+ // XRefArchive is not supported by `docfx download`.
46+ Logger . LogWarning ( $ "Download an xref archive, or reference to an xref archive is not supported. URI: { uri } ") ;
4647 return null ;
4748 }
48- if ( map . Redirections ? . Count > 0 )
49- {
50- await RewriteRedirections ( uri , xa , map ) ;
51- }
52- if ( map . References ? . Count > 0 && map . HrefUpdated != true )
53- {
54- if ( string . IsNullOrEmpty ( map . BaseUrl ) )
55- {
56- XRefMapDownloader . UpdateHref ( map , uri ) ;
57- }
58- }
59- lock ( _syncRoot )
60- {
61- if ( isMajor )
62- {
63- return xa . CreateMajor ( map ) ;
64- }
65- else
66- {
67- return xa . CreateMinor ( map , GetNames ( uri , map ) ) ;
68- }
69- }
70- }
7149
72- private static IEnumerable < string > GetNames ( Uri uri , XRefMap map )
73- {
74- var name = uri . Segments . LastOrDefault ( ) ;
75- yield return name ;
76- if ( map . References ? . Count > 0 )
50+ // If BaseUrl is not set. Use xrefmap file download url as basePath.
51+ if ( string . IsNullOrEmpty ( map . BaseUrl ) )
7752 {
78- yield return map . References [ 0 ] . Uid ;
53+ var baseUrl = uri . GetLeftPart ( UriPartial . Path ) ;
54+ baseUrl = baseUrl . Substring ( 0 , baseUrl . LastIndexOf ( '/' ) + 1 ) ;
55+ map . BaseUrl = baseUrl ;
56+ map . UpdateHref ( new Uri ( baseUrl ) ) ; // Update hrefs from relative to absolute url.
57+ map . HrefUpdated = null ; // Don't save this flag for downloaded XRefMap.
7958 }
80- }
81-
82- #region Rewrite redirections
8359
84- private async Task < List < XRefMapRedirection > > RewriteRedirections ( Uri uri , XRefArchive xa , XRefMap map ) =>
85- ( from list in
86- await Task . WhenAll (
87- from r in map . Redirections
88- where ! string . IsNullOrEmpty ( r . Href )
89- group r by r . Href into g
90- let href = GetHrefUri ( uri , g . Key )
91- where href != null
92- select RewriteRedirectionsCore ( g . ToList ( ) , href , xa ) )
93- from r in list
94- orderby ( r . UidPrefix ?? string . Empty ) . Length descending, ( r . UidPrefix ?? string . Empty )
95- select r ) . ToList ( ) ;
96-
97- private async Task < List < XRefMapRedirection > > RewriteRedirectionsCore ( List < XRefMapRedirection > redirections , Uri uri , XRefArchive xa )
98- {
99- var fileRef = await DownloadCoreAsync ( uri , xa , false ) ;
100- if ( fileRef == null )
60+ // Enforce XRefMap's references are sorted by uid.
61+ // Note:
62+ // Sort is not needed if `map.Sorted == true`.
63+ // But there are some xrefmap files that is not propery sorted by using InvariantCulture.
64+ // (e.g. Unity xrefmap that maintained by community)
65+ if ( map . References != null && map . References . Count > 0 )
10166 {
102- return new List < XRefMapRedirection > ( ) ;
67+ map . References . Sort ( XRefSpecUidComparer . Instance ) ;
68+ map . Sorted = true ;
10369 }
104- return ( from r in redirections
105- select new XRefMapRedirection { UidPrefix = r . UidPrefix , Href = fileRef } ) . ToList ( ) ;
106- }
10770
108- private static Uri GetHrefUri ( Uri uri , string href )
109- {
110- if ( ! Uri . TryCreate ( href , UriKind . RelativeOrAbsolute , out Uri hrefUri ) )
111- {
112- Logger . LogWarning ( $ "Invalid redirection href: { href } .") ;
113- return null ;
114- }
115- if ( ! hrefUri . IsAbsoluteUri )
71+ // Write XRefMap content to `xrefmap.yml`.
72+ lock ( _syncRoot )
11673 {
117- hrefUri = new Uri ( uri , hrefUri ) ;
74+ return xa . CreateMajor ( map ) ;
11875 }
119- return hrefUri ;
12076 }
121-
122- #endregion
12377}
0 commit comments