@@ -79,6 +79,8 @@ func NewProvider(
7979}
8080
8181// CreatePullRequest implements gitprovider.Interface.
82+ const errConvertPullRequestFmt = "error converting pull request %d: %w"
83+
8284func (p * provider ) CreatePullRequest (
8385 ctx context.Context ,
8486 opts * gitprovider.CreatePullRequestOpts ,
@@ -119,7 +121,7 @@ func (p *provider) CreatePullRequest(
119121 }
120122 pr , err := convertADOPullRequest (adoPR )
121123 if err != nil {
122- return nil , fmt .Errorf ("error converting pull request %d: %w" , adoPR .PullRequestId , err )
124+ return nil , fmt .Errorf (errConvertPullRequestFmt , adoPR .PullRequestId , err )
123125 }
124126 return pr , nil
125127}
@@ -143,7 +145,7 @@ func (p *provider) GetPullRequest(
143145 }
144146 pr , err := convertADOPullRequest (adoPR )
145147 if err != nil {
146- return nil , fmt .Errorf ("error converting pull request %d: %w" , id , err )
148+ return nil , fmt .Errorf (errConvertPullRequestFmt , id , err )
147149 }
148150 return pr , nil
149151}
@@ -174,7 +176,7 @@ func (p *provider) ListPullRequests(
174176 for _ , adoPR := range * adoPRs {
175177 pr , err := convertADOPullRequest (& adoPR )
176178 if err != nil {
177- return nil , fmt .Errorf ("error converting pull request %d: %w" , adoPR .PullRequestId , err )
179+ return nil , fmt .Errorf (errConvertPullRequestFmt , adoPR .PullRequestId , err )
178180 }
179181 pts = append (pts , * pr )
180182 }
@@ -218,15 +220,19 @@ func parseRepoURL(repoURL string) (string, string, string, error) {
218220 return parseModernRepoURL (u )
219221 } else if strings .HasSuffix (u .Host , legacyHostSuffix ) {
220222 return parseLegacyRepoURL (u )
223+ } else if strings .Contains (u .Host , ProviderName ) {
224+ return parseSelfHostedRepoUrl (u )
221225 }
222226 return "" , "" , "" , fmt .Errorf ("unsupported host %q" , u .Host )
223227}
224228
229+ const errExtractRepoInfoFmt = "could not extract repository organization, project, and name from URL %q"
230+
225231// parseModernRepoURL parses a modern Azure DevOps repository URL.
226232func parseModernRepoURL (u * url.URL ) (string , string , string , error ) {
227233 parts := strings .Split (u .Path , "/" )
228234 if len (parts ) != 5 {
229- return "" , "" , "" , fmt .Errorf ("could not extract repository organization, project, and name from URL %q" , u )
235+ return "" , "" , "" , fmt .Errorf (errExtractRepoInfoFmt , u )
230236 }
231237 return parts [1 ], parts [2 ], parts [4 ], nil
232238}
@@ -236,7 +242,21 @@ func parseLegacyRepoURL(u *url.URL) (string, string, string, error) {
236242 organization := strings .TrimSuffix (u .Host , ".visualstudio.com" )
237243 parts := strings .Split (u .Path , "/" )
238244 if len (parts ) != 4 {
239- return "" , "" , "" , fmt .Errorf ("could not extract repository organization, project, and name from URL %q" , u )
245+ return "" , "" , "" , fmt .Errorf (errExtractRepoInfoFmt , u )
240246 }
241247 return organization , parts [1 ], parts [3 ], nil
242248}
249+
250+ // parseSelfHostedRepoUrl parses a self hosted Azure DevOps Server URL.
251+ func parseSelfHostedRepoUrl (u * url.URL ) (string , string , string , error ) {
252+ parts := strings .Split (u .Path , "/" )
253+ // Handle the case where the URL is in the format https://<host>/<collection>/<project>/_git/<repo>
254+ if len (parts ) == 5 {
255+ return parts [1 ], parts [2 ], parts [4 ], nil
256+ }
257+ // Handle the case where the URL is in the format https://<host>/tfs/<collection>/<project>/_git/<repo>
258+ if len (parts ) == 6 && parts [1 ] == "tfs" {
259+ return parts [2 ], parts [3 ], parts [5 ], nil
260+ }
261+ return "" , "" , "" , fmt .Errorf (errExtractRepoInfoFmt , u )
262+ }
0 commit comments