Compare commits

..

No commits in common. "9bcb095352ba0dc44e15a30a4be439e4f9f3b07b" and "9b47af7fdb532f6a4bf1f201eaf4db1c1bbe6c35" have entirely different histories.

162 changed files with 9901 additions and 11400 deletions

View file

@ -1,16 +1,15 @@
plugins { plugins {
id 'maven-publish' id "de.marcphilipp.nexus-publish" version "0.4.0"
id 'signing' id "io.codearte.nexus-staging" version "0.21.1"
id "io.github.gradle-nexus.publish-plugin" version "2.0.0-rc-1"
} }
wrapper { wrapper {
gradleVersion = libs.versions.gradle.get() gradleVersion = "${project.property('gradle.wrapper.version')}"
distributionType = Wrapper.DistributionType.ALL distributionType = Wrapper.DistributionType.ALL
} }
ext { ext {
user = 'joerg' user = 'xbib'
name = 'rpm' name = 'rpm'
description = 'RPM implementation in Java with plugins for Ant, Maven, Gradle' description = 'RPM implementation in Java with plugins for Ant, Maven, Gradle'
inceptionYear = '2016' inceptionYear = '2016'
@ -25,10 +24,10 @@ ext {
} }
subprojects { subprojects {
apply from: rootProject.file('gradle/repositories/maven.gradle') apply plugin: 'java-library'
apply from: rootProject.file('gradle/ide/idea.gradle')
apply from: rootProject.file('gradle/compile/java.gradle') apply from: rootProject.file('gradle/compile/java.gradle')
apply from: rootProject.file('gradle/test/junit5.gradle') apply from: rootProject.file('gradle/test/junit5.gradle')
apply from: rootProject.file('gradle/publish/maven.gradle') apply from: rootProject.file('gradle/publishing/publication.gradle')
} }
apply from: rootProject.file('gradle/publish/sonatype.gradle') apply from: rootProject.file('gradle/publishing/sonatype.gradle')
apply from: rootProject.file('gradle/publish/forgejo.gradle')

View file

@ -0,0 +1,56 @@
plugins {
id 'java-gradle-plugin'
id 'com.gradle.plugin-publish' version '0.11.0'
}
group = 'org.xbib.gradle.plugin'
apply plugin: 'groovy'
apply plugin: 'java-gradle-plugin'
apply plugin: 'com.gradle.plugin-publish'
dependencies {
api gradleApi()
api project(':rpm-core')
testImplementation gradleTestKit()
}
compileGroovy {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
compileTestGroovy {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
validatePlugins {
// disable warning as failures because gradle plugin does not recognize @Delegate tag
failOnWarning = false
}
gradlePlugin {
plugins {
rpmPlugin {
id = 'org.xbib.gradle.plugin.rpm'
implementationClass = 'org.xbib.gradle.plugin.RpmPlugin'
}
}
}
if (project.hasProperty('gradle.publish.key')) {
pluginBundle {
website = 'https://github.com/xbib/rpm'
vcsUrl = 'https://github.com/xbib/rpm'
plugins {
rpmPlugin {
id = 'org.xbib.gradle.plugin.rpm'
version = project.version
description = rootProject.ext.description
displayName = rootProject.ext.description
tags = ['gradle', 'plugin', 'rpm']
}
}
}
}

View file

@ -0,0 +1,51 @@
package org.xbib.gradle.plugin
import org.gradle.api.internal.file.copy.CopyAction
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import java.util.concurrent.Callable
class Rpm extends AbstractArchiveTask {
@Delegate
@Nested
RpmExtension rpmExtension
Rpm() {
rpmExtension = project.extensions.findByName('rpm') as RpmExtension
getArchiveExtension().set("rpm")
Callable<String> archiveFileNameProvider = new Callable<String>() {
@Override
String call() throws Exception {
constructArchiveFileName()
}
}
archiveFileName.set(project.provider(archiveFileNameProvider))
}
@Override
protected CopyAction createCopyAction() {
new RpmCopyAction(project, rpmExtension, this)
}
private String constructArchiveFileName() {
StringBuilder sb = new StringBuilder()
if (packageName) {
sb.append(packageName)
}
if (packageVersion) {
sb.append('-').append(packageVersion)
}
if (packageRelease) {
sb.append('-').append(packageRelease)
}
if (arch) {
sb.append('.').append(arch.name().toLowerCase(Locale.ROOT))
}
if (archiveExtension) {
sb.append('.').append(archiveExtension.get())
}
sb.toString()
}
}

View file

@ -0,0 +1,212 @@
package org.xbib.gradle.plugin
import org.gradle.api.Project
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.file.FileCopyDetails
import org.gradle.api.internal.file.CopyActionProcessingStreamAction
import org.gradle.api.internal.file.copy.CopyAction
import org.gradle.api.internal.file.copy.CopyActionProcessingStream
import org.gradle.api.internal.file.copy.FileCopyDetailsInternal
import org.gradle.api.tasks.WorkResult
import org.gradle.api.tasks.WorkResults
import org.xbib.rpm.Dependency
import org.xbib.rpm.Directory
import org.xbib.rpm.Link
import org.xbib.rpm.RpmBuilder
import org.xbib.rpm.payload.Directive
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption
class RpmCopyAction implements CopyAction {
Project project
Rpm task
RpmExtension ext
RpmBuilder builder
Path tempDir
RpmCopyAction(Project project, RpmExtension rpmExtension, Rpm task) {
this.project = project
this.task = task
this.ext = rpmExtension
}
@Override
WorkResult execute(CopyActionProcessingStream copyActionProcessingStream) {
if (ext.enabled) {
task.setDuplicatesStrategy(DuplicatesStrategy.INCLUDE)
tempDir = task.getTemporaryDir().toPath()
this.builder = createRpm()
copyActionProcessingStream.process(new StreamAction())
addOther()
buildRpm()
}
WorkResults.didWork(true)
}
RpmBuilder createRpm() {
RpmBuilder builder = new RpmBuilder()
builder.setPackage ext.packageName, ext.packageVersion, ext.packageRelease, ext.epoch
builder.setType ext.packageType
builder.setPlatform ext.arch, ext.os
builder.setGroup ext.packageGroup
builder.setBuildHost ext.buildHost
builder.setSummary ext.summary
builder.setDescription ext.packageDescription
builder.setLicense ext.license
builder.setPackager ext.packager
builder.setDistribution ext.distribution
builder.setVendor ext.vendor
builder.setUrl ext.url
builder.setPrefixes task.prefixes
builder.setPrivateKeyId task.getSigningKeyId()
builder.setPrivateKeyPassphrase task.getSigningKeyPassphrase()
builder.setPrivateKeyRing task.getSigningKeyRing()
builder.setPrivateKeyHashAlgo task.getSigningKeyHashAlgo()
builder.setSourceRpm(task.sourcePackage)
builder.setPreInstall task.preInstallFile?.text ?: task.preInstall
builder.setPostInstall task.postInstallFile?.text ?: task.postInstall
builder.setPreUninstall task.preUninstallFile?.text ?: task.preUninstall
builder.setPostUninstall task.postUninstallFile?.text ?: task.postUninstall
builder.setPreTrans task.preTransFile?.text ?: task.preTrans
builder.setPostTrans task.postTransFile?.text ?: task.postTrans
builder.setPreInstall prepareScripts(task, task.preInstallCommands)
builder.setPostInstall prepareScripts(task, task.postInstallCommands)
builder.setPreUninstall prepareScripts(task, task.preUninstallCommands)
builder.setPostUninstall prepareScripts(task, task.postUninstallCommands)
builder.setPreTrans prepareScripts(task, task.preTransCommands)
builder.setPostTrans prepareScripts(task, task.postTransCommands)
if (task.changeLogFile) {
builder.addChangelog task.changeLogFile?.toPath()
}
if (task.changeLog) {
builder.addChangelog(task.changeLog)
}
builder
}
void addOther() {
for (Link link : task.links) {
builder.addLink(link.path, link.target, link.permissions)
}
for (Dependency dep : task.dependencies) {
builder.addDependency(dep.packageName, dep.flags, dep.version)
}
for (Dependency obsolete: task.obsoletes) {
builder.addObsoletes(obsolete.packageName, obsolete.flags, obsolete.version)
}
for (Dependency conflict : task.conflicts) {
builder.addConflicts(conflict.packageName, conflict.flags, conflict.version)
}
for (Dependency provides : task.provides) {
builder.addProvides(provides.packageName, provides.flags, provides.version)
}
for (Directory directory : task.directories) {
String user = directory.user ? directory.user : task.user
String group = directory.group ? directory.group : task.group
builder.addDirectory(directory.path, directory.permissions, null, user, group, directory.addParents)
}
}
void buildRpm() {
Path path = task.archiveFile.get().asFile.toPath()
Files.createDirectories(path.parent)
Files.newByteChannel(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING).withCloseable { ch ->
builder.build(ch)
}
}
private class StreamAction implements CopyActionProcessingStreamAction {
@Override
void processFile(FileCopyDetailsInternal fileCopyDetailsInternal) {
boolean addParents = ext.addParentDirs != null ? ext.addParentDirs : task.addParentDirs
Path path = extractPath(tempDir, fileCopyDetailsInternal)
String p = "/${fileCopyDetailsInternal.path}"
if (Files.isSymbolicLink(path)) {
builder.addLink(p, Files.readSymbolicLink(path).toFile().path, -1)
} else if (!fileCopyDetailsInternal.isDirectory()) {
int mode = fileCopyDetailsInternal.mode
int dirmode = -1
EnumSet<Directive> directive = makeDirective(ext.fileType)
String user = ext.user ?: task.user
String group = ext.group ?: task.group
builder.addFile(p, path, mode, dirmode, directive, user, group, addParents)
}
}
}
private static Path extractPath(Path tempDir, FileCopyDetails fileDetails) {
Path path
try {
path = fileDetails.file.toPath()
} catch (UnsupportedOperationException e) {
path = tempDir.resolve(fileDetails.path)
fileDetails.copyTo(path.toFile())
}
path
}
private static EnumSet<Directive> makeDirective(List<String> strings) {
EnumSet<Directive> set = EnumSet.of(Directive.NONE)
for (String string : strings) {
set.add(Directive.valueOf(string.toUpperCase(Locale.ROOT)))
}
set
}
private static String prepareScripts(Rpm task, List<Object> scripts) {
if (scripts != null && !scripts.isEmpty()) {
List<Object> list = []
def stdDefines = standardScriptDefines(task)
if (stdDefines) {
list.add(stdDefines)
}
if (task.commonCommands) {
list.addAll(task.commonCommands)
}
list.addAll(scripts)
return concatAndRemoveShebangLines(list)
} else {
return null
}
}
private static String standardScriptDefines(Rpm task) {
String.format(" RPM_ARCH=%s \n RPM_OS=%s \n RPM_PACKAGE_NAME=%s \n RPM_PACKAGE_VERSION=%s \n RPM_PACKAGE_RELEASE=%s \n\n",
task.arch?.toString()?.toLowerCase()?:'',
task.os?.toString()?.toLowerCase()?: '',
task.packageName,
task.packageVersion,
task.packageRelease)
}
private static String concatAndRemoveShebangLines(Collection<Object> scripts) {
String shebang
StringBuilder result = new StringBuilder()
scripts.each { script ->
script?.eachLine { line ->
if (line.matches('^#!.*$')) {
if (!shebang) {
shebang = line
} else if (line != shebang) {
throw new IllegalArgumentException("mismatching #! script lines")
}
} else {
result.append line
result.append "\n"
}
}
}
if (shebang) {
result.insert(0, shebang + "\n")
}
result.toString()
}
}

View file

@ -0,0 +1,409 @@
package org.xbib.gradle.plugin
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Optional
import org.xbib.rpm.Dependency
import org.xbib.rpm.Directory
import org.xbib.rpm.Link
import org.xbib.rpm.lead.Architecture
import org.xbib.rpm.lead.Os
import org.xbib.rpm.lead.PackageType
class RpmExtension {
@Optional
@Input
boolean enabled = true
@Optional
@Input
String packageName
@Optional
@Input
String packageVersion
@Optional
@Input
String packageRelease
@Optional
@Input
Integer epoch = 0
@Optional
@Input
String signingKeyPassphrase
@Optional
@Input
String signingKeyRing
@Optional
@Input
String signingKeyId
@Optional
@Input
String signingKeyHashAlgo
@Optional
@Input
String user
@Optional
@Input
String group
@Optional
@Input
String buildHost
@Optional
@Input
String packageGroup
@Optional
@Input
String packageDescription = ''
@Optional
@Input
String summary
@Optional
@Input
String license
@Optional
@Input
String packager
@Optional
@Input
String distribution
@Optional
@Input
String vendor
@Optional
@Input
String url
@Optional
@Input
String sourcePackage
@Optional
@Input
List<String> fileType
@Optional
@Input
Boolean addParentDirs = false
@Optional
@Input
Architecture arch = Architecture.X86_64
@Optional
@Input
Os os = Os.LINUX
@Optional
@Input
PackageType packageType = PackageType.BINARY
@Input
List<String> prefixes = new ArrayList<String>()
@Optional
@Input
Integer uid
@Optional
@Input
Integer gid
@Optional
@Input
String maintainer
@Optional
@Input
String uploaders
@Optional
@Input
String priority
@Optional
@Input
String preInstall
@Optional
@Input
File preInstallFile
@Input
List<Object> preInstallCommands = []
@Optional
@Input
String postInstall
@Optional
@Input
File postInstallFile
@Input
List<Object> postInstallCommands = []
@Optional
@Input
String preUninstall
@Optional
@Input
File preUninstallFile
@Input
List<Object> preUninstallCommands = []
@Optional
@Input
String postUninstall
@Optional
@Input
File postUninstallFile
@Input
List<Object> postUninstallCommands = []
@Optional
@Input
String preTrans
@Optional
@Input
File preTransFile
@Input
List<Object> preTransCommands = []
@Optional
@Input
String postTrans
@Optional
@Input
File postTransFile
@Input
List<Object> postTransCommands = []
@Input
List<Object> commonCommands = []
@Input
List<Link> links = []
Link link(String path, String target) {
link(path, target, -1)
}
Link link(String path, String target, int permissions) {
Link link = new Link(path, target, permissions)
links.add(link)
link
}
@Input
List<Dependency> dependencies = []
@Input
List<Dependency> obsoletes = []
@Input
List<Dependency> conflicts = []
@Input
List<Dependency> recommends = []
@Input
List<Dependency> suggests = []
@Input
List<Dependency> enhances = []
@Input
List<Dependency> preDepends = []
@Input
List<Dependency> breaks = []
@Input
List<Dependency> replaces = []
@Input
List<Dependency> provides = []
Dependency requires(String packageName) {
requires(packageName, '')
}
Dependency requires(String packageName, String version){
requires(packageName, version, 0)
}
Dependency requires(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
dependencies.add(dep)
dep
}
Dependency obsoletes(String packageName) {
obsoletes(packageName, '')
}
Dependency obsoletes(String packageName, String version) {
obsoletes(packageName, version, 0)
}
Dependency obsoletes(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
obsoletes.add(dep)
dep
}
Dependency conflicts(String packageName) {
conflicts(packageName, '')
}
Dependency conflicts(String packageName, String version) {
conflicts(packageName, version, 0)
}
Dependency conflicts(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
conflicts.add(dep)
dep
}
Dependency recommends(String packageName) {
recommends(packageName, '')
}
Dependency recommends(String packageName, String version) {
recommends(packageName, version, 0)
}
Dependency recommends(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
recommends.add(dep)
dep
}
Dependency suggests(String packageName) {
suggests(packageName, '')
}
Dependency suggests(String packageName, String version) {
suggests(packageName, version, 0)
}
Dependency suggests(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
suggests.add(dep)
dep
}
Dependency enhances(String packageName) {
enhances(packageName, '')
}
Dependency enhances(String packageName, String version) {
enhances(packageName, version, 0)
}
Dependency enhances(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
enhances.add(dep)
dep
}
Dependency preDepends(String packageName) {
preDepends(packageName, '')
}
Dependency preDepends(String packageName, String version) {
preDepends(packageName, version, 0)
}
Dependency preDepends(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
preDepends.add(dep)
dep
}
Dependency breaks(String packageName) {
breaks(packageName, '')
}
Dependency breaks(String packageName, String version) {
breaks(packageName, version, 0)
}
Dependency breaks(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
breaks.add(dep)
dep
}
Dependency replaces(String packageName) {
replaces(packageName, '')
}
Dependency replaces(String packageName, String version) {
replaces(packageName, version, 0)
}
Dependency replaces(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
replaces.add(dep)
dep
}
Dependency provides(String packageName) {
provides(packageName, '')
}
Dependency provides(String packageName, String version) {
provides(packageName, version, 0)
}
Dependency provides(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
provides.add(dep)
dep
}
@Input
List<Directory> directories = []
Directory directory(String path) {
Directory directory = new Directory(path: path)
directories << directory
directory
}
@Optional
@Input
File changeLogFile
@Optional
@Input
String changeLog
}

View file

@ -0,0 +1,43 @@
package org.xbib.gradle.plugin
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.tasks.TaskProvider
import org.gradle.util.GradleVersion
class RpmPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
checkVersion()
project.plugins.apply(BasePlugin)
project.ext.Rpm = Rpm.class
project.with {
createExtension(project)
}
/*project.afterEvaluate {
addTasks(project)
}*/
}
private static void checkVersion() {
String version = '6.4'
if (GradleVersion.current() < GradleVersion.version(version)) {
throw new GradleException("need Gradle ${version} or higher")
}
}
private static void createExtension(Project project) {
project.extensions.create('rpm', RpmExtension)
}
/*private static void addTasks(Project project) {
TaskProvider<Rpm> taskProvider = project.tasks.register('buildRpm', Rpm) {
group = 'rpm'
description = 'Generate RPM archive'
}
project.tasks.findByName('build').dependsOn taskProvider
}*/
}

View file

@ -0,0 +1,336 @@
package org.xbib.gradle.plugin
import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.xbib.rpm.RpmReader
import org.xbib.rpm.RpmReaderResult
import org.xbib.rpm.format.Format
import org.xbib.rpm.header.IntegerList
import org.xbib.rpm.header.StringList
import java.nio.charset.StandardCharsets
import java.nio.file.Paths
import static org.hamcrest.CoreMatchers.is
import static org.hamcrest.MatcherAssert.assertThat
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.junit.jupiter.api.Assertions.assertNotNull
import static org.xbib.rpm.format.Flags.EQUAL
import static org.xbib.rpm.format.Flags.GREATER
import static org.xbib.rpm.format.Flags.LESS
import static org.xbib.rpm.header.HeaderTag.CONFLICTFLAGS
import static org.xbib.rpm.header.HeaderTag.CONFLICTNAME
import static org.xbib.rpm.header.HeaderTag.CONFLICTVERSION
import static org.xbib.rpm.header.HeaderTag.DISTRIBUTION
import static org.xbib.rpm.header.HeaderTag.FILEGROUPNAME
import static org.xbib.rpm.header.HeaderTag.FILEMODES
import static org.xbib.rpm.header.HeaderTag.FILEUSERNAME
import static org.xbib.rpm.header.HeaderTag.OBSOLETEFLAGS
import static org.xbib.rpm.header.HeaderTag.OBSOLETENAME
import static org.xbib.rpm.header.HeaderTag.OBSOLETEVERSION
import static org.xbib.rpm.header.HeaderTag.PREFIXES
import static org.xbib.rpm.lead.Architecture.I386
import static org.xbib.rpm.lead.Os.LINUX
import static org.xbib.rpm.lead.PackageType.BINARY
import static org.xbib.rpm.payload.CpioHeader.DIR
import static org.xbib.rpm.payload.CpioHeader.FILE
class RpmFullTest {
File projectDir
@BeforeEach
void setup() {
projectDir = new File("build/testrpm")
projectDir.mkdirs()
}
@Test
void testCopySpec() {
File bananaFile = new File(projectDir, 'test/banana')
bananaFile.parentFile.mkdirs()
bananaFile.withWriter {
out -> out.write('banana')
}
File srcDir = new File(projectDir, 'src')
srcDir.mkdirs()
String fruit = 'apple'
File appleFile = new File(srcDir, fruit)
appleFile.withWriter {
out -> out.write(fruit)
}
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'test'
packageVersion = '1.0.0'
packageRelease = '1'
addParentDirs = true
from(bananaFile.absoluteFile.parent) {
into '/usr/share/myproduct/etc'
}
from(appleFile.absoluteFile.parent) {
into '/usr/local/myproduct/bin'
}
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
RpmReaderResult result = rpmReader.read(project.tasks.buildRpm.outputs.files.first().toPath())
assertEquals([
'./usr/local/myproduct',
'./usr/local/myproduct/bin',
'./usr/local/myproduct/bin/apple',
'./usr/share/myproduct',
'./usr/share/myproduct/etc',
'./usr/share/myproduct/etc/banana'], result.files*.name)
assertEquals([DIR, DIR, FILE, DIR, DIR, FILE], result.files*.type)
}
@Test
void testExplicitDirectory() {
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'test'
packageVersion = '1.0.0'
packageRelease = '1'
directory '/lib'
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
RpmReaderResult result = rpmReader.read(project.tasks.buildRpm.outputs.files.first().toPath())
assertNotNull(result.files.find { it.name == './lib' })
}
@Test
void testFilter() {
File appleFile = new File(projectDir, 'src/apple')
appleFile.mkdirs()
appleFile.withWriter {
out -> out.write('{{BASE}}/apple')
}
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'test'
packageVersion = '1.0.0'
packageRelease = '1'
from(appleFile.absoluteFile.parent) {
into '/usr/local/myproduct/bin'
filter({ line ->
return line.replaceAll(/\{\{BASE\}\}/, '/usr/local/myproduct')
})
}
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
RpmReaderResult result = rpmReader.read(project.tasks.buildRpm.outputs.files.first().toPath())
def scannerApple = result.files.find { it.name == './usr/local/myproduct/bin/apple' }
assertEquals(StandardCharsets.UTF_8.decode(scannerApple.contents).toString(), '/usr/local/myproduct/apple')
}
@Test
void testCustomCopySpec() {
File srcDir = new File(projectDir, 'src')
srcDir.mkdirs()
String fruit = 'apple'
File appleFile = new File(srcDir, fruit)
appleFile.withWriter {
out -> out.write(fruit)
}
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
def customCopySpec = project.copySpec {
into('lib') {
from 'src'
}
}
project.task([type: Rpm], 'buildRpm', {
packageName = 'copyspec'
packageVersion = '1.0.0'
packageRelease = '1'
with customCopySpec
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
RpmReaderResult result = rpmReader.read(project.tasks.buildRpm.outputs.files.first().toPath())
assertThat(result.files*.name, is(['./lib/apple']))
}
@Test
void testFileMode() {
File srcDir1 = new File(projectDir, 'src1')
srcDir1.mkdirs()
new File(srcDir1, 'apple').withWriter { out -> out.write('apple') }
File srcDir2 = new File(projectDir, 'src2')
srcDir2.mkdirs()
new File(srcDir2, 'banana').withWriter { out -> out.write('banana') }
File srcDir3 = new File(projectDir, 'src3')
srcDir3.mkdirs()
new File(srcDir3, 'cherry').withWriter { out -> out.write('cherry') }
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'fileMode'
packageVersion = '2.0'
packageRelease = '2'
into '/tiny'
fileMode 0555
from(srcDir1.absoluteFile) {
// should be default group
}
from(srcDir2.absoluteFile) {
fileMode 0666
}
from(srcDir3.absoluteFile) {
fileMode 0555
}
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
RpmReaderResult result = rpmReader.read(project.tasks.buildRpm.outputs.files.first().toPath())
assertEquals([FILE, FILE, FILE], result.files*.type)
assertEquals(['./tiny/apple', './tiny/banana', './tiny/cherry'], result.files*.name)
assertThat([(short)0100555, (short)0100666, (short)0100555], is(result.format.header.getEntry(FILEMODES).values))
}
@Test
void testUserGroup() {
File srcDir = new File(projectDir, 'src')
srcDir.mkdirs()
new File(srcDir, 'apple').withWriter { out -> out.write('apple') }
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'userTest'
packageVersion = '2.0'
packageRelease = '2'
user = 'joerg'
group = 'users'
from srcDir.absoluteFile
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
RpmReaderResult result = rpmReader.read(project.tasks.buildRpm.outputs.files.first().toPath())
assertEquals([FILE], result.files*.type)
StringList users = result.format.header.getEntry(FILEUSERNAME)?.values as StringList
assertThat(['joerg'], is(users))
StringList groups = result.format.header.getEntry(FILEGROUPNAME)?.values as StringList
assertThat(['users'], is(groups))
}
@Test
void testPrefix() {
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'prefixes'
packageVersion = '1.0.0'
packageRelease = '1'
prefixes = ['/opt']
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
RpmReaderResult result = rpmReader.read(project.tasks.buildRpm.outputs.files.first().toPath())
assertThat(StringList.of('/opt') as StringList, is(result.format.header.getEntry(PREFIXES).values))
}
@Test
void testConflictsAndObsoletes() {
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
File srcDir = new File(projectDir, 'src')
srcDir.mkdirs()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'testing'
packageVersion = '1.2'
packageRelease = '3'
packageType = BINARY
arch = I386
os = LINUX
license = 'Free'
distribution = 'SuperSystem'
vendor = 'Super Associates, LLC'
url = 'http://www.example.com/'
obsoletes('blarg', '1.0', GREATER | EQUAL)
conflicts('blech')
conflicts('packageA', '1.0', LESS)
obsoletes('packageB', '2.2', GREATER)
obsoletes('packageC')
from(srcDir)
into '/opt/bleah'
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
def result = rpmReader.read(Paths.get(projectDir.toString(), 'build', 'distributions', 'testing-1.2-3.i386.rpm'))
Format format = result.format
StringList obsoletes = format.header.getEntry(OBSOLETENAME).values as StringList
StringList obsoleteVersions = format.header.getEntry(OBSOLETEVERSION).values as StringList
IntegerList obsoleteComparisons = format.header.getEntry(OBSOLETEFLAGS).values as IntegerList
StringList conflicts = format.header.getEntry(CONFLICTNAME).values as StringList
StringList conflictVersions = format.header.getEntry(CONFLICTVERSION).values as StringList
IntegerList conflictComparisons = format.header.getEntry(CONFLICTFLAGS).values as IntegerList
StringList distribution = format.header.getEntry(DISTRIBUTION).values as StringList
assertThat(StringList.of('SuperSystem') as StringList, is(distribution))
assertThat('blarg', is(obsoletes.get(0)))
assertThat(GREATER | EQUAL, is(obsoleteComparisons.get(0)))
assertThat('blech', is(conflicts.get(0)))
assertThat('', is(conflictVersions.get(0)))
assertThat(0, is(conflictComparisons.get(0)))
assertThat('packageA', is(conflicts.get(1)))
assertThat('1.0', is(conflictVersions.get(1)))
assertThat(LESS, is(conflictComparisons.get(1)))
assertThat('packageB', is(obsoletes.get(1)))
assertThat('2.2', is(obsoleteVersions.get(1)))
assertThat(GREATER, is(obsoleteComparisons.get(1)))
assertThat('packageC', is(obsoletes.get(2)))
}
@Test
void testFilesFromConfiguration() {
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.repositories {
mavenCentral()
}
project.configurations {
myconf
}
project.dependencies {
myconf "junit:junit:4.12"
}
project.task([type: Rpm], 'buildRpm', {
packageName = 'fromconfiguration'
packageVersion = '1.0.0'
packageRelease = '1'
into('/tmp') {
from project.configurations.myconf
}
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
RpmReaderResult result = rpmReader.read(project.tasks.buildRpm.outputs.files.first().toPath())
assertThat(['./tmp/hamcrest-core-1.3.jar', './tmp/junit-4.12.jar'], is(result.files*.name))
}
}

View file

@ -0,0 +1,57 @@
package org.xbib.gradle.plugin
import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import static org.junit.jupiter.api.Assertions.assertEquals
class RpmPluginIntegrationTest {
private File projectDir
private File settingsFile
private File buildFile
@BeforeEach
void setup(@TempDir File testProjectDir) throws IOException {
this.projectDir = testProjectDir
this.settingsFile = new File(testProjectDir, "settings.gradle")
this.buildFile = new File(testProjectDir, "build.gradle")
}
@Test
void testPlugin() {
String settingsFileContent = '''
rootProject.name = 'rpm-test'
'''
settingsFile.write(settingsFileContent)
String buildFileContent = '''
plugins {
id 'org.xbib.gradle.plugin.rpm'
}
rpm {
enabled = true
}
task myRpm(type: Rpm) {
packageName = 'rpmIsUpToDate'
arch = org.xbib.rpm.lead.Architecture.NOARCH
os = org.xbib.rpm.lead.Os.LINUX
}
'''
buildFile.write(buildFileContent)
BuildResult result = GradleRunner.create()
.withProjectDir(projectDir)
.withArguments(":build", "--info")
.withPluginClasspath()
.forwardOutput()
.build()
assertEquals(TaskOutcome.UP_TO_DATE, result.task(":build").getOutcome())
}
}

View file

@ -0,0 +1,156 @@
package org.xbib.gradle.plugin
import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.xbib.rpm.RpmReader
import org.xbib.rpm.changelog.ChangelogParser
import org.xbib.rpm.format.Format
import org.xbib.rpm.header.EntryType
import org.xbib.rpm.header.IntegerList
import org.xbib.rpm.header.StringList
import org.xbib.rpm.header.entry.SpecEntry
import java.time.LocalDateTime
import java.time.ZoneOffset
import static org.hamcrest.MatcherAssert.assertThat
import static org.hamcrest.CoreMatchers.*
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.junit.jupiter.api.Assertions.assertNotNull
import static org.xbib.rpm.header.HeaderTag.POSTINSCRIPT
import static org.xbib.rpm.header.HeaderTag.POSTTRANSSCRIPT
import static org.xbib.rpm.header.HeaderTag.POSTUNSCRIPT
import static org.xbib.rpm.header.HeaderTag.PREINSCRIPT
import static org.xbib.rpm.header.HeaderTag.PRETRANSSCRIPT
import static org.xbib.rpm.header.HeaderTag.PREUNSCRIPT
import static org.xbib.rpm.header.HeaderTag.CHANGELOGNAME
import static org.xbib.rpm.header.HeaderTag.CHANGELOGTEXT
import static org.xbib.rpm.header.HeaderTag.CHANGELOGTIME
class RpmScriptTest {
File projectDir
@BeforeEach
void setup() {
projectDir = new File("build/testrpm")
projectDir.mkdirs()
}
@Test
void testInstallScripts() {
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'installscripts'
packageVersion = '1.0'
packageRelease = '1'
preInstall = "echo 'Hello Pre World'"
postInstall = "echo 'Hello Post World'"
preUninstall = "echo 'Hello PreUn World'"
postUninstall = "echo 'Hello PostUn World'"
preTrans = "echo 'Hello PreTrans World'"
postTrans = "echo 'Hello PostTrans World'"
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
def result = rpmReader.read(project.tasks.buildRpm.outputs.files.first().toPath())
Format format = result.format
assertThat(["echo 'Hello Pre World'"], is(format.header.getEntry(PREINSCRIPT)?.values))
assertThat(["echo 'Hello Post World'"], is(format.header.getEntry(POSTINSCRIPT)?.values))
assertThat(["echo 'Hello PreUn World'"], is(format.header.getEntry(PREUNSCRIPT)?.values))
assertThat(["echo 'Hello PostUn World'"], is(format.header.getEntry(POSTUNSCRIPT)?.values))
assertThat(["echo 'Hello PreTrans World'"], is(format.header.getEntry(PRETRANSSCRIPT)?.values))
assertThat(["echo 'Hello PostTrans World'"], is(format.header.getEntry(POSTTRANSSCRIPT)?.values))
}
@Test
void testInstallScriptFiles() {
String preinstall = getClass().getResource('preinstall.sh').text
File scriptDir = new File(projectDir, 'scripts')
scriptDir.mkdirs()
new File(scriptDir, 'preinstall.sh').withWriter { out -> out.write(preinstall) }
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'installscripts'
packageVersion = '1.0'
packageRelease = '1'
preInstallFile = project.file('scripts/preinstall.sh')
postInstall = "echo 'Hello Post World'"
preUninstall = "echo 'Hello PreUn World'"
postUninstall = "echo 'Hello PostUn World'"
preTrans = "echo 'Hello PreTrans World'"
postTrans = "echo 'Hello PostTrans World'"
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
def result = rpmReader.read(project.tasks.buildRpm.outputs.files.first().toPath())
Format format = result.format
assertThat(["#!/usr/bin/env bash\necho 'Hello from file'\n"], is(format.header.getEntry(PREINSCRIPT)?.values))
assertThat(["echo 'Hello Post World'"], is(format.header.getEntry(POSTINSCRIPT)?.values))
assertThat(["echo 'Hello PreUn World'"], is(format.header.getEntry(PREUNSCRIPT)?.values))
assertThat(["echo 'Hello PostUn World'"], is(format.header.getEntry(POSTUNSCRIPT)?.values))
assertThat(["echo 'Hello PreTrans World'"], is(format.header.getEntry(PRETRANSSCRIPT)?.values))
assertThat(["echo 'Hello PostTrans World'"], is(format.header.getEntry(POSTTRANSSCRIPT)?.values))
}
@Test
void testChangeLog() {
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
String changelog = getClass().getResource('changelog').text
File changelogDir = new File(projectDir, 'changelog')
changelogDir.mkdirs()
new File(changelogDir, 'changelog').withWriter { out -> out.write(changelog) }
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'changelog'
packageVersion = '1.0'
packageRelease = '1'
changeLogFile = project.file('changelog/changelog')
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
def result = rpmReader.read(project.tasks.buildRpm.outputs.files.first().toPath())
Format format = result.format
assertDateEntryHeaderEqualsAt("Tue Feb 24 2015", format,
CHANGELOGTIME, 10, 0)
assertHeaderEqualsAt("Thomas Jefferson", format,
CHANGELOGNAME, 10, 4)
assertHeaderEqualsAt("- Initial rpm for this package", format,
CHANGELOGTEXT, 10, 9)
assertHeaderEqualsAt("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod \n" +
"tempor incididunt ut labore et dolore magna aliqua", format,
CHANGELOGTEXT, 10, 0)
}
private static void assertDateEntryHeaderEqualsAt(String expected, Format format, EntryType entryType, int size, int pos) {
assertNotNull(format, "null format")
SpecEntry<?> entry = format.getHeader().getEntry(entryType)
assertNotNull(entry, "Entry not found : " + entryType.getName())
assertEquals(4, entry.getType(), "Entry type : " + entryType.getName())
IntegerList values = (IntegerList) entry.getValues()
assertNotNull(values, "null values")
assertEquals(size, values.size(), "Entry size : " + entryType.getName())
LocalDateTime localDate = LocalDateTime.ofEpochSecond(values.get(pos), 0, ZoneOffset.UTC)
assertEquals(expected, ChangelogParser.CHANGELOG_FORMAT.format(localDate), "Entry value : " + entryType.getName())
}
private static void assertHeaderEqualsAt(String expected, Format format, EntryType entryType, int size, int pos) {
assertNotNull(format, "null format")
SpecEntry<?> entry = format.getHeader().getEntry(entryType)
assertNotNull(entry, "Entry not found : " + entryType.getName())
assertEquals(8, entry.getType(), "Entry type : " + entryType.getName())
StringList values = (StringList) entry.getValues()
assertNotNull(values, "null values")
assertEquals(size, values.size(), "Entry size : " + entryType.getName())
assertEquals(expected, values.get(pos), "Entry value : " + entryType.getName())
}
}

View file

@ -0,0 +1,62 @@
package org.xbib.gradle.plugin
import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.xbib.rpm.RpmReader
import org.xbib.rpm.signature.SignatureTag
import java.nio.file.Paths
import static org.junit.jupiter.api.Assertions.assertNotNull
import static org.junit.jupiter.api.Assertions.assertNull
import static org.xbib.rpm.lead.Architecture.I386
class RpmSignTest {
File projectDir
@BeforeEach
void setup() {
projectDir = new File("build/testrpm")
projectDir.mkdirs()
}
@Test
void testUnsigned() {
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'bleah'
packageVersion = '1.0'
packageRelease = '1'
arch = I386
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
def res = rpmReader.read(Paths.get(projectDir.toString(), 'build', 'distributions', 'bleah-1.0-1.i386.rpm'))
assertNull(res.format.signatureHeader.getEntry(SignatureTag.LEGACY_PGP))
}
@Test
void testSign() {
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'bleah'
packageVersion = '1.0'
packageRelease = '1'
arch = I386
signingKeyId = 'F02C6D2C'
signingKeyPassphrase = 'test'
signingKeyRing = 'src/test/resources/test-secring.gpg'
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
def res = rpmReader.read(Paths.get(projectDir.toString(), 'build', 'distributions', 'bleah-1.0-1.i386.rpm'))
assertNotNull(res.format.signatureHeader.getEntry(SignatureTag.LEGACY_PGP))
}
}

View file

@ -0,0 +1,104 @@
package org.xbib.gradle.plugin
import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.xbib.rpm.RpmReaderResult
import org.xbib.rpm.RpmReader
import org.xbib.rpm.format.Format
import java.nio.file.Paths
import static org.hamcrest.MatcherAssert.assertThat
import static org.hamcrest.CoreMatchers.*
import static org.junit.jupiter.api.Assertions.assertTrue
import static org.xbib.rpm.format.Flags.EQUAL
import static org.xbib.rpm.format.Flags.GREATER
import static org.xbib.rpm.header.HeaderTag.ARCH
import static org.xbib.rpm.header.HeaderTag.DISTRIBUTION
import static org.xbib.rpm.header.HeaderTag.EPOCH
import static org.xbib.rpm.header.HeaderTag.NAME
import static org.xbib.rpm.header.HeaderTag.OS
import static org.xbib.rpm.header.HeaderTag.RELEASE
import static org.xbib.rpm.header.HeaderTag.VERSION
import static org.xbib.rpm.lead.Architecture.I386
import static org.xbib.rpm.lead.Os.LINUX
import static org.xbib.rpm.lead.PackageType.BINARY
class RpmSimpleTest {
File projectDir
@BeforeEach
void setup() {
projectDir = new File("build/testrpm")
projectDir.mkdirs()
}
@Test
void simpleRpm() {
File srcDir = new File(projectDir, 'src')
srcDir.mkdirs()
new File(srcDir, 'apple').withWriter { out ->
out.write('apple')
}
File noParentsDir = new File(projectDir, 'noParentsDir')
noParentsDir.mkdirs()
new File(noParentsDir, 'alone').withWriter { out ->
out.write('alone')
}
Project project = ProjectBuilder.builder()
.withProjectDir(projectDir)
.build()
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
project.task([type: Rpm], 'buildRpm', {
packageName = 'bleah'
packageVersion = '1.0'
packageRelease = '1'
packageType = BINARY
arch = I386
os = LINUX
packageGroup = 'Development/Libraries'
packageDescription = 'Not a very interesting library.'
summary = 'Bleah blarg'
license = 'Free'
distribution = 'SuperSystem'
vendor = 'Super Associates, LLC'
url = 'http://www.example.com/'
requires('blarg', '1.0', GREATER | EQUAL)
requires('blech')
into '/opt/bleah'
from('src') {
fileType = ['config', 'noreplace']
}
from('noParentsDir') {
into '/a/path/not/to/create'
}
link('/opt/bleah/banana', '/opt/bleah/apple')
})
project.tasks.buildRpm.copy()
RpmReader rpmReader = new RpmReader()
RpmReaderResult result = rpmReader.read(Paths.get(projectDir.toString(), 'build', 'distributions', 'bleah-1.0-1.i386.rpm'))
Format format = result.format
assertThat(['bleah'], is(format.header.getEntry(NAME)?.values))
assertThat(['1.0'], is(format.header.getEntry(VERSION)?.values))
assertThat(['1'], is(format.header.getEntry(RELEASE)?.values))
assertThat([0], is(format.header.getEntry(EPOCH)?.values))
assertThat(['i386'], is(format.header.getEntry(ARCH)?.values))
assertThat(['linux'], is(format.header.getEntry(OS)?.values))
assertThat(['SuperSystem'], is(format.header.getEntry(DISTRIBUTION)?.values))
assertTrue(result.files*.name.every { fileName ->
['./a/path/not/to/create/alone',
'./opt/bleah',
'./opt/bleah/apple',
'./opt/bleah/banana'
].any { path ->
path.startsWith(fileName)
}
})
assertTrue(result.files*.name.every { fileName ->
['./a/path/not/to/create'].every { path ->
!path.startsWith(fileName)
}
})
}
}

View file

@ -0,0 +1,24 @@
* Tue Feb 24 2015 George Washington
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua
* Tue Feb 10 2015 George Washington
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
* Mon Nov 17 2014 George Washington
consectetur, adipisci velit, sed quia non numquam eius modi
sunt explicabo. Nemo enim ipsam voluptatem quia vol
eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat
Excepteur sint occaecat cupidatat non proident, sunt
* Fri Mar 06 2009 John Adams
- nostrum exercitationem ullam corporis suscipit
* Thu Oct 16 2008 Thomas Jefferson
- Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit,
* Thu Aug 23 2007 James Madison
eaque ipsa quae ab illo inventore veritatis et quasi architecto
* Mon Jun 04 2007 James Monroe
- adipisci velit, sed q
* Tue May 08 2007 James Madison
- dolore eu fugiat nulla pariatur
* Tue Apr 10 2007 James Monroe
-+// quis nostrum exercitationem ullam corporis
* Wed Nov 08 2006 James Madison
- Initial rpm for this package

View file

@ -0,0 +1,2 @@
#!/usr/bin/env bash
echo 'Hello from file'

Binary file not shown.

View file

@ -1,3 +1,17 @@
group = org.xbib group = org.xbib
name = rpm name = rpm
version = 4.0.0 version = 2.0.0
gradle.wrapper.version = 6.4.1
gradle.publish.plugin.version = 0.11.0
bouncycastle.version = 1.64
xbib-archive.version = 1.0.0
ant.version = 1.10.8
maven.version = 3.6.3
maven-plugin-annotations.version = 3.6.0
maven-plugin-plugin.version = 3.6.0
maven-wagon.version = 3.3.4
aether-connector-basic.version = 1.1.0
aether-transport-wagon.version = 1.1.0
slf4j.version = 1.7.25
mvel.version = 2.4.5.Final

View file

@ -2,12 +2,17 @@
apply plugin: 'java-library' apply plugin: 'java-library'
java { java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
modularity.inferModulePath.set(true) modularity.inferModulePath.set(true)
withSourcesJar() }
withJavadocJar()
compileJava {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
compileTestJava {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
} }
jar { jar {
@ -16,14 +21,15 @@ jar {
} }
} }
tasks.withType(JavaCompile) { task sourcesJar(type: Jar, dependsOn: classes) {
options.fork = true classifier 'sources'
options.forkOptions.jvmArgs += ['-Duser.language=en','-Duser.country=US'] from sourceSets.main.allSource
options.compilerArgs << '-Xlint:all,-fallthrough'
options.encoding = 'UTF-8'
} }
javadoc { task javadocJar(type: Jar, dependsOn: javadoc) {
options.addStringOption('Xdoclint:none', '-quiet') classifier 'javadoc'
options.encoding = 'UTF-8' }
artifacts {
archives sourcesJar, javadocJar
} }

View file

@ -1,16 +0,0 @@
if (project.hasProperty('forgeJoToken')) {
publishing {
repositories {
maven {
url 'https://xbib.org/api/packages/joerg/maven'
credentials(HttpHeaderCredentials) {
name = "Authorization"
value = "token ${project.property('forgeJoToken')}"
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
}
}

View file

@ -1,27 +0,0 @@
apply plugin: 'ivy-publish'
publishing {
repositories {
ivy {
url = "https://xbib.org/repo"
}
}
publications {
ivy(IvyPublication) {
from components.java
descriptor {
license {
name = 'The Apache License, Version 2.0'
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
author {
name = 'Jörg Prante'
url = 'http://example.com/users/jane'
}
descriptor.description {
text = rootProject.ext.description
}
}
}
}
}

View file

@ -1,11 +0,0 @@
if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')) {
nexusPublishing {
repositories {
sonatype {
username = project.property('ossrhUsername')
password = project.property('ossrhPassword')
packageGroup = "org.xbib"
}
}
}
}

View file

@ -1,10 +1,13 @@
apply plugin: "de.marcphilipp.nexus-publish"
publishing { publishing {
publications { publications {
"${project.name}"(MavenPublication) { mavenJava(MavenPublication) {
from components.java from components.java
artifact sourcesJar
artifact javadocJar
pom { pom {
artifactId = project.name
name = project.name name = project.name
description = rootProject.ext.description description = rootProject.ext.description
url = rootProject.ext.url url = rootProject.ext.url
@ -46,6 +49,16 @@ publishing {
if (project.hasProperty("signing.keyId")) { if (project.hasProperty("signing.keyId")) {
apply plugin: 'signing' apply plugin: 'signing'
signing { signing {
sign publishing.publications."${project.name}" sign publishing.publications.mavenJava
}
}
nexusPublishing {
repositories {
sonatype {
username = project.property('ossrhUsername')
password = project.property('ossrhPassword')
packageGroup = "org.xbib"
}
} }
} }

View file

@ -0,0 +1,11 @@
if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')) {
apply plugin: 'io.codearte.nexus-staging'
nexusStaging {
username = project.property('ossrhUsername')
password = project.property('ossrhPassword')
packageGroup = "org.xbib"
}
}

View file

@ -1,18 +0,0 @@
tasks.withType(Checkstyle) {
ignoreFailures = true
reports {
xml.getRequired().set(true)
html.getRequired().set(true)
}
}
checkstyle {
toolVersion = '10.4'
configFile = rootProject.file('gradle/quality/checkstyle.xml')
ignoreFailures = true
showViolations = false
checkstyleMain {
source = sourceSets.main.allSource
}
}

View file

@ -1,333 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!-- This is a checkstyle configuration file. For descriptions of
what the following rules do, please see the checkstyle configuration
page at http://checkstyle.sourceforge.net/config.html -->
<module name="Checker">
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value=".*(Example|Test|module-info)(\$.*)?"/>
</module>
<module name="FileTabCharacter">
<!-- Checks that there are no tab characters in the file.
-->
</module>
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf"/>
</module>
<module name="RegexpSingleline">
<!-- Checks that FIXME is not used in comments. TODO is preferred.
-->
<property name="format" value="((//.*)|(\*.*))FIXME" />
<property name="message" value='TODO is preferred to FIXME. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="RegexpSingleline">
<!-- Checks that TODOs are named. (Actually, just that they are followed
by an open paren.)
-->
<property name="format" value="((//.*)|(\*.*))TODO[^(]" />
<property name="message" value='All TODOs should be named. e.g. "TODO(johndoe): Refactor when v2 is released."' />
</module>
<module name="JavadocPackage">
<!-- Checks that each Java package has a Javadoc file used for commenting.
Only allows a package-info.java, not package.html. -->
</module>
<!-- All Java AST specific tests live under TreeWalker module. -->
<module name="TreeWalker">
<!--
IMPORT CHECKS
-->
<module name="RedundantImport">
<!-- Checks for redundant import statements. -->
<property name="severity" value="error"/>
</module>
<module name="ImportOrder">
<!-- Checks for out of order import statements. -->
<property name="severity" value="warning"/>
<!-- <property name="tokens" value="IMPORT, STATIC_IMPORT"/> -->
<property name="separated" value="false"/>
<property name="groups" value="*"/>
<!-- <property name="option" value="above"/> -->
<property name="sortStaticImportsAlphabetically" value="true"/>
</module>
<module name="CustomImportOrder">
<!-- <property name="customImportOrderRules" value="THIRD_PARTY_PACKAGE###SPECIAL_IMPORTS###STANDARD_JAVA_PACKAGE###STATIC"/> -->
<!-- <property name="specialImportsRegExp" value="^javax\."/> -->
<!-- <property name="standardPackageRegExp" value="^java\."/> -->
<property name="sortImportsInGroupAlphabetically" value="true"/>
<property name="separateLineBetweenGroups" value="false"/>
</module>
<!--
JAVADOC CHECKS
-->
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="accessModifiers" value="protected"/>
<property name="severity" value="warning"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
</module>
<module name="JavadocType">
<property name="scope" value="protected"/>
<property name="severity" value="error"/>
</module>
<module name="JavadocStyle">
<property name="severity" value="warning"/>
</module>
<!--
NAMING CHECKS
-->
<!-- Item 38 - Adhere to generally accepted naming conventions -->
<module name="PackageName">
<!-- Validates identifiers for package names against the
supplied expression. -->
<!-- Here the default checkstyle rule restricts package name parts to
seven characters, this is not in line with common practice at Google.
-->
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/>
<property name="severity" value="warning"/>
</module>
<module name="TypeNameCheck">
<!-- Validates static, final fields against the
expression "^[A-Z][a-zA-Z0-9]*$". -->
<metadata name="altname" value="TypeName"/>
<property name="severity" value="warning"/>
</module>
<module name="ConstantNameCheck">
<!-- Validates non-private, static, final fields against the supplied
public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". -->
<metadata name="altname" value="ConstantName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="false"/>
<property name="format" value="^([A-Z][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/>
<message key="name.invalidPattern"
value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/>
<property name="severity" value="warning"/>
</module>
<module name="StaticVariableNameCheck">
<!-- Validates static, non-final fields against the supplied
expression "^[a-z][a-zA-Z0-9]*_?$". -->
<metadata name="altname" value="StaticVariableName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/>
<property name="severity" value="warning"/>
</module>
<module name="MemberNameCheck">
<!-- Validates non-static members against the supplied expression. -->
<metadata name="altname" value="MemberName"/>
<property name="applyToPublic" value="true"/>
<property name="applyToProtected" value="true"/>
<property name="applyToPackage" value="true"/>
<property name="applyToPrivate" value="true"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
<property name="severity" value="warning"/>
</module>
<module name="MethodNameCheck">
<!-- Validates identifiers for method names. -->
<metadata name="altname" value="MethodName"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/>
<property name="severity" value="warning"/>
</module>
<module name="ParameterName">
<!-- Validates identifiers for method parameters against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalFinalVariableName">
<!-- Validates identifiers for local final variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<module name="LocalVariableName">
<!-- Validates identifiers for local variables against the
expression "^[a-z][a-zA-Z0-9]*$". -->
<property name="severity" value="warning"/>
</module>
<!--
LENGTH and CODING CHECKS
-->
<module name="LeftCurly">
<!-- Checks for placement of the left curly brace ('{'). -->
<property name="severity" value="warning"/>
</module>
<module name="RightCurly">
<!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on
the same line. e.g., the following example is fine:
<pre>
if {
...
} else
</pre>
-->
<!-- This next example is not fine:
<pre>
if {
...
}
else
</pre>
-->
<property name="option" value="same"/>
<property name="severity" value="warning"/>
</module>
<!-- Checks for braces around if and else blocks -->
<module name="NeedBraces">
<property name="severity" value="warning"/>
<property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/>
</module>
<module name="UpperEll">
<!-- Checks that long constants are defined with an upper ell.-->
<property name="severity" value="error"/>
</module>
<module name="FallThrough">
<!-- Warn about falling through to the next case statement. Similar to
javac -Xlint:fallthrough, but the check is suppressed if a single-line comment
on the last non-blank line preceding the fallen-into case contains 'fall through' (or
some other variants which we don't publicized to promote consistency).
-->
<property name="reliefPattern"
value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/>
<property name="severity" value="error"/>
</module>
<!--
MODIFIERS CHECKS
-->
<module name="ModifierOrder">
<!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and
8.4.3. The prescribed order is:
public, protected, private, abstract, static, final, transient, volatile,
synchronized, native, strictfp
-->
</module>
<!--
WHITESPACE CHECKS
-->
<module name="WhitespaceAround">
<!-- Checks that various tokens are surrounded by whitespace.
This includes most binary operators and keywords followed
by regular or curly braces.
-->
<property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR,
BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN,
EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS,
MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION,
SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/>
<property name="severity" value="error"/>
</module>
<module name="WhitespaceAfter">
<!-- Checks that commas, semicolons and typecasts are followed by
whitespace.
-->
<property name="tokens" value="COMMA, SEMI, TYPECAST"/>
</module>
<module name="NoWhitespaceAfter">
<!-- Checks that there is no whitespace after various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS,
UNARY_PLUS"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="NoWhitespaceBefore">
<!-- Checks that there is no whitespace before various unary operators.
Linebreaks are allowed.
-->
<property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/>
<property name="allowLineBreaks" value="true"/>
<property name="severity" value="error"/>
</module>
<module name="ParenPad">
<!-- Checks that there is no whitespace before close parens or after
open parens.
-->
<property name="severity" value="warning"/>
</module>
</module>
<module name="LineLength">
<!-- Checks if a line is too long. -->
<property name="max" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.max}" default="128"/>
<property name="severity" value="error"/>
<!--
The default ignore pattern exempts the following elements:
- import statements
- long URLs inside comments
-->
<property name="ignorePattern"
value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}"
default="^(package .*;\s*)|(import .*;\s*)|( *(\*|//).*https?://.*)$"/>
</module>
</module>

View file

@ -1,11 +0,0 @@
cyclonedxBom {
includeConfigs = [ 'runtimeClasspath' ]
skipConfigs = [ 'compileClasspath', 'testCompileClasspath' ]
projectType = "library"
schemaVersion = "1.4"
destination = file("build/reports")
outputName = "bom"
outputFormat = "json"
includeBomSerialNumber = true
componentVersion = "2.0.0"
}

View file

@ -1,15 +0,0 @@
tasks.withType(Pmd) {
ignoreFailures = true
reports {
xml.getRequired().set(true)
html.getRequired().set(true)
}
}
pmd {
ignoreFailures = true
consoleOutput = false
toolVersion = "6.51.0"
ruleSetFiles = rootProject.files('gradle/quality/pmd/category/java/bestpractices.xml')
}

File diff suppressed because it is too large Load diff

View file

@ -1,10 +0,0 @@
rulesets.filenames=\
category/java/bestpractices.xml,\
category/java/codestyle.xml,\
category/java/design.xml,\
category/java/documentation.xml,\
category/java/errorprone.xml,\
category/java/multithreading.xml,\
category/java/performance.xml,\
category/java/security.xml

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,144 +0,0 @@
<?xml version="1.0"?>
<ruleset name="Documentation"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>
Rules that are related to code documentation.
</description>
<rule name="CommentContent"
since="5.0"
message="Invalid words or phrases found"
class="net.sourceforge.pmd.lang.java.rule.documentation.CommentContentRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentcontent">
<description>
A rule for the politically correct... we don't want to offend anyone.
</description>
<priority>3</priority>
<example>
<![CDATA[
//OMG, this is horrible, Bob is an idiot !!!
]]>
</example>
</rule>
<rule name="CommentRequired"
since="5.1"
message="Comment is required"
class="net.sourceforge.pmd.lang.java.rule.documentation.CommentRequiredRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentrequired">
<description>
Denotes whether comments are required (or unwanted) for specific language elements.
</description>
<priority>3</priority>
<example>
<![CDATA[
/**
*
*
* @author Jon Doe
*/
]]>
</example>
</rule>
<rule name="CommentSize"
since="5.0"
message="Comment is too large"
class="net.sourceforge.pmd.lang.java.rule.documentation.CommentSizeRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentsize">
<description>
Determines whether the dimensions of non-header comments found are within the specified limits.
</description>
<priority>3</priority>
<example>
<![CDATA[
/**
*
* too many lines!
*
*
*
*
*
*
*
*
*
*
*
*
*/
]]>
</example>
</rule>
<rule name="UncommentedEmptyConstructor"
language="java"
since="3.4"
message="Document empty constructor"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#uncommentedemptyconstructor">
<description>
Uncommented Empty Constructor finds instances where a constructor does not
contain statements, but there is no comment. By explicitly commenting empty
constructors it is easier to distinguish between intentional (commented)
and unintentional empty constructors.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ConstructorDeclaration[@Private='false']
[count(BlockStatement) = 0 and ($ignoreExplicitConstructorInvocation = 'true' or not(ExplicitConstructorInvocation)) and @containsComment = 'false']
[not(../Annotation/MarkerAnnotation/Name[pmd-java:typeIs('javax.inject.Inject')])]
]]>
</value>
</property>
<property name="ignoreExplicitConstructorInvocation" type="Boolean" description="Ignore explicit constructor invocation when deciding whether constructor is empty or not" value="false"/>
</properties>
<example>
<![CDATA[
public Foo() {
// This constructor is intentionally empty. Nothing special is needed here.
}
]]>
</example>
</rule>
<rule name="UncommentedEmptyMethodBody"
language="java"
since="3.4"
message="Document empty method body"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#uncommentedemptymethodbody">
<description>
Uncommented Empty Method Body finds instances where a method body does not contain
statements, but there is no comment. By explicitly commenting empty method bodies
it is easier to distinguish between intentional (commented) and unintentional
empty methods.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//MethodDeclaration/Block[count(BlockStatement) = 0 and @containsComment = 'false']
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public void doSomething() {
}
]]>
</example>
</rule>
</ruleset>

File diff suppressed because it is too large Load diff

View file

@ -1,393 +0,0 @@
<?xml version="1.0"?>
<ruleset name="Multithreading"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>
Rules that flag issues when dealing with multiple threads of execution.
</description>
<rule name="AvoidSynchronizedAtMethodLevel"
language="java"
since="3.0"
message="Use block level rather than method level synchronization"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidsynchronizedatmethodlevel">
<description>
Method-level synchronization can cause problems when new code is added to the method.
Block-level synchronization helps to ensure that only the code that needs synchronization
gets it.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>//MethodDeclaration[@Synchronized='true']</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo {
// Try to avoid this:
synchronized void foo() {
}
// Prefer this:
void bar() {
synchronized(this) {
}
}
// Try to avoid this for static methods:
static synchronized void fooStatic() {
}
// Prefer this:
static void barStatic() {
synchronized(Foo.class) {
}
}
}
]]>
</example>
</rule>
<rule name="AvoidThreadGroup"
language="java"
since="3.6"
message="Avoid using java.lang.ThreadGroup; it is not thread safe"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidthreadgroup">
<description>
Avoid using java.lang.ThreadGroup; although it is intended to be used in a threaded environment
it contains methods that are not thread-safe.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.ThreadGroup')]|
//PrimarySuffix[contains(@Image, 'getThreadGroup')]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class Bar {
void buz() {
ThreadGroup tg = new ThreadGroup("My threadgroup");
tg = new ThreadGroup(tg, "my thread group");
tg = Thread.currentThread().getThreadGroup();
tg = System.getSecurityManager().getThreadGroup();
}
}
]]>
</example>
</rule>
<rule name="AvoidUsingVolatile"
language="java"
since="4.1"
class="net.sourceforge.pmd.lang.rule.XPathRule"
message="Use of modifier volatile is not recommended."
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidusingvolatile">
<description>
Use of the keyword 'volatile' is generally used to fine tune a Java application, and therefore, requires
a good expertise of the Java Memory Model. Moreover, its range of action is somewhat misknown. Therefore,
the volatile keyword should not be used for maintenance purpose and portability.
</description>
<priority>2</priority>
<properties>
<property name="xpath">
<value>//FieldDeclaration[contains(@Volatile,'true')]</value>
</property>
</properties>
<example>
<![CDATA[
public class ThrDeux {
private volatile String var1; // not suggested
private String var2; // preferred
}
]]>
</example>
</rule>
<rule name="DoNotUseThreads"
language="java"
since="4.1"
class="net.sourceforge.pmd.lang.rule.XPathRule"
message="To be compliant to J2EE, a webapp should not use any thread."
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#donotusethreads">
<description>
The J2EE specification explicitly forbids the use of threads.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>//ClassOrInterfaceType[@Image = 'Thread' or @Image = 'Runnable']</value>
</property>
</properties>
<example>
<![CDATA[
// This is not allowed
public class UsingThread extends Thread {
}
// Neither this,
public class OtherThread implements Runnable {
// Nor this ...
public void methode() {
Runnable thread = new Thread(); thread.run();
}
}
]]>
</example>
</rule>
<rule name="DontCallThreadRun"
language="java"
since="4.3"
message="Don't call Thread.run() explicitly, use Thread.start()"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#dontcallthreadrun">
<description>
Explicitly calling Thread.run() method will execute in the caller's thread of control. Instead, call Thread.start() for the intended behavior.
</description>
<priority>4</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//StatementExpression/PrimaryExpression
[
PrimaryPrefix
[
./Name[ends-with(@Image, '.run') or @Image = 'run']
and substring-before(Name/@Image, '.') =//VariableDeclarator/VariableDeclaratorId/@Image
[../../../Type/ReferenceType/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread')]]
or (./AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread')]
and ../PrimarySuffix[@Image = 'run'])
]
]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
Thread t = new Thread();
t.run(); // use t.start() instead
new Thread().run(); // same violation
]]>
</example>
</rule>
<rule name="DoubleCheckedLocking"
language="java"
since="1.04"
message="Double checked locking is not thread safe in Java."
class="net.sourceforge.pmd.lang.java.rule.multithreading.DoubleCheckedLockingRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#doublecheckedlocking">
<description>
Partially created objects can be returned by the Double Checked Locking pattern when used in Java.
An optimizing JRE may assign a reference to the baz variable before it calls the constructor of the object the
reference points to.
Note: With Java 5, you can make Double checked locking work, if you declare the variable to be `volatile`.
For more details refer to: &lt;http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html>
or &lt;http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html>
</description>
<priority>1</priority>
<example>
<![CDATA[
public class Foo {
/*volatile */ Object baz = null; // fix for Java5 and later: volatile
Object bar() {
if (baz == null) { // baz may be non-null yet not fully created
synchronized(this) {
if (baz == null) {
baz = new Object();
}
}
}
return baz;
}
}
]]>
</example>
</rule>
<rule name="NonThreadSafeSingleton"
since="3.4"
message="Singleton is not thread safe"
class="net.sourceforge.pmd.lang.java.rule.multithreading.NonThreadSafeSingletonRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#nonthreadsafesingleton">
<description>
Non-thread safe singletons can result in bad state changes. Eliminate
static singletons if possible by instantiating the object directly. Static
singletons are usually not needed as only a single instance exists anyway.
Other possible fixes are to synchronize the entire method or to use an
[initialize-on-demand holder class](https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom).
Refrain from using the double-checked locking pattern. The Java Memory Model doesn't
guarantee it to work unless the variable is declared as `volatile`, adding an uneeded
performance penalty. [Reference](http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html)
See Effective Java, item 48.
</description>
<priority>3</priority>
<example>
<![CDATA[
private static Foo foo = null;
//multiple simultaneous callers may see partially initialized objects
public static Foo getFoo() {
if (foo==null) {
foo = new Foo();
}
return foo;
}
]]>
</example>
</rule>
<rule name="UnsynchronizedStaticDateFormatter"
since="3.6"
deprecated="true"
message="Static DateFormatter objects should be accessed in a synchronized manner"
class="net.sourceforge.pmd.lang.java.rule.multithreading.UnsynchronizedStaticDateFormatterRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#unsynchronizedstaticdateformatter">
<description>
SimpleDateFormat instances are not synchronized. Sun recommends using separate format instances
for each thread. If multiple threads must access a static formatter, the formatter must be
synchronized either on method or block level.
This rule has been deprecated in favor of the rule {% rule UnsynchronizedStaticFormatter %}.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
private static final SimpleDateFormat sdf = new SimpleDateFormat();
void bar() {
sdf.format(); // poor, no thread-safety
}
synchronized void foo() {
sdf.format(); // preferred
}
}
]]>
</example>
</rule>
<rule name="UnsynchronizedStaticFormatter"
since="6.11.0"
message="Static Formatter objects should be accessed in a synchronized manner"
class="net.sourceforge.pmd.lang.java.rule.multithreading.UnsynchronizedStaticFormatterRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#unsynchronizedstaticformatter">
<description>
Instances of `java.text.Format` are generally not synchronized.
Sun recommends using separate format instances for each thread.
If multiple threads must access a static formatter, the formatter must be
synchronized either on method or block level.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
private static final SimpleDateFormat sdf = new SimpleDateFormat();
void bar() {
sdf.format(); // poor, no thread-safety
}
synchronized void foo() {
sdf.format(); // preferred
}
}
]]>
</example>
</rule>
<rule name="UseConcurrentHashMap"
language="java"
minimumLanguageVersion="1.5"
since="4.2.6"
message="If you run in Java5 or newer and have concurrent access, you should use the ConcurrentHashMap implementation"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#useconcurrenthashmap">
<description>
Since Java5 brought a new implementation of the Map designed for multi-threaded access, you can
perform efficient map reads without blocking other threads.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//Type[../VariableDeclarator/VariableInitializer//AllocationExpression/ClassOrInterfaceType[@Image != 'ConcurrentHashMap']]
/ReferenceType/ClassOrInterfaceType[@Image = 'Map']
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class ConcurrentApp {
public void getMyInstance() {
Map map1 = new HashMap(); // fine for single-threaded access
Map map2 = new ConcurrentHashMap(); // preferred for use with multiple threads
// the following case will be ignored by this rule
Map map3 = someModule.methodThatReturnMap(); // might be OK, if the returned map is already thread-safe
}
}
]]>
</example>
</rule>
<rule name="UseNotifyAllInsteadOfNotify"
language="java"
since="3.0"
message="Call Thread.notifyAll() rather than Thread.notify()"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#usenotifyallinsteadofnotify">
<description>
Thread.notify() awakens a thread monitoring the object. If more than one thread is monitoring, then only
one is chosen. The thread chosen is arbitrary; thus its usually safer to call notifyAll() instead.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//StatementExpression/PrimaryExpression
[PrimarySuffix/Arguments[@ArgumentCount = '0']]
[
PrimaryPrefix[
./Name[@Image='notify' or ends-with(@Image,'.notify')]
or ../PrimarySuffix/@Image='notify'
or (./AllocationExpression and ../PrimarySuffix[@Image='notify'])
]
]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
void bar() {
x.notify();
// If many threads are monitoring x, only one (and you won't know which) will be notified.
// use instead:
x.notifyAll();
}
]]>
</example>
</rule>
</ruleset>

