Gradle copy creates an empty file - file-io

I have a multi-project gradle build that copies some source files from the parent project into the build directory and then attempts to overwrite a token in one of the copied files. Everything runs OK but the file ends up being empty. Here's the file snippet with the template to replace:
---
# file: clients.yaml
#properties shared by all client machines
jmeter_version: "${jmeterVersion}"
Here's snippet of gradle.properties:
jmeterVersion=3.0
And here are two tasks that suppose to do the trick
/** This task copies files from pdo-shared */
task copyFromCommonProject(type:Copy, dependsOn: configurations.commonProjectContent){
from configurations.commonProjectContent.collect{ zipTree(it) }
into "$buildDir"
/*doLast {
updateAnsibleTokens.execute()
}*/
}
task updateAnsibleTokens(type: Copy, dependsOn: copyFromCommonProject) {
from "$buildDir/commons/ansible/group_vars/clients.yml"
into "$buildDir/commons/ansible/group_vars/"
expand(jmeterVersion: "$jmeterVersion")
}
I run this from the parent project as gradle clean :tpcds-benchmark:updateAnsibleTokens
First tasks copies all the files where and as expected it's the 2nd task that does not work
Please notice commented out doLast section. I tried to run these two tasks as gradle clean :tpcds-benchmark:copyFromCommonProject by uncommenting doLast section and removing dependsOn: copyFromCommonProject from the 2nd task
In both instances client.yml ends up completely empty
P.S. Even if I disable expand(jmeterVersion: "$jmeterVersion") line I will get an empty file. With some more tests it seems that copying a file on itself will generate an empty file so perhaps I'm just doing it wrong. The same code I have will work if I only change the destination directory

Basically I had to reread this manual section to understand the lifecycle better.
Following my original example here's 2 tasks that will work as intended. The problem as I started to suspect was that attempt to copy and modify client.yml was happening in the configuration cycle before the actual copying from the source was happening. Adding << for the 2nd task ensured that the modification was happening in the execution cycle after the original file was copied
/** This task copies files from pdo-shared */
task copyFromCommonProject(type:Copy, dependsOn: configurations.commonProjectContent){
from configurations.commonProjectContent.collect{ zipTree(it) }
into "$buildDir"
}
task updateAnsibleTokens(type: Copy, dependsOn: copyFromCommonProject) << {
from "$buildDir/commons/ansible/group_vars/clients.yml"
into "$buildDir/commons/ansible/group_vars/"
expand(jmeterVersion: "$jmeterVersion")
}

I am not sure, why adding the << helped. Nevertheless, doing expand while extracting archive feels much more natural:
task copyFromCommonProject(type:Copy, dependsOn: configurations.commonProjectContent) {
from configurations.commonProjectContent.collect {
zipTree(it)
}
exclude "commons/ansible/group_vars/clients.yml"
with copySpec {
from configurations.commonProjectContent.collect {
zipTree(it)
}
include "commons/ansible/group_vars/clients.yml"
expand(jmeterVersion: "$jmeterVersion")
}
into "$buildDir"
}

Related

How to customize WAR plugin in subproject in Gradle build script (Kotlin)

I create a Gradle project with several sub-modules, and one module needs war plugin, I just want to customize the web app directory, but the code does not work:
apply {
plugin("war")
plugin("org.gretty")
}
// cannot work
tasks.getByName("war") {
from("src/main/webfiles")
}
// cannot work either
tasks.war {
webAppDirName = "src/main/webfiles"
}
//... other code
This is how I code in the sub-project subproject.gradle.kts file, How to solve this? Thanks for any help!
Solved with the code:
configure<WarPluginConvention>{
webAppDirName = "src/main/webfiles"
}

CucumberJs cannot find steps using webdriverio5

