@@ -25,6 +25,8 @@ public abstract class GetSourceLinkUrlGitTask : Task
2525 /// </summary>
2626 public ITaskItem [ ] Hosts { get ; set ; }
2727
28+ public string ImplicitHost { get ; set ; }
29+
2830 [ Output ]
2931 public string SourceLinkUrl { get ; set ; }
3032
@@ -126,35 +128,52 @@ private IEnumerable<UrlMapping> GetUrlMappings()
126128 bool isValidContentUri ( Uri uri )
127129 => uri . Query == "" && uri . UserInfo == "" ;
128130
129- if ( Hosts == null )
130- {
131- yield break ;
132- }
131+ bool tryParseAuthority ( string value , out Uri uri )
132+ => Uri . TryCreate ( "unknown://" + value , UriKind . Absolute , out uri ) && IsAuthorityUri ( uri ) ;
133133
134- foreach ( var item in Hosts )
135- {
136- string authority = item . ItemSpec ;
134+ Uri getDefaultUri ( string authority )
135+ => GetDefaultContentUri ( new Uri ( "https://" + authority , UriKind . Absolute ) ) ;
137136
138- if ( ! Uri . TryCreate ( "unknown://" + authority , UriKind . Absolute , out var authorityUri ) || ! IsAuthorityUri ( authorityUri ) )
137+ if ( Hosts != null )
138+ {
139+ foreach ( var item in Hosts )
139140 {
140- Log . LogError ( CommonResources . ValuePassedToTaskParameterNotValidDomainName , nameof ( Hosts ) , item . ItemSpec ) ;
141- continue ;
141+ string authority = item . ItemSpec ;
142+
143+ if ( ! tryParseAuthority ( authority , out var authorityUri ) )
144+ {
145+ Log . LogError ( CommonResources . ValuePassedToTaskParameterNotValidDomainName , nameof ( Hosts ) , item . ItemSpec ) ;
146+ continue ;
147+ }
148+
149+ Uri contentUri ;
150+ string contentUrl = item . GetMetadata ( ContentUrlMetadataName ) ;
151+ bool hasDefaultContentUri = string . IsNullOrEmpty ( contentUrl ) ;
152+ if ( hasDefaultContentUri )
153+ {
154+ contentUri = getDefaultUri ( authority ) ;
155+ }
156+ else if ( ! Uri . TryCreate ( contentUrl , UriKind . Absolute , out contentUri ) || ! isValidContentUri ( contentUri ) )
157+ {
158+ Log . LogError ( CommonResources . ValuePassedToTaskParameterNotValidHostUri , nameof ( Hosts ) , contentUrl ) ;
159+ continue ;
160+ }
161+
162+ yield return new UrlMapping ( authorityUri , contentUri , hasDefaultContentUri ) ;
142163 }
164+ }
143165
144- Uri contentUri ;
145- string contentUrl = item . GetMetadata ( ContentUrlMetadataName ) ;
146- bool hasDefaultContentUri = string . IsNullOrEmpty ( contentUrl ) ;
147- if ( hasDefaultContentUri )
166+ // Add implicit host last, so that matching prefers explicitly listed hosts over the implicit one.
167+ if ( ! string . IsNullOrEmpty ( ImplicitHost ) )
168+ {
169+ if ( tryParseAuthority ( ImplicitHost , out var authorityUri ) )
148170 {
149- contentUri = GetDefaultContentUri ( new Uri ( "https://" + authority , UriKind . Absolute ) ) ;
171+ yield return new UrlMapping ( authorityUri , getDefaultUri ( ImplicitHost ) , hasDefaultContentUri : true ) ;
150172 }
151- else if ( ! Uri . TryCreate ( contentUrl , UriKind . Absolute , out contentUri ) || ! isValidContentUri ( contentUri ) )
173+ else
152174 {
153- Log . LogError ( CommonResources . ValuePassedToTaskParameterNotValidHostUri , nameof ( Hosts ) , contentUrl ) ;
154- continue ;
175+ Log . LogError ( CommonResources . ValuePassedToTaskParameterNotValidDomainName , nameof ( ImplicitHost ) , ImplicitHost ) ;
155176 }
156-
157- yield return new UrlMapping ( authorityUri , contentUri , hasDefaultContentUri ) ;
158177 }
159178 }
160179
0 commit comments