File diff suppressed because it is too large Load diff

View file

@ -1,65 +0,0 @@
<?xml version="1.0"?>
<ruleset name="Security" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>
Rules that flag potential security flaws.
</description>
<rule name="HardCodedCryptoKey"
since="6.4.0"
message="Do not use hard coded encryption keys"
class="net.sourceforge.pmd.lang.java.rule.security.HardCodedCryptoKeyRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_security.html#hardcodedcryptokey">
<description>
Do not use hard coded values for cryptographic operations. Please store keys outside of source code.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
void good() {
SecretKeySpec secretKeySpec = new SecretKeySpec(Properties.getKey(), "AES");
}
void bad() {
SecretKeySpec secretKeySpec = new SecretKeySpec("my secret here".getBytes(), "AES");
}
}
]]>
</example>
</rule>
<rule name="InsecureCryptoIv"
since="6.3.0"
message="Do not use hard coded initialization vector in crypto operations"
class="net.sourceforge.pmd.lang.java.rule.security.InsecureCryptoIvRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_security.html#insecurecryptoiv">
<description>
Do not use hard coded initialization vector in cryptographic operations. Please use a randomly generated IV.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
void good() {
SecureRandom random = new SecureRandom();
byte iv[] = new byte[16];
random.nextBytes(bytes);
}
void bad() {
byte[] iv = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, };
}
void alsoBad() {
byte[] iv = "secret iv in here".getBytes();
}
}
]]>
</example>
</rule>
</ruleset>

