1
1
import type { Range , Uri } from 'vscode' ;
2
2
import 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' ;
3
6
import type { Brand , Unbrand } from '../../system/brand' ;
4
7
import type { Repository } from '../models/repository' ;
5
8
import type { GkProviderId } from '../models/repositoryIdentities' ;
@@ -11,7 +14,14 @@ const fileRegex = /^\/([^/]+)\/([^/]+?)\/src(.+)$/i;
11
14
const rangeRegex = / ^ l i n e s - ( \d + ) (?: : ( \d + ) ) ? $ / ;
12
15
13
16
export class BitbucketServerRemote extends RemoteProvider {
14
- constructor ( domain : string , path : string , protocol ?: string , name ?: string , custom : boolean = false ) {
17
+ constructor (
18
+ private readonly container : Container ,
19
+ domain : string ,
20
+ path : string ,
21
+ protocol ?: string ,
22
+ name ?: string ,
23
+ custom : boolean = false ,
24
+ ) {
15
25
super ( domain , path , protocol , name , custom ) ;
16
26
}
17
27
@@ -54,14 +64,12 @@ export class BitbucketServerRemote extends RemoteProvider {
54
64
return `${ this . protocol } ://${ this . domain } /projects/${ project } /repos/${ repo } ` ;
55
65
}
56
66
57
- protected override splitPath ( ) : [ string , string ] {
58
- if ( this . path . startsWith ( 'scm/' ) && this . path . indexOf ( '/' ) !== this . path . lastIndexOf ( '/' ) ) {
59
- const path = this . path . replace ( 'scm/' , '' ) ;
60
- const index = path . indexOf ( '/' ) ;
61
- return [ path . substring ( 0 , index ) , path . substring ( index + 1 ) ] ;
67
+ protected override splitArgPath ( argPath : string ) : [ string , string ] {
68
+ if ( argPath . startsWith ( 'scm/' ) && argPath . indexOf ( '/' ) !== argPath . lastIndexOf ( '/' ) ) {
69
+ return super . splitArgPath ( argPath . replace ( 'scm/' , '' ) ) ;
62
70
}
63
71
64
- return super . splitPath ( ) ;
72
+ return super . splitArgPath ( argPath ) ;
65
73
}
66
74
67
75
override get icon ( ) : string {
@@ -158,25 +166,48 @@ export class BitbucketServerRemote extends RemoteProvider {
158
166
}
159
167
160
168
protected override getUrlForComparison ( base : string , head : string , _notation : '..' | '...' ) : string {
161
- return this . encodeUrl ( `${ this . baseUrl } /branches/compare/${ base } %0D ${ head } ` ) . replaceAll ( '%250D' , '%0D' ) ;
169
+ return this . encodeUrl ( `${ this . baseUrl } /branches/compare/${ head } \r ${ base } ` ) ;
162
170
}
163
171
164
- protected override getUrlForCreatePullRequest (
172
+ override async isReadyForForCrossForkPullRequestUrls ( ) : Promise < boolean > {
173
+ const integrationId = remoteProviderIdToIntegrationId ( this . id ) ;
174
+ const integration = integrationId && ( await this . container . integrations . get ( integrationId ) ) ;
175
+ return integration ?. maybeConnected ?? integration ?. isConnected ( ) ?? false ;
176
+ }
177
+
178
+ protected override async getUrlForCreatePullRequest (
165
179
base : { branch ?: string ; remote : { path : string ; url : string } } ,
166
180
head : { branch : string ; remote : { path : string ; url : string } } ,
167
181
options ?: { title ?: string ; description ?: string } ,
168
- ) : string | undefined {
182
+ ) : Promise < string | undefined > {
169
183
const query = new URLSearchParams ( { sourceBranch : head . branch , targetBranch : base . branch ?? '' } ) ;
170
- // TODO: figure this out
171
- // query.set('targetRepoId', base.repoId);
184
+ const [ baseOwner , baseName ] = this . splitArgPath ( base . remote . path ) ;
185
+ if ( base . remote . url !== head . remote . url ) {
186
+ const targetDesc = {
187
+ owner : baseOwner ,
188
+ name : baseName ,
189
+ } ;
190
+ const integrationId = remoteProviderIdToIntegrationId ( this . id ) ;
191
+ const integration = integrationId && ( await this . container . integrations . get ( integrationId ) ) ;
192
+ let targetRepoId = undefined ;
193
+ if ( integration ?. isConnected && integration instanceof HostingIntegration ) {
194
+ targetRepoId = ( await integration . getRepoInfo ?.( targetDesc ) ) ?. id ;
195
+ }
196
+ if ( ! targetRepoId ) {
197
+ return undefined ;
198
+ }
199
+ query . set ( 'targetRepoId' , targetRepoId ) ;
200
+ }
172
201
if ( options ?. title ) {
173
202
query . set ( 'title' , options . title ) ;
174
203
}
175
204
if ( options ?. description ) {
176
205
query . set ( 'description' , options . description ) ;
177
206
}
178
-
179
- return `${ this . encodeUrl ( `${ this . baseUrl } /pull-requests?create` ) } &${ query . toString ( ) } ` ;
207
+ const [ headOwner , headName ] = this . splitArgPath ( head . remote . path ) ;
208
+ return `${ this . encodeUrl (
209
+ `${ this . protocol } ://${ this . domain } /projects/${ headOwner } /repos/${ headName } /pull-requests?create` ,
210
+ ) } &${ query . toString ( ) } `;
180
211
}
181
212
182
213
protected getUrlForFile ( fileName : string , branch ?: string , sha ?: string , range ?: Range ) : string {
0 commit comments