How to make a Gradle project versioneye-friendly? - gradle

I have a Gradle project that I want to import to Versioneye to check if my dependencies are up to date, but it's a complex config file (with external variables etc.) and Versioneye does not manage to handle the dependencies properly.
I don't want to install the Versioneye gradle plugin.
How can I export the dependencies from my repo to Versioneye?

You can list all the dependencies gradle app:dependencies.
With a bit of string manipulation, you can export a "clean" dependencies file and manually upload it to Versioneye.
#!/bin/bash
OUT_DIR='versioneye'
OUT_FILE="${OUT_DIR}/build.gradle"
mkdir -p "${OUT_DIR}"
touch "${OUT_FILE}"
# copy your maven repositories closure below from build.gradle
tee "${OUT_FILE}" <<EOF >/dev/null
allprojects {
repositories {
maven {
url 'https://maven.google.com/maven-google-remote'
}
maven {
url "https://jitpack.io"
}
}
}
EOF
echo 'dependencies {' >> "${OUT_FILE}"
./gradlew app:dependencies | grep '^+---' | sed 's|+--- |compile "|' | sed 's| (\*)||g' | sed 's|$|"|' | sort -u >> "${OUT_FILE}"
echo '}' >> "${OUT_FILE}"
cat "${OUT_FILE}"
cd "${OUT_DIR}"
start .
cd -
echo 'Now, open versioneye.com and manually upload the genreated build.gradle file.'
This will generate a file that looks like this:
allprojects {
repositories {
maven {
url 'https://maven.google.com/maven-google-remote'
}
maven {
url "https://jitpack.io"
}
...
}
}
dependencies {
compile "com.android.support.test.espresso:espresso-contrib:2.2.2"
compile "com.android.support.test.espresso:espresso-core:2.2.2"
compile "com.android.support.test.espresso:espresso-intents:2.2.2"
compile "com.facebook.android:facebook-android-sdk:4.17.0"
compile "com.facebook.fresco:fresco:1.5.0"
compile "com.facebook.fresco:imagepipeline-okhttp3:1.5.0"
...
}
This file can be imported to Versioneye with a file upload and will be processed correctly.

Related

How to delete all "target" directories from gradle (after converting from maven)

I have a huge maven project, lot of people are using it. I'm currently working on converting it to gradle. One of the last steps will be that I merge the gradle files, and delete the pom.xml files. But I'd like to add a gradle task to clean the maven target directories (of all the sub-projects). In shell I would do something like:
find . -type d -name target -exec rm -rf "{}" \;
But I prefer this to be a gradle task. How do I add it? This is what I tried but it doesn't delete anything:
task cleanMaven(type: Delete) {
delete fileTree('.').matching { include '**/target/**' }
}
below will handle all modules of root project and prints true if a target dir existed and is deleted
allprojects {
task mvnClean {
doFirst {
def targetPath = project.projectDir.toString() + '/target'
println "target dir exists: ${Files.deleteIfExists(Paths.get(targetPath))}"
}
}
}
Based on #PrasadU's answer, but this also deletes all the contents of the target/ directories:
allprojects {
task mvnClean {
doFirst {
def targetPath = project.projectDir.toString() + '/target'
project.delete(files("${targetPath}"))
}
}
}

How to get gradle property from command line?

I am trying read a project property from command line interface. There is a task gradle properties, which prints all of them. Therefore, I can write: gradle properties | grep "rootProject: root project" | awk '{print $NF}' | tr -d "'" and get what I want. The returned result is correct. I would like to use a proper gradle command to achieve the same result. What is a gradle command to get the project name?
this is my build.gradle:
plugins {
id 'java'
}
tasks.register("rootProjectName") {
doLast {
println(rootProject.name)
}
}
build {
println 'hi'
}
Looks like you're just after the rootProject.name property. There is no built-in Gradle task that will give you that property. You can write a simple task that prints that value to the console which will simplify your command.
tasks.register("rootProjectName") {
doLast {
println(rootProject.name)
}
}
Then simply call that task with -q:
$ ./gradlew rootProjectName -q
demo
You can see demo is simply printed out for this example.
So far the closest I got is the following build.gradle:
plugins {
id 'java'
}
task printRootProjectName {
doLast {
println('root project: ' + rootProject.name)
}
}
build {
println 'unwanted output'
}
and then:
gradle printRootProjectName -q | grep "root project:" | awk '{print $NF}' | head -n 1