View file

@ -1,10 +0,0 @@
/*
sonarqube {
properties {
property "sonar.projectName", "${project.group} ${project.name}"
property "sonar.sourceEncoding", "UTF-8"
property "sonar.tests", "src/test/java"
property "sonar.scm.provider", "git"
}
}
*/

View file

@ -1,13 +0,0 @@
spotbugs {
effort = "max"
reportLevel = "low"
ignoreFailures = true
}
spotbugsMain {
reports {
xml.getRequired().set(false)
html.getRequired().set(true)
}
}

View file

@ -1,4 +0,0 @@
repositories {
mavenLocal()
mavenCentral()
}

View file

@ -1,10 +1,12 @@
def junitVersion = project.hasProperty('junit.version')?project.property('junit.version'):'5.6.2'
def hamcrestVersion = project.hasProperty('hamcrest.version')?project.property('hamcrest.version'):'2.2'
dependencies { dependencies {
testImplementation testLibs.junit.jupiter.api testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
testImplementation testLibs.junit.jupiter.params testImplementation "org.junit.jupiter:junit-jupiter-params:${junitVersion}"
testImplementation testLibs.hamcrest testImplementation "org.hamcrest:hamcrest-library:${hamcrestVersion}"
testRuntimeOnly testLibs.junit.jupiter.engine testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
testRuntimeOnly testLibs.junit.jupiter.platform.launcher
} }
test { test {

Binary file not shown.

View file

@ -1,7 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

282
gradlew vendored
View file

@ -1,7 +1,7 @@
#!/bin/sh #!/usr/bin/env sh
# #
# Copyright © 2015-2021 the original authors. # Copyright 2015 the original author or authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -17,99 +17,67 @@
# #
############################################################################## ##############################################################################
# ##
# Gradle start up script for POSIX generated by Gradle. ## Gradle start up script for UN*X
# ##
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
############################################################################## ##############################################################################
# Attempt to set APP_HOME # Attempt to set APP_HOME
# Resolve links: $0 may be a link # Resolve links: $0 may be a link
app_path=$0 PRG="$0"
# Need this for relative symlinks.
# Need this for daisy-chained symlinks. while [ -h "$PRG" ] ; do
while ls=`ls -ld "$PRG"`
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path link=`expr "$ls" : '.*-> \(.*\)$'`
[ -h "$app_path" ] if expr "$link" : '/.*' > /dev/null; then
do PRG="$link"
ls=$( ls -ld "$app_path" ) else
link=${ls#*' -> '} PRG=`dirname "$PRG"`"/$link"
case $link in #( fi
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
# This is normally unused APP_NAME="Gradle"
# shellcheck disable=SC2034 APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD="maximum"
warn () { warn () {
echo "$*" echo "$*"
} >&2 }
die () { die () {
echo echo
echo "$*" echo "$*"
echo echo
exit 1 exit 1
} >&2 }
# OS specific support (must be 'true' or 'false'). # OS specific support (must be 'true' or 'false').
cygwin=false cygwin=false
msys=false msys=false
darwin=false darwin=false
nonstop=false nonstop=false
case "$( uname )" in #( case "`uname`" in
CYGWIN* ) cygwin=true ;; #( CYGWIN* )
Darwin* ) darwin=true ;; #( cygwin=true
MSYS* | MINGW* ) msys=true ;; #( ;;
NONSTOP* ) nonstop=true ;; Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@ -119,9 +87,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables # IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java JAVACMD="$JAVA_HOME/jre/sh/java"
else else
JAVACMD=$JAVA_HOME/bin/java JAVACMD="$JAVA_HOME/bin/java"
fi fi
if [ ! -x "$JAVACMD" ] ; then if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@ -130,120 +98,88 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD="java"
if ! command -v java >/dev/null 2>&1 which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
case $MAX_FD in #( MAX_FD_LIMIT=`ulimit -H -n`
max*) if [ $? -eq 0 ] ; then
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
# shellcheck disable=SC2039,SC3045 MAX_FD="$MAX_FD_LIMIT"
MAX_FD=$( ulimit -H -n ) || fi
warn "Could not query maximum file descriptor limit" ulimit -n $MAX_FD
esac if [ $? -ne 0 ] ; then
case $MAX_FD in #( warn "Could not set maximum file descriptor limit: $MAX_FD"
'' | soft) :;; #( fi
*) else
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
# shellcheck disable=SC2039,SC3045 fi
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi fi
# Collect all arguments for the java command, stacking in reverse order: # For Darwin, add options to specify how the application appears in the dock
# * args from the command line if $darwin; then
# * the main class name GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
# * -classpath fi
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=$( cygpath --unix "$JAVACMD" ) JAVACMD=`cygpath --unix "$JAVACMD"`
# Now convert the arguments - kludge to limit ourselves to /bin/sh # We build the pattern for arguments to be converted via cygpath
for arg do ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
if SEP=""
case $arg in #( for dir in $ROOTDIRSRAW ; do
-*) false ;; # don't mess with options #( ROOTDIRS="$ROOTDIRS$SEP$dir"
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath SEP="|"
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Collect all arguments for the java command, following the shell quoting and substitution rules
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@" exec "$JAVACMD" "$@"