I have defined wdio.conf.js file (main file) and environment specific dev-chrome.conf.js file.
I can't get get cucumber to recognize my step definitions folder.
This is my structure:
And this is what I have in dev-chrome.config.js file:
const wdioConfig = require('../../../../../wdio.conf.js');
const commands = require('../../../../../src/commands/commands');
wdioConfig.config.cucumberOpts = [{
// other stuff here
require:
[
'./src/step_definitions/**/*.js',
// Or search a (sub)folder for JS files with a wildcard
// works since version 1.1 of the wdio-cucumber-framework
//'./src/**/*.js',
],
// other stuff here
}];
exports.config = wdioConfig.config;
I am getting an error:
"Step "When I add the product to a cart" is not defined. You can ignore this error by setting cucumberOpts.ignoreUndefinedDefinitions as true."
When I have same path for step definitions defined on main wdio.conf.js file then it works.
My main wdio.conf.js file is located in the root folder of the project.
Do you know how could I make it work in the environment specific conf.js file?
I am using #wdio/cucumber-framework": "^5.13.2"
As per the below example config, the cucumberopts should be an object and I think you are trying to set it as an array.
https://github.com/amiya-pattnaik/webdriverIO-with-cucumberBDD/blob/master/test/config/suite.cucumber.conf.js#L156
Maybe you should follow this example which will help to understand config setup.
Cheers!

Gradle: how to include external project dependency in IntelliJ?

I have got two projects:
Project_A
core
other
and
Project_B
foo
These are two separate projects hosted in two different git repositories. Project_B/foo has a SNAPSHOT-dependency on Project_A/core. I use IntelliJ as IDE. We publish snapshots of Project_A/core whenever there is change that needs to be propagated to Project_B/foo. Sometimes the change rate in Project_A/core is so high that it would save a lot of time to have them in one IDEA project so that we can navigate back and forth and the changes are visible without publishing snapshots.
How can I mount these two projects as one project in IDE? I have tried the following:
configurations.all {
resolutionStrategy.dependencySubstitution.all { DependencySubstitution dependency ->
if (dependency.requested instanceof ModuleComponentSelector && dependency.requested.group == "bar.com" && dependency.requested.module == "core") {
def targetProject = findProject(":${dependency.requested.module}")
if (targetProject != null) {
dependency.useTarget targetProject
}
}
}
}

How do I list only the custom tasks in a Gradle build file?

I have written a gradle build file which several custom tasks. They are all like the following:
task runThis(type:JavaExec) {
doSomething()
}
When I enter "gradle tasks" in a terminal, none of the tasks I have written myself are listed. Only the standard list of tasks which appear when I run this command against a new project.
How do I get the tasks to be listed? And is it possible to print ONLY the custom written tasks?
I think
gradle tasks --all should works, and your customized tasks are in Other tasks category.
In intellij, there is a panel called Gradle projects.
only the custom tasks:
I write a simple task to do the trick:
// run with `gradle printTasks`
task printTasks << {
project.tasks.collect {
task ->
if (!task.group && task.name !='printTasks') {
println task.name
}
}
}

Assigning a class to a custom stage (Puppet)

I'm working on my first Puppet file for provisioning a Vagrant setup, and I'm sort of stuck.
I'm using the RVM module to handle Ruby and RubyGem installations, but apparently they use their own custom stage called 'rvm-install' that runs BEFORE the main stage.
In order to get the dependencies for RVM installed (Package resources), I need to run them before the 'rvm-install' stage. I realized this means I need a custom stage to have run before that.
I've written this class that encompasses the things needing done...but I don't understand how to assign the class to a stage...the documentation at PuppetLabs didn't seem to cover how you're supposed to do it when you already have a block of stuff in the class.
class before-rm {
exec { "apt-get update":
command => "/usr/bin/apt-get update"
}
package { "libxml2":
ensure => present,
require => Exec['apt-get update']
}
package { "nodejs":
ensure => present,
require => Exec['apt-get update']
}
}
Any help would be greatly appreciated. This is how I've got the Stage defined in the same file:
# Custom stage!
stage { 'before-rvm':
before => Stage['rvm-install']
}
Stage['before-rvm'] -> Stage['rvm-install']
Normally you would instantiate the before-rm class like this for the main stage:
include before-rm
which is equivalent to
class { 'before-rm': }
To instantiate a class for another stage you can use the metaparameter (not a parameter of the class, of all classes in general) stage.
class { 'before-rm':
stage => before-rvm
}
Here is a link to this in the docs: http://docs.puppetlabs.com/puppet/2.7/reference/lang_run_stages.html#assigning-classes-to-stages