How can I access resources from dependencies? I have something like this:
Wrapper project build.gradle
..
dependencies {
compile com.company:mysubproject1:2.0.1
compile com.company:mysubproject2:2.0.1
..
Those subprojects have some files in THEIR resource directories e.g. src/main/resources/liquibase/changelog.xml
There can be n of these subprojects and I need my gradle task to
pass through all dependencies and grab all changelog.xml files and create new file from them which will be later used.
It was actually not that hard:
doFirst {
println 'Generating master changelog...'
def changelogFiles = []
configurations.runtime.each {
def zip = new ZipFile(it)
def entries = zip.entries()
entries.findAll { entry -> entry.name.contains("liquibase") }
.findAll { entry -> entry =~ /changelog.xml/ }
.each { entry ->
changelogFiles.add(((ZipEntry) entry).name)
}
}
def resDir = sourceSets.main.output.resourcesDir.path + '/liquibase'
def changelogFile = new File("$resDir/changelog-master.xml")
changelogFile.write("<databaseChangeLog xmlns=\"http://www.liquibase.org/xml/ns/dbchangelog\"\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
" xsi:schemaLocation=\"http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd\">\n\n")
changelogFiles.each {
println("Including $it to changelog.")
changelogFile << " <include file=\"classpath:$it\"/> \n"
}
changelogFile << "\n</databaseChangeLog>"
}
This code just loops through dependencies and digs up file paths for files named 'changelog.xml' and having 'liquibase' in path.
Possible issue would be if 2 dependecies had file with same name and path, I don't know what would be on classpath in that case.
Related
I have a lambda function that is written in nodejs (using AWS nodejs SDK) and we are using gradle (build.gradle) to package and deploy that to AWS.
Deployment is working fine but when I am trying to update tags on this Lambda and redeploying then the new tags are not being applied to that function.
So if I am deploying Lambda using build.gradle first time with TAG A then its working fine (By first time I mean when I am creating a new Lambda) and tag is being applied and I can see that on AWS Console. But when I am re-deploying it again by adding another tag "TAG B" then the new tag is not being applied and it is not updating the existing Lambda tags. Any idea or suggestion what I am doing wrong? Thanks
Below is the section of build.gradle file where I am applying the tags for Lambda.
createOrUpdateFunction {
handler = 'index.handler'
role = cfo.DataDigestContentSearchLambdaIamRoleArn
runtime = 'python3.7'
timeout = 10
tags = [
tagA: 'data-team',
tagB: 'someValue'
]
Here is the complete build.gradle file
import com.amazonaws.services.lambda.model.TagResourceRequest
apply plugin: 'com.abc.gradle.nodejs.yarn'
apply plugin: 'com.abc.gradle.aws.lambda.deployment'
apply from: rootProject.file('gradle/yarn-webpacked-lambda.gradle')
nodejs {
packaging {
name = '#abc/data-fulfillment-facebook-lambda'
dependency project(':core:js')
dependency project(':platforms:facebook:js:core')
dependency '#abc/data-ingest-api', abc_INGEST_SEMVER
dependency '#abc/data-ingest-core', abc_INGEST_SEMVER
dependency 'aws-sdk', AWS_SEMVER
}
}
webpackPackageJson.dependencies << ['fb': FB_SEMVER]
lambdaRepository {
artifactName = 'data-fulfillment-facebook'
}
lambda {
functionName = "${config.aws.target.envPrefix}-${lambdaRepository.artifactName}"
}
def cfo = cloudformation.outputs as Map<String, String>
createOrUpdateFunction {
handler = 'index.handler'
role = cfo.DataFulfillmentFacebookLambdaIamRoleArn
runtime = 'nodejs12.x'
memorySize = 256
timeout = 30
tags = [
team: 'data-team',
name: 'someName'
]
environmentAsMap << [
FACEBOOK_LEDGER_TABLE_NAME: cfo.DataFulfillmentLedgerTableName,
INSTAGRAM_DISCOVERY_TOKEN_SECRET: cfo.DataFulfillmentInstagramDiscoveryTokenSecretName
]
}
task registerTaskProcessor(type: RegisterTaskProcessorTask) {
client 'target'
tableName = cfo.DataFulfillmentTaskProcessorRegistryV2TableName
entryName = 'facebook'
rules << [regex: ['^facebook', [var: 'task.type']]]
type = 'lambda-dispatch'
params << [functionName: lambda.functionName, qualifier: 'live']
}
Below are two tasks hello & printProperties in build.gradle:
task('hello', {
description("Hey student! Run this one :D")
group("Our demo")
doLast({println("Hello World!")})
}
)
plugins({
id('java')
})
ext({
springVersion = "3.1.0.RELEASE"
emailNotification = "build#master.org"
})
sourceSets.all({ ext.purpose = null })
sourceSets({
main({
purpose = "production"
})
test({
purpose = "test"
})
plugin({
purpose = "production"
})
})
task('printProperties', {
doLast({
println(springVersion)
println(emailNotification)
sourceSets.matching({ it.purpose == "production" }.each({ println it.name }))
})
})
that gives error:
> startup failed:
build file '/../../build.gradle': 8:
only buildscript {} and other plugins {} script blocks are allowed before plugins {} blocks, no other statements are allowed
Why plugins({id('java')}) give groovy scripted syntax error?
It's answered here : https://stackoverflow.com/a/48611069/1250435
Whenever you write a build.gradle script and use the new plugins
script block, you need to put it as first block in the file. The only
exceptions from this rule are other plugins blocks or the special
buildScript block, which always must go first.
I use IntelliJ's null-checking mechanism to prevent nullpointer crashes.
I've successfully set up all Java method parameters to be #NonNull by default using this answer.
After creating package-info.java which is used to define package annotations in Java. All java files which are direct descendants of that package have methods with default #NonNull parameters in my Android Studio project.
The obvious problem is that I need to define #ParametersAreNonnullByDefault for all Java classes in that package i.e. including all subpackages.
How can I define #ParametersAreNonnullByDefault so that it propagates down to all subpackage java files? I want to have all of my internal code's method annotated with #NonNull by default.
/**
* File: package-info.java
* Make all method parameters #NonNull by default
*/
#ParametersAreNonnullByDefault
package com.intive.nearbyplaces.main;
import javax.annotation.ParametersAreNonnullByDefault;
The problem was that I couldn't force Android Studio to respect #ParametersAreNonnullByDefault in all subpackages (i.e. recursively for all java files in com.company.name)
I wrote a gradle script, however, to check whether package-info.java files are generated inside each of the subpackage folders and create it if necessary. The script runs just before assembleDebug task.
So it turns out it is possible to force #ParametersAreNonnullByDefault annotation on all java classes in your project.
Download the source here. Remember to replace line 19 with your package name.
Usage:
apply plugin: 'com.android.application'
apply from: 'nonnull.gradle'
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
[...]
}
Remember to include package-info.java files in .gitignore
//File: .gitignore
package-info.java
Checkstyle rule:
<module name="JavadocPackage"/>
checks whether package-info.java is included in each subpackage.
Source:
/**
* File: nonnull.gradle
*
* Generates package-info.java for appropriate packages
* inside src/main/java folder.
*
* This is a workaround to define #ParametersAreNonnullByDefault for all Java classes in a package
* i.e. including all subpackages (note: edit package name in line no. 19).
*/
task generateNonNullJavaFiles(dependsOn: "assembleDebug", type: Copy) {
group = "Copying"
description = "Generate package-info.java classes"
def infoFileContentHeader = getFileContentHeader();
def infoFileContentFooter = getFileContentFooter();
def sourceDir = file( "${projectDir}" + File.separatorChar + "src" + File.separatorChar +
"main" + File.separatorChar + "java" + File.separatorChar +
"com" + File.separatorChar + "company" + File.separatorChar + "name" )
sourceDir.eachDirRecurse { dir ->
def infoFilePath = dir.getAbsolutePath() + File.separatorChar + "package-info.java"
if (!file(infoFilePath).exists()) {
def infoFileContentPackage = getFileContentPackage(dir.getAbsolutePath());
new File(infoFilePath).write(infoFileContentHeader +
infoFileContentPackage + infoFileContentFooter)
println "[dir] " + infoFilePath + " created";
}
}
println "[SUCCESS] NonNull generator: package-info.java files checked"
}
def getFileContentPackage(path) {
def mainSrcPhrase = "src" + File.separatorChar + "main" + File.separatorChar +
"java" + File.separatorChar
def mainSrcPhraseIndex = path.indexOf(mainSrcPhrase)
def output = path.substring(mainSrcPhraseIndex)
// Win hotfix
if (System.properties['os.name'].toLowerCase().contains('windows')) {
output = output.replace("\\", "/")
mainSrcPhrase = mainSrcPhrase.replace("\\", "/")
}
return "package " + output.replaceAll(mainSrcPhrase, "").replaceAll(
"/", ".") + ";\n"
}
def getFileContentHeader() {
return "/** javadoc goes here \n */\n" +
"#ParametersAreNonnullByDefault\n" +
"#ReturnValuesAreNonnullByDefault\n"
}
def getFileContentFooter() {
return "\n" +
"import javax.annotation.ParametersAreNonnullByDefault;\n" +
"\n" +
"import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;"
}
Extended version which generates package info files for src main, test & androidTest folders can be found here.
Findbugs & Lint:
It does work with findbugs & lint.
I am attempting to remove ALL version of java from windows PATH via Puppet.
I will replace it with %JAVA_HOME%\bin.
Here is the current code:
include windows_path
define obsolete_java {
windows_path {
$name:
ensure => absent,
directory => "C:\\Program Files\\Java\\$name\\bin";
}
}
define windows_java::setup (
$ensure = 'present',
$source = undef,
$file = undef,
$package = undef ) {
case $::osfamily {
Windows : { $supported = true }
default : { fail("The ${module_name} module is not supported on ${::osfamily} based systems") }
}
# Validate parameters
if ($source == undef) {
fail('source parameter must be set')
}
if ($file == undef) {
fail('file parameter must be set')
}
if ($package == undef) {
fail('package parameter must be set')
}
# Validate input values for $ensure
if !($ensure in ['present', 'absent']) {
fail('ensure must either be present or absent')
}
if ($caller_module_name == undef) {
$mod_name = $module_name
} else {
$mod_name = $caller_module_name
}
if ($ensure == 'present'){
# ensures main directory exists
file {'C:\Program Files\Java':
ensure => directory,
}
# copies source executable over
file { "C:\\Program Files\\Java\\$source":
ensure => present,
source => "puppet:///extra_files/java/windows/$source",
before => Package["$package"],
source_permissions => ignore,
}
# Name of package must match name when installed
package { "$package":
ensure => installed,
source => "C:\\Program Files\\java\\$source",
install_options => '/s',
}
# sets JAVA_HOME. If already existant, replaces it.
windows_env { "JAVA_HOME=C:\\Program Files\\Java\\$file":
mergemode => clobber,
}
# removes previous Java from path
obsolete_java {'jdk1.7.0_51':}
# Adds JAVA_HOME to the path.
windows_path {'javaPath':
ensure => present,
directory => "%JAVA_PATH%\bin",
}
} else {
package { 'remove-package':
name => "$package",
ensure => absent,
}
windows_env { 'JAVA_HOME':
ensure => 'absent',
mergemode => clobber,
}
windows_path {'remove_java_path':
ensure => absent,
directory => "C:\\Program Files\\Java\\$file\\bin",
}
}
}
Specifically:
define obsolete_java {
windows_path {
$name:
ensure => absent,
directory => "C:\\Program Files\\Java\\$name\\bin";
}
}
called here:
# removes previous Java from path
obsolete_java {'jdk1.7.0_51':}
Is it possible just have it remove anything it finds under: C:\Program Files\Java\any_jdk
bin ?
Edit: More importantly, can I force it to find any directory that contains the word "java" and remove it from PATH?
Seeing as the windows_path type is somewhat complex, there seems to be no conceivable way for the provider to prefetch the full list of existing paths. You will therefor be unable to purge the java paths.
That leaves you with only one option that I can see: Create an external fact (or plain custom fact) to retrieve the list of directories in the PATH. If you don't use Facter 2, you will need to get the delimited PATH string and process it on the master. Facter 2 can hand an array to the master.
If you have them in a variable, say $path_list, you can hand them to a similar defined type as the one you are using already.
filter_path { $path_list: }
define filter_path {
if $name =~ /java/ {
windows_path { $name: ensure => absent, directory => $name }
}
}
In my gradle script I've been able to successfully read properties like this:
def environment = hasProperty('env') ? env : 'dev'
Using this I can execute a build script like this:
gradlew clean assemble -Penv=prod
My issue comes in when I tried moving this to an init.gradle file. The file is recognized and I'm able to use other properties that I define in the script, however I'm not able to get any from the command line. How can I do this?
My init.gradle file:
allprojects {
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
project.ext['nexusDomainName'] = 'https://example.com/nexus'
project.ext['compileSdkVersion'] = 19
project.ext['buildToolsVersion'] = "19"
project.ext['minSdkVersion'] = 8
project.ext['targetSdkVersion'] = 19
project.ext['sourceCompatibility'] = '1.7'
project.ext['targetCompatibility'] = '1.7'
//hasProperty('release') is always false
project.ext['archiveType'] = hasProperty('release') ? '' : '-SNAPSHOT'
project.ext['archiveUrl'] = hasProperty('release') ? "$nexusDomainName/content/repositories/releases/" : "$nexusDomainName/content/repositories/snapshots/"
// This buildEnv property won't read either
project.ext['buildEnv'] = hasProperty('env') ? env : 'dev'
println "prepping for $buildEnv"
project.ext['archivesBaseNameSuffix'] = (project.ext['buildEnv'] == 'stage' || project.ext['buildEnv'] == 'dev') ? '-' + project.ext['buildEnv'] : ''
repositories {
mavenLocal()
maven {
credentials {
username 'username'
password 'password'
}
url "$nexusDomainName/content/groups/public/"
}
mavenCentral()
}
}
-P sets a project property, which isn't immediately available in an init script. (You can access projects and their properties from an init script, but that access will be deferred until the projects have been created.) However, using a system property (-D) should work.