diff --git a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/ScmContext.groovy b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/ScmContext.groovy index f18a5b907..c1e843e24 100644 --- a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/ScmContext.groovy +++ b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/ScmContext.groovy @@ -229,7 +229,7 @@ class ScmContext extends AbstractExtensibleContext { */ @RequiresPlugin(id = 'subversion', minimumVersion = '2.8') void svn(@DslContext(SvnContext) Closure svnClosure) { - SvnContext svnContext = new SvnContext(jobManagement) + SvnContext svnContext = new SvnContext(jobManagement, item) executeInContext(svnClosure, svnContext) checkState(!svnContext.locations.empty, 'One or more locations must be specified') @@ -244,6 +244,10 @@ class ScmContext extends AbstractExtensibleContext { excludedRevprop(svnContext.excludedRevisionProperty ?: '') } + if (svnContext.svnBrowserContext.browser) { + svnNode.children().add(svnContext.svnBrowserContext.browser) + } + ContextHelper.executeConfigureBlock(svnNode, svnContext.configureBlock) scmNodes << svnNode diff --git a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/scm/SvnBrowserContext.groovy b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/scm/SvnBrowserContext.groovy new file mode 100644 index 000000000..28671c6f8 --- /dev/null +++ b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/scm/SvnBrowserContext.groovy @@ -0,0 +1,135 @@ +package javaposse.jobdsl.dsl.helpers.scm + +import javaposse.jobdsl.dsl.AbstractExtensibleContext +import javaposse.jobdsl.dsl.ContextHelper +import javaposse.jobdsl.dsl.ContextType +import javaposse.jobdsl.dsl.Item +import javaposse.jobdsl.dsl.JobManagement + +@ContextType('hudson.scm.RepositoryBrowser') +class SvnBrowserContext extends AbstractExtensibleContext { + Node browser + + protected SvnBrowserContext(JobManagement jobManagement, Item item) { + super(jobManagement, item) + } + + /** + * Use Assembla as repository browser. + * + * @since 1.78 + */ + void assembla(String spaceName) { + browser = NodeBuilder.newInstance().browser(class: 'hudson.scm.browsers.Assembla') { + delegate.spaceName(spaceName) + } + } + + /** + * Use CollabNet SVN as repository browser. + * + * @since 1.78 + */ + void collabNetSVN(String url) { + browser = NodeBuilder.newInstance().browser(class: 'hudson.scm.browsers.CollabNetSVN') { + delegate.url(url) + } + } + + /** + * Use FishEye SVN as repository browser. + * + * @since 1.78 + */ + void fishEyeSVN(String url, String rootModule) { + browser = NodeBuilder.newInstance().browser(class: 'hudson.scm.browsers.FishEyeSVN') { + delegate.url(url) + delegate.rootModule(rootModule) + } + } + + /** + * Use Phabricator as repository browser. + * + * @since 1.78 + */ + void phabricator(String url, String repo) { + browser = NodeBuilder.newInstance().browser(class: 'hudson.scm.browsers.Phabricator') { + delegate.url(url) + delegate.repo(repo) + } + } + + /** + * Use Sventon as repository browser. + * + * @since 1.78 + */ + void sventon(String url, String repositoryInstance) { + browser = NodeBuilder.newInstance().browser(class: 'hudson.scm.browsers.Sventon') { + delegate.url(url) + delegate.repositoryInstance(repositoryInstance) + } + } + + /** + * Use Sventon2 as repository browser. + * + * @since 1.78 + */ + void sventon2(String url, String repositoryInstance) { + browser = NodeBuilder.newInstance().browser(class: 'hudson.scm.browsers.Sventon2') { + delegate.url(url) + delegate.repositoryInstance(repositoryInstance) + } + } + + /** + * Use SVN::Web as repository browser. + * + * @since 1.78 + */ + void svnWeb(String url) { + browser = NodeBuilder.newInstance().browser(class: 'hudson.scm.browsers.SVNWeb') { + delegate.url(url) + } + } + + /** + * Use ViewSVN as repository browser. + * + * @since 1.78 + */ + void viewSVN(String url) { + browser = NodeBuilder.newInstance().browser(class: 'hudson.scm.browsers.ViewSVN') { + delegate.url(url) + } + } + + /** + * Use VisualSVN as repository browser. + * + * @since 1.78 + */ + void visualSVN(String url) { + browser = NodeBuilder.newInstance().browser(class: 'hudson.scm.browsers.VisualSVN') { + delegate.url(url) + } + } + + /** + * Use WebSVN as repository browser. + * + * @since 1.78 + */ + void webSVN(String url) { + browser = NodeBuilder.newInstance().browser(class: 'hudson.scm.browsers.WebSVN') { + delegate.url(url) + } + } + + @Override + protected void addExtensionNode(Node node) { + browser = ContextHelper.toNamedNode('browser', node) + } +} diff --git a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/scm/SvnContext.groovy b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/scm/SvnContext.groovy index 3c78b8ccc..f0a957b64 100644 --- a/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/scm/SvnContext.groovy +++ b/job-dsl-core/src/main/groovy/javaposse/jobdsl/dsl/helpers/scm/SvnContext.groovy @@ -3,9 +3,14 @@ package javaposse.jobdsl.dsl.helpers.scm import javaposse.jobdsl.dsl.AbstractContext import javaposse.jobdsl.dsl.ContextHelper import javaposse.jobdsl.dsl.DslContext +import javaposse.jobdsl.dsl.Item import javaposse.jobdsl.dsl.JobManagement +import static javaposse.jobdsl.dsl.ContextHelper.executeInContext + class SvnContext extends AbstractContext { + private final Item item + List locations = [] SvnCheckoutStrategy checkoutStrategy = SvnCheckoutStrategy.UPDATE List excludedRegions = [] @@ -14,9 +19,11 @@ class SvnContext extends AbstractContext { List excludedCommitMessages = [] String excludedRevisionProperty Closure configureBlock + final SvnBrowserContext svnBrowserContext = new SvnBrowserContext(jobManagement, item) - SvnContext(JobManagement jobManagement) { + SvnContext(JobManagement jobManagement, Item item) { super(jobManagement) + this.item = item } /** @@ -134,6 +141,15 @@ class SvnContext extends AbstractContext { excludedRevisionProperty = revisionProperty } + /** + * Adds a repository browser for browsing the details of changes in an external system. + * + * @since 1.78 + */ + void browser(@DslContext(SvnBrowserContext) Closure svnBrowserClosure) { + executeInContext(svnBrowserClosure, svnBrowserContext) + } + /** * Sets a closure to be called when the XML node structure is created. * The SVN node is passed to the closure as the first parameter. diff --git a/job-dsl-core/src/test/groovy/javaposse/jobdsl/dsl/helpers/ScmContextSpec.groovy b/job-dsl-core/src/test/groovy/javaposse/jobdsl/dsl/helpers/ScmContextSpec.groovy index 3fb671811..d57279297 100644 --- a/job-dsl-core/src/test/groovy/javaposse/jobdsl/dsl/helpers/ScmContextSpec.groovy +++ b/job-dsl-core/src/test/groovy/javaposse/jobdsl/dsl/helpers/ScmContextSpec.groovy @@ -1280,6 +1280,163 @@ class ScmContextSpec extends Specification { (1.._) * mockJobManagement.requireMinimumPluginVersion('subversion', '2.8') } + def 'call svn with Assembla browser'() { + when: + context.svn { + location('url') + browser { + assembla('example') + } + } + + then: + context.scmNodes[0] != null + context.scmNodes[0].browser.size() == 1 + context.scmNodes[0].browser[0].attribute('class') == 'hudson.scm.browsers.Assembla' + context.scmNodes[0].browser[0].'spaceName'[0].value() == 'example' + (1.._) * mockJobManagement.requireMinimumPluginVersion('subversion', '2.8') + } + + def 'call svn with CollabNet SVN browser'() { + when: + context.svn { + location('url') + browser { + collabNetSVN('https://myproject.dev.java.net/source/browse/example') + } + } + + then: + context.scmNodes[0] != null + context.scmNodes[0].browser.size() == 1 + context.scmNodes[0].browser[0].attribute('class') == 'hudson.scm.browsers.CollabNetSVN' + context.scmNodes[0].browser[0].'url'[0].value() == 'https://myproject.dev.java.net/source/browse/example' + (1.._) * mockJobManagement.requireMinimumPluginVersion('subversion', '2.8') + } + + def 'call svn with FishEye SVN browser'() { + when: + context.svn { + location('url') + browser { + fishEyeSVN('http://fisheye5.cenqua.com/browse/example/', 'foo/bar') + } + } + + then: + context.scmNodes[0] != null + context.scmNodes[0].browser.size() == 1 + context.scmNodes[0].browser[0].attribute('class') == 'hudson.scm.browsers.FishEyeSVN' + context.scmNodes[0].browser[0].'url'[0].value() == 'http://fisheye5.cenqua.com/browse/example/' + context.scmNodes[0].browser[0].'rootModule'[0].value() == 'foo/bar' + (1.._) * mockJobManagement.requireMinimumPluginVersion('subversion', '2.8') + } + + def 'call svn with Phabricator browser'() { + when: + context.svn { + location('url') + browser { + phabricator('http://svn.apache.org/wsvn/', 'example') + } + } + + then: + context.scmNodes[0] != null + context.scmNodes[0].browser.size() == 1 + context.scmNodes[0].browser[0].attribute('class') == 'hudson.scm.browsers.Phabricator' + context.scmNodes[0].browser[0].'url'[0].value() == 'http://svn.apache.org/wsvn/' + context.scmNodes[0].browser[0].'repo'[0].value() == 'example' + (1.._) * mockJobManagement.requireMinimumPluginVersion('subversion', '2.8') + } + + def 'call svn with Sventon browser'() { + when: + context.svn { + location('url') + browser { + sventon('http://mycompany/svn/', 'example') + } + } + + then: + context.scmNodes[0] != null + context.scmNodes[0].browser.size() == 1 + context.scmNodes[0].browser[0].attribute('class') == 'hudson.scm.browsers.Sventon' + context.scmNodes[0].browser[0].'url'[0].value() == 'http://mycompany/svn/' + context.scmNodes[0].browser[0].'repositoryInstance'[0].value() == 'example' + (1.._) * mockJobManagement.requireMinimumPluginVersion('subversion', '2.8') + } + + def 'call svn with Sventon2 browser'() { + when: + context.svn { + location('url') + browser { + sventon2('http://mycompany/svn2/', 'example') + } + } + + then: + context.scmNodes[0] != null + context.scmNodes[0].browser.size() == 1 + context.scmNodes[0].browser[0].attribute('class') == 'hudson.scm.browsers.Sventon2' + context.scmNodes[0].browser[0].'url'[0].value() == 'http://mycompany/svn2/' + context.scmNodes[0].browser[0].'repositoryInstance'[0].value() == 'example' + (1.._) * mockJobManagement.requireMinimumPluginVersion('subversion', '2.8') + } + + def 'call svn with SVN::Web browser'() { + when: + context.svn { + location('url') + browser { + svnWeb('http://svn.apache.org/wsvn/') + } + } + + then: + context.scmNodes[0] != null + context.scmNodes[0].browser.size() == 1 + context.scmNodes[0].browser[0].attribute('class') == 'hudson.scm.browsers.SVNWeb' + context.scmNodes[0].browser[0].'url'[0].value() == 'http://svn.apache.org/wsvn/' + (1.._) * mockJobManagement.requireMinimumPluginVersion('subversion', '2.8') + } + + def 'call svn with ViewSVN browser'() { + when: + context.svn { + location('url') + browser { + viewSVN('http://mycompany.com/viewsvn/repo_name') + } + } + + then: + context.scmNodes[0] != null + context.scmNodes[0].browser.size() == 1 + context.scmNodes[0].browser[0].attribute('class') == 'hudson.scm.browsers.ViewSVN' + context.scmNodes[0].browser[0].'url'[0].value() == 'http://mycompany.com/viewsvn/repo_name' + (1.._) * mockJobManagement.requireMinimumPluginVersion('subversion', '2.8') + } + + def 'call svn with WebSVN browser'() { + when: + context.svn { + location('url') + browser { + webSVN('http://mycompany.com/websvn/') + } + } + + then: + context.scmNodes[0] != null + context.scmNodes[0].browser.size() == 1 + context.scmNodes[0].browser[0].attribute('class') == 'hudson.scm.browsers.WebSVN' + context.scmNodes[0].browser[0].'url'[0].value() == 'http://mycompany.com/websvn/' + (1.._) * mockJobManagement.requireMinimumPluginVersion('subversion', '2.8') + } + def 'call svn with no locations'() { when: context.svn {