au.com.ish.gradle.SvnService.groovy Maven / Gradle / Ivy
/*
* Copyright 2012 ish group pty ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package au.com.ish.gradle
import au.com.ish.gradle.SCMService
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.tmatesoft.svn.core.SVNDirEntry
import org.tmatesoft.svn.core.SVNURL
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl
import org.tmatesoft.svn.core.internal.util.SVNPathUtil
import org.tmatesoft.svn.core.io.SVNRepository
import org.tmatesoft.svn.core.io.SVNRepositoryFactory
import org.tmatesoft.svn.core.wc.ISVNOptions;
import org.tmatesoft.svn.core.wc.SVNClientManager
import org.tmatesoft.svn.core.wc.SVNCopySource
import org.tmatesoft.svn.core.wc.SVNInfo
import org.tmatesoft.svn.core.wc.SVNRevision
import org.tmatesoft.svn.core.wc.SVNStatus
import org.tmatesoft.svn.core.wc.SVNWCUtil
import org.tmatesoft.svn.util.SVNDebugLog
class SvnService extends SCMService {
def private Project project
def private SVNStatus wcStatus;
def private svnClientManager
private SVNRepository svnRepo;
SvnService() {
//private constructor only used for tests
}
SvnService(Project project) {
this.project = project;
project.logger.info("Creating SvnService for $project")
// Don't let svnkit try to upgrade the working copy version when it creates a tag
System.setProperty("svnkit.upgradeWC", "false");
// do some basic setup
SVNRepositoryFactoryImpl.setup();
FSRepositoryFactory.setup();
DAVRepositoryFactory.setup();
//set an auth manager which will provide user credentials
project.logger.info("SvnService authentication manager setup")
def ISVNAuthenticationManager authManager
if (scmCreditenialsProvided()) {
project.logger.lifecycle("Release plugin is using subversion scm with provided authentication details (user "+project.extensions.release.username+")")
authManager= SVNWCUtil.createDefaultAuthenticationManager(project.extensions.release.username, project.extensions.release.password);
} else {
project.logger.lifecycle("Release plugin is using subversion scm with authentication details from svn config")
authManager= SVNWCUtil.createDefaultAuthenticationManager();
}
// make sure the credentials are sent, do not wait for the server to require them
authManager.setAuthenticationForced(true);
// svn client manager has to be defined with authManager, otherwise it will use the default one (important for the performTagging)
project.logger.info("Creating SvnClient")
ISVNOptions options = SVNWCUtil.createDefaultOptions(true);
svnClientManager = SVNClientManager.newInstance(options, authManager);
project.logger.info("Getting working copy status")
wcStatus = svnClientManager.getStatusClient().doStatus(project.projectDir,false)
project.logger.info("Got svn version: "+getSCMVersion())
//not sure if the code below is required
def svnRepo = SVNRepositoryFactory.create(wcStatus.getURL())
svnRepo.setAuthenticationManager(authManager);
}
def boolean scmCreditenialsProvided() {
def boolean userDefined = project.extensions.release.username != null && project.extensions.release.username.length() > 0
def boolean passwordDefined = project.extensions.release.password != null && project.extensions.release.password.length() > 0
return userDefined && passwordDefined
}
def boolean localIsAheadOfRemote() {
return false
}
def boolean hasLocalModifications() {
def repoStatus = new UpToDateChecker()
svnClientManager.getStatusClient().doStatus(project.rootDir, true, false, false, false, repoStatus)
return repoStatus.hasModifications()
}
def boolean remoteIsAheadOfLocal() {
return (getSCMVersion() != svnRepo.getLatestRevision())
}
def SVNURL getSCMRemoteURL() {
return wcStatus.getURL()
}
// calculates the svn root URL as string
def String getSvnRootURL() {
String svnRootUrlString = getSCMRemoteURL().toString()
// if svn URL contains "/tags/", then find the name of the branch
if (svnRootUrlString.contains("/tags/")) {
return svnRootUrlString.substring(0, svnRootUrlString.indexOf("/tags/"))
}
if (svnRootUrlString.contains("/branches/")) {
return svnRootUrlString.substring(0, svnRootUrlString.indexOf("/branches/"))
}
return svnRootUrlString.substring(0, svnRootUrlString.indexOf("/trunk"))
}
def String getSCMVersion() {
return wcStatus.getRevision().getNumber().toString()
}
def boolean onTag() {
return getSCMRemoteURL().getPath().contains("/tags/")
}
def boolean onBranch() {
return getSCMRemoteURL().getPath().contains("/branches/")
}
def String getBranchName() {
List splitPath = Arrays.asList(getSCMRemoteURL().getPath().split("/"))
// if svn URL contains "/tags/", then find the name of the branch
if (onTag()) {
assert(splitPath.indexOf("tags") > 0)
assert(splitPath.indexOf("tags") < splitPath.size()-1)
return splitPath.get(splitPath.size()-1)
}
// if svn URL contains "/branches/", then find the name of the branch
if (onBranch()) {
assert(splitPath.indexOf("branches") > 0)
assert(splitPath.indexOf("branches") < splitPath.size()-1)
return splitPath.get(splitPath.size()-1)
}
return "trunk"
}
def String getLatestReleaseTag(String currentBranch) {
def entries = svnRepo.getDir( "tags", -1 , null , (Collection) null );
SVNDirEntry max = entries.max{it2->
def matcher = releaseTagPattern.matcher(it2.name);
if (matcher.matches() && branchName.equals(matcher.group(1))) {
return Integer.valueOf(matcher.group(2))
} else {
return null
}
}
return max.name
}
/**
* creates a url for the new tag
*/
def SVNURL createTagsUrl(String tag) {
if (project != null) {
project.logger.info("$project, Crafting new tag: $tag")
}
// root url to use for tagging
def SVNURL rootURL = SVNURL.parseURIDecoded(getSvnRootURL())
def SVNURL tagsURL = rootURL.appendPath("tags",false)
// need to preseve the path elements after 'branches'/'tags'/'trunk' and the branch name
String urlTail = getSCMRemoteURL().toString().replace(getSvnRootURL(),"").replace("branches", "").replace("tags", "").replace(getBranchName(), "")
List splitUrlTail = Arrays.asList(urlTail.split("/"))
for (String pathElement : splitUrlTail) {
if (pathElement.length() > 0) {
tagsURL = tagsURL.appendPath(pathElement, false);
}
}
tagsURL = tagsURL.appendPath(tag,false)
return tagsURL
}
def performTagging(String tag, String message) {
project.logger.info("$project, Tagging release: $tag")
def tagsURL = createTagsUrl(tag)
//javadoc helper :
//doCopy(SVNCopySource[] sources, SVNURL dst,
// boolean isMove, boolean makeParents, boolean failWhenDstExists,
// java.lang.String commitMessage, SVNProperties revisionProperties)
svnClientManager.getCopyClient().doCopy(
[new SVNCopySource(SVNRevision.HEAD, SVNRevision.HEAD, wcStatus.URL)] as SVNCopySource[],
tagsURL,
false,
true,
true,
message,
null)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy