I'm using this Gradle SSH plugin. It has a method put that will move files from my local machine to the machine the session is connected to.
My app is fully built and exists in build/app and I'm trying to move it to /opt/nginx/latest/html/ such that the file build/app/index.html would exist at /opt/nginx/latest/html/index.html and that any subfolders of build/app are also copied over.
My build.gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.hidetake:gradle-ssh-plugin:1.1.4'
}
}
apply plugin: 'org.hidetake.ssh'
remotes {
target {
host = '<my target vm>'
user = 'user'
password = 'pass'
}
}
...
task deploy() << {
ssh.run {
session(remotes.target) {
put from: 'build/app/', into: '/opt/nginx/latest/html/'
}
}
}
As I have it above, it's putting all the files into /opt/nginx/latest/html/app. If I change the from to use fileTree(dir: 'build/app') then all the files get copied over but I lose the file structure, i.e. build/app/scripts/main.js gets copied to /opt/nginx/latest/html/main.js instead of the expected /opt/nginx/latest/html/scripts/main.js.
How can I copy the CONTENTS of one directory (not the directory itself) into the target directory while retaining folder structure?
Looking through the plugin's code, it says:
static usage = '''put() accepts following signatures:
put(from: String or File, into: String) // put a file or directory
put(from: Iterable<File>, into: String) // put files or directories
put(from: InputStream, into: String) // put a stream into the remote file
put(text: String, into: String) // put a string into the remote file
put(bytes: byte[], into: String) // put a byte array into the remote file'''
You're using option #1 where you are providing a File (which can also be a directory), while you should be using #2, which would be an iterable list of build/app's children. So I would try:
put (from: new File('build/app').listFiles(), into: '/opt/nginx/latest/html/')
Edit: Alternatively,
new File('build/app').listFiles().each{put (from:it, into:'/opt/nginx/latest/html/')}
You could create a FileTree object for your build/app directory and then ssh your entire tree structure to your remote instance:
FileTree myFileTree = fileTree(dir: 'build/app')
task deploy() << {
ssh.run {
session(remotes.target) {
put from: myFileTree.getDir(), into: '/opt/nginx/latest/html/'
}
}
It should copy your structure and files like:
// 'build/app' -> '/opt/nginx/latest/html/
// 'build/app/scripts' -> '/opt/nginx/latest/html/scripts/'
// 'build/app/*.*' -> 'opt/nginx/latest/html/*.*'
// ...
You could add a wildcard to copy all files in the folder:
put from: 'build/app/*', into: '/opt/nginx/latest/html/'
Related
In build.gradle I have the following code:
task copyModifiedSources(type:Copy) {
from ('ApiClient.java.modified') {
rename 'ApiClient.java.modified', 'ApiClient.java'
}
setDuplicatesStrategy(DuplicatesStrategy.INCLUDE)
into 'build/generated/src/main/java/com/client/invoker'
}
I am trying to copy ApiClient.java.modified (renamed to ApiClient.java before copy) file into build/generated/src/main/java/com/client/invoker folder which already has ApiClient.java file.
I am using a duplicate strategy to override APIClient.java from /invoker folder with ApiClient.java.modified.
If I rename the copying file to the file name not in /invoker folder, then it works but does not work with the duplicate file name. The file is not copied successfully.
Could you please help me to figure out what is going wrong?
Gradle -> 6.5.1
Java -> 11
the rename is same level as from not under from.
below example final file in build/gen content is 'override'
task setupFiles() {
doLast {
mkdir 'build/override'
mkdir 'build/gen'
new File('build/gen/ApiClient.java').text = "orig"
new File('build/override/ApiClient.java.modified').text = "override"
}
}
task copyModifiedSources(type: Copy, dependsOn: setupFiles) {
from 'build/override'
include '*.modified'
rename '(.*).modified', '$1'
setDuplicatesStrategy(DuplicatesStrategy.INCLUDE)
into 'build/gen'
}
run gradle clean copyModifiedSources
I have a multi-project Gradle build. In each subproject I have a properties.gradle file like the following:
def usefulMethod() {
return 'foo'
}
ext {
foo = 'bar'
usefulMethod = this.&usefulMethod
}
And then I import it into the subproject build.gradle using apply from: './properties.gradle'.
However, if two subprojects import a variable with the same name, I get this error:
Cannot add extension with name 'foo', as there is an extension already registered with that name.
It seems that adding to ext affects the entire project instead of just the subproject like I wanted. What is the correct way to import properties and variables from an external file in a subproject without leaking them into the entire project build?
The plain ext is the extension for ENTIRE project, the root project and all subprojects. To avoid polluting the root namespace whenever you include a file via apply from..., you should instead use project.ext. project refers to the current project or subproject being built. For example, the below file could be apply from'd to add a downloadFile function to the current project:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'de.undercouch:gradle-download-task:3.4.3'
}
}
project.ext {
apply plugin: de.undercouch.gradle.tasks.download.DownloadTaskPlugin
downloadFile = { String url, File destination ->
if (destination.exists()) {
println "Skipping download because ${destination} already exists"
} else {
download {
src url
dest destination
}
}
}
}
I've got this project structure
journey\
applications\
desktop\
core\
I've got a task that downloads .zip archive.
task download_redis(type: Download) {
src 'https://github.com/MSOpenTech/redis/releases/download/win-3.2.100/Redis-x64-3.2.100.zip'
dest new File("applications/redis/install", 'Redis-x64-3.2.100.zip')
onlyIfNewer true
}
It saves zip file into applications\redis\install.
Then I've got another task that supposed to extract the content of zip file into applications/redis.
task install_redis(dependsOn: download_redis, type: Copy) {
from zipTree(download_redis.dest)
into 'applications/redis'
}
But I get this error
Cannot expand ZIP 'L:\journey\desktop\applications\redis\install\Redis-x64-3.2.100.zip' as it does not exist.
It seems trying to resolve the path to zip from desktop project, despite it being level higher - a root.
How to set for zipTree to use path from root and not from subproject? (Though both these tasks are inside desktop subproject)
You can access various paths like so:
println project(":applications").projectDir
println project(":desktop").projectDir
// root
println project(":").projectDir
Here is an example :desktop:build.gradle file that uses a spoof zip download. Note the applicationsDir variable. (I'm assuming that you are using the same plugin as the one specified.):
plugins {
id "de.undercouch.download" version "1.2"
}
apply plugin: 'de.undercouch.download'
import de.undercouch.gradle.tasks.download.Download
def applicationsDir = project(":applications").projectDir
task download_redis(type: Download) {
src 'https://github.com/codetojoy/Git_Sandbox/raw/master/tmp/example.zip'
dest new File("${applicationsDir}/redis/install", 'Redis-x64-3.2.100.zip')
onlyIfNewer true
}
task install_redis(dependsOn: download_redis, type: Copy) {
from zipTree(download_redis.dest)
into "${applicationsDir}/redis"
}
I created a simple Gradle build that exports the contents of ./src/main/groovy to a zip file. The zip file contains a folder with the exact same name as the zip file. I cannot figure out how to get the files into the root of the zip file using the distribution plugin.
i.e. gradlew clean distZip produces:
helloDistribution-1.0.zip -> helloDistribution-1.0 -> files
what I would like:
helloDistribution-1.0.zip -> files
My build.gradle file:
apply plugin: 'groovy'
apply plugin: 'distribution'
version = '1.0'
distributions {
main {
contents {
from {
'src/main/groovy'
}
}
}
}
I have attempted to fix the problem by adding into { 'dir' } but to no avail.
Using into '/' seems to do the trick:
contents {
from {
'src/main/groovy'
}
into '/'
}
Unfortunately, penfold's answer did not work for me. Here is the solution I came up with:
task Package(type: Zip) {
from {
def rootScriptFiles = [] // collection of script files at the root of the src folder
new File('src/main/groovy/').eachFile { if (it.name.endsWith('.groovy')) rootScriptFiles.add(it) }
['build/libs/', // build binaries
'src/res/', // resources
rootScriptFiles, // groovy root source files
]
}
baseName = pluginName
}
To copy files into the root of helloDistribution-1.0.zip -> helloDistribution-1.0 -> use
contents {
from {
'some/file'
}
into ''
}
I created a simple Gradle build that exports the contents of ./src/main/groovy to a zip file. The zip file contains a folder with the exact same name as the zip file. I cannot figure out how to get the files into the root of the zip file using the distribution plugin.
i.e. gradlew clean distZip produces:
helloDistribution-1.0.zip -> helloDistribution-1.0 -> files
what I would like:
helloDistribution-1.0.zip -> files
My build.gradle file:
apply plugin: 'groovy'
apply plugin: 'distribution'
version = '1.0'
distributions {
main {
contents {
from {
'src/main/groovy'
}
}
}
}
I have attempted to fix the problem by adding into { 'dir' } but to no avail.
Using into '/' seems to do the trick:
contents {
from {
'src/main/groovy'
}
into '/'
}
Unfortunately, penfold's answer did not work for me. Here is the solution I came up with:
task Package(type: Zip) {
from {
def rootScriptFiles = [] // collection of script files at the root of the src folder
new File('src/main/groovy/').eachFile { if (it.name.endsWith('.groovy')) rootScriptFiles.add(it) }
['build/libs/', // build binaries
'src/res/', // resources
rootScriptFiles, // groovy root source files
]
}
baseName = pluginName
}
To copy files into the root of helloDistribution-1.0.zip -> helloDistribution-1.0 -> use
contents {
from {
'some/file'
}
into ''
}