Files
i2p.i2p-bote/gradle/i2p-make-plugin.gradle

354 lines
12 KiB
Groovy

/*
* Copyright Jack Grigg <str4d@mail.i2p>
*/
apply plugin: I2PPlugin
class Pack200Task extends DefaultTask {
@InputFiles
def FileCollection inputJars
@OutputDirectory
def File outputDir
@TaskAction
def packJars(IncrementalTaskInputs inputs) {
if (!inputs.incremental)
project.delete(outputDir.listFiles())
inputs.outOfDate { jar ->
def tmp = jar.file
def packed = "$outputDir/${jar.file.name}.pack"
// Pretend that WARs are JARs
if (jar.file.name.endsWith('.war')) {
project.copy {
from jar.file
into temporaryDir
rename { "${it}.jar" }
}
tmp = "$temporaryDir/${jar.file.name}.jar"
}
project.exec {
executable 'pack200'
args '--no-gzip',
'--effort=9',
'--modification-time=latest',
packed,
tmp
}
}
inputs.removed { jar ->
println "removed: ${jar.file.name}"
def targetFile = new File(outputDir, "${jar.file.name}.pack")
targetFile.delete()
}
}
}
class I2PPlugin implements Plugin<Project> {
def pluginProps = [
'name': ['name', true],
'signer': ['signer', true],
'version': ['version', true],
'author': ['author', false],
'description': ['description', false],
'websiteURL': ['websiteUrl', false],
'updateURL': ['updateUrl', false],
'updateURL.su3': ['su3UpdateUrl', false],
'license': ['license', false],
'disableStop': ['disableStop', false],
'consoleLinkName': ['consoleLinkName', false],
'consoleLinkURL': ['consoleLinkURL', false],
'consoleLinkTooltip': ['consoleLinkTooltip', false],
'console-icon': ['consoleIcon', false],
'icon-code': ['consoleIconCode', false],
'min-i2p-version': ['minI2PVersion', false],
'max-i2p-version': ['maxI2PVersion', false],
'min-java-version': ['minJavaVersion', false],
'min-jetty-version': ['minJettyVersion', false],
'max-jetty-version': ['maxJettyVersion', false],
'dont-start-at-install': ['dontStartAtInstall', false],
'router-restart-required': ['routerRestartRequired', false],
'update-only': ['updateOnly', false],
'install-only': ['installOnly', false],
'min-installed-version': ['minInstalledVersion', false],
'max-installed-version': ['maxInstalledVersion', false],
]
def pluginLibs(Project project) {
project.configurations.runtime.filter { lib -> !(
// These are all in the standard classpath
lib.name.startsWith('i2p-') ||
lib.name.startsWith('mstreaming-') ||
lib.name.startsWith('streaming-')
)}
}
def pubKeyFile(Project project) {
project.file(project.i2p.plugin.pubKeyFile ?
project.i2p.plugin.pubKeyFile :
"$project.i2p.plugin.pubKeyDir/$project.i2p.plugin.pubKeyFileName")
}
def privKeyFile(Project project) {
project.file(project.i2p.plugin.privKeyFile ?
project.i2p.plugin.privKeyFile :
"$project.i2p.plugin.pubKeyDir/$project.i2p.plugin.privKeyFileName")
}
def b64KeyFile(Project project) {
project.file(project.i2p.plugin.b64KeyFile ?
project.i2p.plugin.b64KeyFile :
"$project.i2p.plugin.pubKeyDir/$project.i2p.plugin.b64KeyFileName")
}
def pubKeyStore(Project project) {
project.file(project.i2p.plugin.pubKeyStore ?
project.i2p.plugin.pubKeyStore :
"$project.i2p.plugin.pubKeyDir/$project.i2p.plugin.pubKeyStoreName")
}
def privKeyStore(Project project) {
project.file(project.i2p.plugin.privKeyStore ?
project.i2p.plugin.privKeyStore :
"$project.i2p.plugin.pubKeyDir/$project.i2p.plugin.privKeyStoreName")
}
void apply(Project project) {
project.extensions.create('i2p', I2PExtension)
project.i2p.extensions.create('plugin', I2PPluginExtension)
project.i2p.plugin.extensions.create('webapp', I2PPluginWebappExtension)
def pluginBuildDir = "$project.buildDir/plugin.tmp"
def tmpPluginConfig = "$pluginBuildDir/plugin.config"
def tmpWebappsConfig = "$pluginBuildDir/webapps.config"
project.task('preparePluginConfig') << {
def hasProp = []
project.delete(tmpPluginConfig)
project.copy {
from 'src/main/i2p/plugin.config'
into pluginBuildDir
filter { line ->
for (p in pluginProps) {
if (line.startsWith("$p.key=")) {
if (project.i2p.plugin[p.value[0]]) {
return null
} else {
hasProp.add(p.key)
}
}
}
line
}
}
File file = new File(tmpPluginConfig)
for (p in pluginProps) {
if (!(p.key in hasProp)) {
def (confName, required) = p.value
if (project.i2p.plugin[confName]) {
file << System.getProperty('line.separator')
file << "$p.key=" << project.i2p.plugin[confName]
} else if (required) {
throw new InvalidUserDataException(
"You must set i2p.plugin.$confName in your build.gradle")
}
}
}
file << System.getProperty('line.separator')
file << 'date=' << System.currentTimeMillis()
file << System.getProperty('line.separator')
file << 'key=' << b64KeyFile(project).text
}
project.task('prepareWebappsConfig') << {
project.delete(tmpWebappsConfig)
File file = new File(tmpWebappsConfig)
file << 'webapps.' << project.archivesBaseName << '.classpath='
if (project.i2p.plugin.webapp.includeTaglib) {
file << '$I2P/lib/jstl.jar,$I2P/lib/standard.jar,'
}
file << pluginLibs(project).collect { lib ->
'$PLUGIN/lib/' + lib.name
}.join(',')
file << System.getProperty('line.separator')
file << 'webapps.' << project.archivesBaseName << '.startOnLoad='
file << project.i2p.plugin.webapp.startOnLoad
}
project.task('packWebapp', type: Pack200Task) {
inputJars = project.war.outputs.files
outputDir project.file("$project.buildDir/packWebapp")
}
project.task('packLibs', type: Pack200Task) {
inputJars = pluginLibs(project)
outputDir project.file("$project.buildDir/packLibs")
}
project.task('pluginZip', type: Zip) {
archiveName = 'plugin.zip'
destinationDir = project.file(pluginBuildDir)
from tmpPluginConfig
into('console') {
from tmpWebappsConfig
into('webapps') {
from project.packWebapp.outputs.files
}
}
into('lib') {
from project.packLibs.outputs.files
}
}
project.pluginZip.dependsOn project.preparePluginConfig
project.pluginZip.dependsOn project.prepareWebappsConfig
project.task('checkKeys') << {
def pkf = privKeyFile(project)
if (!pkf.exists()) {
println 'TODO: Creating new XPI2P DSA keys'
}
def pks = privKeyStore(project)
if (!pks.exists()) {
println "TODO: Creating new SU3 $project.i2p.plugin.keyType keys for $project.i2p.plugin.signer"
}
}
project.configurations.create('i2pPluginSign')
project.dependencies.add('i2pPluginSign', 'net.i2p:i2p:+')
project.dependencies.add('i2pPluginSign', project.files('/usr/share/java/gnu-getopt.jar'))
project.afterEvaluate { p ->
def pluginDir = p.file("$p.buildDir/plugin")
p.task('signXPI2PPlugin', type: JavaExec) {
def xpi2pFile = p.file("$pluginDir/${p.i2p.plugin.name}.xpi2p")
outputs.files xpi2pFile
main = 'net.i2p.crypto.TrustedUpdate'
classpath = p.configurations.i2pPluginSign
args 'sign',
p.pluginZip.outputs.files[0].absolutePath,
xpi2pFile,
privKeyFile(p),
p.i2p.plugin.version
doFirst {
p.mkdir(pluginDir)
}
}
p.signXPI2PPlugin.dependsOn p.pluginZip
p.signXPI2PPlugin.dependsOn p.checkKeys
p.task('signSU3Plugin', type: JavaExec) {
def su3File = p.file("$pluginDir/${p.i2p.plugin.name}.su3")
outputs.files su3File
standardInput = System.in
main = 'net.i2p.crypto.SU3File'
classpath = p.configurations.i2pPluginSign
args 'sign',
'-c',
'PLUGIN',
'-t',
p.i2p.plugin.keyType,
p.pluginZip.outputs.files[0].absolutePath,
su3File,
privKeyStore(p),
p.i2p.plugin.version,
p.i2p.plugin.signer
doFirst {
p.mkdir(pluginDir)
}
}
p.signSU3Plugin.dependsOn p.pluginZip
p.signSU3Plugin.dependsOn p.checkKeys
p.task('verifyXPI2PPlugin', type: JavaExec) {
def b64Key = b64KeyFile(p).text
main = 'net.i2p.crypto.TrustedUpdate'
classpath = p.configurations.i2pPluginSign
jvmArgs "-Drouter.trustedUpdateKeys=$b64Key"
args 'verifysig',
p.signXPI2PPlugin.outputs.files[0].absolutePath
}
p.task('verifySU3Plugin', type: JavaExec) {
main = 'net.i2p.crypto.SU3File'
classpath = p.configurations.i2pPluginSign
args 'verifysig',
'-k',
pubKeyStore(p),
p.signSU3Plugin.outputs.files[0].absolutePath
}
p.task('plugin') << {
}
p.plugin.dependsOn p.signXPI2PPlugin
p.plugin.dependsOn p.signSU3Plugin
p.plugin.dependsOn p.verifyXPI2PPlugin
p.plugin.dependsOn p.verifySU3Plugin
}
}
}
class I2PExtension {
}
class I2PPluginExtension {
def String pubKeyDir = System.getProperty('user.home') + '/.i2p-plugin-keys'
def String pubKeyFileName = 'plugin-public-signing.key'
def String pubKeyFile
def String privKeyFileName = 'plugin-private-signing.key'
def String privKeyFile
def String b64KeyFileName = 'plugin-public-signing.txt'
def String b64KeyFile
def String pubKeyStoreName = 'plugin-su3-public-signing.crt'
def String pubKeyStore
def String privKeyStoreName = 'plugin-su3-keystore.ks'
def String privKeyStore
def String keyType = 'RSA_SHA512_4096'
def String name
def String signer
def String version
def String author
def String description
def String websiteUrl
def String updateUrl
def String su3UpdateUrl
def String license
def String disableStop
def String consoleLinkName
def String consoleLinkURL
def String consoleLinkTooltip
def String consoleIcon
def String consoleIconCode
def String minI2PVersion
def String maxI2PVersion
def String minJavaVersion
def String minJettyVersion
def String maxJettyVersion
def String dontStartAtInstall
def String routerRestartRequired
def String updateOnly
def String installOnly
def String minInstalledVersion
def String maxInstalledVersion
}
class I2PPluginWebappExtension {
def boolean startOnLoad = true
def boolean includeTaglib = false
}