354 lines
12 KiB
Groovy
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
|
|
}
|