34
gradlew.bat vendored
View file

@ -14,7 +14,7 @@
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@ -25,8 +25,7 @@
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%" == "" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@ -41,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if "%ERRORLEVEL%" == "0" goto init
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -55,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto init
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -65,6 +64,21 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
@ -72,19 +86,17 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd if "%ERRORLEVEL%"=="0" goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL% if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
if %EXIT_CODE% equ 0 set EXIT_CODE=1 exit /b 1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal

View file

@ -0,0 +1,13 @@
This is a derived work of
https://github.com/spaulg/redlinerpm-maven-plugin
licensed under Apache Software License 2.0
Copyright 2014 Simon Paulger spaulger@codezen.co.uk
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

View file

@ -0,0 +1,73 @@
apply plugin: 'maven'
// for this script, see https://gist.github.com/fikovnik/ffc1fed1867bc7fa679aaf8e48f00c21
configurations {
mavenEmbedder
}
dependencies {
api project(':rpm-core')
api "org.apache.ant:ant:${project.property('ant.version')}"
implementation "org.mvel:mvel2:${project.property('mvel.version')}"
compileOnly "org.apache.maven:maven-core:${project.property('maven.version')}"
compileOnly "org.apache.maven:maven-plugin-api:${project.property('maven.version')}"
compileOnly "org.apache.maven.plugin-tools:maven-plugin-annotations:${project.property('maven-plugin-annotations.version')}"
testImplementation "org.apache.maven:maven-core:${project.property('maven.version')}"
testImplementation "org.apache.maven:maven-plugin-api:${project.property('maven.version')}"
testImplementation "org.apache.maven.plugin-tools:maven-plugin-annotations:${project.property('maven-plugin-annotations.version')}"
mavenEmbedder "org.apache.maven:maven-embedder:${project.property('maven.version')}"
mavenEmbedder "org.apache.maven:maven-compat:${project.property('maven.version')}"
mavenEmbedder "org.slf4j:slf4j-simple:${project.property('slf4j.version')}"
mavenEmbedder "org.apache.maven.wagon:wagon-http:${project.property('maven-wagon.version')}:shaded"
mavenEmbedder "org.apache.maven.wagon:wagon-provider-api:${project.property('maven-wagon.version')}"
mavenEmbedder "org.eclipse.aether:aether-connector-basic:${project.property('aether-connector-basic.version')}"
mavenEmbedder "org.eclipse.aether:aether-transport-wagon:${project.property('aether-transport-wagon.version')}"
}
test {
systemProperty 'project.build.testOutputDirectory', project.buildDir.path + "/resources/test"
}
install.repositories.mavenInstaller.pom.with {
groupId = project.group
artifactId = project.name
version = project.version
packaging = 'maven-plugin'
}
task generatePluginDescriptor(type: JavaExec, dependsOn: compileJava) {
def pomFile = file("$buildDir/pom.xml")
def pluginDescriptorFile = new File(file(project.compileJava.destinationDir), 'META-INF/maven/plugin.xml')
def directory = buildDir.canonicalPath
def outputDirectory = compileJava.destinationDir.canonicalPath
inputs.files project.compileJava.outputs.files
outputs.file pluginDescriptorFile
classpath = configurations.mavenEmbedder
main = 'org.apache.maven.cli.MavenCli'
systemProperties['maven.multiModuleProjectDirectory'] = projectDir
args = [
'--update-snapshots',
'--errors',
'--batch-mode',
'--settings', "${project.projectDir}/config/maven/repo-settings.xml",
'--file', "${buildDir}/pom.xml",
"org.apache.maven.plugins:maven-plugin-plugin:${project.property('maven-plugin-plugin.version')}:descriptor"
]
doFirst {
install.repositories.mavenInstaller.pom.withXml {
asNode().appendNode('build').with {
appendNode('directory', directory)
appendNode('outputDirectory', outputDirectory)
}
}.writeTo(pomFile)
assert pomFile.file, "${pomFile.canonicalPath}: was not generated"
logger.info("POM is generated in ${pomFile.canonicalPath}")
}
doLast {
assert pluginDescriptorFile.file, "${pluginDescriptorFile.canonicalPath}: was not generated"
logger.info("Maven plugin descriptor generated in ${pluginDescriptorFile.canonicalPath}")
}
}
project.jar.dependsOn(generatePluginDescriptor)

View file

@ -0,0 +1,24 @@
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<localRepository>~/.m2/repository</localRepository>
<activeProfiles>
<activeProfile>xbib</activeProfile>
</activeProfiles>
<profiles>
<profile>
<id>xbib</id>
<repositories>
<repository>
<id>xbib</id>
<url>https://xbib.org/repository</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</settings>

View file

@ -0,0 +1,95 @@
package org.xbib.maven.plugin.rpm;
/**
*
*/
public abstract class RpmBaseObject {
/**
* Destination permissions.
*/
private int permissions = 0;
/**
* Destination file owner.
*/
private String owner = null;
/**
* Destination file group.
*/
private String group = null;
protected abstract RpmPackage getPackage();
/**
* Set permissions.
*
* @param permissions permissions
*/
public void setPermissions(int permissions) {
this.permissions = permissions;
}
/**
* Get permissions, or the default setting if not set.
*
* @return permissions
*/
public int getPermissionsOrDefault() {
if (0 == permissions) {
return getPackage().getMojo().getDefaultFileMode();
} else {
return permissions;
}
}
/**
* Set owner.
*
* @param owner owner
*/
public void setOwner(String owner) {
if (null != owner && owner.equals("")) {
owner = null;
}
this.owner = owner;
}
/**
* Get owner, or the default setting if not set.
*
* @return owner
*/
public String getOwnerOrDefault() {
if (null == this.owner) {
return this.getPackage().getMojo().getDefaultOwner();
} else {
return this.owner;
}
}
/**
* Set group.
*
* @param group group
*/
public void setGroup(String group) {
if (null != group && group.equals("")) {
group = null;
}
this.group = group;
}
/**
* Get group, or the default setting if not set.
*
* @return group
*/
public String getGroupOrDefault() {
if (null == this.group) {
return this.getPackage().getMojo().getDefaultGroup();
} else {
return this.group;
}
}
}

View file

