Executing SQL in a Gradle task? - sql

How can I execute SQL in a Gradle task?
configurations {
compile
}
repositories {
mavenCentral()
}
dependencies {
compile 'postgresql:postgresql:9.0-801.jdbc4'
}
task sql << {
driverName = 'org.postgresql.Driver'
Class.forName(driverName)
groovy.sql.Sql sql = Sql.newInstance(
'jdbc:postgresql://localhost:5432/postgres',
'username',
'password',
driverName
)
sql.execute 'create table test (id int not null)'
sql.execute 'insert into test (id) values(1)'
sql.eachRow 'select * from test' {
println it
}
}
I get a
java.lang.ClassNotFoundException: org.postgresql.Driver exception when executing the sql task.

To define external dependencies for the build script itself you got to put it into the build scripts' classpath. You can do that by defining it within the buildscript closure.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'postgresql:postgresql:9.0-801.jdbc4'
}
}

If you don't mind depending on yet another tool, you can leverage dbdeploy in your project. There is also a gradle plugin that let you import SQL scripts as is.

buildscript {
dependencies {
classpath 'com.oracle:ojdbc6:11.2.0.3'
}
}
task tmp() {
dependsOn configurations.batch
doLast {
ant.sql(classpath: buildscript.configurations.classpath.asPath,
driver: "oracle.jdbc.OracleDriver",
url: "${dbConn}", userid: "${dbUser}", password: "${dbPass}",
"select 1 from dual")
}
}
Alternatively:
ant.sql(classpath: buildscript.configurations.classpath.asPath,
driver: "oracle.jdbc.OracleDriver",
url: "${dbConn}", userid: "${dbUser}", password: "${dbPass}") {
fileset(dir: dir) {
include(name: "**/*.sql")
}
}

Found runsql-gradle-plugin that allows executing SQL script files defined in custom Gradle task.
After adding these strings to my build.gradle.kts:
plugins {
id("com.nocwriter.runsql") version ("1.0.3")
}
task<RunSQL>("initData") {
dependencies {
implementation("org.postgresql:postgresql")
}
config {
url = "jdbc:postgresql://localhost:5432/test"
driverClassName = "org.postgresql.Driver"
username = "test"
password = "test"
scriptFile = "data.sql"
}
}
I could execute data.sql by:
./gradlew initData

Here is one way:
gradle.class.classLoader.addURL(new File('../../../../lib/server/mssql/sqljdbc4.jar').toURI().toURL())
def Sql sql = Sql.newInstance(dbConnectionURL, dbUserName, dbPassword, dbDriverName)
String sqlString = new File(dbSchemaFile as String).text
sql.execute(sqlString)

Related

Kotlin Gradle Cucumber: Undefined Step

