11import type { Range , Uri } from 'vscode' ;
22import type { AutolinkReference , DynamicAutolinkReference } from '../../autolinks/models/autolinks' ;
3+ import type { Container } from '../../container' ;
4+ import { HostingIntegration } from '../../plus/integrations/integration' ;
5+ import { remoteProviderIdToIntegrationId } from '../../plus/integrations/integrationService' ;
6+ import { parseAzureHttpsUrl } from '../../plus/integrations/providers/azure/models' ;
37import type { Brand , Unbrand } from '../../system/brand' ;
48import type { Repository } from '../models/repository' ;
59import type { GkProviderId } from '../models/repositoryIdentities' ;
@@ -17,7 +21,14 @@ const rangeRegex = /line=(\d+)(?:&lineEnd=(\d+))?/;
1721
1822export class AzureDevOpsRemote extends RemoteProvider {
1923 private readonly project : string | undefined ;
20- constructor ( domain : string , path : string , protocol ?: string , name ?: string , legacy : boolean = false ) {
24+ constructor (
25+ private readonly container : Container ,
26+ domain : string ,
27+ path : string ,
28+ protocol ?: string ,
29+ name ?: string ,
30+ legacy : boolean = false ,
31+ ) {
2132 let repoProject ;
2233 if ( sshDomainRegex . test ( domain ) ) {
2334 path = path . replace ( sshPathRegex , '' ) ;
@@ -182,8 +193,38 @@ export class AzureDevOpsRemote extends RemoteProvider {
182193 return this . encodeUrl ( `${ this . baseUrl } /commit/${ sha } ` ) ;
183194 }
184195
185- protected override getUrlForComparison ( base : string , compare : string , _notation : '..' | '...' ) : string {
186- return this . encodeUrl ( `${ this . baseUrl } /branchCompare?baseVersion=GB${ base } &targetVersion=GB${ compare } ` ) ;
196+ protected override getUrlForComparison ( base : string , head : string , _notation : '..' | '...' ) : string {
197+ return this . encodeUrl ( `${ this . baseUrl } /branchCompare?baseVersion=GB${ base } &targetVersion=GB${ head } ` ) ;
198+ }
199+
200+ protected override async getUrlForCreatePullRequest (
201+ base : { branch ?: string ; remote : { path : string ; url : string } } ,
202+ head : { branch : string ; remote : { path : string ; url : string } } ,
203+ ) : Promise < string | undefined > {
204+ const query = new URLSearchParams ( { sourceRef : head . branch , targetRef : base . branch ?? '' } ) ;
205+ if ( base . remote . url !== head . remote . url ) {
206+ const parsedBaseUrl = parseAzureUrl ( base . remote . url ) ;
207+ if ( parsedBaseUrl == null ) {
208+ return undefined ;
209+ }
210+ const { org : baseOrg , project : baseProject , repo : baseName } = parsedBaseUrl ;
211+ const targetDesc = { project : baseProject , name : baseName , owner : baseOrg } ;
212+
213+ const integrationId = remoteProviderIdToIntegrationId ( this . id ) ;
214+ const integration = integrationId && ( await this . container . integrations . get ( integrationId ) ) ;
215+ let targetRepoId = undefined ;
216+ if ( integration ?. isConnected && integration instanceof HostingIntegration ) {
217+ targetRepoId = ( await integration . getRepoInfo ?.( targetDesc ) ) ?. id ;
218+ }
219+
220+ if ( ! targetRepoId ) {
221+ return undefined ;
222+ }
223+ query . set ( 'targetRepositoryId' , targetRepoId ) ;
224+ // query.set('sourceRepositoryId', compare.repoId); // ?? looks like not needed
225+ }
226+
227+ return `${ this . encodeUrl ( `${ this . getRepoBaseUrl ( head . remote . path ) } /pullrequestcreate` ) } ?${ query . toString ( ) } ` ;
187228 }
188229
189230 protected getUrlForFile ( fileName : string , branch ?: string , sha ?: string , range ?: Range ) : string {
@@ -207,3 +248,22 @@ export class AzureDevOpsRemote extends RemoteProvider {
207248 return this . encodeUrl ( `${ this . baseUrl } ?path=/${ fileName } ${ line } ` ) ;
208249 }
209250}
251+
252+ const azureSshUrlRegex = / ^ (?: [ ^ @ ] + @ ) ? ( [ ^ : ] + ) : v \d \/ / ;
253+ function parseAzureUrl ( url : string ) : { org : string ; project : string ; repo : string } | undefined {
254+ if ( azureSshUrlRegex . test ( url ) ) {
255+ // Examples of SSH urls:
256+ // - old one: [email protected] :v3/bbbchiv/MyFirstProject/test 257+ // - modern one: [email protected] :v3/bbbchiv2/MyFirstProject/test 258+ url = url . replace ( azureSshUrlRegex , '' ) ;
259+ const match = orgAndProjectRegex . exec ( url ) ;
260+ if ( match != null ) {
261+ const [ , org , project , rest ] = match ;
262+ return { org : org , project : project , repo : rest } ;
263+ }
264+ } else {
265+ const [ org , project , rest ] = parseAzureHttpsUrl ( url ) ;
266+ return { org : org , project : project , repo : rest } ;
267+ }
268+ return undefined ;
269+ }
0 commit comments