Skip to content

Commit dc6cc41

Browse files
jorgeepditommaso
andauthored
Fix azure repos when clone URL is used (#5667) [ci fast]
Signed-off-by: jorgee <jorge.ejarque@seqera.io> Signed-off-by: Jorge Ejarque <jorgee@users.noreply.github.com> Signed-off-by: Paolo Di Tommaso <paolo.ditommaso@gmail.com> Co-authored-by: Paolo Di Tommaso <paolo.ditommaso@gmail.com>
1 parent c10ac5b commit dc6cc41

File tree

4 files changed

+62
-31
lines changed

4 files changed

+62
-31
lines changed

modules/nextflow/src/main/groovy/nextflow/scm/AzureRepositoryProvider.groovy

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,38 @@ final class AzureRepositoryProvider extends RepositoryProvider {
3939
private String continuationToken
4040

4141
AzureRepositoryProvider(String project, ProviderConfig config=null) {
42-
/*
43-
Azure repo format follows Organization/Project/Repository where Project can be optional
44-
If Project is not present then Repository is used as Project (and also as Repository)
45-
*/
4642
this.urlPath = project
47-
def tokens = project.tokenize('/')
43+
def tokens = getUniformPath(project)
4844
this.repo = tokens.removeLast()
49-
if( tokens.size() == 1){
50-
this.project = [tokens.first(), this.repo].join('/')
51-
}else{
52-
this.project = tokens.join('/')
53-
}
45+
this.project = tokens.join('/')
5446
this.config = config ?: new ProviderConfig('azurerepos')
5547
this.continuationToken = null
5648
}
5749

50+
/**
51+
* An Azure repo is identified with the Organization/Project/Repository parameters.
52+
* This function gets these parameters for the different URL path formats supported in Nextflow for Azure repositories.
53+
*
54+
* @param urlPath Path of the Azure repo URL
55+
* @return List with the azure repo parameters with the following order [ Organization, Project, Repository ]
56+
*/
57+
static List<String> getUniformPath(String urlPath){
58+
def tokens = urlPath.tokenize('/')
59+
if( tokens.size() == 2 ){
60+
// URL is just organization/project. project and repo are the same.
61+
return [tokens[0], tokens[1], tokens[1]]
62+
}
63+
if( tokens.size() == 3 ){
64+
// URL is as expected organization/project/repository.
65+
return tokens
66+
}
67+
if( tokens.size() == 4 && tokens[2] == '_git' ){
68+
// Clone URL organization/project/_git/repository
69+
return [tokens[0], tokens[1], tokens[3]]
70+
}
71+
throw new IllegalArgumentException("Unexpected Azure repository path format - offending value: '$urlPath'")
72+
}
73+
5874
/** {@inheritDoc} */
5975
@Override
6076
String getName() { "Azure Repos" }

modules/nextflow/src/main/groovy/nextflow/scm/ProviderConfig.groovy

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,7 @@ class ProviderConfig {
362362
}
363363

364364
if( server == 'https://dev.azure.com' ) {
365-
final parts = project.tokenize('/')
366-
if( parts[2]=='_git' )
367-
project = "${parts[0]}/${parts[1]}"
365+
project = AzureRepositoryProvider.getUniformPath(project).join('/')
368366
}
369367

370368
return project.stripStart('/')

modules/nextflow/src/test/groovy/nextflow/scm/AzureRepositoryProviderTest.groovy

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,45 +42,61 @@ class AzureRepositoryProviderTest extends Specification {
4242
}
4343
'''
4444

45-
def 'should return repo url' () {
45+
def 'should parse repo fields from path' () {
46+
expect:
47+
AzureRepositoryProvider.getUniformPath(PATH) == EXPECTED
4648

47-
given:
48-
def config = new ConfigSlurper().parse(CONFIG)
49-
def obj = new ProviderConfig('azurerepos', config.providers.azurerepos as ConfigObject)
49+
where:
50+
PATH | EXPECTED
51+
't-neumann/hello' | ['t-neumann', 'hello', 'hello']
52+
'ORGANIZATION/PROJECT/hello' | ['ORGANIZATION','PROJECT','hello']
53+
'ORGANIZATION/PROJECT/_git/hello' | ['ORGANIZATION','PROJECT','hello']
5054

51-
expect:
52-
new AzureRepositoryProvider('t-neumann/hello', obj).getEndpointUrl() == 'https://dev.azure.com/t-neumann/hello/_apis/git/repositories/hello'
5355
}
5456

55-
def 'should return repo with organization url' () {
57+
def 'should throw exception if wrong path' () {
58+
when:
59+
def path = AzureRepositoryProvider.getUniformPath(PATH)
5660

57-
given:
58-
def config = new ConfigSlurper().parse(CONFIG)
59-
def obj = new ProviderConfig('azurerepos', config.providers.azurerepos as ConfigObject)
61+
then :
62+
def exception = thrown(IllegalArgumentException)
63+
exception?.message == EXCEPTION
6064

61-
expect:
62-
new AzureRepositoryProvider('ORGANIZATION/PROJECT/hello', obj).getEndpointUrl() == 'https://dev.azure.com/ORGANIZATION/PROJECT/_apis/git/repositories/hello'
65+
where:
66+
PATH | EXCEPTION
67+
'incorrect_path_1' | "Unexpected Azure repository path format - offending value: 'incorrect_path_1'"
68+
'ORG/PROJ/hello/incorrect' | "Unexpected Azure repository path format - offending value: 'ORG/PROJ/hello/incorrect'"
6369
}
6470

65-
def 'should return project URL' () {
71+
def 'should return repo url' () {
6672

6773
given:
6874
def config = new ConfigSlurper().parse(CONFIG)
6975
def obj = new ProviderConfig('azurerepos', config.providers.azurerepos as ConfigObject)
7076

7177
expect:
72-
new AzureRepositoryProvider('t-neumann/hello', obj).getRepositoryUrl() == 'https://dev.azure.com/t-neumann/hello'
78+
new AzureRepositoryProvider(PATH, obj).getEndpointUrl() == EXPECTED
7379

80+
where:
81+
PATH | EXPECTED
82+
't-neumann/hello' | 'https://dev.azure.com/t-neumann/hello/_apis/git/repositories/hello'
83+
'ORGANIZATION/PROJECT/hello' | 'https://dev.azure.com/ORGANIZATION/PROJECT/_apis/git/repositories/hello'
84+
'ORGANIZATION/PROJECT/_git/hello' | 'https://dev.azure.com/ORGANIZATION/PROJECT/_apis/git/repositories/hello'
7485
}
7586

76-
def 'should return project with organization URL' () {
87+
def 'should return project URL' () {
7788

7889
given:
7990
def config = new ConfigSlurper().parse(CONFIG)
8091
def obj = new ProviderConfig('azurerepos', config.providers.azurerepos as ConfigObject)
8192

8293
expect:
83-
new AzureRepositoryProvider('ORGANIZATION/PROJECT/hello', obj).getRepositoryUrl() == 'https://dev.azure.com/ORGANIZATION/PROJECT/hello'
94+
new AzureRepositoryProvider(PATH, obj).getRepositoryUrl() == EXPECTED
95+
where:
96+
PATH | EXPECTED
97+
't-neumann/hello' | 'https://dev.azure.com/t-neumann/hello'
98+
'ORGANIZATION/PROJECT/hello' | 'https://dev.azure.com/ORGANIZATION/PROJECT/hello'
99+
'ORGANIZATION/PROJECT/_git/hello' | 'https://dev.azure.com/ORGANIZATION/PROJECT/_git/hello'
84100

85101
}
86102

modules/nextflow/src/test/groovy/nextflow/scm/ProviderConfigTest.groovy

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,9 @@ class ProviderConfigTest extends Specification {
238238
'a/b/c' | 'http://dot.com/a' | 'b/c'
239239
'a/b/c' | 'http://dot.com/a/' | 'b/c'
240240
and:
241-
'paolo0758/nf-azure-repo' | 'https://dev.azure.com' | 'paolo0758/nf-azure-repo'
242-
'paolo0758/nf-azure-repo/_git/nf-azure-repo' | 'https://dev.azure.com' | 'paolo0758/nf-azure-repo'
241+
'paolo0758/nf-azure-repo' | 'https://dev.azure.com' | 'paolo0758/nf-azure-repo/nf-azure-repo'
242+
'paolo0758/nf-azure-repo/_git/nf-azure-repo' | 'https://dev.azure.com' | 'paolo0758/nf-azure-repo/nf-azure-repo'
243+
'paolo0758/nf-azure-repo/_git/another-azure-repo' | 'https://dev.azure.com' | 'paolo0758/nf-azure-repo/another-azure-repo'
243244
}
244245

245246
}

0 commit comments

Comments
 (0)