I am building a selenium automation project using cucumber and kotlin, but after I have set up the skeleton. The steps can't be identified by cucumber. I mainly call gradle cucumber on terminal to begin the test.
build.gradle
plugins {
id 'java'
id 'org.jetbrains.kotlin.jvm' version '1.3.21'
id "com.github.spacialcircumstances.gradle-cucumber-reporting" version "0.1.7"
}
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
jcenter()
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
testCompile group: 'junit', name: 'junit', version: '4.12'
testImplementation 'io.cucumber:cucumber-java8:4.7.1'
testImplementation 'io.cucumber:cucumber-junit:4.3.1'
implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
testImplementation 'no.tornado:tornadofx:1.7.17'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
configurations {
cucumberRuntime {
extendsFrom testImplementation
}
}
task cucumber() {
dependsOn assemble, compileTestJava
doLast {
javaexec {
main = "cucumber.api.cli.Main"
classpath = configurations.cucumberRuntime + sourceSets.test.output
args = ['--plugin', 'json:test_reports/' + getDate() + '_automation_test_result.json', '--glue', 'src/test/kotlin/steps', 'src/test/resources/feature']
}
}
}
cucumberReports {
outputDir = file('test_reports/' + getDate()+ '_html')
buildId = '0'
reports = files('test_reports/' + getDate() + '_automation_test_result.json', 'test_reports/cucumber-json.json')
}
static def getDate() {
def date = new Date()
def formattedDate = date.format('yyyy-MM-dd')
return formattedDate
}
Below is the structure:
This is the folders
Below is the result:
Task :cucumber
Sep 18, 2019 5:27:40 PM cucumber.api.cli.Main run
WARNING: You are using deprecated Main class. Please use io.cucumber.core.cli.Main
Undefined scenarios:
src/test/resources/feature/test.feature:15 # Input something in the search bar
src/test/resources/feature/test.feature:16 # Input something in the search bar
src/test/resources/feature/test.feature:25 # Change to different sub-page
src/test/resources/feature/test.feature:26 # Change to different sub-page
src/test/resources/feature/test.feature:27 # Change to different sub-page
src/test/resources/feature/test.feature:28 # Change to different sub-page
6 Scenarios (6 undefined)
30 Steps (30 undefined)
0m0.100s
You can implement missing steps with the snippets below:
Given("I have logged in as a super admin", () -> {
// Write code here that turns the phrase above into concrete actions
throw new cucumber.api.PendingException();
});
Given("I have navigated to CRM", () -> {
// Write code here that turns the phrase above into concrete actions
throw new cucumber.api.PendingException();
});
Given("I have clicked the client button on the navigation bar", () -> {
// Write code here that turns the phrase above into concrete actions
throw new cucumber.api.PendingException();
});
When("I input {string} in the search bar", (String string) -> {
// Write code here that turns the phrase above into concrete actions
throw new cucumber.api.PendingException();
});
Then("the search result should contain {string}", (String string) -> {
// Write code here that turns the phrase above into concrete actions
throw new cucumber.api.PendingException();
});
Given("I have navigated to the home page on CRM", () -> {
// Write code here that turns the phrase above into concrete actions
throw new cucumber.api.PendingException();
});
When("I click the {string} on the navigation bar", (String string) -> {
// Write code here that turns the phrase above into concrete actions
throw new cucumber.api.PendingException();
});
Then("I should be brought to different page", () -> {
// Write code here that turns the phrase above into concrete actions
throw new cucumber.api.PendingException();
});
BUILD SUCCESSFUL in 2s
4 actionable tasks: 1 executed, 3 up-to-date
I can navigate to the step file when I ctrl+click on the implemented Given or When steps. It seems it can't find the steps definition when it runs. What am i doing wrong here?
I had this exact issue and the answer above is correct, but a bit unclear. (I removed everything else rather than leaving the resources folder in there too!)
This is the task cucumber() section of my build.gradle file:
task cucumber() {
dependsOn assemble, compileTestKotlin
doLast {
javaexec {
main = "io.cucumber.core.cli.Main"
classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
args = ['--plugin', 'pretty', '--glue', 'hellocucumber', 'src/test/resources']
}
}
}
where hellocucumber is my package name, as outlined in this example.
I hope it helps!

Issue using Mobbeel Fataar plugin with uploadArchives task

