project.Scp = Scp.class project.SshExec = SshExec.class project.SshTask = SshTask.class configurations { sshAntTask } dependencies { sshAntTask "org.apache.ant:ant-jsch:1.8.2" } tasks.withType(SshTask) { sshAntClasspath = configurations.sshAntTask } class SshTask extends DefaultTask { @InputFiles FileCollection sshAntClasspath @Input String host @Input String userName @Input String password boolean verbose = false private boolean antInited = false protected initAnt() { if (!antInited) { ant.taskdef(name: 'scp', classname: 'org.apache.tools.ant.taskdefs.optional.ssh.Scp', classpath: sshAntClasspath.asPath, loaderref: 'ssh') ant.taskdef(name: 'sshexec', classname: 'org.apache.tools.ant.taskdefs.optional.ssh.SSHExec', classpath: sshAntClasspath.asPath, loaderref: 'ssh') antInited = true } } protected withInfoLogging(Closure action) { def oldLogLevel = logging.level logging.level = [LogLevel.INFO, oldLogLevel].min() try { action() } finally { if (oldLogLevel) { logging.level = oldLogLevel } } } def scpFile(source, destination) { initAnt() withInfoLogging { ant.scp(localFile: project.files(source).singleFile, remoteToFile: "${userName}@${host}:${destination}", password: password, verbose: verbose) } } def scpDir(source, destination) { initAnt() withInfoLogging { ant.sshexec(host: host, username: userName, password: password, command: "mkdir -p ${destination}") ant.scp(remoteTodir: "${userName}@${host}:${destination}", password: password, verbose: verbose) { project.files(source).addToAntBuilder(ant, "fileSet", FileCollection.AntType.FileSet) } } } def ssh(Object... commandLine) { initAnt() withInfoLogging { ant.sshexec(host: host, username: userName, password: password, command: commandLine.join(' ')) } } } class Scp extends SshTask { @InputFiles @SkipWhenEmpty source @Input destination boolean isDir = false @TaskAction void doActions() { if (isDir) { scpDir(source, destination) return } project.files(source).each { doFile(it) } } void doFile(File file) { if (file.directory) { file.eachFile { doFile(it) } } else { scpFile(file, destination) } } } class SshExec extends SshTask { @Input List commandLines = [] void commandLine(String... commandLine) { commandLines << commandLine } @TaskAction void doActions() { commandLines.each { commandLine -> ssh(* commandLine) } } }