RPM compression not working with spring-boot gradle

Ive made a spring boot project with gradle, and have made an rpm build for it. The jar file works fine before i run my rpm, but after its compressed i get this error:
Exception in thread "main" java.lang.IllegalStateException: Failed to get nested archive for entry BOOT-INF/lib/castor-core-1.3.3.jar
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:109)
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchives(JarFileArchive.java:87)
at org.springframework.boot.loader.ExecutableArchiveLauncher.getClassPathArchives(ExecutableArchiveLauncher.java:70)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:49)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Caused by: java.io.IOException: Unable to open nested jar file 'BOOT-INF/lib/castor-core-1.3.3.jar'
at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:253)
at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:238)
at org.springframework.boot.loader.archive.JarFileArchive.getNestedArchive(JarFileArchive.java:104)
... 4 more
Caused by: java.lang.IllegalStateException: Unable to open nested entry 'BOOT-INF/lib/castor-core-1.3.3.jar'. It has been compressed and nested jar files must be stored without compression. Please check the mechanism used to create your executable jar file
at org.springframework.boot.loader.jar.JarFile.createJarFileFromFileEntry(JarFile.java:281)
at org.springframework.boot.loader.jar.JarFile.createJarFileFromEntry(JarFile.java:261)
at org.springframework.boot.loader.jar.JarFile.getNestedJarFile(JarFile.java:249)
... 6 more
I have tried diabling rpms compression with %global __os_install_post %{nil} at the top of my .spec file, and then it works. So ive narrowed it down to my issue being that it is compressed when i build the rpm. However im not really interested in it not being compressed, as the file may eventually get rather large . So how do i actually fix this. Do i have to add something to gradle telling it to decompress before running or something?
rpm was build with this .sh file:
#!/bin/bash
# This script expects the Jenkins job to have moved the securityservice-files into the rpmbuild/SOURCES dir
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
echo ""
source common.sh
# Remove old RPMS, just for good measure
rm -rf rpmbuild/RPMS/*
# Move build files into SOURCES
cp ../sf_securityservice/build/libs/securityservice-0.0.1.jar rpmbuild/SOURCES
cp ../sf_securityservice/dist-resources/log4j2.xml rpmbuild/SOURCES
cp ../sf_securityservice/dist-resources/config.xml rpmbuild/SOURCES
#Define paths
BIN_DIR=$C3A_BIN_DIR/securityservice
ETC_DIR=$C3A_ETC_DIR/securityservice
LOG_DIR=$C3A_LOG_DIR/securityservice
VAR_DIR=$C3A_VAR_DIR/securityservice
JDK_VERSION_STRING=$(select_java_version "Frankfurt")
RELEASE=$(package_version)
VERSION="1.0"
#Set default args
cat <<DEFAULT_ARGS > rpmbuild/SOURCES/default_args
#
# Changes in this file WILL be replaced on update.
# Persistent changes goes in ${ETC_DIR}/custom_args.
#
JVM_ARGS="-Dlog4j.configurationFile=/opt/c3a/etc/securityservice/log4j2.xml"
CMD_ARGS="${ETC_DIR}/config.xml"
DEFAULT_ARGS
#Make empty file for custom args
touch rpmbuild/SOURCES/custom_args
cat <<RUNSH > rpmbuild/SOURCES/run.sh
#!/bin/bash
source $BIN_DIR/default_args
source $ETC_DIR/custom_args
/usr/bin/java \$JVM_ARGS -XX:OnOutOfMemoryError='kill -9 %p' -jar $BIN_DIR/securityservice-0.0.1.jar \$CMD_ARGS
RUNSH
cat <<EOF > rpmbuild/SOURCES/c3a-securityservice.service
[Unit]
Description=Cetrea SecurityService
After=syslog.target network.target
[Service]
Type=simple
WorkingDirectory=$VAR_DIR
User=securityservice
Group=c3a
Restart=always
StartLimitInterval=900
StartLimitBurst=3
RestartSec=10
ExecStart=$BIN_DIR/run.sh
SyslogIdentifier=cas
LimitNOFILE=25000
[Install]
WantedBy=multi-user.target
EOF
cd rpmbuild
rm -rf ./BUILDROOT/*
rpmbuild --target noarch \
-D "VERSION $VERSION" \
-D "RELEASE $RELEASE" \
-D "BIN_DIR $BIN_DIR" \
-D "ETC_DIR $ETC_DIR" \
-D "LOG_DIR $LOG_DIR" \
-D "VAR_DIR $VAR_DIR" \
-D "JDK_VERSION_STRING $JDK_VERSION_STRING" \
-D "_topdir ${PWD}" \
-bb SPECS/securityservice.spec
RPM=$DIR/rpmbuild/RPMS/noarch/securityservice-${VERSION}-${RELEASE}.noarch.rpm
echo $RPM
and this .spec
%description
this package contains Cetrea SecurityService.
%prep
#Unpack the release here using %setup
%build
#nothing here
%install
#Make target folders
mkdir -p $RPM_BUILD_ROOT%{LOG_DIR}
mkdir -p $RPM_BUILD_ROOT%{BIN_DIR}
mkdir -p $RPM_BUILD_ROOT%{ETC_DIR}
mkdir -p $RPM_BUILD_ROOT%{VAR_DIR}
mkdir -p $RPM_BUILD_ROOT/usr/lib/systemd/system/
cp $RPM_SOURCE_DIR/c3a-securityservice.service $RPM_BUILD_ROOT/usr/lib/systemd/system/
# Copy things into said folders
cp $RPM_SOURCE_DIR/default_args $RPM_BUILD_ROOT%{BIN_DIR}
cp $RPM_SOURCE_DIR/run.sh $RPM_BUILD_ROOT%{BIN_DIR}
cp $RPM_SOURCE_DIR/custom_args $RPM_BUILD_ROOT%{ETC_DIR}
cp $RPM_SOURCE_DIR/log4j2.xml $RPM_BUILD_ROOT%{ETC_DIR}
cp $RPM_SOURCE_DIR/config.xml $RPM_BUILD_ROOT%{ETC_DIR}
cp $RPM_SOURCE_DIR/securityservice.log $RPM_BUILD_ROOT%{VAR_DIR}
install -m 644 $RPM_SOURCE_DIR/securityservice-0.0.1.jar $RPM_BUILD_ROOT%{BIN_DIR}/
%pre
groupadd c3a || true
useradd -d %{VAR_DIR} -g c3a securityservice || true
%post
# Start the SecurityService once the install has completed
systemctl daemon-reload
if [ $1 -gt 1 ] ; then
echo "restart SecurityService"
systemctl restart c3a-securityservice || true
else
echo "start SecurityService"
systemctl enable c3a-securityservice || true
systemctl start c3a-securityservice || true
fi
%preun
# the preun section is where you can run commands before the rpm is removed
if [ $1 == 0 ] ; then
echo "stop SecurityService"
systemctl stop c3a-securityservice || true
systemctl disable c3a-securityservice || true
systemctl daemon-reload
systemctl reset-failed c3a-securityservice || true
fi
%clean
#rm -rf $RPM_BUILD_ROOT
#rm -rf %{_tmppath}/%{name}
#rm -rf %{_topdir}/BUILD/%{name}
%files
# list files owned by the package here
%attr(-, securityservice, c3a) %dir %{BIN_DIR}
%attr(-, securityservice, c3a) %dir %{LOG_DIR}
%attr(-, securityservice, c3a) %dir %{VAR_DIR}
%attr(644, securityservice, c3a) %{BIN_DIR}/securityservice-0.0.1.jar
%attr(-, securityservice, c3a) %{BIN_DIR}/default_args
%attr(750, securityservice, c3a) %{BIN_DIR}/run.sh
%attr(-,securityservice, c3a) %VAR_DIR/securityservice.log
%attr(664, securityservice, c3a) %config(noreplace) %{ETC_DIR}/*
/usr/lib/systemd/system/c3a-securityservice.service
%changelog
The gradle file:
buildscript {
ext {
springBootVersion = '2.0.0.RC2'
}
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'jacoco'
group = 'com.cetrea'
version = '0.0.1'
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
// Exclude springboots own logging framework as we want log4j2
configurations {
all*.exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-log4j2')
compile('org.springframework:spring-oxm')
compile('org.codehaus.castor:castor-xml:1.3.3')
compile('org.apache.commons:commons-collections4:4.1')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.springframework.security:spring-security-test')
}
jacoco{
toolVersion = "0.7.9"
}
jacocoTestReport {
group = "reporting"
description = "generate Jacoco coverage reports after running tests."
additionalSourceDirs = files(sourceSets.main.allJava.srcDirs)
}
jar {
baseName = 'securityservice'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
manifest {
attributes 'Main-Class': 'com.cetrea.securityservice.SecurityService'
}
}
Is this a gradle problem or an rpm problem?

Maven tool is not set in Jenkins pipeline

I have this stage in my Jenkins pipeline:
stage('Build') {
def mvnHome = tool 'M3'
sh '''for f in i7j-*; do
(cd $f && ${mvnHome}/bin/mvn clean package)
done
wait'''
}
In Jenkins » Manage Jenkins » Global Tool Configuration I have a Maven installation called M3, version 3.3.9.
When running this pipeline, mvnHome is empty because I get this in the log:
+ /bin/mvn clean install -Dmaven.test.skip=true
/var/lib/jenkins/jobs/***SNIP***/script.sh: 3: /var/lib/jenkins/jobs/***SNIP***/script.sh: /bin/mvn: not found
I did find a path /var/lib/jenkins/tools/hudson.tasks.Maven_MavenInstallation/M3 on the Jenkins server, which works, but I would prefer not to use a hard coded path to mvn in this script.
How do I fix this?
EDIT: Summary of the answer, using tool and withEnv.
My working code is now:
stage('Build') {
def mvn_version = 'M3'
withEnv( ["PATH+MAVEN=${tool mvn_version}/bin"] ) {
sh '''for f in i7j-*; do
(cd $f && mvn clean package -Dmaven.test.skip=true -Dadditionalparam=-Xdoclint:none | tee ../jel-mvn-$f.log) &
done
wait'''
}
}
You can use your Tools in Jenkinsfile with the tool and withEnv snippets.
Should looks like this:
def mvn_version = 'M3'
withEnv( ["PATH+MAVEN=${tool mvn_version}/bin"] ) {
//sh "mvn clean package"
}
The easiest way should be to use is tools directives:
pipeline {
agent any
tools {
maven 'M3'
}
stages {
stage('Build') {
steps {
sh 'mvn -B -DskipTests clean package'
}
}
}
}
M3 is the name pre-configured in Global Tool Configuration, see the docs: https://jenkins.io/doc/book/pipeline/syntax/#tools
What about using the construct:
withMaven(mavenOpts: MAVEN_OPTS, maven: 'M3', mavenLocalRepo: MAVEN_LOCAL_REPOSITORY, mavenSettingsConfig: MAVEN_SETTINGS) {
sh "mvn ..."
}