@ -0,0 +1,68 @@
package org.xbib.maven.plugin.rpm;
/**
*
*/
public class RpmLink extends RpmBaseObject {
private RpmPackage rpmPackage;
private String path;
private String target;
/**
* Get associated RPM package.
*
* @return RPM package
*/
@Override
public RpmPackage getPackage() {
return this.rpmPackage;
}
/**
* Set associated RPM package.
*
* @param rpmPackage RPM package
*/
public void setPackage(RpmPackage rpmPackage) {
this.rpmPackage = rpmPackage;
}
/**
* Get symlink path.
*
* @return symlink path
*/
public String getPath() {
return path;
}
/**
* Set symlink path.
*
* @param path symlink path
*/
public void setPath(String path) {
this.path = path;
}
/**
* Get symlink target.
*
* @return symlink target
*/
public String getTarget() {
return target;
}
/**
* Set symlink target.
*
* @param target symlink target
*/
public void setTarget(String target) {
this.target = target;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,124 @@
package org.xbib.maven.plugin.rpm;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* RPM package association (i.e. obsoletes, dependencies, conflicts).
*/
public class RpmPackageAssociation {
/**
* Association name.
*/
private String name = null;
/**
* Association maven style version.
*/
private String version = null;
/**
* Min version requirement.
*/
private String minVersion = null;
/**
* Max version requirement.
*/
private String maxVersion = null;
/**
* Version requirement has range.
*/
private boolean isRange = false;
/**
* Get name.
*
* @return Association name
*/
public String getName() {
return this.name;
}
/**
* Set name.
*
* @param name Association name
*/
public void setName(String name) {
this.name = name;
}
/**
* Is version range.
*
* @return Version range, true or false
*/
public boolean isVersionRange() {
return isRange;
}
/**
* Get version.
*
* @return Maven style version.
*/
public String getVersion() {
return version;
}
/**
* Set version.
*
* @param version Maven style version.
*/
public void setVersion(String version) {
if (version == null || version.equals("RELEASE") || version.equals("")) {
isRange = false;
this.version = null;
minVersion = null;
maxVersion = null;
return;
}
Pattern versionPattern = Pattern.compile("\\[([0-9\\.]*),([0-9\\.]*)\\)");
Matcher matcher = versionPattern.matcher(version);
if (matcher.matches()) {
this.isRange = true;
this.version = null;
String minVersion = matcher.group(1);
String maxVersion = matcher.group(2);
if (minVersion.equals("")) {
minVersion = null;
}
if (maxVersion.equals("")) {
maxVersion = null;
}
this.minVersion = minVersion;
this.maxVersion = maxVersion;
} else {
this.isRange = false;
this.version = version;
this.minVersion = null;
this.maxVersion = null;
}
}
/**
* Get min version requirement.
*
* @return Min version requirement
*/
public String getMinVersion() {
return this.minVersion;
}
/**
* Get max version requirement.
*
* @return Max version requirement
*/
public String getMaxVersion() {
return this.maxVersion;
}
}

View file

@ -0,0 +1,259 @@
package org.xbib.maven.plugin.rpm;
import org.apache.maven.plugin.logging.Log;
import org.apache.tools.ant.DirectoryScanner;
import org.xbib.maven.plugin.rpm.mojo.RpmMojo;
import org.xbib.rpm.RpmBuilder;
import org.xbib.rpm.exception.InvalidDirectiveException;
import org.xbib.rpm.exception.InvalidPathException;
import org.xbib.rpm.exception.PathOutsideBuildPathException;
import org.xbib.rpm.exception.RpmException;
import org.xbib.rpm.payload.Directive;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
/**
* RPM rule, represents a file to be included within the RPM.
*/
public class RpmPackageRule extends RpmBaseObject {
/**
* RPM package.
*/
private RpmPackage rpmPackage = null;
/**
* Rule base path, relative to plugin buildPath.
*/
private String base = File.separator;
/**
* Destination path of files within RPM.
*/
private String destination = null;
/**
* List of file include rules.
*/
private List<String> includes = new ArrayList<>();
/**
* List of file exclude rules.
*/
private List<String> excludes = new ArrayList<>();
/**
* File directives.
*/
private EnumSet<Directive> directive;
/**
* Get associated RPM package.
*
* @return RPM package
*/
@Override
public RpmPackage getPackage() {
return this.rpmPackage;
}
/**
* Set associated RPM package.
*
* @param rpmPackage RPM package
*/
public void setPackage(RpmPackage rpmPackage) {
this.rpmPackage = rpmPackage;
}
/**
* Get base path, relative to the buildPath.
*
* @return Base path
*/
public String getBase() {
return this.base;
}
/**
* Set base path, relative to the buildPath.
*
* @param base Base path
*/
public void setBase(String base) {
if (null == base || base.equals("")) {
base = File.separator;
}
this.base = base;
}
/**
* Get file destination.
*
* @return File destination
*/
public String getDestination() {
return this.destination;
}
/**
* Set file destination.
*
* @param destination File destination
*/
public void setDestination(String destination) {
if (null != destination && destination.equals("")) {
destination = null;
}
this.destination = destination;
}
/**
* Get the file destination, or the default setting if not set.
*
* @return File destination
*/
public String getDestinationOrDefault() {
if (null == this.destination) {
return this.getPackage().getMojo().getDefaultDestination();
} else {
return this.destination;
}
}
/**
* Get file inclusion rules.
*
* @return File inclusion rules
*/
public List<String> getIncludes() {
return this.includes;
}
/**
* Set file inclusion rules.
*
* @param includes File inclusion rules
*/
public void setIncludes(List<String> includes) {
this.includes = includes;
}
/**
* Get file exclusion rules.
*
* @return File exclusion rules
*/
public List<String> getExcludes() {
return this.excludes;
}
/**
* Set file exclusion rules.
*
* @param excludes File exclusion rules
*/
public void setExcludes(List<String> excludes) {
this.excludes = excludes;
}
/**
* Get file directives.
*
* @return File directives
*/
public EnumSet<Directive> getDirectives() {
return this.directive;
}
/**
* Set file directives.
*
* @param directives File directives
* @throws InvalidDirectiveException if there is an invalid RPM directive
*/
public void setDirectives(List<String> directives) throws InvalidDirectiveException {
this.directive = Directive.newDirective(directives);
}
/**
* Get path used for scanning for files to be included by the rule.
*
* @return Scan path
* @throws InvalidPathException if path is invalid
*/
public String getScanPath() throws InvalidPathException {
String scanPath = String.format("%s%s%s",
this.rpmPackage.getMojo().getBuildPath(), File.separator, this.getBase());
try {
return Paths.get(scanPath).toRealPath().toString();
} catch (IOException ex) {
throw new InvalidPathException(scanPath, ex);
}
}
/**
* Get the Maven logger.
*
* @return Maven logger
*/
public Log getLog() {
return this.getPackage().getMojo().getLog();
}
/**
* List all files found by the rule to the package.
*
* @return Matched file list
* @throws RpmException if files can not be listed
*/
public String[] listFiles() throws RpmException {
RpmMojo mojo = rpmPackage.getMojo();
String buildPath = mojo.getBuildPath();
String scanPath = getScanPath();
if (!String.format("%s%s", scanPath, File.separator).startsWith(String.format("%s%s", buildPath, File.separator))) {
throw new PathOutsideBuildPathException(scanPath, buildPath);
}
DirectoryScanner ds = new DirectoryScanner();
ds.setIncludes(getIncludes().toArray(new String[0]));
ds.setExcludes(getExcludes().toArray(new String[0]));
ds.setBasedir(scanPath);
ds.setFollowSymlinks(false);
ds.setCaseSensitive(true);
getLog().debug("Scanning for files for package rule");
ds.scan();
return ds.getIncludedFiles();
}
/**
* Add all files found by the rule to the package.
*
* @param builder RPM builder
* @return Matched file list
* @throws IOException if file could not be added
* @throws RpmException if RPM archive could not be listed
*/
public String[] addFiles(RpmBuilder builder) throws IOException, RpmException {
String[] includedFiles = listFiles();
String scanPath = getScanPath();
getLog().debug(String.format("Adding %d files found to package.", includedFiles.length));
for (String includedFile : includedFiles) {
String destinationPath = this.getDestinationOrDefault() + File.separator + includedFile;
String sourcePath = String.format("%s%s%s", scanPath, File.separator, includedFile);
String owner = getOwnerOrDefault();
String group = getGroupOrDefault();
int fileMode = getPermissionsOrDefault();
getLog().debug(String.format("Adding file: %s to path %s with owner '%s', " +
"group '%s', with file mode %o.",
sourcePath, destinationPath, owner, group, fileMode));
builder.addFile(destinationPath, Paths.get(sourcePath), fileMode, -1,
getDirectives(), owner, group, true);
}
return includedFiles;
}
}

View file

@ -0,0 +1,53 @@
package org.xbib.maven.plugin.rpm;
import org.mvel2.templates.TemplateRuntime;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
/**
* RPM script template renderer.
*/
public class RpmScriptTemplateRenderer {
/**
* Template parameter map.
*/
private Map<String, Object> parameterMap = new HashMap<>();
/**
* Add parameter to parameter map.
*
* @param name Parameter Name
* @param value Parameter value
*/
public void addParameter(String name, Object value) {
this.parameterMap.put(name, value);
}
/**
* Render a script template file.
*
* @param templateFile Template file
* @param renderedFile Rendered output file
* @throws IOException if rendering fails
*/
public void render(Path templateFile, Path renderedFile) throws IOException {
char[] buffer = new char[1024];
StringBuilder stringBuilder = new StringBuilder();
try (BufferedReader reader = Files.newBufferedReader(templateFile)) {
int bytesRead;
while (-1 != (bytesRead = reader.read(buffer))) {
stringBuilder.append(buffer, 0, bytesRead);
}
}
String renderedTemplate = (String) TemplateRuntime.eval(stringBuilder.toString(), this.parameterMap);
try (BufferedWriter writer = Files.newBufferedWriter(renderedFile)) {
writer.write(renderedTemplate);
}
}
}

View file

@ -0,0 +1,217 @@
package org.xbib.maven.plugin.rpm;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
/**
* RPM trigger.
*/
public class RpmTrigger {
/**
* Pre install event hook script path.
*/
private Path preInstallScriptPath = null;
/**
* Pre install event hook program.
*/
private String preInstallProgram = null;
/**
* Post install event hook script path.
*/
private Path postInstallScriptPath = null;
/**
* Post install event hook program.
*/
private String postInstallProgram = null;
/**
* Pre uninstall event hook script path.
*/
private Path preUninstallScriptPath = null;
/**
* Pre uninstall event hook script program.
*/
private String preUninstallProgram = null;
/**
* Post uninstall event hook script path.
*/
private Path postUninstallScriptPath = null;
/**
* Post uninstall event hook program.
*/
private String postUninstallProgram = null;
/**
* Trigger package associations.
*/
private List<RpmPackageAssociation> dependencies = new ArrayList<>();
/**
* Get pre install script path.
*
* @return Pre install script path
*/
public Path getPreInstallScriptPath() {
return this.preInstallScriptPath;
}
/**
* Set pre install script path.
*
* @param preInstallScriptPath Pre install script path
*/
public void setPreInstallScriptPath(Path preInstallScriptPath) {
this.preInstallScriptPath = preInstallScriptPath;
}
/**
* Get pre install program.
*
* @return Pre install program
*/
public String getPreInstallProgram() {
return this.preInstallProgram;
}
/**
* Set pre install program.
*
* @param preInstallProgram Pre install program
*/
public void setPreInstallProgram(String preInstallProgram) {
this.preInstallProgram = preInstallProgram;
}
/**
* Get post install script path.
*
* @return Post install script path
*/
public Path getPostInstallScriptPath() {
return this.postInstallScriptPath;
}
/**
* Set post install script path.
*
* @param postInstallScriptPath Post install script path
*/
public void setPostInstallScriptPath(Path postInstallScriptPath) {
this.postInstallScriptPath = postInstallScriptPath;
}
/**
* Get post install program.
*
* @return Post install program
*/
public String getPostInstallProgram() {
return this.postInstallProgram;
}
/**
* Set post install program.
*
* @param postInstallProgram Post install program
*/
public void setPostInstallProgram(String postInstallProgram) {
this.postInstallProgram = postInstallProgram;
}
/**
* Get pre uninstall script path.
*
* @return Pre uninstall script path
*/
public Path getPreUninstallScriptPath() {
return this.preUninstallScriptPath;
}
/**
* Set pre uninstall script path.
*
* @param preUninstallScriptPath Pre uninstall script path
*/
public void setPreUninstallScriptPath(Path preUninstallScriptPath) {
this.preUninstallScriptPath = preUninstallScriptPath;
}
/**
* Get pre uninstall program.
*
* @return Pre uninstall program
*/
public String getPreUninstallProgram() {
return this.preUninstallProgram;
}
/**
* Set pre uninstall program.
*
* @param preUninstallProgram Pre uninstall program
*/
public void setPreUninstallProgram(String preUninstallProgram) {
this.preUninstallProgram = preUninstallProgram;
}
/**
* Get post uninstall script path.
*
* @return Post uninstall script path
*/
public Path getPostUninstallScriptPath() {
return this.postUninstallScriptPath;
}
/**
* Set post uninstall script path.
*
* @param postUninstallScriptPath Post uninstall script path
*/
public void setPostUninstallScriptPath(Path postUninstallScriptPath) {
this.postUninstallScriptPath = postUninstallScriptPath;
}
/**
* Get post uninstall program.
*
* @return Post uninstall program
*/
public String getPostUninstallProgram() {
return this.postUninstallProgram;
}
/**
* Set post uninstall program.
*
* @param postUninstallProgram Post uninstall program
*/
public void setPostUninstallProgram(String postUninstallProgram) {
this.postUninstallProgram = postUninstallProgram;
}
/**
* Get trigger packages.
*
* @return Trigger packages
*/
public List<RpmPackageAssociation> getDependencies() {
return dependencies;
}
/**
* Set trigger packages.
*
* @param dependencies Trigger packages
*/
public void setDependencies(List<RpmPackageAssociation> dependencies) {
this.dependencies = dependencies;
}
}

View file

@ -0,0 +1,407 @@
package org.xbib.maven.plugin.rpm.mojo;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.model.License;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.tools.ant.DirectoryScanner;
import org.xbib.maven.plugin.rpm.RpmPackage;
import org.xbib.maven.plugin.rpm.RpmScriptTemplateRenderer;
import org.xbib.rpm.exception.InvalidPathException;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
/**
*
*/
public abstract class AbstractRpmMojo extends AbstractMojo implements RpmMojo {
/**
* Set of master files (all files in build path).
*/
protected Set<String> masterFiles = new HashSet<>();
/**
* Event hook template renderer.
*/
private RpmScriptTemplateRenderer templateRenderer = null;
/**
* Maven project.
*/
@Parameter(defaultValue = "${project}", readonly = true)
protected MavenProject project = null;
/**
* Build path.
*/
@Parameter(defaultValue = "${project.build.outputDirectory}")
private String buildPath = null;
/**
* RPM package declarations from configuration.
*/
@Parameter
protected List<RpmPackage> packages = new ArrayList<>();
/**
* Default mode.
*/
@Parameter
private int defaultFileMode = 0644;
/**
* Default owner.
*/
@Parameter
private String defaultOwner = "root";
/**
* Default group.
*/
@Parameter
private String defaultGroup = "root";
/**
* Default installation destination.
*/
@Parameter
private String defaultDestination = File.separator;
/**
* List of file exclude patterns.
*/
@Parameter
protected List<String> excludes = new ArrayList<>();
/**
* Perform checking for extra files not included within any packages,
* or excluded from all packages.
*/
@Parameter
private boolean performCheckingForExtraFiles = true;
/**
* Get Maven project.
*
* @return Maven project
*/
protected MavenProject getProject() {
return project;
}
/**
* Set Maven project.
*
* @param project Maven project
*/
public void setProject(MavenProject project) {
this.project = project;
}
/**
* Get event hook template renderer.
*
* @return Event hook template renderer
*/
@Override
public RpmScriptTemplateRenderer getTemplateRenderer() {
if (templateRenderer == null) {
templateRenderer = new RpmScriptTemplateRenderer();
templateRenderer.addParameter("project", getProject());
templateRenderer.addParameter("env", System.getenv());
Properties systemProperties = System.getProperties();
for (String propertyName : systemProperties.stringPropertyNames()) {
templateRenderer.addParameter(propertyName, systemProperties.getProperty(propertyName));
}
Properties projectProperties = getProject().getProperties();
for (String propertyName : projectProperties.stringPropertyNames()) {
templateRenderer.addParameter(propertyName, projectProperties.getProperty(propertyName));
}
}
return templateRenderer;
}
/**
* Get the project artifact id.
*
* @return Artifact id
*/
@Override
public String getProjectArtifactId() {
return getProject().getArtifactId();
}
/**
* Get the project version.
*
* @return Project version
*/
@Override
public String getProjectVersion() {
return getProject().getVersion();
}
/**
* Get the project url.
*
* @return Project url
*/
@Override
public String getProjectUrl() {
return getProject().getUrl();
}
/**
* Get project packaging type.
*
* @return Packaging type
*/
@Override
public String getProjectPackagingType() {
return getProject().getPackaging();
}
/**
* Get collapsed project licensing.
*
* @return Project licenses, collapsed in to a single line, separated by commas.
*/
@Override
public String getCollapsedProjectLicense() {
StringBuilder collapsedLicenseList = new StringBuilder();
for (License license : getProject().getLicenses()) {
if (collapsedLicenseList.toString().equals("")) {
collapsedLicenseList = new StringBuilder(license.getName());
} else {
collapsedLicenseList.append(", ").append(license.getName());
}
}
return (collapsedLicenseList.length() > 0 ? collapsedLicenseList.toString() : null);
}
/**
* Get build output directory.
*
* @return Build output directory
*/
@Override
public String getBuildDirectory() {
return project.getBuild().getDirectory();
}
/**
* Set the primary artifact.
*
* @param artifactFile Primary artifact
* @param classifier Artifact classifier
*/
@Override
public void setPrimaryArtifact(Path artifactFile, String classifier) {
DefaultArtifactHandler handler = new DefaultArtifactHandler();
handler.setExtension("rpm");
Artifact artifact = new DefaultArtifact(getProject().getGroupId(),
getProject().getArtifactId(),
getProject().getVersion(),
null,
"rpm",
classifier,
handler
);
artifact.setFile(artifactFile.toFile());
getProject().setArtifact(artifact);
}
/**
* Add a secondary artifact.
*
* @param artifactFile Secondary artifact file
* @param artifactId Artifact Id
* @param version Artifact version
* @param classifier Artifact classifier
*/
@Override
public void addSecondaryArtifact(Path artifactFile, String artifactId, String version, String classifier) {
DefaultArtifactHandler handler = new DefaultArtifactHandler();
handler.setExtension("rpm");
Artifact artifact = new DefaultArtifact(
getProject().getGroupId(),
artifactId,
version,
null,
"rpm",
classifier,
handler
);
artifact.setFile(artifactFile.toFile());
getProject().addAttachedArtifact(artifact);
}
/**
* Get the build root path.
*
* @return Build root path
*/
@Override
public String getBuildPath() throws InvalidPathException {
try {
return new File(buildPath).getCanonicalPath();
} catch (IOException ex) {
throw new InvalidPathException(buildPath, ex);
}
}
/**
* Set the build root path.
*
* @param buildPath Build root path
*/
public void setBuildPath(String buildPath) {
this.buildPath = buildPath;
}
/**
* Set the RPM packages defined by the configuration.
*
* @param packages List of RPM packages
*/
public void setPackages(List<RpmPackage> packages) {
for (RpmPackage rpmPackage : packages) {
rpmPackage.setMojo(this);
}
this.packages = packages;
}
/**
* Get default mode.
*
* @return Default mode
*/
@Override
public int getDefaultFileMode() {
return defaultFileMode;
}
/**
* Set default mode.
*
* @param defaultFileMode Default mode
*/
public void setDefaultFileMode(int defaultFileMode) {
this.defaultFileMode = defaultFileMode;
}
/**
* Get default owner.
*
* @return Default owner
*/
@Override
public String getDefaultOwner() {
return defaultOwner;
}
/**
* Set default owner.
*
* @param defaultOwner Default owner
*/
public void setDefaultOwner(String defaultOwner) {
this.defaultOwner = defaultOwner;
}
/**
* Get default group.
*
* @return Default group
*/
@Override
public String getDefaultGroup() {
return defaultGroup;
}
/**
* Set default group.
*
* @param defaultGroup Default group
*/
public void setDefaultGroup(String defaultGroup) {
this.defaultGroup = defaultGroup;
}
/**
* Get default destination.
*
* @return Default destination
*/
@Override
public String getDefaultDestination() {
return defaultDestination;
}
/**
* Set default destination.
*
* @param defaultDestination Default destination
*/
public void setDefaultDestination(String defaultDestination) {
this.defaultDestination = defaultDestination;
}
/**
* Set the list of file exclude patterns.
*
* @param excludes List of file exclude patterns
*/
public void setExcludes(List<String> excludes) {
this.excludes = excludes;
}
/**
* Get ignore extra files.
*
* @return Ignore extra files
*/
public boolean isPerformCheckingForExtraFiles() {
return performCheckingForExtraFiles;
}
/**
* Set ignore extra files.
*
* @param performCheckingForExtraFiles Ignore extra files
*/
public void setPerformCheckingForExtraFiles(boolean performCheckingForExtraFiles) {
this.performCheckingForExtraFiles = performCheckingForExtraFiles;
}
/**
* Scan the build path for all files for inclusion in an RPM archive.
* Excludes are applied also. This is because it doesn't matter
* if a file ends up being included within an RPM as the master list
* is only for us to know which files have been missed by a packaging
* rule.
*/
protected void scanMasterFiles() {
DirectoryScanner ds = new DirectoryScanner();
ds.setIncludes(null);
ds.setExcludes(excludes.toArray(new String[0]));
ds.setBasedir(buildPath);
ds.setFollowSymlinks(false);
ds.setCaseSensitive(true);
ds.scan();
String[] fileMatches = ds.getIncludedFiles();
masterFiles = new HashSet<>(fileMatches.length);
Collections.addAll(masterFiles, fileMatches);
}
}

View file

@ -0,0 +1,43 @@
package org.xbib.maven.plugin.rpm.mojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.xbib.maven.plugin.rpm.RpmPackage;
import org.xbib.rpm.exception.RpmException;
import java.util.Set;
/**
*
*/
@Mojo(name = "listfiles", defaultPhase = LifecyclePhase.PACKAGE)
public class ListFilesRpmMojo extends AbstractRpmMojo {
/**
* Execute goal.
*
* @throws MojoExecutionException There was a problem running the Mojo.
* Further details are available in the message and cause properties.
*/
@Override
public void execute() throws MojoExecutionException {
getLog().info("Declared packages:");
scanMasterFiles();
for (RpmPackage rpmPackage : this.packages) {
Set<String> includedFiles;
try {
includedFiles = rpmPackage.listFiles();
} catch (RpmException e) {
throw new MojoExecutionException(e.getMessage());
}
masterFiles.removeAll(includedFiles);
}
if (masterFiles.size() > 0) {
getLog().info("Unmatched files:");
for (String unmatchedFile : this.masterFiles) {
getLog().info(String.format(" - %s", unmatchedFile));
}
}
}
}

View file

@ -0,0 +1,54 @@
package org.xbib.maven.plugin.rpm.mojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.xbib.maven.plugin.rpm.RpmPackage;
import java.util.Set;
/**
* Build an RPM using Maven, allowing for operating system agnostic RPM builds.
*/
@Mojo(name = "package", defaultPhase = LifecyclePhase.PACKAGE)
public class PackageRpmMojo extends AbstractRpmMojo {
/**
* Execute goal.
*
* @throws MojoExecutionException There was a problem running the Mojo.
* Further details are available in the message and cause properties.
*/
public void execute() throws MojoExecutionException {
scanMasterFiles();
long totalFilesPackaged = 0;
for (RpmPackage rpmPackage : this.packages) {
Set<String> includedFiles;
try {
includedFiles = rpmPackage.build();
} catch (Exception ex) {
getLog().error(String.format("Unable to build package %s", rpmPackage.getName()), ex);
throw new MojoExecutionException(String.format("Unable to build package %s", rpmPackage.getName()), ex);
}
masterFiles.removeAll(includedFiles);
totalFilesPackaged += includedFiles.size();
}
if (isPerformCheckingForExtraFiles() && masterFiles.size() > 0) {
getLog().error(String.format("%d file(s) listed below were found in the build path that have not been " +
"included in any package or explicitly excluded. Maybe you need to exclude them?", masterFiles.size()));
for (String missedFile : this.masterFiles) {
getLog().error(String.format(" - %s", missedFile));
}
throw new MojoExecutionException(String.format("%d file(s) were found in the build path that have not been " +
"included or explicitly excluded. Maybe you need to exclude them?",
masterFiles.size()));
}
if (0 < packages.size() && 0 == totalFilesPackaged) {
// No files were actually packaged. Perhaps something got missed.
getLog().error("No files were included when packaging RPM artifacts. " +
"Did you specify the correct output path?");
throw new MojoExecutionException("No files were included when packaging RPM artifacts. " +
"Did you specify the correct output path?");
}
}
}

View file

@ -0,0 +1,122 @@
package org.xbib.maven.plugin.rpm.mojo;
import org.apache.maven.plugin.logging.Log;
import org.xbib.maven.plugin.rpm.RpmScriptTemplateRenderer;
import org.xbib.rpm.exception.InvalidPathException;
import java.nio.file.Path;
/**
* Plugin mojo implementation.
*/
public interface RpmMojo {
/**
* Get event hook template renderer.
*
* @return Event hook template renderer
*/
RpmScriptTemplateRenderer getTemplateRenderer();
/**
* Set the primary artifact.
*
* @param artifactFile Primary artifact
* @param classifier Artifact classifier
*/
void setPrimaryArtifact(Path artifactFile, String classifier);
/**
* Add a secondary artifact.
*
* @param artifactFile Secondary artifact file
* @param artifactId Artifact Id
* @param version Artifact version
* @param classifier Artifact classifier
*/
void addSecondaryArtifact(Path artifactFile, String artifactId, String version, String classifier);
/**
* Get build output directory.
*
* @return Build output directory
*/
String getBuildDirectory();
/**
* Get the project artifact id.
*
* @return Artifact id
*/
String getProjectArtifactId();
/**
* Get the project version.
*
* @return Project version
*/
String getProjectVersion();
/**
* Get the project url.
*
* @return Project url
*/
String getProjectUrl();
/**
* Get project packaging type.
*
* @return Packaging type
*/
String getProjectPackagingType();
/**
* Get collapsed project licensing.
*
* @return Project licenses, collapsed in to a single line, separated by commas.
*/
String getCollapsedProjectLicense();
/**
* Get the build root path.
*
* @return Build root path
* @throws InvalidPathException Build path is invalid and could not be retrieved
*/
String getBuildPath() throws InvalidPathException;
/**
* Get default mode.
*
* @return Default mode
*/
int getDefaultFileMode();
/**
* Get default owner.
*
* @return Default owner
*/
String getDefaultOwner();
/**
* Get default group.
*
* @return Default group
*/
String getDefaultGroup();
/**
* Get default destination.
*
* @return Default destination
*/
String getDefaultDestination();
/**
* Get logger.
*
* @return Logger
*/
Log getLog();
}

View file

@ -0,0 +1,4 @@
/**
*
*/
package org.xbib.maven.plugin.rpm.mojo;

View file

@ -0,0 +1,4 @@
/**
*
*/
package org.xbib.maven.plugin.rpm;

View file

@ -0,0 +1,19 @@
<component-set>
<components>
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>rpm</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
<instantiation-strategy>per-lookup</instantiation-strategy>
<configuration>
<phases>
<process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
<compile>org.apache.maven.plugins:maven-compiler-plugin:compile</compile>
<package>org.xbib:maven-plugin-rpm:package</package>
<install>org.apache.maven.plugins:maven-install-plugin:install</install>
<deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
</phases>
</configuration>
</component>
</components>
</component-set>

View file

@ -0,0 +1,21 @@
package org.xbib.maven.plugin.rpm;
import org.xbib.rpm.RpmBuilder;
import java.io.IOException;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Path;
/**
*
*/
public class MockBuilder extends RpmBuilder {
@Override
public void build(Path directory) throws IOException {
}
@Override
public void build(SeekableByteChannel channel) throws IOException {
}
}

View file

@ -0,0 +1,49 @@
package org.xbib.maven.plugin.rpm;
import org.apache.maven.plugin.MojoExecutionException;
import org.xbib.maven.plugin.rpm.mojo.AbstractRpmMojo;
import java.util.List;
import java.util.Set;
/**
*
*/
public class MockMojo extends AbstractRpmMojo {
@Override
public void execute() throws MojoExecutionException {
}
@Override
public void scanMasterFiles() {
super.scanMasterFiles();
}
/**
* Get master file set.
*
* @return Master file set
*/
public Set<String> getMasterFiles() {
return this.masterFiles;
}
/**
* Get excludes.
*
* @return Excludes
*/
public List<String> getExcludes() {
return this.excludes;
}
/**
* Get packages.
*
* @return Packages
*/
public List<RpmPackage> getPackages() {
return this.packages;
}
}

View file

@ -0,0 +1,45 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
/**
*
*/
public abstract class RpmBaseObjectTest {
protected abstract RpmBaseObject getRpmBaseObject();
@Test
public void modeAccessors() {
assertEquals(0644, getRpmBaseObject().getPermissionsOrDefault());
getRpmBaseObject().setPermissions(0755);
assertEquals(0755, getRpmBaseObject().getPermissionsOrDefault());
}
@Test
public void ownerAccessors() {
getRpmBaseObject().setOwner("");
assertEquals("root", getRpmBaseObject().getOwnerOrDefault());
getRpmBaseObject().setOwner(null);
assertEquals("root", getRpmBaseObject().getOwnerOrDefault());
assertEquals("root", getRpmBaseObject().getOwnerOrDefault());
getRpmBaseObject().setOwner("owner");
assertEquals("owner", getRpmBaseObject().getOwnerOrDefault());
getRpmBaseObject().setOwner("");
assertEquals("root", getRpmBaseObject().getOwnerOrDefault());
}
@Test
public void groupAccessors() {
getRpmBaseObject().setGroup("");
assertEquals("root", getRpmBaseObject().getGroupOrDefault());
getRpmBaseObject().setGroup(null);
assertEquals("root", getRpmBaseObject().getGroupOrDefault());
assertEquals("root", getRpmBaseObject().getGroupOrDefault());
getRpmBaseObject().setGroup("group");
assertEquals("group", getRpmBaseObject().getGroupOrDefault());
getRpmBaseObject().setGroup("");
assertEquals("root", getRpmBaseObject().getGroupOrDefault());
}
}

View file

@ -0,0 +1,42 @@
package org.xbib.maven.plugin.rpm;
import org.apache.maven.monitor.logging.DefaultLog;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.junit.jupiter.api.BeforeEach;
import org.xbib.maven.plugin.rpm.mojo.PackageRpmMojo;
import java.io.File;
/**
*
*/
public class RpmLinkTest extends RpmBaseObjectTest {
private RpmLink rpmLink;
@BeforeEach
public void setUp() throws Exception {
String testOutputPath = System.getProperty("project.build.testOutputDirectory");
PackageRpmMojo mojo = new PackageRpmMojo();
mojo.setDefaultFileMode(0644);
mojo.setDefaultOwner("root");
mojo.setDefaultGroup("root");
mojo.setDefaultDestination(String.format("%svar%swww%stest", File.separator, File.separator, File.separator));
mojo.setBuildPath(testOutputPath);
MavenProject mavenProject = new MavenProject();
mojo.setProject(mavenProject);
Log log = new DefaultLog(new ConsoleLogger());
mojo.setLog(log);
RpmPackage rpmPackage = new RpmPackage();
rpmPackage.setMojo(mojo);
rpmLink = new RpmLink();
rpmLink.setPackage(rpmPackage);
}
@Override
public RpmBaseObject getRpmBaseObject() {
return rpmLink;
}
}

View file

@ -0,0 +1,81 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
*
*/
public class RpmPackageAssociationTest {
private RpmPackageAssociation association;
@BeforeEach
public void setUp() {
association = new RpmPackageAssociation();
}
@Test
public void nameAccessors() {
assertNull(association.getName());
association.setName("testname");
assertEquals("testname", association.getName());
}
@Test
public void unassignedVersion() {
assertNull(association.getVersion());
assertNull(association.getMinVersion());
assertNull(association.getMaxVersion());
}
@Test
public void latestVersion() {
association.setVersion(null);
assertNull(association.getVersion());
assertNull(association.getMinVersion());
assertNull(association.getMaxVersion());
association.setVersion("");
assertNull(association.getVersion());
assertNull(association.getMinVersion());
assertNull(association.getMaxVersion());
association.setVersion("RELEASE");
assertNull(association.getVersion());
assertNull(association.getMinVersion());
assertNull(association.getMaxVersion());
}
@Test
public void specificVersion() {
association.setVersion("1.2.3");
assertEquals("1.2.3", association.getVersion());
assertNull(association.getMinVersion());
assertNull(association.getMaxVersion());
}
@Test
public void minVersionRange() {
association.setVersion("[1.2.3,)");
assertNull(association.getVersion());
assertEquals("1.2.3", association.getMinVersion());
assertNull(association.getMaxVersion());
}
@Test
public void maxVersionRange() {
association.setVersion("[,1.2.3)");
assertNull(association.getVersion());
assertNull(association.getMinVersion());
assertEquals("1.2.3", association.getMaxVersion());
}
@Test
public void minMaxVersionRange() {
association.setVersion("[1.2.3,1.2.5)");
assertNull(association.getVersion());
assertEquals("1.2.3", association.getMinVersion());
assertEquals("1.2.5", association.getMaxVersion());
}
}

View file

@ -0,0 +1,135 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import org.xbib.rpm.exception.InvalidDirectiveException;
import org.xbib.rpm.payload.Directive;
import java.util.EnumSet;
/**
*
*/
public class RpmPackageRuleDirectiveTest {
@Test
public void configDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.CONFIG);
assertTrue(directiveList.contains(Directive.CONFIG));
assertFalse(directiveList.contains(Directive.DOC));
}
@Test
public void docDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.DOC);
assertTrue(directiveList.contains(Directive.DOC));
assertFalse(directiveList.contains(Directive.ICON));
}
@Test
public void iconDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.ICON);
assertTrue(directiveList.contains(Directive.ICON));
assertFalse(directiveList.contains(Directive.MISSINGOK));
}
@Test
public void missingOkDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.MISSINGOK);
assertTrue(directiveList.contains(Directive.MISSINGOK));
assertFalse(directiveList.contains(Directive.NOREPLACE));
}
@Test
public void noReplaceDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.NOREPLACE);
assertTrue(directiveList.contains(Directive.NOREPLACE));
assertFalse(directiveList.contains(Directive.SPECFILE));
}
@Test
public void specFileDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.SPECFILE);
assertTrue(directiveList.contains(Directive.SPECFILE));
assertFalse(directiveList.contains(Directive.GHOST));
}
@Test
public void ghostDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.GHOST);
assertTrue(directiveList.contains(Directive.GHOST));
assertFalse(directiveList.contains(Directive.LICENSE));
}
@Test
public void licenseDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.LICENSE);
assertTrue(directiveList.contains(Directive.LICENSE));
assertFalse(directiveList.contains(Directive.README));
}
@Test
public void readmeDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.README);
assertTrue(directiveList.contains(Directive.README));
assertFalse(directiveList.contains(Directive.EXCLUDE));
}
@Test
public void excludeDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.EXCLUDE);
assertTrue(directiveList.contains(Directive.EXCLUDE));
assertFalse(directiveList.contains(Directive.UNPATCHED));
}
@Test
public void unpatchedDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.UNPATCHED);
assertTrue(directiveList.contains(Directive.UNPATCHED));
assertFalse(directiveList.contains(Directive.POLICY));
}
@Test
public void pubkeyDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.PUBKEY);
assertTrue(directiveList.contains(Directive.PUBKEY));
assertFalse(directiveList.contains(Directive.POLICY));
}
@Test
public void policyDirective() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.POLICY);
assertTrue(directiveList.contains(Directive.POLICY));
}
@Test
public void multipleDirectives() throws InvalidDirectiveException {
EnumSet<Directive> directiveList = EnumSet.of(Directive.NONE);
directiveList.add(Directive.CONFIG);
directiveList.add(Directive.NOREPLACE);
directiveList.add(Directive.LICENSE);
directiveList.add(Directive.README);
assertTrue(directiveList.contains(Directive.CONFIG));
assertTrue(directiveList.contains(Directive.NOREPLACE));
assertTrue(directiveList.contains(Directive.LICENSE));
assertTrue(directiveList.contains(Directive.README));
assertFalse(directiveList.contains(Directive.UNPATCHED));
assertFalse(directiveList.contains(Directive.PUBKEY));
assertFalse(directiveList.contains(Directive.POLICY));
assertFalse(directiveList.contains(Directive.DOC));
}
}

View file

@ -0,0 +1,156 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import org.apache.maven.monitor.logging.DefaultLog;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.xbib.maven.plugin.rpm.mojo.PackageRpmMojo;
import org.xbib.rpm.exception.InvalidDirectiveException;
import org.xbib.rpm.exception.InvalidPathException;
import org.xbib.rpm.exception.PathOutsideBuildPathException;
import org.xbib.rpm.exception.RpmException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class RpmPackageRuleTest extends RpmBaseObjectTest {
private String testOutputPath;
private Log log;
private RpmPackageRule rpmFileRule;
private RpmPackage rpmPackage;
@BeforeEach
public void setUp() {
testOutputPath = System.getProperty("project.build.testOutputDirectory");
PackageRpmMojo mojo = new PackageRpmMojo();
mojo.setDefaultFileMode(0644);
mojo.setDefaultOwner("root");
mojo.setDefaultGroup("root");
mojo.setDefaultDestination(String.format("%svar%swww%stest", File.separator, File.separator, File.separator));
mojo.setBuildPath(testOutputPath);
MavenProject mavenProject = new MavenProject();
mojo.setProject(mavenProject);
log = new DefaultLog(new ConsoleLogger());
mojo.setLog(log);
rpmPackage = new RpmPackage();
rpmPackage.setMojo(mojo);
rpmFileRule = new RpmPackageRule();
rpmFileRule.setPackage(rpmPackage);
rpmFileRule.setBase("files");
}
@Override
public RpmBaseObject getRpmBaseObject() {
return rpmFileRule;
}
@Test
public void directiveAccessors() throws InvalidDirectiveException {
List<String> directives = new ArrayList<>();
directives.add("noreplace");
rpmFileRule.setDirectives(directives);
assertNotNull(rpmFileRule.getDirectives());
}
@Test
public void packageAccessors() {
assertEquals(rpmPackage, rpmFileRule.getPackage());
}
@Test
public void baseAccessors() {
rpmFileRule.setBase("");
assertEquals(File.separator, rpmFileRule.getBase());
rpmFileRule.setBase(null);
assertEquals(File.separator, rpmFileRule.getBase());
rpmFileRule.setBase(String.format("%sfoo", File.separator));
assertEquals(String.format("%sfoo", File.separator), rpmFileRule.getBase());
}
@Test
public void destinationAccessors() {
rpmFileRule.setDestination("");
assertNull(rpmFileRule.getDestination());
rpmFileRule.setDestination(null);
assertNull(rpmFileRule.getDestination());
assertEquals(String.format("%svar%swww%stest", File.separator, File.separator, File.separator),
rpmFileRule.getDestinationOrDefault());
rpmFileRule.setDestination(String.format("%sfoo", File.separator));
assertEquals(String.format("%sfoo", File.separator), rpmFileRule.getDestination());
assertEquals(String.format("%sfoo", File.separator), rpmFileRule.getDestinationOrDefault());
}
@Test
public void includeAccessors() {
List<String> includes = new ArrayList<>();
rpmFileRule.setIncludes(includes);
assertEquals(includes, rpmFileRule.getIncludes());
}
@Test
public void excludeAccessors() {
List<String> excludes = new ArrayList<>();
rpmFileRule.setExcludes(excludes);
assertEquals(excludes, rpmFileRule.getExcludes());
}
@Test
public void logAccessor() {
assertEquals(log, rpmFileRule.getLog());
}
@Test
public void scanPathAccessor() throws InvalidPathException {
String scanPath = String.format("%s%sfiles", new File(testOutputPath).getAbsolutePath(), File.separator);
assertEquals(scanPath, rpmFileRule.getScanPath());
}
@Test
public void testListFiles() throws RpmException {
List<String> includes = new ArrayList<>();
includes.add("**");
List<String> excludes = new ArrayList<>();
excludes.add("composer.*");
rpmFileRule.setIncludes(includes);
rpmFileRule.setExcludes(excludes);
String[] files = rpmFileRule.listFiles();
assertEquals(62, files.length);
}
@Test
public void testListFilesOutsideBuildPath() throws RpmException {
Assertions.assertThrows(PathOutsideBuildPathException.class, () -> {
rpmFileRule.setBase(String.format("..%s", File.separator));
rpmFileRule.listFiles();
});
}
@Test
public void testAddFiles() throws IOException, RpmException {
MockBuilder builder = new MockBuilder();
List<String> includes = new ArrayList<>();
includes.add("**");
List<String> excludes = new ArrayList<>();
excludes.add("composer.*");
rpmFileRule.setIncludes(includes);
rpmFileRule.setExcludes(excludes);
String[] files = rpmFileRule.addFiles(builder);
assertEquals(62, files.length);
assertEquals(92, builder.getContents().size());
}
}

View file