I'm in the process of trying to create a fat AAR to distribute my Android library. I'm using the Mobbeel Fataar plugin to package all of my dependencies into an AAR for ease of distribution. This works perfectly, and when I run ./gradlew build, I get an AAR file in mylibrary/build/outputs/aar/ called mylibrary-release.aar and it includes all of my dependencies in its libs directory. The issue arises when I attempt to distribute the AAR.
In order to distribute, I found this tutorial to take me through it, which I'm using virtually unchanged. Here's that code (in my build.gradle):
apply plugin: 'maven'
apply plugin: 'signing'
def isReleaseBuild() {
return VERSION_NAME.contains("SNAPSHOT") == false
}
def getReleaseRepositoryUrl() {
return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
: "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
}
def getSnapshotRepositoryUrl() {
return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
: "https://oss.sonatype.org/content/repositories/snapshots/"
}
def getRepositoryUsername() {
return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
}
def getRepositoryPassword() {
return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
}
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
pom.groupId = GROUP
pom.artifactId = POM_ARTIFACT_ID
pom.version = VERSION_NAME
repository(url: getReleaseRepositoryUrl()) {
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
}
snapshotRepository(url: getSnapshotRepositoryUrl()) {
authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
}
pom.project {
name POM_NAME
packaging POM_PACKAGING
description POM_DESCRIPTION
url POM_URL
scm {
url POM_SCM_URL
connection POM_SCM_CONNECTION
developerConnection POM_SCM_DEV_CONNECTION
}
licenses {
license {
name POM_LICENCE_NAME
url POM_LICENCE_URL
distribution POM_LICENCE_DIST
}
}
developers {
developer {
id POM_DEVELOPER_ID
name POM_DEVELOPER_NAME
}
}
}
}
}
}
signing {
required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
sign configurations.archives
}
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.sourceFiles
}
artifacts {
archives androidSourcesJar
}
}
The issue is that, when I run ./gradlew :mylibrary:uploadArchives, it creates a mylibrary-1.0.aar file in mylibrary/build/outputs/aar/ and uploads that file. The problem is that it doesn't have my dependencies bundled in.
I'd like to somehow create mylibrary-1.0.aar with all of my dependencies bundled, and then have that be uploaded. Unfortunately I don't have a completely clear understanding of how the upload code I'm using works. Does anyone know how I can do what I want?

Custom Gradle task to build all projects without testing?

I know I can execute 'gradle build -x test', but is there a way to create a custom Gradle task, say, buildNoTests, which will build all of my projects but will completely ignore tests (don't compile/run them)?
I read that the 'assemble' task is not enough as it may miss other tasks which are not tests but are included in the 'build' task.
Put this in the root build.gradle
allprojects {
afterEvaluate {
def buildTask = tasks.findByPath('build')
if (buildTask) {
task buildNoTests {
dependsOn buildTask
}
gradle.taskGraph.whenReady { TaskExecutionGraph graph ->
if (graph.hasTask(buildNoTests)) {
def skipNames = ['test', 'compileTestJava', 'processTestResources', 'testClasses'] as Set
Collection<Task> testTasks = graph.allTasks.findAll { skipNames.contains(it.name) }
testTasks.each { it.enabled = false }
}
}
}
}
}

Not able to run testng xml with gradle build command

I have created a gradle project and configured the testng in eClipse. I have created a sample testng script and which is getting executed successfully when I run the testng.xml through eClipse.
However, when I am executing gradle build/test etc commands from command prompt, my testng.xml is not getting executed.
I am not facing any error, however not able to run the testng.xml with gradle commands.
Could you please help me on this. Below is build.gradle which I am using.
apply plugin: "java"
apply plugin: "maven"
group = "myorg"
version = 1.0
def poiVersion = "3.10.1"
repositories {
maven {
url "rep_url"
}
}
sourceSets.all { set ->
def jarTask = task("${set.name}Jar", type: Jar) {
baseName = baseName + "-$set.name"
from set.output
}
artifacts {
archives jarTask
}
}
sourceSets {
api
impl
}
dependencies {
apiCompile 'commons-codec:commons-codec:1.5'
implCompile sourceSets.api.output
implCompile 'commons-lang:commons-lang:2.6'
testCompile 'junit:junit:4.9'
testCompile sourceSets.api.output
testCompile sourceSets.impl.output
testCompile group: 'org.testng', name: 'testng', version: '6.9.5'
runtime configurations.apiRuntime
runtime configurations.implRuntime
compile('org.seleniumhq.selenium:selenium-java:2.47.1') {
exclude group: 'org.seleniumhq.selenium', module: 'selenium-htmlunit-driver'
exclude group: 'org.seleniumhq.selenium', module: 'selenium-android-driver'
exclude group: 'org.seleniumhq.selenium', module: 'selenium-iphone-driver'
exclude group: 'org.seleniumhq.selenium', module: 'selenium-safari-driver'
exclude group: 'org.webbitserver', module: 'webbit'
exclude group: 'commons-codec', module: 'commons-codec'
exclude group: 'cglib', module: 'cglib-nodep'
}
compile "org.apache.poi:poi:${poiVersion}"
compile "org.apache.poi:poi-ooxml:${poiVersion}"
compile "org.apache.poi:ooxml-schemas:1.1"
}
tasks.withType(Test) {
scanForTestClasses = false
include "**/*.xml" // whatever Ant pattern matches your test class files
}
jar {
from sourceSets.api.output
from sourceSets.impl.output
}
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri("${buildDir}/repo"))
addFilter("main") { artifact, file -> artifact.name == project.name }
["api", "impl"].each { type ->
addFilter(type) { artifact, file -> artifact.name.endsWith("-$type") }
// We now have to map our configurations to the correct maven scope for each pom
["compile", "runtime"].each { scope ->
configuration = configurations[type + scope.capitalize()]
["main", type].each { pomName ->
pom(pomName).scopeMappings.addMapping 1, configuration, scope
}
}
}
}
}
}
Thanks in advance for your help on this.
I am able to achieve this by adding below code in the build.gradle.
test {
useTestNG() {
// runlist to executed. path is relative to current folder
suites 'src/test/resources/runlist/Sanity.xml'
}
}
Thanks!