How can I get a list of my projects dependencies in a flattened form using Gradle?

I know that Gradle has the excellent dependencies task that lists out all dependencies for a project. However, it returns them in a tree listing.
I would like to get a list of all my dependencies as they are resolved in just a flat list. Similar to how the Maven dependency plugin list goal behaves.
Here is a short task that meets that need:
task('dependenciesList') << {
println "Compile dependencies"
def selectedDeps = project.configurations.compile.incoming.resolutionResult.allDependencies.collect { dep ->
"${dep.selected}"
}
selectedDeps.unique().sort().each { println it}
}
The third line is the interesting part. You need to get the configuration you care about (compile) then instead of getting dependencies there, the incoming.resolutionResult will provide the resolved values and versions.
<< was removed in Gradle 5. To make the task work in Gradle 5 and later versions, remove << and use doLast { } instead. Also, use runtimeClasspath or compileClasspath for the configuration instead of compile:
task('dependenciesList') {
doLast {
println "Compile dependencies"
def selectedDeps = project.configurations.compileClasspath.incoming.resolutionResult.allDependencies.collect { dep ->
"${dep.selected}"
}
selectedDeps.unique().sort().each { println it}
}
}
Without modifying the build, flatten the tree using sed, sort, and uniq as follows:
$ gradle dependencies | sed 's/^.* //' | sort | uniq
Alternatively, with slightly tighter sed matching:
./gradlew dependencies \
| sed -n 's/.*--- \([^ ]*\).*/\1/p' \
| grep -v "^project$" \
| sort \
| uniq
Thanks for the answers already supplied.
Finally I complete it by a more standard way:
project.gradle.addListener(new DependencyResolutionListener() {
#Override
void beforeResolve(ResolvableDependencies dependencies) {}
#Override
void afterResolve(ResolvableDependencies dependencies) {
dependencies.resolutionResult.allComponents.each { select ->
println "selected component: ${select} " + select.selectionReason
}
}
})
Project implementation will also be resolved in this way, and the final selected component version will be resolved correctly.

Resources