@ -0,0 +1,407 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.maven.model.Build;
import org.apache.maven.project.MavenProject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.xbib.maven.plugin.rpm.mojo.PackageRpmMojo;
import org.xbib.rpm.exception.RpmException;
import org.xbib.rpm.exception.UnknownArchitectureException;
import org.xbib.rpm.exception.UnknownOperatingSystemException;
import org.xbib.rpm.lead.Architecture;
import org.xbib.rpm.lead.Os;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class RpmPackageTest {
private String testOutputPath;
private RpmPackage rpmPackage;
private MavenProject project;
@BeforeEach
public void setUp() {
testOutputPath = System.getProperty("project.build.testOutputDirectory");
Build projectBuild = new Build();
projectBuild.setDirectory(testOutputPath);
rpmPackage = new RpmPackage();
project = new MavenProject();
project.setArtifactId("test-artifact");
project.setName("test");
project.setVersion("1.0");
project.setBuild(projectBuild);
PackageRpmMojo mojo = new PackageRpmMojo();
mojo.setProject(project);
mojo.setBuildPath(String.format("%s%sfiles", testOutputPath, File.separator));
rpmPackage.setMojo(mojo);
}
@Test
public void nameAccessors() {
assertEquals("test-artifact", rpmPackage.getName());
rpmPackage.setName("name");
assertEquals("name", rpmPackage.getName());
}
@Test
public void versionAccessors() {
assertEquals("1.0", rpmPackage.getVersion());
assertEquals("1.0", rpmPackage.getProjectVersion());
rpmPackage.setVersion("2.0");
assertEquals("2.0", rpmPackage.getVersion());
assertEquals("2.0", rpmPackage.getProjectVersion());
rpmPackage.setVersion("2.0-SNAPSHOT");
assertEquals("2.0.SNAPSHOT", rpmPackage.getVersion());
assertEquals("2.0-SNAPSHOT", rpmPackage.getProjectVersion());
rpmPackage.setVersion(null);
assertEquals("1.0", rpmPackage.getVersion());
assertEquals("1.0", rpmPackage.getProjectVersion());
rpmPackage.setVersion("");
assertEquals("1.0", rpmPackage.getVersion());
assertEquals("1.0", rpmPackage.getProjectVersion());
}
@Test
public void releaseAccessors() {
assertTrue(rpmPackage.getRelease().matches("\\d+"));
rpmPackage.setRelease("release");
assertEquals("release", rpmPackage.getRelease());
}
@Test
public void finalNameAccessors() {
rpmPackage.setName("name");
rpmPackage.setVersion("1.0-SNAPSHOT");
rpmPackage.setRelease("3");
assertEquals("name-1.0.SNAPSHOT-3.noarch.rpm", rpmPackage.getFinalName());
rpmPackage.setFinalName("finalname");
assertEquals("finalname", rpmPackage.getFinalName());
}
@Test
public void dependenciesAccessors() {
List<RpmPackageAssociation> dependencies = new ArrayList<>();
assertNotNull(rpmPackage.getDependencies());
rpmPackage.setDependencies(dependencies);
assertEquals(dependencies, rpmPackage.getDependencies());
}
@Test
public void obsoletesAccessors() {
List<RpmPackageAssociation> obsoletes = new ArrayList<>();
assertNotNull(rpmPackage.getObsoletes());
rpmPackage.setObsoletes(obsoletes);
assertEquals(obsoletes, rpmPackage.getObsoletes());
}
@Test
public void conflictsAccessors() {
List<RpmPackageAssociation> conflicts = new ArrayList<>();
assertNotNull(rpmPackage.getConflicts());
rpmPackage.setConflicts(conflicts);
assertEquals(conflicts, rpmPackage.getConflicts());
}
@Test
public void urlAccessors() {
assertNull(rpmPackage.getUrl());
rpmPackage.setUrl("http://www.example.com/foo");
assertEquals("http://www.example.com/foo", rpmPackage.getUrl());
}
@Test
public void groupAccessors() {
assertNull(rpmPackage.getGroup());
rpmPackage.setGroup("group/subgroup");
assertEquals("group/subgroup", rpmPackage.getGroup());
}
@Test
public void licenseAccessors() {
assertNull(rpmPackage.getLicense());
rpmPackage.setLicense("license");
assertEquals("license", rpmPackage.getLicense());
}
@Test
public void summaryAccessors() {
assertNull(rpmPackage.getSummary());
rpmPackage.setSummary("summary");
assertEquals("summary", rpmPackage.getSummary());
}
@Test
public void descriptionAccessors() {
assertNull(rpmPackage.getDescription());
rpmPackage.setDescription("description");
assertEquals("description", rpmPackage.getDescription());
}
@Test
public void distributionAccessors() {
assertNull(rpmPackage.getDistribution());
rpmPackage.setDistribution("distribution");
assertEquals("distribution", rpmPackage.getDistribution());
}
@Test
public void architectureAccessors() throws UnknownArchitectureException {
assertEquals(Architecture.NOARCH, rpmPackage.getArchitecture());
rpmPackage.setArchitecture("SPARC");
assertEquals(Architecture.SPARC, rpmPackage.getArchitecture());
}
@Test
public void architectureInvalidException() {
Assertions.assertThrows(UnknownArchitectureException.class, () ->
rpmPackage.setArchitecture("NONEXISTENT"));
}
@Test
public void architectureBlankException() {
Assertions.assertThrows(UnknownArchitectureException.class, () ->
rpmPackage.setArchitecture(""));
}
@Test
public void architectureNullException() {
Assertions.assertThrows(UnknownArchitectureException.class, () ->
rpmPackage.setArchitecture(null));
}
@Test
public void operatingSystemAccessors() throws UnknownOperatingSystemException {
assertEquals(Os.LINUX, rpmPackage.getOperatingSystem());
rpmPackage.setOperatingSystem("LINUX390");
assertEquals(Os.LINUX390, rpmPackage.getOperatingSystem());
}
@Test
public void operatingSystemInvalidException() {
Assertions.assertThrows(UnknownOperatingSystemException.class, () ->
rpmPackage.setOperatingSystem("NONEXISTENT"));
}
@Test
public void operatingSystemBlankException() {
Assertions.assertThrows(UnknownOperatingSystemException.class, () ->
rpmPackage.setOperatingSystem(""));
}
@Test
public void operatingSystemNullException() {
Assertions.assertThrows(UnknownOperatingSystemException.class, () ->
rpmPackage.setOperatingSystem(null));
}
@Test
public void buildHostNameAccessors() throws Exception {
assertNotNull(rpmPackage.getBuildHostName());
rpmPackage.setBuildHostName("buildhost");
assertEquals("buildhost", rpmPackage.getBuildHostName());
}
@Test
public void packagerAccessors() {
assertNull(rpmPackage.getPackager());
rpmPackage.setPackager("packager");
assertEquals("packager", rpmPackage.getPackager());
}
@Test
public void attachAccessors() {
assertTrue(rpmPackage.isAttach());
rpmPackage.setAttach(false);
assertFalse(rpmPackage.isAttach());
}
@Test
public void classifierAccessors() {
assertNull(rpmPackage.getClassifier());
rpmPackage.setClassifier("classifier");
assertEquals("classifier", rpmPackage.getClassifier());
}
@Test
public void rulesAccessors() {
List<RpmPackageRule> rules = new ArrayList<>();
rules.add(new RpmPackageRule());
rules.add(new RpmPackageRule());
rpmPackage.setRules(rules);
assertEquals(rules, rpmPackage.getRules());
rpmPackage.setRules(null);
assertNull(rpmPackage.getRules());
}
@Test
public void eventHookAccessors() {
Path scriptFile = Paths.get("samplescript.sh");
assertNull(rpmPackage.getPreTransactionScriptPath());
rpmPackage.setPreTransactionScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPreTransactionScriptPath());
assertNull(rpmPackage.getPreTransactionProgram());
rpmPackage.setPreTransactionProgram("/bin/sh");
assertEquals("/bin/sh", rpmPackage.getPreTransactionProgram());
assertNull(rpmPackage.getPreInstallScriptPath());
rpmPackage.setPreInstallScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPreInstallScriptPath());
assertNull(rpmPackage.getPreInstallProgram());
rpmPackage.setPreInstallProgram("/bin/sh");
assertEquals("/bin/sh", rpmPackage.getPreInstallProgram());
assertNull(rpmPackage.getPostInstallScriptPath());
rpmPackage.setPostInstallScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPostInstallScriptPath());
assertNull(rpmPackage.getPostInstallProgram());
rpmPackage.setPostInstallProgram("/bin/sh");
assertEquals("/bin/sh", rpmPackage.getPostInstallProgram());
assertNull(rpmPackage.getPreUninstallScriptPath());
rpmPackage.setPreUninstallScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPreUninstallScriptPath());
assertNull(rpmPackage.getPreUninstallProgram());
rpmPackage.setPreUninstallProgram("/bin/sh");
assertEquals("/bin/sh", rpmPackage.getPreUninstallProgram());
assertNull(rpmPackage.getPostUninstallScriptPath());
rpmPackage.setPostUninstallScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPostUninstallScriptPath());
assertNull(rpmPackage.getPostUninstallProgram());
rpmPackage.setPostUninstallProgram("/bin/sh");
assertEquals("/bin/sh", rpmPackage.getPostUninstallProgram());
assertNull(rpmPackage.getPostTransactionScriptPath());
rpmPackage.setPostTransactionScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPostTransactionScriptPath());
assertNull(rpmPackage.getPostTransactionProgram());
rpmPackage.setPostTransactionProgram("/bin/sh");
assertEquals("/bin/sh", rpmPackage.getPostTransactionProgram());
}
@Test
public void triggerAccessors() {
List<RpmTrigger> triggers = new ArrayList<>();
assertNotNull(rpmPackage.getTriggers());
rpmPackage.setTriggers(triggers);
assertEquals(triggers, rpmPackage.getTriggers());
}
@Test
public void signingKeyAccessors() {
assertNull(rpmPackage.getSigningKey());
rpmPackage.setSigningKey("key");
assertEquals("key", rpmPackage.getSigningKey());
assertNull(rpmPackage.getSigningKeyId());
rpmPackage.setSigningKeyId(0L);
assertEquals(Long.valueOf(0L), rpmPackage.getSigningKeyId());
assertNull(rpmPackage.getSigningKeyPassPhrase());
rpmPackage.setSigningKeyPassPhrase("passphrase");
assertEquals("passphrase", rpmPackage.getSigningKeyPassPhrase());
}
@Test
public void prefixesAccessors() {
List<String> prefixes = new ArrayList<>();
assertNotNull(rpmPackage.getPrefixes());
rpmPackage.setPrefixes(null);
assertNotNull(rpmPackage.getPrefixes());
rpmPackage.setPrefixes(prefixes);
assertEquals(prefixes, rpmPackage.getPrefixes());
}
@Test
public void builtinsAccessors() {
List<String> builtins = new ArrayList<>();
assertNotNull(rpmPackage.getBuiltins());
rpmPackage.setBuiltins(null);
assertNotNull(rpmPackage.getBuiltins());
rpmPackage.setBuiltins(builtins);
assertEquals(builtins, rpmPackage.getBuiltins());
}
@Test
public void build() throws IOException, RpmException {
project.setArtifactId("build");
List<RpmPackageAssociation> dependencies = new ArrayList<>();
RpmPackageAssociation dependency = new RpmPackageAssociation();
dependency.setName("dependency");
dependencies.add(dependency);
rpmPackage.setDependencies(dependencies);
List<RpmPackageAssociation> obsoletes = new ArrayList<>();
RpmPackageAssociation obsolete = new RpmPackageAssociation();
obsolete.setName("obsolete");
obsoletes.add(obsolete);
rpmPackage.setObsoletes(obsoletes);
List<RpmPackageAssociation> conflicts = new ArrayList<>();
RpmPackageAssociation conflict = new RpmPackageAssociation();
conflict.setName("conflict");
conflicts.add(conflict);
rpmPackage.setConflicts(conflicts);
List<RpmPackageRule> rules = new ArrayList<>();
RpmPackageRule rule = new RpmPackageRule();
rules.add(rule);
rpmPackage.setRules(rules);
Path scriptFile = Paths.get(String.format("%s%s/rpm/RpmPackage.sh",
testOutputPath, File.separator));
rpmPackage.setPreTransactionScriptPath(scriptFile);
rpmPackage.setPreTransactionProgram("/bin/sh");
rpmPackage.setPreInstallScriptPath(scriptFile);
rpmPackage.setPreInstallProgram("/bin/sh");
rpmPackage.setPostInstallScriptPath(scriptFile);
rpmPackage.setPostInstallProgram("/bin/sh");
rpmPackage.setPreUninstallScriptPath(scriptFile);
rpmPackage.setPreUninstallProgram("/bin/sh");
rpmPackage.setPostUninstallScriptPath(scriptFile);
rpmPackage.setPostUninstallProgram("/bin/sh");
rpmPackage.setPostTransactionScriptPath(scriptFile);
rpmPackage.setPostTransactionProgram("/bin/sh");
rpmPackage.build();
String rpmFileName = String.format("%s%s%s", testOutputPath, File.separator, rpmPackage.getFinalName());
assertTrue(new File(rpmFileName).exists());
}
@Test
public void buildSecondaryAttachmentNameDifference() throws IOException, RpmException {
rpmPackage.setName("buildSecondaryAttachment");
rpmPackage.build();
String rpmFileName = String.format("%s%s%s", testOutputPath, File.separator, rpmPackage.getFinalName());
assertTrue(new File(rpmFileName).exists());
}
@Test
public void buildSecondaryAttachmentVersionDifference() throws IOException, RpmException {
rpmPackage.setVersion("2.0");
rpmPackage.build();
String rpmFileName = String.format("%s%s%s", testOutputPath, File.separator, rpmPackage.getFinalName());
assertTrue(new File(rpmFileName).exists());
}
@Test
public void buildSecondaryAttachmentNameAndVersionDifference() throws IOException, RpmException {
rpmPackage.setName("buildSecondaryAttachmentNameAndVersionDifference");
rpmPackage.setVersion("2.0");
rpmPackage.build();
String rpmFileName = String.format("%s%s%s", testOutputPath, File.separator, rpmPackage.getFinalName());
assertTrue(new File(rpmFileName).exists());
}
@Test
public void buildWithoutAttachment() throws IOException, RpmException {
project.setArtifactId("buildWithoutAttachment");
rpmPackage.setAttach(false);
rpmPackage.build();
String rpmFileName = String.format("%s%s%s", testOutputPath, File.separator, rpmPackage.getFinalName());
assertTrue(new File(rpmFileName).exists());
}
}

View file

@ -0,0 +1,60 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
*
*/
public class RpmScriptTemplateRendererTest {
private String testOutputPath;
@BeforeEach
public void setUp() {
this.testOutputPath = System.getProperty("project.build.testOutputDirectory");
}
@Test
public void render() throws Exception {
Path templateScriptFile = Paths.get(
String.format("%s/rpm/RpmScriptTemplateRenderer-template",
this.testOutputPath));
Path expectedScriptFile = Paths.get(
String.format("%s/rpm/RpmScriptTemplateRenderer-template-expected",
this.testOutputPath));
Path actualScriptFile = Paths.get(
String.format("%s/rpm/RpmScriptTemplateRenderer-template-actual",
this.testOutputPath));
RpmScriptTemplateRenderer renderer = new RpmScriptTemplateRenderer();
renderer.addParameter("testdata1", true);
renderer.addParameter("testdata2", "test");
renderer.addParameter("testdata3", 123);
//assertFalse(Files.exists(actualScriptFile));
renderer.render(templateScriptFile, actualScriptFile);
assertTrue(Files.exists(actualScriptFile));
char[] buff = new char[1024];
StringBuilder stringBuilder;
int bytesRead;
stringBuilder = new StringBuilder();
try (Reader reader = Files.newBufferedReader(actualScriptFile)) {
while (-1 != (bytesRead = reader.read(buff))) {
stringBuilder.append(buff, 0, bytesRead);
}
}
String actualTemplateContents = stringBuilder.toString();
stringBuilder = new StringBuilder();
try (Reader reader = Files.newBufferedReader(expectedScriptFile)) {
while (-1 != (bytesRead = reader.read(buff))) {
stringBuilder.append(buff, 0, bytesRead);
}
}
String expectedTemplateContents = stringBuilder.toString();
assertEquals(expectedTemplateContents, actualTemplateContents);
}
}

View file

@ -0,0 +1,48 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import org.junit.jupiter.api.Test;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class RpmTriggerTest {
@Test
public void accessors() {
List<RpmPackageAssociation> dependencies = new ArrayList<>();
RpmTrigger trigger = new RpmTrigger();
Path triggerScript = Paths.get("/path/to/file");
assertNull(trigger.getPreInstallScriptPath());
trigger.setPreInstallScriptPath(triggerScript);
assertEquals(triggerScript, trigger.getPreInstallScriptPath());
assertNull(trigger.getPreInstallProgram());
trigger.setPreInstallProgram("/bin/sh");
assertEquals("/bin/sh", trigger.getPreInstallProgram());
assertNull(trigger.getPostInstallScriptPath());
trigger.setPostInstallScriptPath(triggerScript);
assertEquals(triggerScript, trigger.getPostInstallScriptPath());
assertNull(trigger.getPostInstallProgram());
trigger.setPostInstallProgram("/bin/sh");
assertEquals("/bin/sh", trigger.getPostInstallProgram());
assertNull(trigger.getPreUninstallScriptPath());
trigger.setPreUninstallScriptPath(triggerScript);
assertEquals(triggerScript, trigger.getPreUninstallScriptPath());
assertNull(trigger.getPreUninstallProgram());
trigger.setPreUninstallProgram("/bin/sh");
assertEquals("/bin/sh", trigger.getPreUninstallProgram());
assertNull(trigger.getPostUninstallScriptPath());
trigger.setPostUninstallScriptPath(triggerScript);
assertEquals(triggerScript, trigger.getPostUninstallScriptPath());
assertNull(trigger.getPostUninstallProgram());
trigger.setPostUninstallProgram("/bin/sh");
assertEquals("/bin/sh", trigger.getPostUninstallProgram());
trigger.setDependencies(dependencies);
assertEquals(dependencies, trigger.getDependencies());
}
}

View file

@ -0,0 +1,170 @@
package org.xbib.maven.plugin.rpm.mojo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.maven.model.Build;
import org.apache.maven.model.License;
import org.apache.maven.project.MavenProject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.xbib.maven.plugin.rpm.MockMojo;
import org.xbib.maven.plugin.rpm.RpmPackage;
import org.xbib.maven.plugin.rpm.RpmScriptTemplateRenderer;
import org.xbib.rpm.exception.InvalidPathException;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
*
*/
public class AbstractRpmMojoTest {
private String testOutputPath;
private MockMojo mojo;
private MavenProject project;
@BeforeEach
public void setUp() {
testOutputPath = System.getProperty("project.build.testOutputDirectory");
Build projectBuild = new Build();
projectBuild.setDirectory("target");
project = new MavenProject();
project.setGroupId("org.xbib");
project.setArtifactId("test-artifact");
project.setName("test");
project.setVersion("1.0-SNAPSHOT");
project.setUrl("http://www.example.com");
project.setBuild(projectBuild);
List<License> licenses = new ArrayList<>();
License license1 = new License();
license1.setName("GPL");
licenses.add(license1);
License license2 = new License();
license2.setName("LGPL");
licenses.add(license2);
project.setLicenses(licenses);
mojo = new MockMojo();
mojo.setProject(project);
}
@Test
public void projectAccessors() {
mojo.setProject(null);
assertNull(mojo.getProject());
mojo.setProject(project);
assertEquals(project, mojo.getProject());
assertEquals("test-artifact", mojo.getProjectArtifactId());
assertEquals("1.0-SNAPSHOT", mojo.getProjectVersion());
assertEquals("http://www.example.com", mojo.getProjectUrl());
assertEquals("GPL, LGPL", mojo.getCollapsedProjectLicense());
assertEquals("target", mojo.getBuildDirectory());
}
@Test
public void templateRenderer() throws IOException {
RpmScriptTemplateRenderer renderer = mojo.getTemplateRenderer();
assertNotNull(renderer);
Path templateScriptFile =
Paths.get(testOutputPath, "mojo/AbstractRpmMojo-template");
Path expectedScriptFile =
Paths.get(testOutputPath, "mojo/AbstractRpmMojo-template-expected");
Path actualScriptFile =
Paths.get(testOutputPath, "mojo/AbstractRpmMojo-template-actual");
renderer.render(templateScriptFile, actualScriptFile);
assertTrue(Files.exists(actualScriptFile));
char[] buff = new char[1024];
StringBuilder stringBuilder;
int bytesRead;
stringBuilder = new StringBuilder();
try (BufferedReader reader = Files.newBufferedReader(actualScriptFile)) {
while (-1 != (bytesRead = reader.read(buff))) {
stringBuilder.append(buff, 0, bytesRead);
}
}
String actualTemplateContents = stringBuilder.toString();
stringBuilder = new StringBuilder();
try (BufferedReader reader = Files.newBufferedReader(expectedScriptFile)) {
while (-1 != (bytesRead = reader.read(buff))) {
stringBuilder.append(buff, 0, bytesRead);
}
}
String expectedTemplateContents = stringBuilder.toString();
assertEquals(expectedTemplateContents, actualTemplateContents);
assertEquals(renderer, mojo.getTemplateRenderer());
}
@Test
public void projectArtifacts() {
Path artifact = Paths.get(String.format("%s/artifact.rpm", testOutputPath));
mojo.setPrimaryArtifact(artifact, "test");
mojo.addSecondaryArtifact(artifact, "secondary-artifact", "1.0", "test");
mojo.addSecondaryArtifact(artifact, "secondary-artifact", "1.0", null);
assertNotNull(project.getArtifact());
assertEquals(2, project.getAttachedArtifacts().size());
}
@Test
public void buildPath() throws InvalidPathException {
mojo.setBuildPath(testOutputPath);
assertEquals(testOutputPath, mojo.getBuildPath());
}
@Test
public void packages() {
List<RpmPackage> packages = new ArrayList<>();
packages.add(new RpmPackage());
mojo.setPackages(packages);
assertEquals(packages, mojo.getPackages());
}
@Test
public void defaults() {
assertEquals(0644, mojo.getDefaultFileMode());
mojo.setDefaultFileMode(0755);
assertEquals(0755, mojo.getDefaultFileMode());
assertEquals("root", mojo.getDefaultOwner());
mojo.setDefaultOwner("nobody");
assertEquals("nobody", mojo.getDefaultOwner());
assertEquals("root", mojo.getDefaultGroup());
mojo.setDefaultGroup("nobody");
assertEquals("nobody", mojo.getDefaultGroup());
assertEquals(File.separator, mojo.getDefaultDestination());
mojo.setDefaultDestination(String.format("%sdestination", File.separator));
assertEquals(String.format("%sdestination", File.separator), mojo.getDefaultDestination());
}
@Test
public void excludes() {
List<String> excludes = new ArrayList<>();
mojo.setExcludes(excludes);
assertEquals(excludes, mojo.getExcludes());
}
@Test
public void checkingForExtraFiles() {
mojo.setPerformCheckingForExtraFiles(true);
assertTrue(mojo.isPerformCheckingForExtraFiles());
mojo.setPerformCheckingForExtraFiles(false);
assertFalse(mojo.isPerformCheckingForExtraFiles());
}
@Test
public void scanMasterFiles() {
mojo.setBuildPath(String.format("%s%sfiles", testOutputPath, File.separator));
mojo.scanMasterFiles();
Set<String> masterFiles = mojo.getMasterFiles();
assertEquals(62, masterFiles.size());
}
}

View file

@ -0,0 +1,63 @@
package org.xbib.maven.plugin.rpm.mojo;
import org.apache.maven.model.Build;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.xbib.maven.plugin.rpm.RpmPackage;
import org.xbib.maven.plugin.rpm.RpmPackageRule;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class ListFilesRpmMojoTest {
private String testOutputPath;
private ListFilesRpmMojo mojo;
private RpmPackageRule packageRule;
@BeforeEach
public void setUp() {
this.testOutputPath = System.getProperty("project.build.testOutputDirectory");
Build projectBuild = new Build();
projectBuild.setDirectory(this.testOutputPath);
MavenProject project = new MavenProject();
project.setGroupId("uk.co.codezen");
project.setArtifactId("listfilesmojo-artifact");
project.setName("test");
project.setVersion("1.0-SNAPSHOT");
project.setUrl("http://www.example.com");
project.setBuild(projectBuild);
this.mojo = new ListFilesRpmMojo();
this.mojo.setProject(project);
List<RpmPackageRule> packageRules = new ArrayList<>();
this.packageRule = new RpmPackageRule();
packageRules.add(this.packageRule);
RpmPackage rpmPackage = new RpmPackage();
rpmPackage.setRules(packageRules);
List<RpmPackage> packages = new ArrayList<>();
packages.add(rpmPackage);
this.mojo.setPackages(packages);
this.mojo.setBuildPath(String.format("%s%sfiles", this.testOutputPath, File.separator));
}
@Test
public void packageRpm() throws MojoExecutionException {
List<String> includes = new ArrayList<>();
includes.add("**");
packageRule.setIncludes(includes);
this.mojo.execute();
}
@Test
public void packageRpmMissedFiles() throws MojoExecutionException {
List<String> includes = new ArrayList<>();
packageRule.setIncludes(includes);
this.mojo.execute();
}
}