Configuring multiple upload repositories in Gradle build

I want to upload my artifacts to a remote Nexus repo. Therefore I have configured a snaphot and a release repo in Nexus. Deployment to both works.
Now I want to configure my build so I can decide in which repo I want to deploy:
gradle uploadArchives should deploy to my snapshots repo
gradle release uploadArchives should deploy to my release repo
This was my try:
apply plugin: 'war'
apply plugin: 'maven'
group = 'testgroup'
version = '2.0.0'
def release = false
repositories {
mavenCentral()
mavenLocal()
}
dependencies{ providedCompile 'javax:javaee-api:6.0' }
task release <<{
release = true;
println 'releasing!'
}
uploadArchives {
repositories {
mavenDeployer {
repository(url: "http://.../nexus/content/repositories/releases"){
authentication(userName: "admin", password: "admin123")
}
addFilter('lala'){ x, y -> release }
}
mavenDeployer {
repository(url: "http://.../nexus/content/repositories/snapshots"){
authentication(userName: "admin", password: "admin123")
}
addFilter('lala'){ x, y ->!release}
pom.version = version + '-SNAPSHOT'
}
}
}
The build works if I comment out one of the two mavenDeployer configs, but not as a whole.
Any ideas how to configure two target archives in one build file?
One solution is to add an if-else statement that adds exactly one of the two deployers depending on the circumstances. For example:
// should defer decision until end of configuration phase
gradle.projectsEvaluated {
uploadArchives {
repositories {
mavenDeployer {
if (version.endsWith("-SNAPSHOT")) { ... } else { ... }
}
}
}
}
If you do need to vary the configuration based on whether some task is "present", you can either make an eager decision based on gradle.startParameter.taskNames (but then you'll only catch tasks that are specified as part of the Gradle invocation), or use the gradle.taskGraph.whenReady callback (instead of gradle.projectsEvaluated) and check whether the task is scheduled for execution.
Correct me if I'm wrong, but shouldn't you use the separate snapshotRepository in this case (as opposed to an if statement)? For example,
mavenDeployer {
repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
authentication(userName: sonatypeUsername, password: sonatypePassword)
}
snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
authentication(userName: sonatypeUsername, password: sonatypePassword)
}
}