View file

@ -0,0 +1,115 @@
package org.xbib.maven.plugin.rpm.mojo;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.apache.maven.model.Build;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.xbib.maven.plugin.rpm.RpmPackage;
import org.xbib.maven.plugin.rpm.RpmPackageRule;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class PackageRpmMojoTest {
private PackageRpmMojo mojo;
private MavenProject project;
private RpmPackageRule packageRule;
@BeforeEach
public void setUp() {
// Test output path
String testOutputPath = System.getProperty("project.build.testOutputDirectory");
Build projectBuild = new Build();
projectBuild.setDirectory(testOutputPath);
project = new MavenProject();
project.setGroupId("org.xbib");
project.setArtifactId("packagerpmmojo-artifact");
project.setName("test");
project.setUrl("http://www.example.com");
project.setBuild(projectBuild);
project.setPackaging("rpm");
mojo = new PackageRpmMojo();
mojo.setProject(project);
List<RpmPackageRule> packageRules = new ArrayList<>();
packageRule = new RpmPackageRule();
packageRules.add(packageRule);
RpmPackage rpmPackage = new RpmPackage();
rpmPackage.setRules(packageRules);
List<RpmPackage> packages = new ArrayList<>();
packages.add(rpmPackage);
mojo.setPackages(packages);
mojo.setBuildPath(String.format("%s%sfiles", testOutputPath, File.separator));
}
@Test
public void packageRpm() throws MojoExecutionException {
project.setVersion("1.0-SNAPSHOT");
List<String> includes = new ArrayList<>();
includes.add("**");
packageRule.setIncludes(includes);
mojo.execute();
assertTrue(project.getArtifact().getFile().exists());
}
@Test
public void packageRpmNonRpmPackagingType() throws MojoExecutionException {
project.setPackaging("jar");
project.setVersion("1.1-SNAPSHOT");
List<String> includes = new ArrayList<>();
includes.add("**");
packageRule.setIncludes(includes);
mojo.execute();
assertNull(project.getArtifact());
}
@Test
public void packageRpmMissedFiles() throws MojoExecutionException {
Assertions.assertThrows(MojoExecutionException.class, () -> {
project.setVersion("2.0-SNAPSHOT");
List<String> includes = new ArrayList<>();
packageRule.setIncludes(includes);
mojo.execute();
});
}
@Test
public void packageRpmMissedFilesWithoutChecks() throws MojoExecutionException {
mojo.setPerformCheckingForExtraFiles(false);
project.setVersion("3.0-SNAPSHOT");
List<String> includes = new ArrayList<>();
includes.add("**/*.php");
packageRule.setIncludes(includes);
mojo.execute();
}
@Test
public void packageRpmNoFilesPackaged() throws MojoExecutionException {
Assertions.assertThrows(MojoExecutionException.class, () -> {
mojo.setPerformCheckingForExtraFiles(false);
project.setVersion("4.0-SNAPSHOT");
List<String> includes = new ArrayList<>();
packageRule.setIncludes(includes);
mojo.execute();
});
}
@Test
public void packageRpmNoFilesPackagedNoPackages() throws MojoExecutionException {
mojo.setPackages(new ArrayList<>());
mojo.setPerformCheckingForExtraFiles(false);
project.setVersion("5.0-SNAPSHOT");
List<String> includes = new ArrayList<>();
packageRule.setIncludes(includes);
mojo.execute();
}
}

View file

@ -0,0 +1,4 @@
/**
*
*/
package org.xbib.maven.plugin.rpm.mojo;

View file

@ -0,0 +1,4 @@
/**
*
*/
package org.xbib.maven.plugin.rpm;

View file

@ -0,0 +1,11 @@
/web/bundles/
/app/bootstrap.php.cache
/app/cache/*
/app/config/parameters.yml
/app/logs/*
!app/cache/.gitkeep
!app/logs/.gitkeep
/build/
/vendor/
/bin/
/composer.phar

View file

@ -0,0 +1,170 @@
Symfony Standard Edition
========================
Welcome to the Symfony Standard Edition - a fully-functional Symfony2
application that you can use as the skeleton for your new applications.
This document contains information on how to download, install, and start
using Symfony. For a more detailed explanation, see the [Installation][1]
chapter of the Symfony Documentation.
1) Installing the Standard Edition
----------------------------------
When it comes to installing the Symfony Standard Edition, you have the
following options.
### Use Composer (*recommended*)
As Symfony uses [Composer][2] to manage its dependencies, the recommended way
to create a new project is to use it.
If you don't have Composer yet, download it following the instructions on
http://getcomposer.org/ or just run the following command:
curl -s http://getcomposer.org/installer | php
Then, use the `create-project` command to generate a new Symfony application:
php composer.phar create-project symfony/framework-standard-edition path/to/install
Composer will install Symfony and all its dependencies under the
`path/to/install` directory.
### Download an Archive File
To quickly test Symfony, you can also download an [archive][3] of the Standard
Edition and unpack it somewhere under your web server root directory.
If you downloaded an archive "without vendors", you also need to install all
the necessary dependencies. Download composer (see above) and run the
following command:
php composer.phar install
2) Checking your System Configuration
-------------------------------------
Before starting coding, make sure that your local system is properly
configured for Symfony.
Execute the `check.php` script from the command line:
php app/check.php
The script returns a status code of `0` if all mandatory requirements are met,
`1` otherwise.
Access the `config.php` script from a browser:
http://localhost/path-to-project/web/config.php
If you get any warnings or recommendations, fix them before moving on.
3) Browsing the Demo Application
--------------------------------
Congratulations! You're now ready to use Symfony.
From the `config.php` page, click the "Bypass configuration and go to the
Welcome page" link to load up your first Symfony page.
You can also use a web-based configurator by clicking on the "Configure your
Symfony Application online" link of the `config.php` page.
To see a real-live Symfony page in action, access the following page:
web/app_dev.php/demo/hello/Fabien
4) Getting started with Symfony
-------------------------------
This distribution is meant to be the starting point for your Symfony
applications, but it also contains some sample code that you can learn from
and play with.
A great way to start learning Symfony is via the [Quick Tour][4], which will
take you through all the basic features of Symfony2.
Once you're feeling good, you can move onto reading the official
[Symfony2 book][5].
A default bundle, `AcmeDemoBundle`, shows you Symfony2 in action. After
playing with it, you can remove it by following these steps:
* delete the `src/Acme` directory;
* remove the routing entry referencing AcmeDemoBundle in `app/config/routing_dev.yml`;
* remove the AcmeDemoBundle from the registered bundles in `app/AppKernel.php`;
* remove the `web/bundles/acmedemo` directory;
* empty the `security.yml` file or tweak the security configuration to fit
your needs.
What's inside?
---------------
The Symfony Standard Edition is configured with the following defaults:
* Twig is the only configured template engine;
* Doctrine ORM/DBAL is configured;
* Swiftmailer is configured;
* Annotations for everything are enabled.
It comes pre-configured with the following bundles:
* **FrameworkBundle** - The core Symfony framework bundle
* [**SensioFrameworkExtraBundle**][6] - Adds several enhancements, including
template and routing annotation capability
* [**DoctrineBundle**][7] - Adds support for the Doctrine ORM
* [**TwigBundle**][8] - Adds support for the Twig templating engine
* [**SecurityBundle**][9] - Adds security by integrating Symfony's security
component
* [**SwiftmailerBundle**][10] - Adds support for Swiftmailer, a library for
sending emails
* [**MonologBundle**][11] - Adds support for Monolog, a logging library
* [**AsseticBundle**][12] - Adds support for Assetic, an asset processing
library
* **WebProfilerBundle** (in dev/test env) - Adds profiling functionality and
the web debug toolbar
* **SensioDistributionBundle** (in dev/test env) - Adds functionality for
configuring and working with Symfony distributions
* [**SensioGeneratorBundle**][13] (in dev/test env) - Adds code generation
capabilities
* **AcmeDemoBundle** (in dev/test env) - A demo bundle with some example
code
All libraries and bundles included in the Symfony Standard Edition are
released under the MIT or BSD license.
Enjoy!
[1]: http://symfony.com/doc/2.5/book/installation.html
[2]: http://getcomposer.org/
[3]: http://symfony.com/download
[4]: http://symfony.com/doc/2.5/quick_tour/the_big_picture.html
[5]: http://symfony.com/doc/2.5/index.html
[6]: http://symfony.com/doc/2.5/bundles/SensioFrameworkExtraBundle/index.html
[7]: http://symfony.com/doc/2.5/book/doctrine.html
[8]: http://symfony.com/doc/2.5/book/templating.html
[9]: http://symfony.com/doc/2.5/book/security.html
[10]: http://symfony.com/doc/2.5/cookbook/email.html
[11]: http://symfony.com/doc/2.5/cookbook/logging/monolog.html
[12]: http://symfony.com/doc/2.5/cookbook/assetic/asset_management.html
[13]: http://symfony.com/doc/2.5/bundles/SensioGeneratorBundle/index.html

View file

@ -0,0 +1,30 @@
UPGRADE FROM 2.1 to 2.2
=======================
* The [`web/.htaccess`](https://github.com/symfony/symfony-standard/blob/2.2/web/.htaccess)
file has been enhanced substantially to prevent duplicate content with and
without `/app.php` in the URI. It also improves functionality when using
Apache aliases or when mod_rewrite is not available. So you might want to
update your `.htaccess` file as well.
* The ``_internal`` route is not used any more. It should then be removed
from both your routing and security configurations. A ``fragments`` key has
been added to the framework configuration and must be specified when ESI or
Hinclude are in use. No security configuration is required for this path as
by default ESI access is only permitted for trusted hosts and Hinclude
access uses an URL signing mechanism.
```
framework:
# ...
fragments: { path: /_proxy }
```
Functional Tests
----------------
* The profiler has been disabled by default in the test environment. You can
enable it again by modifying the ``config_test.yml`` configuration file or
even better, you can just enable it for the very next request by calling
``$client->enableProfiler()`` when you need the profiler in a test (that
speeds up functional tests quite a bit).

View file

@ -0,0 +1,52 @@
UPGRADE FROM 2.2 to 2.3
=======================
When upgrading Symfony from 2.2 to 2.3, you need to do the following changes
to the code that came from the Standard Edition:
* The debugging tools are not enabled by default anymore and should be added
to the
[`web/app_dev.php`](https://github.com/symfony/symfony-standard/blob/2.3/web/app_dev.php)
front controller manually, just after including the bootstrap cache:
use Symfony\Component\Debug\Debug;
Debug::enable();
You also need to enable debugging in the
[`app/console`](https://github.com/symfony/symfony-standard/blob/2.3/app/console)
script, after the `$debug` variable is defined:
use Symfony\Component\Debug\Debug;
if ($debug) {
Debug::enable();
}
* The `parameters.yml` file can now be managed by the
`incenteev/composer-parameter-handler` bundle that comes with the 2.3
Standard Edition:
* add `"incenteev/composer-parameter-handler": "~2.0"` to your
`composer.json` file;
* add `/app/config/parameters.yml` to your `.gitignore` file;
* create a
[`app/config/parameters.yml.dist`](https://github.com/symfony/symfony-standard/blob/2.3/app/config/parameters.yml.dist)
file with sensible values for all your parameters.
* It is highly recommended that you switch the minimum stability to `stable`
in your `composer.json` file.
* If you are using Apache, have a look at the new
[`.htaccess`](https://github.com/symfony/symfony-standard/blob/2.3/web/.htaccess)
configuration and change yours accordingly.
* In the
[`app/autoload.php`](https://github.com/symfony/symfony-standard/blob/2.3/app/autoload.php)
file, the section about `intl` should be removed as it is not needed anymore.
You can also have a look at the
[diff](https://github.com/symfony/symfony-standard/compare/v2.2.0%E2%80%A62.3)
between the 2.2 version of the Standard Edition and the 2.3 version.

View file

@ -0,0 +1,9 @@
UPGRADE FROM 2.3 to 2.4
=======================
When upgrading Symfony from 2.3 to 2.4, you need to do the following changes
to the code that came from the Standard Edition:
* We recommend to comment or remove the `firephp` and `chromephp` Monolog
handlers as they might cause issues with some configuration (`chromephp`
with Nginx for instance).

View file

@ -0,0 +1,268 @@
Symfony Standard Edition Upgrade
================================
From Symfony 2.0 to Symfony 2.1
-------------------------------
### Project Dependencies
As of Symfony 2.1, project dependencies are managed by
[Composer](http://getcomposer.org/):
* The `bin/vendors` script can be removed as `composer.phar` does all the work
now (it is recommended to install it globally on your machine).
* The `deps` file need to be replaced with the `composer.json` one.
* The `composer.lock` is the equivalent of the generated `deps.lock` file and
it is automatically generated by Composer.
Download the default
[`composer.json`](https://raw.github.com/symfony/symfony-standard/2.1/composer.json)
and
[`composer.lock`](https://raw.github.com/symfony/symfony-standard/2.1/composer.lock)
files for Symfony 2.1 and put them into the main directory of your project. If
you have customized your `deps` file, move the added dependencies to the
`composer.json` file (many bundles and PHP libraries are already available as
Composer packages -- search for them on [Packagist](http://packagist.org/)).
Remove your current `vendor` directory.
Finally, run Composer:
$ composer.phar install
Note: You must complete the upgrade steps below so composer can successfully generate the autoload files.
### `app/autoload.php`
The default `autoload.php` reads as follows (it has been simplified a lot as
autoloading for libraries and bundles declared in your `composer.json` file is
automatically managed by the Composer autoloader):
<?php
use Doctrine\Common\Annotations\AnnotationRegistry;
$loader = include __DIR__.'/../vendor/autoload.php';
// intl
if (!function_exists('intl_get_error_code')) {
require_once __DIR__.'/../vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs/functions.php';
$loader->add('', __DIR__.'/../vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs');
}
AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
return $loader;
### `app/config/config.yml`
The `framework.charset` setting must be removed. If you are not using `UTF-8`
for your application, override the `getCharset()` method in your `AppKernel`
class instead:
class AppKernel extends Kernel
{
public function getCharset()
{
return 'ISO-8859-1';
}
// ...
}
You might want to add the new `strict_requirements` parameter to
`framework.router` (it avoids fatal errors in the production environment when
a link cannot be generated):
framework:
router:
strict_requirements: "%kernel.debug%"
You can even disable the requirements check on production with `null` as you should
know that the parameters for URL generation always pass the requirements, e.g. by
validating them beforehand. This additionally enhances performance. See
[config_prod.yml](https://github.com/symfony/symfony-standard/blob/master/app/config/config_prod.yml).
The `default_locale` parameter is now a setting of the main `framework`
configuration (it was under the `framework.session` in 2.0):
framework:
default_locale: "%locale%"
The `auto_start` setting under `framework.session` must be removed as it is
not used anymore (the session is now always started on-demand). If
`auto_start` was the only setting under the `framework.session` entry, don't
remove it entirely, but set its value to `~` (`~` means `null` in YAML)
instead:
framework:
session: ~
The `trust_proxy_headers` setting was added in the default configuration file
(as it should be set to `true` when you install your application behind a
reverse proxy):
framework:
trust_proxy_headers: false
An empty `bundles` entry was added to the `assetic` configuration:
assetic:
bundles: []
The default `swiftmailer` configuration now has the `spool` setting configured
to the `memory` type to defer email sending after the response is sent to the
user (recommended for better end-user performance):
swiftmailer:
spool: { type: memory }
The `jms_security_extra` configuration was moved to the `security.yml`
configuration file.
### `app/config/config_dev.yml`
An example of how to send all emails to a unique address was added:
#swiftmailer:
# delivery_address: me@example.com
### `app/config/config_test.yml`
The `storage_id` setting must be changed to `session.storage.mock_file`:
framework:
session:
storage_id: session.storage.mock_file
### `app/config/parameters.ini`
The file has been converted to a YAML file which reads as follows:
parameters:
database_driver: pdo_mysql
database_host: localhost
database_port: ~
database_name: symfony
database_user: root
database_password: ~
mailer_transport: smtp
mailer_host: localhost
mailer_user: ~
mailer_password: ~
locale: en
secret: ThisTokenIsNotSoSecretChangeIt
Note that if you convert your parameters file to YAML, you must also change
its reference in `app/config/config.yml`.
### `app/config/routing_dev.yml`
The `_assetic` entry was removed:
#_assetic:
# resource: .
# type: assetic
### `app/config/security.yml`
Under `security.access_control`, the default rule for internal routes was changed:
security:
access_control:
#- { path: ^/_internal/secure, roles: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 }
Under `security.providers`, the `in_memory` example was updated to the following:
security:
providers:
in_memory:
memory:
users:
user: { password: userpass, roles: [ 'ROLE_USER' ] }
admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
### `app/AppKernel.php`
The following bundles have been added to the list of default registered bundles:
new JMS\AopBundle\JMSAopBundle(),
new JMS\DiExtraBundle\JMSDiExtraBundle($this),
You must also rename the DoctrineBundle from:
new Symfony\Bundle\DoctrineBundle\DoctrineBundle(),
to:
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
### `web/app.php`
The default `web/app.php` file now reads as follows:
<?php
use Symfony\Component\ClassLoader\ApcClassLoader;
use Symfony\Component\HttpFoundation\Request;
$loader = require_once __DIR__.'/../app/bootstrap.php.cache';
// Use APC for autoloading to improve performance.
// Change 'sf2' to a unique prefix in order to prevent cache key conflicts
// with other applications also using APC.
/*
$loader = new ApcClassLoader('sf2', $loader);
$loader->register(true);
*/
require_once __DIR__.'/../app/AppKernel.php';
//require_once __DIR__.'/../app/AppCache.php';
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
//$kernel = new AppCache($kernel);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
### `web/app_dev.php`
The default `web/app_dev.php` file now reads as follows:
<?php
use Symfony\Component\HttpFoundation\Request;
// If you don't want to setup permissions the proper way, just uncomment the following PHP line
// read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information
//umask(0000);
// This check prevents access to debug front controllers that are deployed by accident to production servers.
// Feel free to remove this, extend it, or make something more sophisticated.
if (isset($_SERVER['HTTP_CLIENT_IP'])
|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
|| !in_array(@$_SERVER['REMOTE_ADDR'], array(
'127.0.0.1',
'::1',
))
) {
header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
$loader = require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';
$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

View file

@ -0,0 +1,7 @@
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from all
</IfModule>

View file

@ -0,0 +1,9 @@
<?php
require_once __DIR__.'/AppKernel.php';
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
class AppCache extends HttpCache
{
}

View file

@ -0,0 +1,35 @@
<?php
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = array(
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Symfony\Bundle\AsseticBundle\AsseticBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
);
if (in_array($this->getEnvironment(), array('dev', 'test'))) {
$bundles[] = new Acme\DemoBundle\AcmeDemoBundle();
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
$bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
$bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
}
return $bundles;
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
}
}

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>

View file

@ -0,0 +1,707 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/*
* Users of PHP 5.2 should be able to run the requirements checks.
* This is why the file and all classes must be compatible with PHP 5.2+
* (e.g. not using namespaces and closures).
*
* ************** CAUTION **************
*
* DO NOT EDIT THIS FILE as it will be overridden by Composer as part of
* the installation/update process. The original file resides in the
* SensioDistributionBundle.
*
* ************** CAUTION **************
*/
/**
* Represents a single PHP requirement, e.g. an installed extension.
* It can be a mandatory requirement or an optional recommendation.
* There is a special subclass, named PhpIniRequirement, to check a php.ini configuration.
*
* @author Tobias Schultze <http://tobion.de>
*/
class Requirement
{
private $fulfilled;
private $testMessage;
private $helpText;
private $helpHtml;
private $optional;
/**
* Constructor that initializes the requirement.
*
* @param bool $fulfilled Whether the requirement is fulfilled
* @param string $testMessage The message for testing the requirement
* @param string $helpHtml The help text formatted in HTML for resolving the problem
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
* @param bool $optional Whether this is only an optional recommendation not a mandatory requirement
*/
public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false)
{
$this->fulfilled = (bool) $fulfilled;
$this->testMessage = (string) $testMessage;
$this->helpHtml = (string) $helpHtml;
$this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText;
$this->optional = (bool) $optional;
}
/**
* Returns whether the requirement is fulfilled.
*
* @return bool true if fulfilled, otherwise false
*/
public function isFulfilled()
{
return $this->fulfilled;
}
/**
* Returns the message for testing the requirement.
*
* @return string The test message
*/
public function getTestMessage()
{
return $this->testMessage;
}
/**
* Returns the help text for resolving the problem
*
* @return string The help text
*/
public function getHelpText()
{
return $this->helpText;
}
/**
* Returns the help text formatted in HTML.
*
* @return string The HTML help
*/
public function getHelpHtml()
{
return $this->helpHtml;
}
/**
* Returns whether this is only an optional recommendation and not a mandatory requirement.
*
* @return bool true if optional, false if mandatory
*/
public function isOptional()
{
return $this->optional;
}
}
/**
* Represents a PHP requirement in form of a php.ini configuration.
*
* @author Tobias Schultze <http://tobion.de>
*/
class PhpIniRequirement extends Requirement
{
/**
* Constructor that initializes the requirement.
*
* @param string $cfgName The configuration name used for ini_get()
* @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
* @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
* @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
* @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
* @param bool $optional Whether this is only an optional recommendation not a mandatory requirement
*/
public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false)
{
$cfgValue = ini_get($cfgName);
if (is_callable($evaluation)) {
if (null === $testMessage || null === $helpHtml) {
throw new InvalidArgumentException('You must provide the parameters testMessage and helpHtml for a callback evaluation.');
}
$fulfilled = call_user_func($evaluation, $cfgValue);
} else {
if (null === $testMessage) {
$testMessage = sprintf('%s %s be %s in php.ini',
$cfgName,
$optional ? 'should' : 'must',
$evaluation ? 'enabled' : 'disabled'
);
}
if (null === $helpHtml) {
$helpHtml = sprintf('Set <strong>%s</strong> to <strong>%s</strong> in php.ini<a href="#phpini">*</a>.',
$cfgName,
$evaluation ? 'on' : 'off'
);
}
$fulfilled = $evaluation == $cfgValue;
}
parent::__construct($fulfilled || ($approveCfgAbsence && false === $cfgValue), $testMessage, $helpHtml, $helpText, $optional);
}
}
/**
* A RequirementCollection represents a set of Requirement instances.
*
* @author Tobias Schultze <http://tobion.de>
*/
class RequirementCollection implements IteratorAggregate
{
private $requirements = array();
/**
* Gets the current RequirementCollection as an Iterator.
*
* @return Traversable A Traversable interface
*/
public function getIterator()
{
return new ArrayIterator($this->requirements);
}
/**
* Adds a Requirement.
*
* @param Requirement $requirement A Requirement instance
*/
public function add(Requirement $requirement)
{
$this->requirements[] = $requirement;
}
/**
* Adds a mandatory requirement.
*
* @param bool $fulfilled Whether the requirement is fulfilled
* @param string $testMessage The message for testing the requirement
* @param string $helpHtml The help text formatted in HTML for resolving the problem
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
*/
public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null)
{
$this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, false));
}
/**
* Adds an optional recommendation.
*
* @param bool $fulfilled Whether the recommendation is fulfilled
* @param string $testMessage The message for testing the recommendation
* @param string $helpHtml The help text formatted in HTML for resolving the problem
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
*/
public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null)
{
$this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, true));
}
/**
* Adds a mandatory requirement in form of a php.ini configuration.
*
* @param string $cfgName The configuration name used for ini_get()
* @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
* @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
* @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
* @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
*/
public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
{
$this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, false));
}
/**
* Adds an optional recommendation in form of a php.ini configuration.
*
* @param string $cfgName The configuration name used for ini_get()
* @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
* @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
* @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
* @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
* @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
*/
public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
{
$this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, true));
}
/**
* Adds a requirement collection to the current set of requirements.
*
* @param RequirementCollection $collection A RequirementCollection instance
*/
public function addCollection(RequirementCollection $collection)
{
$this->requirements = array_merge($this->requirements, $collection->all());
}
/**
* Returns both requirements and recommendations.
*
* @return array Array of Requirement instances
*/
public function all()
{
return $this->requirements;
}
/**
* Returns all mandatory requirements.
*
* @return array Array of Requirement instances
*/
public function getRequirements()
{
$array = array();
foreach ($this->requirements as $req) {
if (!$req->isOptional()) {
$array[] = $req;
}
}
return $array;
}
/**
* Returns the mandatory requirements that were not met.
*
* @return array Array of Requirement instances
*/
public function getFailedRequirements()
{
$array = array();
foreach ($this->requirements as $req) {
if (!$req->isFulfilled() && !$req->isOptional()) {
$array[] = $req;
}
}
return $array;
}
/**
* Returns all optional recommendations.
*
* @return array Array of Requirement instances
*/
public function getRecommendations()
{
$array = array();
foreach ($this->requirements as $req) {
if ($req->isOptional()) {
$array[] = $req;
}
}
return $array;
}
/**
* Returns the recommendations that were not met.
*
* @return array Array of Requirement instances
*/
public function getFailedRecommendations()
{
$array = array();
foreach ($this->requirements as $req) {
if (!$req->isFulfilled() && $req->isOptional()) {
$array[] = $req;
}
}
return $array;
}
/**
* Returns whether a php.ini configuration is not correct.
*
* @return bool php.ini configuration problem?
*/
public function hasPhpIniConfigIssue()
{
foreach ($this->requirements as $req) {
if (!$req->isFulfilled() && $req instanceof PhpIniRequirement) {
return true;
}
}
return false;
}
/**
* Returns the PHP configuration file (php.ini) path.
*
* @return string|false php.ini file path
*/
public function getPhpIniConfigPath()
{
return get_cfg_var('cfg_file_path');
}
}
/**
* This class specifies all requirements and optional recommendations that
* are necessary to run the Symfony Standard Edition.
*
* @author Tobias Schultze <http://tobion.de>
* @author Fabien Potencier <fabien@symfony.com>
*/
class SymfonyRequirements extends RequirementCollection
{
const REQUIRED_PHP_VERSION = '5.3.3';
/**
* Constructor that initializes the requirements.
*/
public function __construct()
{
/* mandatory requirements follow */
$installedPhpVersion = phpversion();
$this->addRequirement(
version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>='),
sprintf('PHP version must be at least %s (%s installed)', self::REQUIRED_PHP_VERSION, $installedPhpVersion),
sprintf('You are running PHP version "<strong>%s</strong>", but Symfony needs at least PHP "<strong>%s</strong>" to run.
Before using Symfony, upgrade your PHP installation, preferably to the latest version.',
$installedPhpVersion, self::REQUIRED_PHP_VERSION),
sprintf('Install PHP %s or newer (installed version is %s)', self::REQUIRED_PHP_VERSION, $installedPhpVersion)
);
$this->addRequirement(
version_compare($installedPhpVersion, '5.3.16', '!='),
'PHP version must not be 5.3.16 as Symfony won\'t work properly with it',
'Install PHP 5.3.17 or newer (or downgrade to an earlier PHP version)'
);
$this->addRequirement(
is_dir(__DIR__.'/../vendor/composer'),
'Vendor libraries must be installed',
'Vendor libraries are missing. Install composer following instructions from <a href="http://getcomposer.org/">http://getcomposer.org/</a>. '.
'Then run "<strong>php composer.phar install</strong>" to install them.'
);
$cacheDir = is_dir(__DIR__.'/../var/cache') ? __DIR__.'/../var/cache' : __DIR__.'/cache';
$this->addRequirement(
is_writable($cacheDir),
'app/cache/ or var/cache/ directory must be writable',
'Change the permissions of either "<strong>app/cache/</strong>" or "<strong>var/cache/</strong>" directory so that the web server can write into it.'
);
$logsDir = is_dir(__DIR__.'/../var/logs') ? __DIR__.'/../var/logs' : __DIR__.'/logs';
$this->addRequirement(
is_writable($logsDir),
'app/logs/ or var/logs/ directory must be writable',
'Change the permissions of either "<strong>app/logs/</strong>" or "<strong>var/logs/</strong>" directory so that the web server can write into it.'
);
$this->addPhpIniRequirement(
'date.timezone', true, false,
'date.timezone setting must be set',
'Set the "<strong>date.timezone</strong>" setting in php.ini<a href="#phpini">*</a> (like Europe/Paris).'
);
if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) {
$timezones = array();
foreach (DateTimeZone::listAbbreviations() as $abbreviations) {
foreach ($abbreviations as $abbreviation) {
$timezones[$abbreviation['timezone_id']] = true;
}
}
$this->addRequirement(
isset($timezones[date_default_timezone_get()]),
sprintf('Configured default timezone "%s" must be supported by your installation of PHP', date_default_timezone_get()),
'Your default timezone is not supported by PHP. Check for typos in your <strong>php.ini</strong> file and have a look at the list of deprecated timezones at <a href="http://php.net/manual/en/timezones.others.php">http://php.net/manual/en/timezones.others.php</a>.'
);
}
$this->addRequirement(
function_exists('json_encode'),
'json_encode() must be available',
'Install and enable the <strong>JSON</strong> extension.'
);
$this->addRequirement(
function_exists('session_start'),
'session_start() must be available',
'Install and enable the <strong>session</strong> extension.'
);
$this->addRequirement(
function_exists('ctype_alpha'),
'ctype_alpha() must be available',
'Install and enable the <strong>ctype</strong> extension.'
);
$this->addRequirement(
function_exists('token_get_all'),
'token_get_all() must be available',
'Install and enable the <strong>Tokenizer</strong> extension.'
);
$this->addRequirement(
function_exists('simplexml_import_dom'),
'simplexml_import_dom() must be available',
'Install and enable the <strong>SimpleXML</strong> extension.'
);
if (function_exists('apc_store') && ini_get('apc.enabled')) {
if (version_compare($installedPhpVersion, '5.4.0', '>=')) {
$this->addRequirement(
version_compare(phpversion('apc'), '3.1.13', '>='),
'APC version must be at least 3.1.13 when using PHP 5.4',
'Upgrade your <strong>APC</strong> extension (3.1.13+).'
);
} else {
$this->addRequirement(
version_compare(phpversion('apc'), '3.0.17', '>='),
'APC version must be at least 3.0.17',
'Upgrade your <strong>APC</strong> extension (3.0.17+).'
);
}
}
$this->addPhpIniRequirement('detect_unicode', false);
if (extension_loaded('suhosin')) {
$this->addPhpIniRequirement(
'suhosin.executor.include.whitelist',
create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'),
false,
'suhosin.executor.include.whitelist must be configured correctly in php.ini',
'Add "<strong>phar</strong>" to <strong>suhosin.executor.include.whitelist</strong> in php.ini<a href="#phpini">*</a>.'
);
}
if (extension_loaded('xdebug')) {
$this->addPhpIniRequirement(
'xdebug.show_exception_trace', false, true
);
$this->addPhpIniRequirement(
'xdebug.scream', false, true
);
$this->addPhpIniRecommendation(
'xdebug.max_nesting_level',
create_function('$cfgValue', 'return $cfgValue > 100;'),
true,
'xdebug.max_nesting_level should be above 100 in php.ini',
'Set "<strong>xdebug.max_nesting_level</strong>" to e.g. "<strong>250</strong>" in php.ini<a href="#phpini">*</a> to stop Xdebug\'s infinite recursion protection erroneously throwing a fatal error in your project.'
);
}
$pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null;
$this->addRequirement(
null !== $pcreVersion,
'PCRE extension must be available',
'Install the <strong>PCRE</strong> extension (version 8.0+).'
);
/* optional recommendations follow */
$this->addRecommendation(
file_get_contents(__FILE__) === file_get_contents(__DIR__.'/../vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/skeleton/app/SymfonyRequirements.php'),
'Requirements file should be up-to-date',
'Your requirements file is outdated. Run composer install and re-check your configuration.'
);
$this->addRecommendation(
version_compare($installedPhpVersion, '5.3.4', '>='),
'You should use at least PHP 5.3.4 due to PHP bug #52083 in earlier versions',
'Your project might malfunction randomly due to PHP bug #52083 ("Notice: Trying to get property of non-object"). Install PHP 5.3.4 or newer.'
);
$this->addRecommendation(
version_compare($installedPhpVersion, '5.3.8', '>='),
'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156',
'Install PHP 5.3.8 or newer if your project uses annotations.'
);
$this->addRecommendation(
version_compare($installedPhpVersion, '5.4.0', '!='),
'You should not use PHP 5.4.0 due to the PHP bug #61453',
'Your project might not work properly due to the PHP bug #61453 ("Cannot dump definitions which have method calls"). Install PHP 5.4.1 or newer.'
);
$this->addRecommendation(
version_compare($installedPhpVersion, '5.4.11', '>='),
'When using the logout handler from the Symfony Security Component, you should have at least PHP 5.4.11 due to PHP bug #63379 (as a workaround, you can also set invalidate_session to false in the security logout handler configuration)',
'Install PHP 5.4.11 or newer if your project uses the logout handler from the Symfony Security Component.'
);
$this->addRecommendation(
(version_compare($installedPhpVersion, '5.3.18', '>=') && version_compare($installedPhpVersion, '5.4.0', '<'))
||
version_compare($installedPhpVersion, '5.4.8', '>='),
'You should use PHP 5.3.18+ or PHP 5.4.8+ to always get nice error messages for fatal errors in the development environment due to PHP bug #61767/#60909',
'Install PHP 5.3.18+ or PHP 5.4.8+ if you want nice error messages for all fatal errors in the development environment.'
);
if (null !== $pcreVersion) {
$this->addRecommendation(
$pcreVersion >= 8.0,
sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion),
'<strong>PCRE 8.0+</strong> is preconfigured in PHP since 5.3.2 but you are using an outdated version of it. Symfony probably works anyway but it is recommended to upgrade your PCRE extension.'
);
}
$this->addRecommendation(
class_exists('DomDocument'),
'PHP-XML module should be installed',
'Install and enable the <strong>PHP-XML</strong> module.'
);
$this->addRecommendation(
function_exists('mb_strlen'),
'mb_strlen() should be available',
'Install and enable the <strong>mbstring</strong> extension.'
);
$this->addRecommendation(
function_exists('iconv'),
'iconv() should be available',
'Install and enable the <strong>iconv</strong> extension.'
);
$this->addRecommendation(
function_exists('utf8_decode'),
'utf8_decode() should be available',
'Install and enable the <strong>XML</strong> extension.'
);
$this->addRecommendation(
function_exists('filter_var'),
'filter_var() should be available',
'Install and enable the <strong>filter</strong> extension.'
);
if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
$this->addRecommendation(
function_exists('posix_isatty'),
'posix_isatty() should be available',
'Install and enable the <strong>php_posix</strong> extension (used to colorize the CLI output).'
);
}
$this->addRecommendation(
class_exists('Locale'),
'intl extension should be available',
'Install and enable the <strong>intl</strong> extension (used for validators).'
);
if (class_exists('Collator')) {
$this->addRecommendation(
null !== new Collator('fr_FR'),
'intl extension should be correctly configured',
'The intl extension does not behave properly. This problem is typical on PHP 5.3.X x64 WIN builds.'
);
}
if (class_exists('Locale')) {
if (defined('INTL_ICU_VERSION')) {
$version = INTL_ICU_VERSION;
} else {
$reflector = new ReflectionExtension('intl');
ob_start();
$reflector->info();
$output = strip_tags(ob_get_clean());
preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches);
$version = $matches[1];
}
$this->addRecommendation(
version_compare($version, '4.0', '>='),
'intl ICU version should be at least 4+',
'Upgrade your <strong>intl</strong> extension with a newer ICU version (4+).'
);
}
$accelerator =
(extension_loaded('eaccelerator') && ini_get('eaccelerator.enable'))
||
(extension_loaded('apc') && ini_get('apc.enabled'))
||
(extension_loaded('Zend Optimizer+') && ini_get('zend_optimizerplus.enable'))
||
(extension_loaded('Zend OPcache') && ini_get('opcache.enable'))
||
(extension_loaded('xcache') && ini_get('xcache.cacher'))
||
(extension_loaded('wincache') && ini_get('wincache.ocenabled'))
;
$this->addRecommendation(
$accelerator,
'a PHP accelerator should be installed',
'Install and/or enable a <strong>PHP accelerator</strong> (highly recommended).'
);
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$this->addPhpIniRecommendation(
'realpath_cache_size',
create_function('$cfgValue', 'return (int) $cfgValue > 1000;'),
false,
'realpath_cache_size should be above 1024 in php.ini',
'Set "<strong>realpath_cache_size</strong>" to e.g. "<strong>1024</strong>" in php.ini<a href="#phpini">*</a> to improve performance on windows.'
);
}
$this->addPhpIniRecommendation('short_open_tag', false);
$this->addPhpIniRecommendation('magic_quotes_gpc', false, true);
$this->addPhpIniRecommendation('register_globals', false, true);
$this->addPhpIniRecommendation('session.auto_start', false);
$this->addRecommendation(
class_exists('PDO'),
'PDO should be installed',
'Install <strong>PDO</strong> (mandatory for Doctrine).'
);
if (class_exists('PDO')) {
$drivers = PDO::getAvailableDrivers();
$this->addRecommendation(
count($drivers) > 0,
sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'),
'Install <strong>PDO drivers</strong> (mandatory for Doctrine).'
);
}
}
}

View file

@ -0,0 +1,22 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SymfonyStandard;
use Composer\Script\CommandEvent;
class Composer
{
public static function hookRootPackageInstall(CommandEvent $event)
{
$event->getComposer()->getEventDispatcher()->addSubscriber(new RootPackageInstallSubscriber());
}
}

View file

@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SymfonyStandard;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\Script\ScriptEvents;
use Composer\Script\CommandEvent;
use Sensio\Bundle\DistributionBundle\Composer\ScriptHandler;
class RootPackageInstallSubscriber implements EventSubscriberInterface
{
public static function installAcmeDemoBundle(CommandEvent $event)
{
ScriptHandler::installAcmeDemoBundle($event);
}
public static function setupNewDirectoryStructure(CommandEvent $event)
{
ScriptHandler::defineDirectoryStructure($event);
}
public static function getSubscribedEvents()
{
return array(
ScriptEvents::POST_INSTALL_CMD => array(
array('setupNewDirectoryStructure', 512),
array('installAcmeDemoBundle', 0)
),
);
}
}

View file

@ -0,0 +1,13 @@
<?php
use Doctrine\Common\Annotations\AnnotationRegistry;
use Composer\Autoload\ClassLoader;
/**
* @var ClassLoader $loader
*/
$loader = require __DIR__.'/../vendor/autoload.php';
AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
return $loader;

View file

@ -0,0 +1,142 @@
<?php
require_once dirname(__FILE__).'/SymfonyRequirements.php';
$lineSize = 70;
$symfonyRequirements = new SymfonyRequirements();
$iniPath = $symfonyRequirements->getPhpIniConfigPath();
echo_title('Symfony2 Requirements Checker');
echo '> PHP is using the following php.ini file:'.PHP_EOL;
if ($iniPath) {
echo_style('green', ' '.$iniPath);
} else {
echo_style('warning', ' WARNING: No configuration file (php.ini) used by PHP!');
}
echo PHP_EOL.PHP_EOL;
echo '> Checking Symfony requirements:'.PHP_EOL.' ';
$messages = array();
foreach ($symfonyRequirements->getRequirements() as $req) {
/** @var $req Requirement */
if ($helpText = get_error_message($req, $lineSize)) {
echo_style('red', 'E');
$messages['error'][] = $helpText;
} else {
echo_style('green', '.');
}
}
$checkPassed = empty($messages['error']);
foreach ($symfonyRequirements->getRecommendations() as $req) {
if ($helpText = get_error_message($req, $lineSize)) {
echo_style('yellow', 'W');
$messages['warning'][] = $helpText;
} else {
echo_style('green', '.');
}
}
if ($checkPassed) {
echo_block('success', 'OK', 'Your system is ready to run Symfony2 projects', true);
} else {
echo_block('error', 'ERROR', 'Your system is not ready to run Symfony2 projects', true);
echo_title('Fix the following mandatory requirements', 'red');
foreach ($messages['error'] as $helpText) {
echo ' * '.$helpText.PHP_EOL;
}
}
if (!empty($messages['warning'])) {
echo_title('Optional recommendations to improve your setup', 'yellow');
foreach ($messages['warning'] as $helpText) {
echo ' * '.$helpText.PHP_EOL;
}
}
echo PHP_EOL;
echo_style('title', 'Note');
echo ' The command console could use a different php.ini file'.PHP_EOL;
echo_style('title', '~~~~');
echo ' than the one used with your web server. To be on the'.PHP_EOL;
echo ' safe side, please check the requirements from your web'.PHP_EOL;
echo ' server using the ';
echo_style('yellow', 'web/config.php');
echo ' script.'.PHP_EOL;
echo PHP_EOL;
exit($checkPassed ? 0 : 1);
function get_error_message(Requirement $requirement, $lineSize)
{
if ($requirement->isFulfilled()) {
return;
}
$errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL;
$errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL;
return $errorMessage;
}
function echo_title($title, $style = null)
{
$style = $style ?: 'title';
echo PHP_EOL;
echo_style($style, $title.PHP_EOL);
echo_style($style, str_repeat('~', strlen($title)).PHP_EOL);
echo PHP_EOL;
}
function echo_style($style, $message)
{
// ANSI color codes
$styles = array(
'reset' => "\033[0m",
'red' => "\033[31m",
'green' => "\033[32m",
'yellow' => "\033[33m",
'error' => "\033[37;41m",
'success' => "\033[37;42m",
'title' => "\033[34m",
);
$supports = has_color_support();
echo ($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : '');
}
function echo_block($style, $title, $message)
{
$message = ' '.trim($message).' ';
$width = strlen($message);
echo PHP_EOL.PHP_EOL;
echo_style($style, str_repeat(' ', $width).PHP_EOL);
echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT).PHP_EOL);
echo_style($style, str_pad($message, $width, ' ', STR_PAD_RIGHT).PHP_EOL);
echo_style($style, str_repeat(' ', $width).PHP_EOL);
}
function has_color_support()
{
static $support;
if (null === $support) {
if (DIRECTORY_SEPARATOR == '\\') {
$support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI');
} else {
$support = function_exists('posix_isatty') && @posix_isatty(STDOUT);
}
}
return $support;
}

View file

@ -0,0 +1,72 @@
imports:
- { resource: parameters.yml }
- { resource: security.yml }
framework:
#esi: ~
#translator: { fallback: "%locale%" }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
templating:
engines: ['twig']
#assets_version: SomeVersionScheme
default_locale: "%locale%"
trusted_hosts: ~
trusted_proxies: ~
session:
# handler_id set to null will use default session handler from php.ini
handler_id: ~
fragments: ~
http_method_override: true
# Twig Configuration
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
# Assetic Configuration
assetic:
debug: "%kernel.debug%"
use_controller: false
bundles: [ ]
#java: /usr/bin/java
filters:
cssrewrite: ~
#closure:
# jar: "%kernel.root_dir%/Resources/java/compiler.jar"
#yui_css:
# jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"
# Doctrine Configuration
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: "%kernel.root_dir%/data/data.db3"
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
# path: "%database_path%"
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
# Swiftmailer Configuration
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
spool: { type: memory }

View file

@ -0,0 +1,36 @@
imports:
- { resource: config.yml }
framework:
router:
resource: "%kernel.root_dir%/config/routing_dev.yml"
strict_requirements: true
profiler: { only_exceptions: false }
web_profiler:
toolbar: "%debug_toolbar%"
intercept_redirects: "%debug_redirects%"
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console
bubble: false
# uncomment to get logging in your browser
# you may have to allow bigger header sizes in your Web server configuration
#firephp:
# type: firephp
# level: info
#chromephp:
# type: chromephp
# level: info
assetic:
use_controller: "%use_assetic_controller%"
#swiftmailer:
# delivery_address: me@example.com

View file

@ -0,0 +1,25 @@
imports:
- { resource: config.yml }
#framework:
# validation:
# cache: apc
#doctrine:
# orm:
# metadata_cache_driver: apc
# result_cache_driver: apc
# query_cache_driver: apc
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console

View file

@ -0,0 +1,16 @@
imports:
- { resource: config_dev.yml }
framework:
test: ~
session:
storage_id: session.storage.mock_file
profiler:
collect: false
web_profiler:
toolbar: false
intercept_redirects: false
swiftmailer:
disable_delivery: true

View file

@ -0,0 +1,24 @@
# This file is a "template" of what your parameters.yml file should look like
parameters:
database_driver: pdo_mysql
database_host: 127.0.0.1
database_port: ~
database_name: symfony
database_user: root
database_password: ~
# You should uncomment this if you want use pdo_sqlite
# database_path: "%kernel.root_dir%/data.db3"
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: ~
mailer_password: ~
locale: en
# A secret key that's used to generate certain security-related tokens
secret: ThisTokenIsNotSoSecretChangeIt
debug_toolbar: true
debug_redirects: false
use_assetic_controller: true

View file

@ -0,0 +1,18 @@
_wdt:
resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml"
prefix: /_wdt
_profiler:
resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml"
prefix: /_profiler
_configurator:
resource: "@SensioDistributionBundle/Resources/config/routing/webconfigurator.xml"
prefix: /_configurator
_main:
resource: routing.yml
# AcmeDemoBundle routes (to be removed)
_acme_demo:
resource: "@AcmeDemoBundle/Resources/config/routing.yml"

View file

@ -0,0 +1,52 @@
# you can read more about security in the related section of the documentation
# http://symfony.com/doc/current/book/security.html
security:
# http://symfony.com/doc/current/book/security.html#encoding-the-user-s-password
encoders:
Symfony\Component\Security\Core\User\User: plaintext
# http://symfony.com/doc/current/book/security.html#hierarchical-roles
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
providers:
in_memory:
memory:
users:
user: { password: userpass, roles: [ 'ROLE_USER' ] }
admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }
# the main part of the security, where you can set up firewalls
# for specific sections of your app
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
# the login page has to be accessible for everybody
demo_login:
pattern: ^/demo/secured/login$
security: false
# secures part of the application
demo_secured_area:
pattern: ^/demo/secured/
# it's important to notice that in this case _demo_security_check and _demo_login
# are route names and that they are specified in the AcmeDemoBundle
form_login:
check_path: _demo_security_check
login_path: _demo_login
logout:
path: _demo_logout
target: _demo
#anonymous: ~
#http_basic:
# realm: "Secured Demo Area"
# with these settings you can restrict or allow access for different parts
# of your application based on roles, ip, host or methods
# http://symfony.com/doc/current/book/security.html#security-book-access-control-matching-options
access_control:
#- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https }

View file

@ -0,0 +1,27 @@
#!/usr/bin/env php
<?php
// if you don't want to setup permissions the proper way, just uncomment the following PHP line
// read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information
//umask(0000);
set_time_limit(0);
require_once __DIR__.'/bootstrap.php.cache';
require_once __DIR__.'/AppKernel.php';
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Debug\Debug;
$input = new ArgvInput();
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';
if ($debug) {
Debug::enable();
}
$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->run($input);

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- http://phpunit.de/manual/4.1/en/appendixes.configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="bootstrap.php.cache"
>
<testsuites>
<testsuite name="Project Test Suite">
<directory>../src/*/*Bundle/Tests</directory>
<directory>../src/*/Bundle/*Bundle/Tests</directory>
</testsuite>
</testsuites>
<!--
<php>
<server name="KERNEL_DIR" value="/path/to/your/app/" />
</php>
-->
<filter>
<whitelist>
<directory>../src</directory>
<exclude>
<directory>../src/*/*Bundle/Resources</directory>
<directory>../src/*/*Bundle/Tests</directory>
<directory>../src/*/Bundle/*Bundle/Resources</directory>
<directory>../src/*/Bundle/*Bundle/Tests</directory>
</exclude>
</whitelist>
</filter>
</phpunit>

Some files were not shown because too many files have changed in this diff Show more