initial commit

This commit is contained in:
Jörg Prante 2017-10-07 13:14:33 +02:00
commit 7d2c49af64
239 changed files with 21704 additions and 0 deletions

26
.gitignore vendored Normal file
View file

@ -0,0 +1,26 @@
data
work
out
logs
/.idea
/target
/.settings
/.classpath
/.project
/.gradle
/plugins
/sessions
.DS_Store
*.iml
*~
.secret
build
**/alkmene.json
**/alkmene*.options
**/herakles.json
**/herakles*.options
**/prod.json
**/prod*.options
**/*.crt
**/*.pkcs8
**/*.gz

18
LICENSE-bouncycastle.txt Normal file
View file

@ -0,0 +1,18 @@
Copyright (c) 2000 - 2017 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in the
Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

203
LICENSE.txt Normal file
View file

@ -0,0 +1,203 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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.

108
build.gradle Normal file
View file

@ -0,0 +1,108 @@
plugins {
id "org.sonarqube" version "2.5"
id "io.codearte.nexus-staging" version "0.7.0"
}
allprojects {
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'signing'
apply plugin: 'findbugs'
apply plugin: 'pmd'
apply plugin: 'checkstyle'
apply plugin: "jacoco"
repositories {
mavenLocal()
mavenCentral()
}
configurations {
wagon
}
dependencies {
testCompile 'junit:junit:4.12'
wagon 'org.apache.maven.wagon:wagon-ssh:2.12'
}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:all" << "-profile" << "compact1"
}
test {
testLogging {
showStandardStreams = false
exceptionFormat = 'full'
}
}
clean {
delete 'out'
}
tasks.withType(FindBugs) {
ignoreFailures = true
reports {
xml.enabled = false
html.enabled = true
}
}
tasks.withType(Pmd) {
ignoreFailures = true
reports {
xml.enabled = true
html.enabled = true
}
}
tasks.withType(Checkstyle) {
ignoreFailures = true
reports {
xml.enabled = true
html.enabled = true
}
}
jacocoTestReport {
reports {
xml.enabled = true
csv.enabled = false
}
}
sonarqube {
properties {
property "sonar.projectName", "xbib RPM"
property "sonar.sourceEncoding", "UTF-8"
property "sonar.tests", "src/test/java"
property "sonar.scm.provider", "git"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.junit.reportsPath", "build/test-results/test/"
}
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier 'javadoc'
}
artifacts {
archives sourcesJar, javadocJar
}
if (project.hasProperty('signing.keyId')) {
signing {
sign configurations.archives
}
}
apply from: "${rootProject.projectDir}/gradle/ext.gradle"
apply from: "${rootProject.projectDir}/gradle/publish.gradle"
}

View file

@ -0,0 +1,323 @@
<?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="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="groups" value="com.google,android,junit,net,org,java,javax"/>
<!-- This ensures that static imports go first. -->
<property name="option" value="top"/>
<property name="tokens" value="STATIC_IMPORT, IMPORT"/>
</module>
<!--
JAVADOC CHECKS
-->
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="protected"/>
<property name="severity" value="warning"/>
<property name="allowMissingJavadoc" value="true"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
<property name="allowUndeclaredRTE" 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="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 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>

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>http://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,5 @@
This is a derived work of
https://github.com/nebula-plugins/gradle-ospackage-plugin
licensed under Apache Software License 2.0.

View file

@ -0,0 +1,50 @@
plugins {
id 'java-gradle-plugin'
id 'com.gradle.plugin-publish' version '0.9.7'
}
apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'signing'
apply plugin: 'com.gradle.plugin-publish'
dependencies {
compile gradleApi()
compile project(':rpm-core')
compileOnly "org.codehaus.groovy:groovy-all:${project.property('groovy.version')}"
testCompile "junit:junit:${project.property('junit.version')}"
testCompile("org.spockframework:spock-core:${project.property('spock-core.version')}") {
exclude module: 'groovy-all'
exclude module: 'junit'
}
testCompile "org.xbib:guice:${project.property('xbib-guice.version')}"
}
compileGroovy {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
test {
testLogging {
showStandardStreams = true
exceptionFormat = 'full'
}
}
if (project.hasProperty('gradle.publish.key')) {
pluginBundle {
website = 'https://github.com/xbib/gradle-plugin-rpm'
vcsUrl = 'https://github.com/xbib/gradle-plugin-rpm'
plugins {
rpmPlugin {
id = 'org.xbib.gradle.plugin.rpm'
version = project.version
description = projectDescription
displayName = projectDescription
tags = ['gradle', 'plugin', 'rpm']
}
}
}
}

View file

@ -0,0 +1,323 @@
<?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="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="groups" value="com.google,android,junit,net,org,java,javax"/>
<!-- This ensures that static imports go first. -->
<property name="option" value="top"/>
<property name="tokens" value="STATIC_IMPORT, IMPORT"/>
</module>
<!--
JAVADOC CHECKS
-->
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="protected"/>
<property name="severity" value="warning"/>
<property name="allowMissingJavadoc" value="true"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
<property name="allowUndeclaredRTE" 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="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 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>

View file

@ -0,0 +1,77 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.api.file.CopySpec
import org.gradle.api.internal.file.copy.CopySpecWrapper
import org.gradle.internal.impldep.org.apache.commons.lang.reflect.FieldUtils
/**
*
*/
@Category(CopySpec)
class CopySpecEnhancement {
static void appendFieldToCopySpec(CopySpec spec, String fieldName, Object value) {
def directSpec = spec
if (spec instanceof CopySpecWrapper) {
def delegateField = FieldUtils.getField(CopySpecWrapper, 'delegate', true)
directSpec = delegateField.get(spec)
}
directSpec.metaClass["get${fieldName.capitalize()}"] = { value }
}
static void user(CopySpec spec, String user) {
appendFieldToCopySpec(spec, 'user', user)
}
static void setUser(CopySpec spec, String userArg) {
user(spec, userArg)
}
static void permissionGroup(CopySpec spec, String permissionGroup) {
appendFieldToCopySpec(spec, 'permissionGroup', permissionGroup)
}
static void setPermissionGroup(CopySpec spec, String permissionGroupArg) {
permissionGroup(spec, permissionGroupArg)
}
static void setFileType(CopySpec spec, List<String> fileTypeArg) {
fileType(spec, fileTypeArg)
}
static void fileType(CopySpec spec, List<String> fileType) {
appendFieldToCopySpec(spec, 'fileType', fileType)
}
static void addParentDirs(CopySpec spec, boolean addParentDirs) {
appendFieldToCopySpec(spec, 'addParentDirs', addParentDirs)
}
static void setAddParentDirs(CopySpec spec, boolean addParentDirsArg) {
addParentDirs(spec, addParentDirsArg)
}
static void createDirectoryEntry(CopySpec spec, boolean createDirectoryEntry) {
appendFieldToCopySpec(spec, 'createDirectoryEntry', createDirectoryEntry)
}
static void setCreateDirectoryEntry(CopySpec spec, boolean createDirectoryEntryArg) {
createDirectoryEntry(spec, createDirectoryEntryArg)
}
static void uid(CopySpec spec, int uid) {
appendFieldToCopySpec(spec, 'uid', uid)
}
static void setUid(CopySpec spec, int uidArg) {
uid(spec, uidArg)
}
static void gid(CopySpec spec, int gid) {
appendFieldToCopySpec(spec, 'gid', gid)
}
static void setGid(CopySpec spec, int gidArg) {
gid(spec, gidArg)
}
}

View file

@ -0,0 +1,55 @@
package org.xbib.gradle.plugin.rpm
import groovy.transform.EqualsAndHashCode
import org.xbib.rpm.format.Flags
@EqualsAndHashCode
class Dependency implements Serializable {
String packageName
String version
int flag = 0
Dependency alternative = null
Dependency(String packageName, String version, int flag=0) {
if (packageName.contains(',')) {
throw new IllegalArgumentException('package name can not contain comma')
}
this.packageName = packageName
this.version = version
this.flag = flag
}
Dependency or(String packageName, String version='', int flag=0) {
alternative = new Dependency(packageName, version, flag)
alternative
}
String toDebString() {
def signMap = [
(Flags.GREATER|Flags.EQUAL): '>=',
(Flags.LESS|Flags.EQUAL): '<=',
(Flags.EQUAL): '=',
(Flags.GREATER): '>>',
(Flags.LESS): '<<'
]
def depStr = this.packageName
if (this.flag && this.version) {
def sign = signMap[this.flag]
if (sign==null) {
throw new IllegalArgumentException()
}
depStr += " (${sign} ${this.version})"
} else if (this.version) {
depStr += " (${this.version})"
}
if (alternative) {
depStr += " | " + alternative.toDebString()
}
depStr
}
}

View file

@ -0,0 +1,14 @@
package org.xbib.gradle.plugin.rpm
class Directory {
String path
int permissions = -1
String user = null
String permissionGroup = null
boolean addParents = false
}

View file

@ -0,0 +1,21 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.api.file.FileCopyDetails
import org.gradle.api.tasks.AbstractCopyTask
import java.nio.file.Files
class FromConfigurationFactory {
static Closure<AbstractCopyTask> preserveSymlinks(delegate) {
return {
delegate.eachFile { FileCopyDetails details ->
if (Files.isSymbolicLink(details.file.toPath())) {
details.exclude()
def toFile = Files.readSymbolicLink(details.file.toPath()).toFile()
delegate.link(details.relativePath.toString(), toFile.toString())
}
}
}
}
}

View file

@ -0,0 +1,13 @@
package org.xbib.gradle.plugin.rpm
import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode
class Link implements Serializable {
String path
String target
int permissions = -1
}

View file

@ -0,0 +1,257 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.file.CopyProcessingSpec
import org.gradle.api.file.CopySpec
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.file.FileCopyDetails
import org.gradle.api.file.FileTree
import org.gradle.api.file.FileTreeElement
import org.gradle.api.file.RelativePath
import org.gradle.api.internal.file.FileResolver
import org.gradle.api.internal.file.copy.CopySpecInternal
import org.gradle.api.internal.file.copy.DefaultCopySpec
import org.gradle.api.internal.project.ProjectInternal
import org.gradle.api.specs.Spec
import org.gradle.internal.reflect.Instantiator
import java.util.regex.Pattern
/**
* An extension which can be attached to the project.
* This is a superset of SystemPackagingExtension because we don't
* want the @Delegate to inherit the copy spec parts.
*
* We can't extends DefaultCopySpec, since it's @NotExtensible, meaning that we won't get any convention
* mappings. If we extend DelegatingCopySpec we get groovy compilation errors around the return types between
* CopySourceSpec's methods and the ones overriden in DelegatingCopySpec, even though that's perfectly valid
* Java code. The theory is that it's some bug in groovyc.
*/
class ProjectPackagingExtension extends SystemPackagingExtension {
CopySpecInternal delegateCopySpec
ProjectPackagingExtension(Project project) {
FileResolver resolver = ((ProjectInternal) project).getFileResolver()
Instantiator instantiator = ((ProjectInternal) project).getServices().get(Instantiator.class)
delegateCopySpec = new DefaultCopySpec( resolver, instantiator)
}
/*
* Special Use cases that involve Closure's which we want to wrap.
*/
CopySpec from(Object sourcePath, Closure c) {
def preserveSymlinks = FromConfigurationFactory.preserveSymlinks(this)
use(CopySpecEnhancement) {
return getDelegateCopySpec().from(sourcePath, c << preserveSymlinks)
}
}
CopySpec from(Object... sourcePaths) {
def spec = null
for (Object sourcePath : sourcePaths) {
spec = from(sourcePath, {})
}
spec
}
CopySpec into(Object destPath, Closure configureClosure) {
use(CopySpecEnhancement) {
return getDelegateCopySpec().into(destPath, configureClosure)
}
}
CopySpec include(Closure includeSpec) {
use(CopySpecEnhancement) {
return getDelegateCopySpec().include(includeSpec)
}
}
CopySpec exclude(Closure excludeSpec) {
use(CopySpecEnhancement) {
return getDelegateCopySpec().exclude(excludeSpec)
}
}
CopySpec filter(Closure closure) {
use(CopySpecEnhancement) {
return getDelegateCopySpec().filter(closure)
}
}
CopySpec rename(Closure closure) {
use(CopySpecEnhancement) {
return getDelegateCopySpec().rename(closure)
}
}
CopySpec eachFile(Closure closure) {
use(CopySpecEnhancement) {
return getDelegateCopySpec().eachFile(closure)
}
}
/*
* Copy and Paste from org.gradle.api.internal.file.copy.DelegatingCopySpec, since extending it causes
* compilation problems. The methods above are special cases and are commented out below.
*/
RelativePath getDestPath() {
getDelegateCopySpec().getDestPath()
}
FileTree getSource() {
getDelegateCopySpec().getSource()
}
boolean hasSource() {
getDelegateCopySpec().hasSource()
}
Collection<? extends Action<? super FileCopyDetails>> getAllCopyActions() {
getDelegateCopySpec().getAllCopyActions()
}
boolean isCaseSensitive() {
getDelegateCopySpec().isCaseSensitive()
}
void setCaseSensitive(boolean caseSensitive) {
getDelegateCopySpec().setCaseSensitive(caseSensitive)
}
boolean getIncludeEmptyDirs() {
getDelegateCopySpec().getIncludeEmptyDirs()
}
void setIncludeEmptyDirs(boolean includeEmptyDirs) {
getDelegateCopySpec().setIncludeEmptyDirs(includeEmptyDirs)
}
DuplicatesStrategy getDuplicatesStrategy() {
getDelegateCopySpec().getDuplicatesStrategy()
}
void setDuplicatesStrategy(DuplicatesStrategy strategy) {
getDelegateCopySpec().setDuplicatesStrategy(strategy)
}
CopySpec filesMatching(String pattern, Action<? super FileCopyDetails> action) {
getDelegateCopySpec().filesMatching(pattern, action)
}
CopySpec filesNotMatching(String pattern, Action<? super FileCopyDetails> action) {
getDelegateCopySpec().filesNotMatching(pattern, action)
}
CopySpec with(CopySpec... sourceSpecs) {
getDelegateCopySpec().with(sourceSpecs)
}
CopySpec setIncludes(Iterable<String> includes) {
getDelegateCopySpec().setIncludes(includes)
}
CopySpec setExcludes(Iterable<String> excludes) {
getDelegateCopySpec().setExcludes(excludes)
}
CopySpec include(String... includes) {
getDelegateCopySpec().include(includes)
}
CopySpec include(Iterable<String> includes) {
getDelegateCopySpec().include(includes)
}
CopySpec include(Spec<FileTreeElement> includeSpec) {
getDelegateCopySpec().include(includeSpec)
}
CopySpec exclude(String... excludes) {
getDelegateCopySpec().exclude(excludes)
}
CopySpec exclude(Iterable<String> excludes) {
getDelegateCopySpec().exclude(excludes)
}
CopySpec exclude(Spec<FileTreeElement> excludeSpec) {
getDelegateCopySpec().exclude(excludeSpec)
}
CopySpec into(Object destPath) {
getDelegateCopySpec().into(destPath)
}
CopySpec rename(String sourceRegEx, String replaceWith) {
getDelegateCopySpec().rename(sourceRegEx, replaceWith)
}
CopyProcessingSpec rename(Pattern sourceRegEx, String replaceWith) {
getDelegateCopySpec().rename(sourceRegEx, replaceWith)
}
CopySpec filter(Map<String, ?> properties, Class<? extends FilterReader> filterType) {
getDelegateCopySpec().filter(properties, filterType)
}
CopySpec filter(Class<? extends FilterReader> filterType) {
getDelegateCopySpec().filter(filterType)
}
CopySpec expand(Map<String, ?> properties) {
getDelegateCopySpec().expand(properties)
}
CopySpec eachFile(Action<? super FileCopyDetails> action) {
getDelegateCopySpec().eachFile(action)
}
Integer getFileMode() {
getDelegateCopySpec().getFileMode()
}
CopyProcessingSpec setFileMode(Integer mode) {
getDelegateCopySpec().setFileMode(mode)
}
Integer getDirMode() {
getDelegateCopySpec().getDirMode()
}
CopyProcessingSpec setDirMode(Integer mode) {
getDelegateCopySpec().setDirMode(mode)
}
Set<String> getIncludes() {
getDelegateCopySpec().getIncludes()
}
Set<String> getExcludes() {
getDelegateCopySpec().getExcludes()
}
Iterable<CopySpecInternal> getChildren() {
getDelegateCopySpec().getChildren()
}
FileTree getAllSource() {
getDelegateCopySpec().getAllSource()
}
DefaultCopySpec addChild() {
getDelegateCopySpec().addChild()
}
DefaultCopySpec addFirst() {
getDelegateCopySpec().addFirst()
}
void walk(Action<? super CopySpecInternal> action) {
action.execute(this)
for (CopySpecInternal child : getChildren()) {
child.walk(action)
}
}
}

View file

@ -0,0 +1,390 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.api.file.FileCollection
import org.gradle.api.internal.ConventionMapping
import org.gradle.api.internal.IConventionAware
import org.gradle.api.tasks.AbstractCopyTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.SkipWhenEmpty
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.xbib.rpm.lead.Architecture
import org.xbib.rpm.lead.Os
import org.xbib.rpm.lead.PackageType
import java.nio.file.Path
/**
*
*/
class Rpm extends AbstractArchiveTask {
@Input
@Optional
Path changeLogFile
@Delegate
@Nested
SystemPackagingExtension systemPackagingExtension
ProjectPackagingExtension projectPackagingExtension
Rpm() {
super()
systemPackagingExtension = new SystemPackagingExtension()
projectPackagingExtension = project.extensions.findByType(ProjectPackagingExtension)
if (projectPackagingExtension) {
getRootSpec().with(projectPackagingExtension.delegateCopySpec)
}
extension = 'rpm'
}
@Override
@TaskAction
protected void copy() {
use(CopySpecEnhancement) {
super.copy()
}
}
@Override
AbstractCopyTask from(Object... sourcePaths) {
for (Object sourcePath : sourcePaths) {
from(sourcePath, {})
}
this
}
@Override
AbstractCopyTask from(Object sourcePath, Closure c) {
def preserveSymlinks = FromConfigurationFactory.preserveSymlinks(this)
use(CopySpecEnhancement) {
getMainSpec().from(sourcePath, c << preserveSymlinks)
}
this
}
@Override
AbstractArchiveTask into(Object destPath, Closure configureClosure) {
use(CopySpecEnhancement) {
getMainSpec().into(destPath, configureClosure)
}
this
}
@Override
AbstractCopyTask exclude(Closure excludeSpec) {
use(CopySpecEnhancement) {
getMainSpec().exclude(excludeSpec)
}
this
}
@Override
AbstractCopyTask filter(Closure closure) {
use(CopySpecEnhancement) {
getMainSpec().filter(closure)
}
this
}
@Override
AbstractCopyTask rename(Closure closure) {
use(CopySpecEnhancement) {
getMainSpec().rename(closure)
}
this
}
@Override
RpmCopyAction createCopyAction() {
new RpmCopyAction(this)
}
@Input
@Optional
void setArch(Object arch) {
setArchStr((arch instanceof Architecture)?arch.name():arch.toString())
}
@Input
@Optional
List<Object> getAllConfigurationPaths() {
return getConfigurationPaths() + (projectPackagingExtension?.getConfigurationPaths()?: [])
}
@Input
@Optional
List<Object> getAllPreInstallCommands() {
return getPreInstallCommands() + (projectPackagingExtension?.getPreInstallCommands() ?: [])
}
@Input
@Optional
List<Object> getAllPostInstallCommands() {
return getPostInstallCommands() + (projectPackagingExtension?.getPostInstallCommands() ?: [])
}
@Input
@Optional
List<Object> getAllPreUninstallCommands() {
return getPreUninstallCommands() + (projectPackagingExtension?.getPreUninstallCommands() ?: [])
}
@Input
@Optional
List<Object> getAllPostUninstallCommands() {
return getPostUninstallCommands() + (projectPackagingExtension?.getPostUninstallCommands() ?: [])
}
@Input
@Optional
List<Object> getAllPreTransCommands() {
return getPreTransCommands() + projectPackagingExtension?.getPreTransCommands()
}
@Input
@Optional
List<Object> getAllPostTransCommands() {
return getPostTransCommands() + projectPackagingExtension?.getPostTransCommands()
}
@Input
@Optional
List<Object> getAllCommonCommands() {
return getCommonCommands() + projectPackagingExtension?.getCommonCommands()
}
@Input
@Optional
List<Object> getAllSupplementaryControlFiles() {
return getSupplementaryControlFiles() + (projectPackagingExtension?.getSupplementaryControlFiles() ?: [])
}
@Input
@Optional
List<Link> getAllLinks() {
if (projectPackagingExtension) {
return getLinks() + projectPackagingExtension.getLinks()
} else {
return getLinks()
}
}
@Input
@Optional
List<Dependency> getAllDependencies() {
if (projectPackagingExtension) {
return getDependencies() + projectPackagingExtension.getDependencies()
} else {
return getDependencies()
}
}
@Input
@Optional
def getAllPrefixes() {
if (projectPackagingExtension) {
return (getPrefixes() + projectPackagingExtension.getPrefixes()).unique()
} else {
return getPrefixes()
}
}
@Input
@Optional
List<Dependency> getAllProvides() {
if (projectPackagingExtension) {
return projectPackagingExtension.getProvides() + getProvides()
} else {
return getProvides()
}
}
@Input
@Optional
List<Dependency> getAllObsoletes() {
if (projectPackagingExtension) {
return getObsoletes() + projectPackagingExtension.getObsoletes()
} else {
return getObsoletes()
}
}
@Input
@Optional
List<Dependency> getAllConflicts() {
if (projectPackagingExtension) {
return getConflicts() + projectPackagingExtension.getConflicts()
} else {
return getConflicts()
}
}
/**
* Defines input files annotation with @SkipWhenEmpty as a workaround to force building the archive even if no
* from clause is declared. Without this method the task would be marked UP-TO-DATE - the actual archive creation
* would be skipped.
*
* The provided file collection is not supposed to be used or modified anywhere else in the task.
*
* @return Collection of files
*/
@InputFiles
@SkipWhenEmpty
private final FileCollection getFakeFiles() {
project.files('fake')
}
void applyConventions() {
ConventionMapping mapping = ((IConventionAware) this).getConventionMapping()
mapping.map('packageName', {
projectPackagingExtension?.getPackageName()?:getBaseName()
})
mapping.map('release', {
projectPackagingExtension?.getRelease()?:getClassifier()
})
mapping.map('version', {
sanitizeVersion(projectPackagingExtension?.getVersion()?:project.getVersion().toString())
})
mapping.map('epoch', {
projectPackagingExtension?.getEpoch()?:0
})
mapping.map('signingKeyId', {
projectPackagingExtension?.getSigningKeyId()
})
mapping.map('signingKeyPassphrase', {
projectPackagingExtension?.getSigningKeyPassphrase()
})
mapping.map('signingKeyRing', {
projectPackagingExtension?.getSigningKeyRing()
})
mapping.map('user', {
projectPackagingExtension?.getUser()?:getPackager()
})
mapping.map('maintainer', {
projectPackagingExtension?.getMaintainer()?:getPackager()
})
mapping.map('uploaders', {
projectPackagingExtension?.getUploaders()?:getPackager()
})
mapping.map('permissionGroup', {
projectPackagingExtension?.getPermissionGroup()?:''
})
mapping.map('packageGroup', {
projectPackagingExtension?.getPackageGroup()
})
mapping.map('buildHost', {
projectPackagingExtension?.getBuildHost()?: getLocalHostName()
})
mapping.map('summary', {
projectPackagingExtension?.getSummary()?:getPackageName()
})
mapping.map('packageDescription', {
String packageDescription = projectPackagingExtension?.getPackageDescription()?:project.getDescription()
packageDescription ?: ''
})
mapping.map('license', {
projectPackagingExtension?.getLicense()?:''
})
mapping.map('packager', {
projectPackagingExtension?.getPackager()?:System.getProperty('user.name', '')
})
mapping.map('distribution', {
projectPackagingExtension?.getDistribution()?:''
})
mapping.map('vendor', {
projectPackagingExtension?.getVendor()?:''
})
mapping.map('url', {
projectPackagingExtension?.getUrl()?:''
})
mapping.map('sourcePackage', {
projectPackagingExtension?.getSourcePackage()?:''
})
mapping.map('createDirectoryEntry', {
projectPackagingExtension?.getCreateDirectoryEntry()?:false
})
mapping.map('priority', {
projectPackagingExtension?.getPriority()?:'optional'
})
mapping.map('preInstall', {
projectPackagingExtension?.getPreInstall()
})
mapping.map('postInstall', {
projectPackagingExtension?.getPostInstall()
})
mapping.map('preUninstall', {
projectPackagingExtension?.getPreUninstall()
})
mapping.map('postUninstall', {
projectPackagingExtension?.getPostUninstall()
})
mapping.map('archiveName', {
assembleArchiveName()
})
mapping.map('fileType', {
projectPackagingExtension?.getFileType()
})
mapping.map('addParentDirs', {
projectPackagingExtension?.getAddParentDirs()?:true
})
mapping.map('archStr', {
projectPackagingExtension?.getArchStr()?:Architecture.NOARCH.name()
})
mapping.map('os', {
projectPackagingExtension?.getOs()?:Os.UNKNOWN
})
mapping.map('type', {
projectPackagingExtension?.getType()?:PackageType.BINARY
})
mapping.map('prefixes', {
projectPackagingExtension?.getPrefixes()?:[]
})
}
String assembleArchiveName() {
String name = getPackageName()
name += getVersion() ? "-${getVersion()}" : ''
name += getRelease() ? "-${getRelease()}" : ''
name += getArchString() ? ".${getArchString()}" : ''
name += getExtension() ? ".${getExtension()}" : ''
name
}
String getArchString() {
getArchStr()?.toLowerCase()
}
void prefixes(String... addPrefixes) {
systemPackagingExtension.prefixes.addAll(addPrefixes)
}
List<String> getPrefixes() {
systemPackagingExtension.prefixes
}
void setChangeLogFile(Path changeLogFile) {
this.changeLogFile = changeLogFile
}
Path getChangeLogFile() {
changeLogFile
}
static String sanitizeVersion(String version) {
version.replaceAll(/\+.*/, '').replaceAll(/-/, '~')
}
static String getLocalHostName() {
try {
return InetAddress.localHost.hostName
} catch (UnknownHostException ignore) {
return "unknown"
}
}
}

View file

@ -0,0 +1,317 @@
package org.xbib.gradle.plugin.rpm
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.CopySpecInternal
import org.gradle.api.internal.file.copy.CopySpecResolver
import org.gradle.api.internal.file.copy.DefaultCopySpec
import org.gradle.api.internal.file.copy.DefaultFileCopyDetails
import org.gradle.api.internal.file.copy.FileCopyDetailsInternal
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.gradle.api.tasks.WorkResult
import org.gradle.api.tasks.WorkResults
import org.gradle.internal.UncheckedException
import org.xbib.gradle.plugin.rpm.validation.RpmTaskPropertiesValidator
import org.xbib.rpm.RpmBuilder
import org.xbib.rpm.lead.Architecture
import org.xbib.rpm.header.HeaderTag
import org.xbib.rpm.payload.Directive
import java.lang.reflect.Field
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption
/**
*
*/
class RpmCopyAction implements CopyAction {
private static final Logger logger = Logging.getLogger(RpmCopyAction.class)
Rpm task
Path tempDir
RpmBuilder builder
boolean includeStandardDefines = true
private final RpmTaskPropertiesValidator rpmTaskPropertiesValidator = new RpmTaskPropertiesValidator()
private RpmFileVisitorStrategy rpmFileVisitorStrategy
RpmCopyAction(Rpm task) {
this.task = task
rpmTaskPropertiesValidator.validate(task)
}
WorkResult execute(CopyActionProcessingStream stream) {
try {
startVisit(this)
stream.process(new StreamAction())
endVisit()
} catch (Exception e) {
UncheckedException.throwAsUncheckedException(e)
}
WorkResults.didWork(true)
}
private class StreamAction implements CopyActionProcessingStreamAction {
@Override
void processFile(FileCopyDetailsInternal details) {
def ourSpec = extractSpec(details)
if (details.isDirectory()) {
visitDir(details, ourSpec)
} else {
visitFile(details, ourSpec)
}
}
}
void endVisit() {
for (Link link : task.getAllLinks()) {
logger.debug "adding link {} -> {}", link.path, link.target
addLink link
}
for (Dependency dep : task.getAllDependencies()) {
logger.debug "adding dependency on {} {}", dep.packageName, dep.version
addDependency dep
}
for (Dependency obsolete: task.getAllObsoletes()) {
logger.debug "adding obsoletes on {} {}", obsolete.packageName, obsolete.version
addObsolete obsolete
}
for (Dependency conflict : task.getAllConflicts()) {
logger.debug "adding conflicts on {} {}", conflict.packageName, conflict.version
addConflict conflict
}
for (Dependency provides : task.getAllProvides()) {
logger.debug "adding provides on {} {}", provides.packageName, provides.version
addProvides(provides)
}
task.directories.each { directory ->
logger.debug "adding directory {}", directory.path
addDirectory(directory)
}
end()
}
static String concat(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()
}
static CopySpecInternal extractSpec(FileCopyDetailsInternal fileDetails) {
if (fileDetails instanceof DefaultFileCopyDetails) {
def startingClass = fileDetails.getClass()
while( startingClass != null && startingClass != DefaultFileCopyDetails) {
startingClass = startingClass.superclass
}
Field specField = startingClass.getDeclaredField('specResolver')
specField.setAccessible(true)
CopySpecResolver specResolver = specField.get(fileDetails)
Field field = DefaultCopySpec.DefaultCopySpecResolver.class.getDeclaredField('this$0')
field.setAccessible(true)
CopySpecInternal spec = field.get(specResolver)
return spec
} else {
return null
}
}
Path extractPath(FileCopyDetailsInternal fileDetails) {
Path path
try {
path = fileDetails.getFile().toPath()
} catch (UnsupportedOperationException uoe) {
path = tempDir.resolve(fileDetails.path)
fileDetails.copyTo(path.toFile())
}
path
}
void startVisit(CopyAction action) {
tempDir = task.getTemporaryDir().toPath()
if (!task.getVersion()) {
throw new IllegalArgumentException('RPM requires a version string')
}
if ([task.preInstall, task.postInstall, task.preUninstall, task.postUninstall].any()) {
logger.warn('at least one of (preInstall|postInstall|preUninstall|postUninstall) is defined ' +
'and will be ignored for RPM builds')
}
builder = new RpmBuilder()
builder.setPackage task.packageName, task.version, task.release, task.epoch
builder.setType task.type
builder.setPlatform Architecture.valueOf(task.archStr.toUpperCase()), task.os
builder.setGroup task.packageGroup
builder.setBuildHost task.buildHost
builder.setSummary task.summary
builder.setDescription task.packageDescription ?: ''
builder.setLicense task.license
builder.setPackager task.packager
builder.setDistribution task.distribution
builder.setVendor task.vendor
builder.setUrl task.url
if (task.allPrefixes) {
builder.setPrefixes(task.allPrefixes as String[])
}
if (task.getSigningKeyId() && task.getSigningKeyPassphrase() && task.getSigningKeyRing()) {
builder.setPrivateKeyId task.getSigningKeyId()
builder.setPrivateKeyPassphrase task.getSigningKeyPassphrase()
builder.setPrivateKeyRing task.getSigningKeyRing()
}
String sourcePackage = task.sourcePackage
if (!sourcePackage) {
sourcePackage = builder.defaultSourcePackage
}
builder.addHeaderEntry HeaderTag.SOURCERPM, sourcePackage
builder.setPreInstall task.getPreInstall()
builder.setPostInstall task.getPostInstall()
builder.setPreUninstall task.getPreUninstall()
builder.setPostUninstall task.getPostUninstall()
builder.setPreTrans task.getPreTrans()
builder.setPostTrans task.getPostTrans()
builder.setPreInstallValue(scriptWithUtils(task.allCommonCommands, task.allPreInstallCommands))
builder.setPostInstallValue(scriptWithUtils(task.allCommonCommands, task.allPostInstallCommands))
builder.setPreUninstallValue(scriptWithUtils(task.allCommonCommands, task.allPreUninstallCommands))
builder.setPostUninstallValue(scriptWithUtils(task.allCommonCommands, task.allPostUninstallCommands))
builder.setPreTransValue(scriptWithUtils(task.allCommonCommands, task.allPreTransCommands))
builder.setPostTransValue(scriptWithUtils(task.allCommonCommands, task.allPostTransCommands))
if (((Rpm) task).changeLogFile != null) {
builder.addChangelog(((Rpm) task).changeLogFile)
}
rpmFileVisitorStrategy = new RpmFileVisitorStrategy(builder)
}
void visitFile(FileCopyDetailsInternal fileDetails, def specToLookAt) {
logger.debug "adding file {}", fileDetails.relativePath.pathString
def inputFile = extractPath(fileDetails)
EnumSet<Directive> fileType = lookup(specToLookAt, 'fileType')
String user = lookup(specToLookAt, 'user') ?: task.user
String group = lookup(specToLookAt, 'permissionGroup') ?: task.permissionGroup
int fileMode = lookup(specToLookAt, 'fileMode') ?: fileDetails.mode
def specAddParentsDir = lookup(specToLookAt, 'addParentDirs')
boolean addParentsDir = specAddParentsDir!=null ? specAddParentsDir : task.addParentDirs
rpmFileVisitorStrategy.addFile(fileDetails, inputFile, fileMode, -1, fileType, user, group, addParentsDir)
}
void visitDir(FileCopyDetailsInternal dirDetails, def specToLookAt) {
if (specToLookAt == null) {
logger.info("Got an empty spec from ${dirDetails.class.name} for ${dirDetails.path}/${dirDetails.name}")
return
}
// Have to take booleans specially, since they would fail an elvis operator if set to false
def specCreateDirectoryEntry = lookup(specToLookAt, 'createDirectoryEntry')
boolean createDirectoryEntry = specCreateDirectoryEntry!=null ? specCreateDirectoryEntry : task.createDirectoryEntry
def specAddParentsDir = lookup(specToLookAt, 'addParentDirs')
boolean addParentsDir = specAddParentsDir != null ? specAddParentsDir : task.addParentDirs
if (createDirectoryEntry) {
logger.debug 'adding directory {}', dirDetails.relativePath.pathString
int dirMode = lookup(specToLookAt, 'dirMode') ?: dirDetails.mode
List<String> directiveList = (lookup(specToLookAt, 'fileType') ?: task.fileType) as List<String>
EnumSet<Directive> directive = makeDirective(directiveList)
String user = lookup(specToLookAt, 'user') ?: task.user
String group = lookup(specToLookAt, 'permissionGroup') ?: task.permissionGroup
rpmFileVisitorStrategy.addDirectory(dirDetails, dirMode, directive, user, group, addParentsDir)
}
}
protected void addLink(Link link) {
builder.addLink link.path, link.target, link.permissions
}
protected void addDependency(Dependency dep) {
builder.addDependency(dep.packageName, dep.flag, dep.version)
}
protected void addConflict(Dependency dep) {
builder.addConflicts(dep.packageName, dep.flag, dep.version)
}
protected void addObsolete(Dependency dep) {
builder.addObsoletes(dep.packageName, dep.flag, dep.version)
}
protected void addProvides(Dependency dep) {
builder.addProvides(dep.packageName, dep.version, dep.flag)
}
protected void addDirectory(Directory directory) {
def user = directory.user ? directory.user : task.user
def permissionGroup = directory.permissionGroup ? directory.permissionGroup : task.permissionGroup
builder.addDirectory(directory.path, directory.permissions, null, user, permissionGroup, directory.addParents)
}
protected void end() {
Path path = task.getArchivePath().toPath()
Files.newByteChannel(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING).withCloseable { ch ->
builder.build(ch)
}
logger.info 'Created RPM archive {}', path
}
String standardScriptDefines() {
includeStandardDefines ?
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.getArchString(),
task.os?.toString()?.toLowerCase() ?: '',
task.getPackageName(),
task.getVersion(),
task.getRelease()) : null
}
String scriptWithUtils(List<Object> utils, List<Object> scripts) {
def list = []
def stdDefines = standardScriptDefines()
if (stdDefines) {
list.add(stdDefines)
}
list.addAll(utils)
list.addAll(scripts)
concat(list)
}
static <T> T lookup(def specToLookAt, String propertyName) {
if (specToLookAt?.metaClass?.hasProperty(specToLookAt, propertyName) != null) {
def prop = specToLookAt.metaClass.getProperty(specToLookAt, propertyName)
if (prop instanceof MetaBeanProperty) {
return prop?.getProperty(specToLookAt) as T
} else {
return prop as T
}
} else {
return null
}
}
static EnumSet<Directive> makeDirective(List<String> strings) {
EnumSet<Directive> set = EnumSet.of(Directive.NONE)
for (String string : strings) {
set.add(Directive.valueOf(string))
}
set
}
}

View file

@ -0,0 +1,63 @@
package org.xbib.gradle.plugin.rpm
import org.xbib.rpm.RpmBuilder
import org.xbib.rpm.payload.Directive
import org.gradle.api.file.FileCopyDetails
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
class RpmFileVisitorStrategy {
protected final RpmBuilder builder
RpmFileVisitorStrategy(RpmBuilder builder) {
this.builder = builder
}
void addFile(FileCopyDetails details, Path source, int mode, int dirmode, EnumSet<Directive> directive, String uname, String gname, boolean addParents) {
try {
if (!Files.isSymbolicLink(Paths.get(details.file.parentFile.path))) {
addFileToBuilder(details, source, mode, dirmode, directive, uname, gname, addParents)
}
}
catch (UnsupportedOperationException e) {
// For file details that have filters, accessing the file throws this exception
addFileToBuilder(details, source, mode, dirmode, directive, uname, gname, addParents)
}
}
void addDirectory(FileCopyDetails details, int permissions, EnumSet<Directive> directive, String uname,
String gname, boolean addParents) {
try {
if (Files.isSymbolicLink(Paths.get(details.file.path))) {
addLinkToBuilder(details)
}
else {
addDirectoryToBuilder(details, permissions, directive, uname, gname, addParents)
}
} catch (UnsupportedOperationException e) {
// For file details that have filters, accessing the directory throws this exception
addDirectoryToBuilder(details, permissions, directive, uname, gname, addParents)
}
}
protected void addFileToBuilder(FileCopyDetails details, Path source, int mode, int dirmode, EnumSet<Directive> directive, String uname, String gname, boolean addParents) {
builder.addFile(getRootPath(details), source, mode, dirmode, directive, uname, gname, addParents)
}
protected void addDirectoryToBuilder(FileCopyDetails details, int permissions, EnumSet<Directive> directive, String uname, String gname, boolean addParents) {
builder.addDirectory(getRootPath(details), permissions, directive, uname, gname, addParents)
}
private void addLinkToBuilder(FileCopyDetails details) {
Path path = Paths.get(details.file.path)
Path target = Files.readSymbolicLink(path)
builder.addLink(getRootPath(details), target.toFile().path)
}
private static String getRootPath(FileCopyDetails details) {
"/${details.path}".toString()
}
}

View file

@ -0,0 +1,65 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.api.plugins.BasePlugin
import org.xbib.rpm.RpmBuilder
import org.xbib.rpm.lead.Architecture
import org.xbib.rpm.format.Flags
import org.xbib.rpm.lead.Os
import org.xbib.rpm.lead.PackageType
import org.xbib.rpm.payload.Directive
import org.gradle.api.Plugin
import org.gradle.api.Project
import java.lang.reflect.Field
import java.lang.reflect.Modifier
/**
*
*/
class RpmPlugin implements Plugin<Project> {
void apply(Project project) {
project.plugins.apply(BasePlugin)
project.ext.Rpm = Rpm.class
RpmBuilder.metaClass.getDefaultSourcePackage() {
format.getLead().getName() + "-src.rpm"
}
project.tasks.withType(Rpm) { Rpm task ->
applyAliases(task)
task.applyConventions()
}
}
def static applyAliases(def dynamicObjectAware) {
aliasEnumValues(Architecture.values(), dynamicObjectAware)
aliasEnumValues(Os.values(), dynamicObjectAware)
aliasEnumValues(PackageType.values(), dynamicObjectAware)
aliasStaticInstances(Directive.class, dynamicObjectAware)
aliasStaticInstances(Flags.class, int.class, dynamicObjectAware)
}
private static <T extends Enum<T>> void aliasEnumValues(T[] values, dynAware) {
for (T value : values) {
dynAware.metaClass."${value.name()}" = value
}
}
private static <T> void aliasStaticInstances(Class<T> forClass, dynAware) {
aliasStaticInstances(forClass, forClass, dynAware)
}
private static <T, U> void aliasStaticInstances(Class<T> forClass, Class<U> ofClass, dynAware) {
for (Field field : forClass.fields) {
if (field.type == ofClass && hasModifier(field, Modifier.STATIC)) {
dynAware.metaClass."${field.name}" = field.get(null)
}
}
}
private static boolean hasModifier(Field field, int modifier) {
(field.modifiers & modifier) == modifier
}
}

View file

@ -0,0 +1,490 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Optional
import org.xbib.rpm.lead.Architecture
import org.xbib.rpm.lead.Os
import org.xbib.rpm.lead.PackageType
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
/**
* Extension that can be used to configure RPM.
*/
class SystemPackagingExtension {
@Input @Optional
String packageName
@Input @Optional
String release
@Input @Optional
String version
@Input @Optional
Integer epoch
@Input @Optional
String signingKeyPassphrase
@Input @Optional
String signingKeyRing
@Input @Optional
String signingKeyId
@Input @Optional
String user
@Input @Optional
String permissionGroup
@Input @Optional
String packageGroup
@Input @Optional
String buildHost
@Input @Optional
String summary
@Input @Optional
String packageDescription
@Input @Optional
String license
@Input @Optional
String packager
@Input @Optional
String distribution
@Input @Optional
String vendor
@Input @Optional
String url
@Input @Optional
String sourcePackage
String archStr
@Input @Optional
void setArch(Object arch) {
archStr = (arch instanceof Architecture) ? arch.name() : arch.toString()
}
@Input @Optional
List<String> fileType
@Input @Optional
Boolean createDirectoryEntry
@Input @Optional
Boolean addParentDirs
@Input @Optional
Os os
@Input @Optional
PackageType type
List<String> prefixes = new ArrayList<String>()
def prefix(String prefixStr) {
prefixes << prefixStr
return this
}
@Input @Optional
Integer uid
@Input @Optional
Integer gid
@Input @Optional
String maintainer
@Input @Optional
String uploaders
@Input @Optional
String priority
@Input @Optional
final List<Object> supplementaryControlFiles = []
def supplementaryControl(Object file) {
supplementaryControlFiles << file
return this
}
@Input @Optional
String preInstall
@Input @Optional
String postInstall
@Input @Optional
String preUninstall
@Input @Optional
String postUninstall
@Input @Optional
String preTrans
@Input @Optional
String postTrans
final List<Object> configurationPaths = []
final List<Object> preInstallCommands = []
final List<Object> postInstallCommands = []
final List<Object> preUninstallCommands = []
final List<Object> postUninstallCommands = []
final List<Object> preTransCommands = []
final List<Object> postTransCommands = []
final List<Object> commonCommands = []
def setInstallUtils(Path script) {
installUtils(script)
}
def installUtils(String script) {
commonCommands << script
return this
}
def installUtils(Path script) {
commonCommands << script
return this
}
def setConfigurationPath(String script) {
configurationPath(script)
}
def configurationPath(String path) {
configurationPaths << path
this
}
def setPreInstall(String script) {
preInstall(script)
}
def setPreInstall(Path script) {
preInstall(script)
}
def preInstall(String script) {
preInstall(Paths.get(script))
}
def preInstall(Path script) {
if (Files.exists(script)) {
preInstallValue(script.text)
}
this
}
def preInstallValue(String content) {
preInstallCommands << content
this
}
def setPostInstall(String script) {
postInstall(script)
}
def setPostInstall(Path script) {
postInstall(script)
}
def postInstall(String script) {
postInstall(Paths.get(script))
}
def postInstall(Path script) {
if (Files.exists(script)) {
postInstallValue(script.text)
}
this
}
def postInstallValue(String content) {
postInstallCommands << content
this
}
def setPreUninstall(String script) {
preUninstall(script)
}
def setPreUninstall(Path script) {
preUninstall(script)
}
def preUninstall(String script) {
preUninstall(Paths.get(script))
}
def preUninstall(Path script) {
if (Files.exists(script)) {
preUninstallValue(script.text)
}
this
}
def preUninstallValue(String script) {
preUninstallCommands << script
this
}
def setPostUninstall(String script) {
postUninstall(script)
}
def setPostUninstall(Path script) {
postUninstall(script)
}
def postUninstall(String script) {
postUninstall(Paths.get(script))
}
def postUninstall(Path script) {
if (Files.exists(script)) {
postUninstallValue(script.text)
}
this
}
def postUninstallValue(String content) {
postUninstallCommands << content
this
}
def setPreTrans(String script) {
preTrans(script)
}
def setPreTrans(Path script) {
preTrans(script)
}
def preTrans(String script) {
preTrans(Paths.get(script))
}
def preTrans(Path script) {
if (Files.exists(script)) {
preTransValue(script.text)
}
this
}
def preTransValue(String script) {
preTransCommands << script
this
}
def setPostTrans(String script) {
postTrans(script)
}
def setPostTrans(Path script) {
postTrans(script)
}
def postTrans(String script) {
postTrans(Paths.get(script))
}
def postTrans(Path script) {
if (Files.exists(script)) {
postTransValue(script.text)
}
return this
}
def postTransValue(String script) {
postTransCommands << script
return this
}
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()
link.path = path
link.target = target
link.permissions = permissions
links.add(link)
link
}
List<Dependency> dependencies = []
List<Dependency> obsoletes = []
List<Dependency> conflicts = []
List<Dependency> recommends = []
List<Dependency> suggests = []
List<Dependency> enhances = []
List<Dependency> preDepends = []
List<Dependency> breaks = []
List<Dependency> replaces = []
List<Dependency> provides = []
Dependency requires(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
dependencies.add(dep)
dep
}
Dependency requires(String packageName, String version){
requires(packageName, version, 0)
}
Dependency requires(String packageName) {
requires(packageName, '', 0)
}
Dependency obsoletes(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
obsoletes.add(dep)
dep
}
Dependency obsoletes(String packageName) {
obsoletes(packageName, '', 0)
}
Dependency conflicts(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
conflicts.add(dep)
dep
}
Dependency conflicts(String packageName) {
conflicts(packageName, '', 0)
}
Dependency recommends(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
recommends.add(dep)
dep
}
Dependency recommends(String packageName) {
recommends(packageName, '', 0)
}
Dependency suggests(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
suggests.add(dep)
dep
}
Dependency suggests(String packageName) {
suggests(packageName, '', 0)
}
Dependency enhances(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
enhances.add(dep)
dep
}
Dependency enhances(String packageName) {
enhances(packageName, '', 0)
}
Dependency preDepends(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
preDepends.add(dep)
dep
}
Dependency preDepends(String packageName) {
preDepends(packageName, '', 0)
}
Dependency breaks(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
breaks.add(dep)
dep
}
Dependency breaks(String packageName) {
breaks(packageName, '', 0)
}
Dependency replaces(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
replaces.add(dep)
dep
}
Dependency replaces(String packageName) {
replaces(packageName, '', 0)
}
Dependency provides(String packageName, String version, int flag) {
def dep = new Dependency(packageName, version, flag)
provides.add(dep)
dep
}
Dependency provides(String packageName) {
provides(packageName, '', 0)
}
List<Directory> directories = []
Directory directory(String path) {
Directory directory = directory(path, -1)
directories << directory
directory
}
Directory directory(String path, boolean addParents) {
Directory directory = new Directory(path: path, addParents: addParents)
directories << directory
directory
}
Directory directory(String path, int permissions) {
Directory directory = new Directory(path: path, permissions: permissions)
directories << directory
directory
}
Directory directory(String path, int permissions, boolean addParents) {
Directory directory = new Directory(path: path, permissions: permissions, addParents: addParents)
directories << directory
directory
}
Directory directory(String path, int permissions, String user, String permissionGroup) {
Directory directory = new Directory(path: path, permissions: permissions, user: user,
permissionGroup: permissionGroup)
directories << directory
directory
}
Directory directory(String path, int permissions, String user, String permissionGroup, boolean addParents) {
Directory directory = new Directory(path: path, permissions: permissions, user: user,
permissionGroup: permissionGroup, addParents: addParents)
directories << directory
directory
}
private static IllegalStateException multipleFilesDefined(String fileName) {
new IllegalStateException("Cannot specify more than one $fileName File")
}
private static IllegalStateException conflictingDefinitions(String type) {
new IllegalStateException("Cannot specify $type File and $type Commands")
}
}

View file

@ -0,0 +1,18 @@
package org.xbib.gradle.plugin.rpm.validation
class RpmPackageNameAttributeValidator implements SystemPackagingAttributeValidator {
@Override
boolean validate(String packageName) {
matchesExpectedCharacters(packageName)
}
private static boolean matchesExpectedCharacters(String packageName) {
packageName ==~ /[a-zA-Z0-9-._+]+/
}
@Override
String getErrorMessage(String attribute) {
"Invalid package name '$attribute' - a valid package name must only contain [a-zA-Z0-9-._+]"
}
}

View file

@ -0,0 +1,16 @@
package org.xbib.gradle.plugin.rpm.validation
import org.xbib.gradle.plugin.rpm.Rpm
import org.gradle.api.InvalidUserDataException
class RpmTaskPropertiesValidator implements SystemPackagingTaskPropertiesValidator<Rpm> {
private final SystemPackagingAttributeValidator packageNameValidator = new RpmPackageNameAttributeValidator()
@Override
void validate(Rpm task) {
if (!packageNameValidator.validate(task.getPackageName())) {
throw new InvalidUserDataException(packageNameValidator.getErrorMessage(task.getPackageName()))
}
}
}

View file

@ -0,0 +1,8 @@
package org.xbib.gradle.plugin.rpm.validation
interface SystemPackagingAttributeValidator {
boolean validate(String attribute)
String getErrorMessage(String attribute)
}

View file

@ -0,0 +1,8 @@
package org.xbib.gradle.plugin.rpm.validation
import org.gradle.api.Task
interface SystemPackagingTaskPropertiesValidator<T extends Task> {
void validate(T task)
}

View file

@ -0,0 +1 @@
implementation-class=org.xbib.gradle.plugin.rpm.RpmPlugin

View file

@ -0,0 +1,52 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import org.junit.Rule
import org.junit.rules.TestName
import spock.lang.Specification
abstract class AbstractProjectSpec extends Specification {
static final String CLEAN_PROJECT_DIR_SYS_PROP = 'cleanProjectDir'
File ourProjectDir
@Rule TestName testName = new TestName()
String canonicalName
Project project
MultiProjectHelper helper
void setup() {
ourProjectDir = new File("build/nebulatest/${this.class.canonicalName}/${testName.methodName.replaceAll(/\W+/, '-')}").absoluteFile
if (ourProjectDir.exists()) {
ourProjectDir.deleteDir()
}
ourProjectDir.mkdirs()
canonicalName = testName.getMethodName().replaceAll(' ', '-')
project = ProjectBuilder.builder().withName(canonicalName).withProjectDir(ourProjectDir).build()
helper = new MultiProjectHelper(project)
}
void cleanup() {
if (deleteProjectDir()) {
ourProjectDir.deleteDir()
}
}
boolean deleteProjectDir() {
String cleanProjectDirSystemProperty = System.getProperty(CLEAN_PROJECT_DIR_SYS_PROP)
cleanProjectDirSystemProperty ? cleanProjectDirSystemProperty.toBoolean() : true
}
Project addSubproject(String subprojectName) {
helper.addSubproject(subprojectName)
}
Project addSubprojectWithDirectory(String subprojectName) {
helper.addSubprojectWithDirectory(subprojectName)
}
}

View file

@ -0,0 +1,120 @@
package org.xbib.gradle.plugin.rpm
import org.junit.Rule
import org.junit.rules.TestName
import spock.lang.Specification
abstract class BaseIntegrationSpec extends Specification {
@Rule
TestName testName = new TestName()
File projectDir
def setup() {
projectDir = new File("build/xbibtest/${this.class.canonicalName}/${testName.methodName.replaceAll(/\W+/, '-')}").absoluteFile
if (projectDir.exists()) {
projectDir.deleteDir()
}
projectDir.mkdirs()
}
protected File directory(String path, File baseDir = getProjectDir()) {
new File(baseDir, path).with {
mkdirs()
it
}
}
protected File file(String path, File baseDir = getProjectDir()) {
def splitted = path.split('/')
def directory = splitted.size() > 1 ? directory(splitted[0..-2].join('/'), baseDir) : baseDir
def file = new File(directory, splitted[-1])
file.createNewFile()
file
}
protected File createFile(String path, File baseDir = getProjectDir()) {
File file = file(path, baseDir)
if (!file.exists()) {
assert file.parentFile.mkdirs() || file.parentFile.exists()
file.createNewFile()
}
file
}
protected static void checkForDeprecations(String output) {
def deprecations = output.readLines().findAll {
it.contains("has been deprecated and is scheduled to be removed in Gradle")
}
if (!System.getProperty("ignoreDeprecations") && !deprecations.isEmpty()) {
throw new IllegalArgumentException("Deprecation warnings were found (Set the ignoreDeprecations system property during the test to ignore):\n" + deprecations.collect {
" - $it"
}.join("\n"))
}
}
protected void writeHelloWorld(String packageDotted, File baseDir = getProjectDir()) {
def path = 'src/main/java/' + packageDotted.replace('.', '/') + '/HelloWorld.java'
def javaFile = createFile(path, baseDir)
javaFile << """\
package ${packageDotted};
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello Integration Test");
}
}
""".stripIndent()
}
/**
* Creates a unit test for testing your plugin.
* @param failTest true if you want the test to fail, false if the test should pass
* @param baseDir the directory to begin creation from, defaults to projectDir
*/
protected void writeUnitTest(boolean failTest, File baseDir = getProjectDir()) {
writeTest('src/test/java/', 'nebula', failTest, baseDir)
}
/**
*
* Creates a unit test for testing your plugin.
* @param srcDir the directory in the project where the source file should be created.
* @param packageDotted the package for the unit test class, written in dot notation (ex. - nebula.integration)
* @param failTest true if you want the test to fail, false if the test should pass
* @param baseDir the directory to begin creation from, defaults to projectDir
*/
protected void writeTest(String srcDir, String packageDotted, boolean failTest, File baseDir = getProjectDir()) {
def path = srcDir + packageDotted.replace('.', '/') + '/HelloWorldTest.java'
def javaFile = createFile(path, baseDir)
javaFile << """\
package ${packageDotted};
import org.junit.Test;
import static org.junit.Assert.assertFalse;
public class HelloWorldTest {
@Test public void doesSomething() {
assertFalse( $failTest );
}
}
""".stripIndent()
}
/**
* Creates a properties file to included as project resource.
* @param srcDir the directory in the project where the source file should be created.
* @param fileName to be used for the file, sans extension. The .properties extension will be added to the name.
* @param baseDir the directory to begin creation from, defaults to projectDir
*/
protected void writeResource(String srcDir, String fileName, File baseDir = getProjectDir()) {
def path = "$srcDir/${fileName}.properties"
def resourceFile = createFile(path, baseDir)
resourceFile.text = "firstProperty=foo.bar"
}
protected void addResource(String srcDir, String filename, String contents, File baseDir = getProjectDir()) {
def resourceFile = createFile("${srcDir}/${filename}", baseDir)
resourceFile.text = contents
}
}

View file

@ -0,0 +1,96 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.tooling.BuildException
import org.gradle.tooling.BuildLauncher
import org.gradle.tooling.ProgressEvent
import org.gradle.tooling.ProgressListener
class BuildLauncherBackedGradleHandle implements GradleHandle {
final private ByteArrayOutputStream standardOutput = new ByteArrayOutputStream()
final private ByteArrayOutputStream standardError = new ByteArrayOutputStream()
final private BuildLauncher launcher
final private boolean forkedProcess
final private List<String> tasksExecuted
public static final String PROGRESS_TASK_PREFIX = "Execute :"
private GradleHandleBuildListener buildListener
BuildLauncherBackedGradleHandle(BuildLauncher launcher, boolean forkedProcess) {
this.forkedProcess = forkedProcess
launcher.setStandardOutput(standardOutput)
launcher.setStandardError(standardError)
tasksExecuted = new ArrayList<String>()
launcher.addProgressListener(new ProgressListener() {
@Override
void statusChanged(ProgressEvent event) {
// These are free form strings, :-(
if (event.getDescription().startsWith(PROGRESS_TASK_PREFIX)) { // E.g. "Execute :echo"
String taskName = event.getDescription().substring(PROGRESS_TASK_PREFIX.length() - 1)
tasksExecuted.add(taskName)
}
}
})
this.launcher = launcher
}
@Override
void registerBuildListener(GradleHandleBuildListener buildListener) {
this.buildListener = buildListener
}
@Override
boolean isForkedProcess() {
forkedProcess
}
private String getStandardOutput() {
return standardOutput.toString()
}
private String getStandardError() {
return standardError.toString()
}
@Override
ExecutionResult run() {
Throwable failure = null
try {
buildListener?.buildStarted()
launcher.run()
} catch(BuildException e) {
failure = e.getCause()
} catch(Exception e) {
failure = e
}
finally {
buildListener?.buildFinished()
}
String stdout = getStandardOutput()
List<MinimalExecutedTask> tasks = new ArrayList<MinimalExecutedTask>()
for (String taskName: tasksExecuted) {
boolean upToDate = isTaskUpToDate(stdout, taskName)
boolean skipped = isTaskSkipped(stdout, taskName)
tasks.add(new MinimalExecutedTask(taskName, upToDate, skipped))
}
boolean success = failure == null
new ToolingExecutionResult(success, stdout, getStandardError(), tasks, failure)
}
private isTaskUpToDate(String stdout, String taskName) {
containsOutput(stdout, taskName, 'UP-TO-DATE')
}
private isTaskSkipped(String stdout, String taskName) {
containsOutput(stdout, taskName, 'SKIPPED')
}
private boolean containsOutput(String stdout, String taskName, String stateIdentifier) {
stdout.contains("$taskName $stateIdentifier".toString())
}
}

View file

@ -0,0 +1,58 @@
package org.xbib.gradle.plugin.rpm
import com.google.common.base.Function
import com.google.common.base.Predicate
import com.google.common.collect.FluentIterable
import org.gradle.internal.ErroringAction
import org.gradle.internal.IoActions
import org.gradle.internal.classloader.ClasspathUtil
import org.gradle.internal.classpath.ClassPath
import org.gradle.util.TextUtil
class ClasspathAddingInitScriptBuilder {
private ClasspathAddingInitScriptBuilder() {
}
static void build(File initScriptFile, final ClassLoader classLoader, Predicate<URL> classpathFilter) {
build(initScriptFile, getClasspathAsFiles(classLoader, classpathFilter))
}
static void build(File initScriptFile, final List<File> classpath) {
IoActions.writeTextFile(initScriptFile, new ErroringAction<Writer>() {
@Override
protected void doExecute(Writer writer) throws Exception {
writer.write("allprojects {\n")
writer.write(" buildscript {\n")
writer.write(" dependencies {\n")
for (File file : classpath) {
writer.write(String.format(" classpath files('%s')\n", TextUtil.escapeString(file.getAbsolutePath())))
}
writer.write(" }\n")
writer.write(" }\n")
writer.write("}\n")
}
})
}
static List<File> getClasspathAsFiles(ClassLoader classLoader, Predicate<URL> classpathFilter) {
List<URL> classpathUrls = getClasspathUrls(classLoader)
return FluentIterable.from(classpathUrls).filter(classpathFilter).transform(new Function<URL, File>() {
@Override
File apply(URL url) {
return new File(url.toURI())
}
}).toList()
}
private static List<URL> getClasspathUrls(ClassLoader classLoader) {
Object cp = ClasspathUtil.getClasspath(classLoader)
if (cp instanceof List<URL>) {
return (List<URL>) cp
}
if (cp instanceof ClassPath) {
return ((ClassPath) cp).asURLs
}
throw new IllegalStateException("Unable to extract classpath urls from type ${cp.class.canonicalName}")
}
}

View file

@ -0,0 +1,35 @@
package org.xbib.gradle.plugin.rpm;
import com.google.common.base.Predicate
import org.gradle.util.GFileUtils
class ClasspathInjectingGradleHandleFactory implements GradleHandleFactory {
private final ClassLoader classLoader
private final GradleHandleFactory delegateFactory
private Predicate<URL> classpathFilter
ClasspathInjectingGradleHandleFactory(ClassLoader classLoader, GradleHandleFactory delegateFactory,
Predicate<URL> classpathFilter) {
this.classpathFilter = classpathFilter
this.classLoader = classLoader
this.delegateFactory = delegateFactory
}
@Override
GradleHandle start(File projectDir, List<String> arguments, List<String> jvmArguments = []) {
File testKitDir = new File(projectDir, ".gradle-test-kit")
if (!testKitDir.exists()) {
GFileUtils.mkdirs(testKitDir)
}
File initScript = new File(testKitDir, "init.gradle");
ClasspathAddingInitScriptBuilder.build(initScript, classLoader, classpathFilter)
List<String> ammendedArguments = new ArrayList<String>(arguments.size() + 2)
ammendedArguments.add("--init-script")
ammendedArguments.add(initScript.getAbsolutePath())
ammendedArguments.addAll(arguments)
return delegateFactory.start(projectDir, ammendedArguments, jvmArguments)
}
}

View file

@ -0,0 +1,18 @@
package org.xbib.gradle.plugin.rpm
import groovy.transform.Immutable
@Immutable
class Coordinate {
String group
String artifact
String version
@Override
String toString() {
"${group}:${artifact}:${version}"
}
}

View file

@ -0,0 +1,107 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.api.internal.file.DefaultFileLookup
import org.gradle.api.internal.file.FileResolver
import org.gradle.api.internal.file.copy.DefaultCopySpec
import org.gradle.api.tasks.util.PatternSet
import org.gradle.api.tasks.util.internal.PatternSets
import org.gradle.internal.Factory
import org.gradle.internal.nativeintegration.filesystem.FileSystem
import org.gradle.internal.nativeintegration.services.NativeServices
import org.gradle.internal.reflect.DirectInstantiator
import org.gradle.internal.reflect.Instantiator
import org.junit.Test
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertNull
class CopySpecEnhancementTest {
private final FileResolver fileResolver = [resolve: { it as File }, getPatternSetFactory: {
TestFiles.getPatternSetFactory()
}] as FileResolver
private final Instantiator instantiator = DirectInstantiator.INSTANCE
def spec = new DefaultCopySpec(fileResolver, instantiator)
@Test
public void addUser() {
assertNull(spec.metaClass.hasProperty('user'))
CopySpecEnhancement.user(spec, 'USER')
assertEquals('USER', spec.user)
}
@Test
public void addAddParentDirs() {
CopySpecEnhancement.setAddParentDirs(spec, true)
assertEquals(true, spec.addParentDirs)
}
@Test
public void addCreateDirectoryEntry() {
use(CopySpecEnhancement) {
spec.createDirectoryEntry false
}
assertEquals(false, spec.createDirectoryEntry)
use(CopySpecEnhancement) {
spec.createDirectoryEntry true
}
assertEquals(true, spec.createDirectoryEntry)
use(CopySpecEnhancement) {
spec.setCreateDirectoryEntry(false)
}
assertEquals(false, spec.createDirectoryEntry)
use(CopySpecEnhancement) {
spec.setCreateDirectoryEntry(true)
}
assertEquals(true, spec.createDirectoryEntry)
}
}
// Copied from Gradle core as DefaultCopySpec can no longer have null arguments
class TestFiles {
private static final FileSystem FILE_SYSTEM = NativeServicesTestFixture.getInstance().get(FileSystem.class);
private static final DefaultFileLookup FILE_LOOKUP = new DefaultFileLookup(FILE_SYSTEM, PatternSets.getNonCachingPatternSetFactory());
/**
* Returns a resolver with no base directory.
*/
static FileResolver resolver() {
return FILE_LOOKUP.getFileResolver()
}
static Factory<PatternSet> getPatternSetFactory() {
return resolver().getPatternSetFactory()
}
}
class NativeServicesTestFixture {
static NativeServices nativeServices
static boolean initialized
static void initialize() {
if (!initialized) {
File nativeDir = new File("build/native-libs")
NativeServices.initialize(nativeDir)
initialized = true
}
}
static synchronized NativeServices getInstance() {
if (nativeServices == null) {
initialize()
nativeServices = NativeServices.getInstance()
}
nativeServices
}
}

View file

@ -0,0 +1,90 @@
package org.xbib.gradle.plugin.rpm;
import org.gradle.api.GradleException
abstract class DefaultExecutionResult implements ExecutionResult {
private final Boolean success
private final String standardOutput
private final String standardError
private final List<? extends ExecutedTask> executedTasks
private final Throwable failure
DefaultExecutionResult(Boolean success, String standardOutput, String standardError,
List<? extends ExecutedTask> executedTasks, Throwable failure) {
this.success = success
this.standardOutput = standardOutput
this.standardError = standardError
this.executedTasks = executedTasks
this.failure = failure
}
@Override
Boolean getSuccess() {
success
}
@Override
String getStandardOutput() {
standardOutput
}
@Override
String getStandardError() {
standardError
}
@Override
boolean wasExecuted(String taskPath) {
executedTasks.any { ExecutedTask task ->
taskPath = normalizeTaskPath(taskPath)
def match = task.path == taskPath
return match
}
}
@Override
boolean wasUpToDate(String taskPath) {
getExecutedTaskByPath(taskPath).upToDate
}
@Override
boolean wasSkipped(String taskPath) {
getExecutedTaskByPath(taskPath).skipped
}
String normalizeTaskPath(String taskPath) {
taskPath.startsWith(':') ? taskPath : ":$taskPath"
}
private ExecutedTask getExecutedTaskByPath(String taskPath) {
taskPath = normalizeTaskPath(taskPath)
def task = executedTasks.find { ExecutedTask task ->
task.path == taskPath
}
if (task == null) {
throw new RuntimeException("Task with path $taskPath was not found")
}
task
}
@Override
Throwable getFailure() {
failure
}
@Override
ExecutionResult rethrowFailure() {
if (failure instanceof GradleException) {
throw (GradleException) failure
}
if (failure != null) {
throw new GradleException("Build aborted because of an internal error.", failure)
}
this
}
}

View file

@ -0,0 +1,25 @@
package org.xbib.gradle.plugin.rpm
class DefaultGradleRunner implements GradleRunner {
private final GradleHandleFactory handleFactory
DefaultGradleRunner(GradleHandleFactory handleFactory) {
this.handleFactory = handleFactory
}
@Override
ExecutionResult run(File projectDir, List<String> arguments, List<String> jvmArguments = [],
List<PreExecutionAction> preExecutionActions = []) {
handle(projectDir, arguments, jvmArguments, preExecutionActions).run()
}
@Override
GradleHandle handle(File projectDir, List<String> arguments, List<String> jvmArguments = [],
List<PreExecutionAction> preExecutionActions = []) {
preExecutionActions?.each {
it.execute(projectDir, arguments, jvmArguments)
}
handleFactory.start(projectDir, arguments, jvmArguments)
}
}

View file

@ -0,0 +1,37 @@
package org.xbib.gradle.plugin.rpm
class DependencyGraph {
Collection<DependencyGraphNode> nodes = []
DependencyGraph(List<String> graph) {
graph.each { nodes << parseNode(it) }
}
DependencyGraph(String... graph) {
this(graph as List)
}
DependencyGraph(Map tuple) {
nodes = tuple.nodes
}
private DependencyGraphNode parseNode(String s) {
// Don't use tokenize, it'll make each character a possible delimeter, e.g. \t\n would tokenize on both
// \t OR \n, not the combination of \t\n.
def parts = s.split('->')
def (group, artifact, version) = parts[0].trim().tokenize(':')
def coordinate = new Coordinate(group: group, artifact: artifact, version: version)
def dependencies = (parts.size() > 1) ? parseDependencies(parts[1]) : []
new DependencyGraphNode(coordinate: coordinate, dependencies: dependencies)
}
private List<Coordinate> parseDependencies(String s) {
List<Coordinate> dependencies = []
s.tokenize('|').each { String dependency ->
def (group, artifact, version) = dependency.trim().tokenize(':')
dependencies << new Coordinate(group: group, artifact: artifact, version: version)
}
dependencies
}
}

View file

@ -0,0 +1,16 @@
package org.xbib.gradle.plugin.rpm
import groovy.transform.Immutable
@Immutable
class DependencyGraphNode {
@Delegate Coordinate coordinate
List<Coordinate> dependencies = []
@Override
String toString() {
"${group}:${artifact}:${version}"
}
}

View file

@ -0,0 +1,10 @@
package org.xbib.gradle.plugin.rpm
interface ExecutedTask {
String getPath()
boolean isUpToDate()
boolean isSkipped()
}

View file

@ -0,0 +1,20 @@
package org.xbib.gradle.plugin.rpm;
interface ExecutionResult {
Boolean getSuccess()
String getStandardOutput()
String getStandardError()
boolean wasExecuted(String taskPath)
boolean wasUpToDate(String taskPath)
boolean wasSkipped(String taskPath)
Throwable getFailure()
ExecutionResult rethrowFailure()
}

View file

@ -0,0 +1,151 @@
package org.xbib.gradle.plugin.rpm
class GradleDependencyGenerator {
static final String STANDARD_SUBPROJECT_BLOCK = '''\
subprojects {
apply plugin: 'maven-publish'
apply plugin: 'ivy-publish'
apply plugin: 'java'
publishing {
repositories {
maven {
url "../mavenrepo"
}
ivy {
url "../ivyrepo"
layout('pattern') {
ivy '[organisation]/[module]/[revision]/[module]-[revision]-ivy.[ext]'
artifact '[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]'
m2compatible = true
}
}
}
publications {
maven(MavenPublication) {
artifactId artifactName
from components.java
}
ivy(IvyPublication) {
module artifactName
from components.java
}
}
}
}
'''.stripIndent()
static final String BUILD_GRADLE = 'build.gradle'
private boolean generated = false
DependencyGraph graph
File gradleRoot
File ivyRepoDir
File mavenRepoDir
GradleDependencyGenerator(DependencyGraph graph, String directory = 'build/testrepogen') {
this.graph = graph
this.gradleRoot = new File(directory)
this.ivyRepoDir = new File(directory, 'ivyrepo')
this.mavenRepoDir = new File(directory, 'mavenrepo')
generateGradleFiles()
}
File generateTestMavenRepo() {
runTasks('publishMavenPublicationToMavenRepository')
mavenRepoDir
}
String getMavenRepoDirPath() {
mavenRepoDir.absolutePath
}
String getMavenRepoUrl() {
mavenRepoDir.toURI().toURL()
}
String getMavenRepositoryBlock() {
"""\
maven { url '${getMavenRepoUrl()}' }
""".stripIndent()
}
File generateTestIvyRepo() {
runTasks('publishIvyPublicationToIvyRepository')
ivyRepoDir
}
String getIvyRepoDirPath() {
ivyRepoDir.absolutePath
}
String getIvyRepoUrl() {
ivyRepoDir.toURI().toURL()
}
String getIvyRepositoryBlock() {
"""\
ivy {
url '${getIvyRepoUrl()}'
layout('pattern') {
ivy '[organisation]/[module]/[revision]/[module]-[revision]-ivy.[ext]'
artifact '[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]'
m2compatible = true
}
}
""".stripIndent()
}
private void generateGradleFiles() {
if (generated) {
return
} else {
generated = true
}
gradleRoot.mkdirs()
def rootBuildGradle = new File(gradleRoot, BUILD_GRADLE)
rootBuildGradle.text = STANDARD_SUBPROJECT_BLOCK
def includes = []
graph.nodes.each { DependencyGraphNode n ->
String subName = "${n.group}.${n.artifact}_${n.version.replaceAll(/\./, '_')}"
includes << subName
def subfolder = new File(gradleRoot, subName)
subfolder.mkdir()
def subBuildGradle = new File(subfolder, BUILD_GRADLE)
subBuildGradle.text = generateSubBuildGradle(n)
}
def settingsGradle = new File(gradleRoot, 'settings.gradle')
settingsGradle.text = 'include ' + includes.collect { "'${it}'"}.join(', ')
}
private String generateSubBuildGradle(DependencyGraphNode node) {
StringWriter block = new StringWriter()
if (node.dependencies) {
block.withPrintWriter { writer ->
writer.println 'dependencies {'
node.dependencies.each { writer.println " compile '${it}'" }
writer.println '}'
}
}
"""\
group = '${node.group}'
version = '${node.version}'
ext {
artifactName = '${node.artifact}'
}
""".stripIndent() + block.toString()
}
private void runTasks(String tasks) {
def runner = GradleRunnerFactory.createTooling()
runner.run(gradleRoot, tasks.tokenize()).rethrowFailure()
}
}

View file

@ -0,0 +1,10 @@
package org.xbib.gradle.plugin.rpm
interface GradleHandle {
ExecutionResult run()
void registerBuildListener(GradleHandleBuildListener buildListener)
boolean isForkedProcess()
}

View file

@ -0,0 +1,8 @@
package org.xbib.gradle.plugin.rpm
interface GradleHandleBuildListener {
void buildStarted()
void buildFinished()
}

View file

@ -0,0 +1,8 @@
package org.xbib.gradle.plugin.rpm
interface GradleHandleFactory {
GradleHandle start(File dir, List<String> arguments)
GradleHandle start(File dir, List<String> arguments, List<String> jvmArguments)
}

View file

@ -0,0 +1,78 @@
package org.xbib.gradle.plugin.rpm
import com.google.common.base.Predicate
import com.google.common.base.Predicates
import com.google.common.base.StandardSystemProperty
interface GradleRunner {
// These predicates are here, instead of on GradleRunnerFactory due to a Groovy static compiler bug
// https://issues.apache.org/jira/browse/GROOVY-7159
static final Predicate<URL> CLASSPATH_GRADLE_CACHE = new Predicate<URL>() {
@Override
boolean apply(URL url) {
return url.path.contains('/caches/modules-')
}
}
static final Predicate<URL> CLASSPATH_PROJECT_DIR = new Predicate<URL>() {
@Override
boolean apply(URL url) {
File userDir = new File(StandardSystemProperty.USER_DIR.value())
return url.path.startsWith(userDir.toURI().toURL().path)
}
}
static final Predicate<URL> CLASSPATH_PROJECT_DEPENDENCIES = new Predicate<URL>() {
@Override
boolean apply(URL url) {
return url.path.contains('/build/classes') ||
url.path.contains('/build/resources') ||
url.path.contains('/build/libs') ||
url.path.contains('/out/')
}
}
/**
* Attempts to provide a classpath that approximates the 'normal' Gradle runtime classpath. Use {@link #CLASSPATH_ALL}
* to default to pre-2.2.2 behaviour.
*/
static final Predicate<URL> CLASSPATH_DEFAULT =
Predicates.or(CLASSPATH_PROJECT_DIR, CLASSPATH_GRADLE_CACHE, CLASSPATH_PROJECT_DEPENDENCIES)
/**
* Accept all URLs. Provides pre-2.2.2 behaviour.
*/
static final Predicate<URL> CLASSPATH_ALL = new Predicate<URL>() {
@Override
boolean apply(URL url) {
return true
}
}
/**
* Create handle and run build
* @param directory
* @param args
* @return results from execution
*/
ExecutionResult run(File directory, List<String> args)
ExecutionResult run(File directory, List<String> args, List<String> jvmArgs)
ExecutionResult run(File directory, List<String> args, List<String> jvmArgs,
List<PreExecutionAction> preExecutionActions)
/**
* Handle on instance of Gradle that can be run.
* @param directory
* @param args
* @return handle
*/
GradleHandle handle(File directory, List<String> args)
GradleHandle handle(File directory, List<String> args, List<String> jvmArgs)
GradleHandle handle(File directory, List<String> args, List<String> jvmArgs,
List<PreExecutionAction> preExecutionActions)
}

View file

@ -0,0 +1,26 @@
package org.xbib.gradle.plugin.rpm
import com.google.common.base.Predicate
class GradleRunnerFactory {
static GradleRunner createTooling(boolean fork = false, String version = null,
Integer daemonMaxIdleTimeInSeconds = null,
Predicate<URL> classpathFilter = null) {
GradleHandleFactory toolingApiHandleFactory =
new ToolingApiGradleHandleFactory(fork, version, daemonMaxIdleTimeInSeconds)
return create(toolingApiHandleFactory, classpathFilter ?: GradleRunner.CLASSPATH_DEFAULT)
}
static GradleRunner create(GradleHandleFactory handleFactory, Predicate<URL> classpathFilter = null) {
ClassLoader sourceClassLoader = GradleRunnerFactory.class.getClassLoader()
create(handleFactory, sourceClassLoader, classpathFilter ?: GradleRunner.CLASSPATH_DEFAULT)
}
static GradleRunner create(GradleHandleFactory handleFactory, ClassLoader sourceClassLoader,
Predicate<URL> classpathFilter) {
GradleHandleFactory classpathInjectingHandleFactory =
new ClasspathInjectingGradleHandleFactory(sourceClassLoader, handleFactory, classpathFilter)
return new DefaultGradleRunner(classpathInjectingHandleFactory)
}
}

View file

@ -0,0 +1,185 @@
package org.xbib.gradle.plugin.rpm
import com.google.common.base.Predicate
import org.gradle.api.logging.LogLevel
abstract class IntegrationSpec extends BaseIntegrationSpec {
private static final String DEFAULT_REMOTE_DEBUG_JVM_ARGUMENTS = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
private static final Integer DEFAULT_DAEMON_MAX_IDLE_TIME_IN_SECONDS_IN_MEMORY_SAFE_MODE = 15;
private ExecutionResult result
protected String gradleVersion
protected LogLevel logLevel = LogLevel.INFO
protected String moduleName
protected File settingsFile
protected File buildFile
protected boolean fork = false
protected boolean remoteDebug = false
protected List<String> jvmArguments = []
protected Predicate<URL> classpathFilter
protected List<File> initScripts = []
protected List<PreExecutionAction> preExecutionActions = []
//Shutdown Gradle daemon after a few seconds to release memory. Useful for testing with multiple Gradle versions on shared CI server
protected boolean memorySafeMode = false
protected Integer daemonMaxIdleTimeInSecondsInMemorySafeMode = DEFAULT_DAEMON_MAX_IDLE_TIME_IN_SECONDS_IN_MEMORY_SAFE_MODE
private String findModuleName() {
getProjectDir().getName().replaceAll(/_\d+/, '')
}
def setup() {
moduleName = findModuleName()
if (!settingsFile) {
settingsFile = new File(getProjectDir(), 'settings.gradle')
settingsFile.text = "rootProject.name='${moduleName}'\n"
}
if (!buildFile) {
buildFile = new File(getProjectDir(), 'build.gradle')
}
buildFile << "// Running test for ${moduleName}\n"
}
protected GradleHandle launcher(String... args) {
List<String> arguments = calculateArguments(args)
List<String> jvmArguments = calculateJvmArguments()
Integer daemonMaxIdleTimeInSeconds = calculateMaxIdleDaemonTimeoutInSeconds()
GradleRunner runner = GradleRunnerFactory.createTooling(fork, gradleVersion, daemonMaxIdleTimeInSeconds, classpathFilter)
runner.handle(getProjectDir(), arguments, jvmArguments, preExecutionActions)
}
private List<String> calculateArguments(String... args) {
List<String> arguments = []
// Gradle will use these files name from the PWD, instead of the project directory. It's easier to just leave
// them out and let the default find them, since we're not changing their default names.
//arguments += '--build-file'
//arguments += (buildFile.canonicalPath - projectDir.canonicalPath).substring(1)
//arguments += '--settings-file'
//arguments += (settingsFile.canonicalPath - projectDir.canonicalPath).substring(1)
//arguments += '--no-daemon'
switch (getLogLevel()) {
case LogLevel.INFO:
arguments += '--info'
break
case LogLevel.DEBUG:
arguments += '--debug'
break
}
arguments += '--stacktrace'
arguments.addAll(args)
arguments.addAll(initScripts.collect { file -> '-I' + file.absolutePath })
arguments
}
private List<String> calculateJvmArguments() {
return jvmArguments + (remoteDebug ? [DEFAULT_REMOTE_DEBUG_JVM_ARGUMENTS] : [] as List) as List
}
private Integer calculateMaxIdleDaemonTimeoutInSeconds() {
return memorySafeMode ? daemonMaxIdleTimeInSecondsInMemorySafeMode : null
}
protected void addInitScript(File initFile) {
initScripts.add(initFile)
}
protected void addPreExecute(PreExecutionAction preExecutionAction) {
preExecutionActions.add(preExecutionAction)
}
/**
* Override to alter its value
* @return
*/
protected LogLevel getLogLevel() {
return logLevel
}
/*protected void copyResources(String srcDir, String destination) {
ClassLoader classLoader = getClass().getClassLoader();
URL resource = classLoader.getResource(srcDir);
if (resource == null) {
throw new RuntimeException("Could not find classpath resource: $srcDir")
}
File destinationFile = file(destination)
File resourceFile = new File(resource.toURI())
if (resourceFile.file) {
FileUtils.copyFile(resourceFile, destinationFile)
} else {
FileUtils.copyDirectory(resourceFile, destinationFile)
}
}*/
protected String applyPlugin(Class pluginClass) {
"apply plugin: $pluginClass.name"
}
/* Checks */
protected boolean fileExists(String path) {
new File(projectDir, path).exists()
}
@Deprecated
protected boolean wasExecuted(String taskPath) {
result.wasExecuted(taskPath)
}
@Deprecated
protected boolean wasUpToDate(String taskPath) {
result.wasUpToDate(taskPath)
}
@Deprecated
protected String getStandardError() {
result.standardError
}
@Deprecated
protected String getStandardOutput() {
result.standardOutput
}
protected ExecutionResult runTasksSuccessfully(String... tasks) {
ExecutionResult result = runTasks(tasks)
if (result.failure) {
result.rethrowFailure()
}
result
}
protected ExecutionResult runTasksWithFailure(String... tasks) {
ExecutionResult result = runTasks(tasks)
assert result.failure
result
}
protected ExecutionResult runTasks(String... tasks) {
ExecutionResult result = launcher(tasks).run()
this.result = result
return checkForDeprecations(result)
}
protected ExecutionResult checkForDeprecations(ExecutionResult result) {
checkForDeprecations(result.standardOutput)
return result
}
File getSettingsFile() {
return settingsFile
}
}

View file

@ -0,0 +1,20 @@
package org.xbib.gradle.plugin.rpm
class MinimalExecutedTask implements ExecutedTask {
String path
boolean upToDate
boolean skipped
MinimalExecutedTask(String path, boolean upToDate, boolean skipped) {
this.path = path
this.upToDate = upToDate
this.skipped = skipped
}
String toString() {
"executed $path"
}
}

View file

@ -0,0 +1,43 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
class MultiProjectHelper {
Project parent
MultiProjectHelper(Project parent) {
this.parent = parent
}
Map<String, MultiProjectInfo> create(Collection<String> projectNames) {
Map<String, MultiProjectInfo> info = [:]
projectNames.each {
def subproject = ProjectBuilder.builder().withName(it).withParent(parent).build()
info[it] = new MultiProjectInfo(name: it, project: subproject, parent: parent)
}
info
}
Map<String, MultiProjectInfo> createWithDirectories(Collection<String> projectNames) {
Map<String, MultiProjectInfo> info = [:]
projectNames.each {
def subDirectory = new File(parent.projectDir, it)
subDirectory.mkdirs()
def subproject = ProjectBuilder.builder().withName(it).withProjectDir(subDirectory).withParent(parent).build()
info[it] = new MultiProjectInfo(name: it, project: subproject, parent: parent, directory: subDirectory)
}
info
}
Project addSubproject(String name) {
ProjectBuilder.builder().withName(name).withParent(parent).build()
}
Project addSubprojectWithDirectory(String name) {
def dir = new File(parent.projectDir, name)
dir.mkdirs()
ProjectBuilder.builder().withName(name).withProjectDir(dir).withParent(parent).build()
}
}

View file

@ -0,0 +1,14 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.api.Project
class MultiProjectInfo {
String name
Project parent
Project project
File directory
}

View file

@ -0,0 +1,6 @@
package org.xbib.gradle.plugin.rpm
interface PreExecutionAction {
void execute(File projectDir, List<String> arguments, List<String> jvmArguments)
}

View file

@ -0,0 +1,8 @@
package org.xbib.gradle.plugin.rpm
class ProjectSpec extends AbstractProjectSpec {
File getProjectDir() {
ourProjectDir
}
}

View file

@ -0,0 +1,50 @@
package org.xbib.gradle.plugin.rpm
import org.junit.Before
import org.junit.Test
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertTrue
class RpmCopySpecVisitorTest extends ProjectSpec {
RpmCopyAction visitor
@Before
void setup() {
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
Rpm rpmTask = project.task('buildRpm', type: Rpm) {
packageName = 'can-execute-rpm-task-with-valid-version'
}
visitor = new RpmCopyAction(rpmTask)
}
@Test
void withoutUtils() {
visitor.includeStandardDefines = false
File script = resourceFile("script.sh")
Object result = visitor.scriptWithUtils([], [script])
assertTrue result instanceof String
assertEquals(
"#!/bin/bash\n" +
"hello\n", result)
}
@Test
void withUtils() {
visitor.includeStandardDefines = false
Object result = visitor.scriptWithUtils([resourceFile("utils.sh")], [resourceFile("script.sh")])
assertTrue result instanceof String
assertEquals(
"#!/bin/bash\n" +
"function hello() {\n" +
" echo 'Hello, world.'\n" +
"}\n" +
"hello\n", result)
}
File resourceFile(String name) {
new File(getClass().getResource(name).getPath())
}
}

View file

@ -0,0 +1,26 @@
package org.xbib.gradle.plugin.rpm
class RpmPluginIntegrationTest extends IntegrationSpec {
def "rpm task is marked up-to-date when setting arch or os property"() {
given:
buildFile << '''
apply plugin: 'org.xbib.gradle.plugin.rpm'
task buildRpm(type: Rpm) {
packageName = 'rpmIsUpToDate'
arch = NOARCH
os = LINUX
}
'''
when:
runTasksSuccessfully('buildRpm')
and:
def result = runTasksSuccessfully('buildRpm')
then:
result.wasUpToDate(':buildRpm')
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,131 @@
package org.xbib.gradle.plugin.rpm
import groovy.transform.Canonical
import org.xbib.io.compress.bzip2.Bzip2InputStream
import org.xbib.io.compress.xz.XZInputStream
import org.xbib.rpm.header.Header
import org.xbib.rpm.header.HeaderTag
import org.xbib.rpm.header.entry.SpecEntry
import org.xbib.rpm.io.ChannelWrapper
import org.xbib.rpm.io.ReadableChannelWrapper
import org.xbib.rpm.format.Format
import org.xbib.rpm.payload.CompressionType
import org.xbib.rpm.payload.CpioHeader
import org.spockframework.util.Nullable
import java.nio.ByteBuffer
import java.nio.CharBuffer
import java.nio.channels.Channels
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets
import java.nio.file.Path
import java.util.zip.GZIPInputStream
import static org.xbib.rpm.header.HeaderTag.HEADERIMMUTABLE
import static org.xbib.rpm.signature.SignatureTag.SIGNATURES
import static org.junit.Assert.assertEquals
/**
*
*/
class RpmReader {
@Canonical
static class ReaderResult {
Format format
List<ReaderFile> files
}
@Canonical
static class ReaderFile {
@Delegate
CpioHeader header
@Nullable
ByteBuffer contents
String asString() {
if (contents == null ) {
return null
}
Charset charset = StandardCharsets.UTF_8
CharBuffer buffer = charset.decode(contents)
return buffer.toString()
}
}
static ReaderResult read(Path path) throws Exception {
ReaderResult readerResult = null
path.withInputStream { InputStream inputStream ->
readerResult = read(inputStream)
}
readerResult
}
static ReaderResult read(InputStream inputStream, boolean includeContents = true) {
ReadableChannelWrapper wrapper = new ReadableChannelWrapper(Channels.newChannel(inputStream))
Format format = readHeader(wrapper)
InputStream uncompressed = createUncompressedStream(format.getHeader(), inputStream)
wrapper = new ReadableChannelWrapper(Channels.newChannel(uncompressed))
CpioHeader header = null
def files = []
int total = 0
while (header == null || !header.isLast()) {
header = new CpioHeader()
total = header.read(wrapper, total)
final int fileSize = header.getFileSize()
boolean includingContents = includeContents && header.type == CpioHeader.FILE
if (!header.isLast()) {
ByteBuffer descriptor = includingContents ? ChannelWrapper.fill(wrapper, fileSize) : null
files += new ReaderFile(header, descriptor)
}
if (!includingContents) {
assertEquals(fileSize, uncompressed.skip(fileSize))
}
total += fileSize
}
return new ReaderResult(format,files)
}
static InputStream createUncompressedStream(Header header, InputStream inputStream) {
InputStream compressedInput = inputStream
SpecEntry<?> pcEntry = header.getEntry(HeaderTag.PAYLOADCOMPRESSOR)
String[] pc = (String[]) pcEntry.getValues()
CompressionType compressionType = CompressionType.valueOf(pc[0].toUpperCase())
switch (compressionType) {
case CompressionType.NONE:
break
case CompressionType.GZIP:
compressedInput = new GZIPInputStream(inputStream)
break
case CompressionType.BZIP2:
compressedInput = new Bzip2InputStream(inputStream)
break
case CompressionType.XZ:
compressedInput = new XZInputStream(inputStream)
break
}
compressedInput
}
static Format readHeader(ReadableChannelWrapper wrapper) throws Exception {
Format format = new Format()
format.getLead().read(wrapper)
int count = format.signatureHeader.read(wrapper)
int expected = ByteBuffer.wrap(format.signatureHeader.getEntry(SIGNATURES).values, 8, 4).getInt() / -16
assertEquals(expected, count)
count = format.getHeader().read(wrapper)
expected = ByteBuffer.wrap(format.getHeader().getEntry(HEADERIMMUTABLE).values, 8, 4).getInt() / -16
assertEquals(expected, count)
return format
}
def static getHeaderEntry(ReaderResult res, tag) {
def header = res.format.header
header.getEntry(tag.code)
}
def static getHeaderEntryString(ReaderResult res, tag) {
getHeaderEntry(res, tag)?.values?.join('')
}
}

View file

@ -0,0 +1,77 @@
package org.xbib.gradle.plugin.rpm
import spock.lang.Specification
import java.nio.file.Paths
class SystemPackagingExtensionTest extends Specification {
SystemPackagingExtension extension = new SystemPackagingExtension()
def "Can define required package name without version and flag"() {
given:
String packageName = 'myPackage'
when:
extension.requires(packageName)
then:
extension.dependencies.size() == 1
Dependency dep = extension.dependencies[0]
dep.packageName == packageName
dep.version == ''
dep.flag == 0
}
def "Can define required package name with version and without flag"(){
given:
String packageName = 'myPackage'
when:
extension.requires(packageName, '1.0.0')
then:
extension.dependencies.size() == 1
Dependency dep = extension.dependencies[0]
dep.packageName == packageName
dep.version == '1.0.0'
dep.flag == 0
}
def "Can define required package name with version and flag"() {
given:
String packageName = 'myPackage'
when:
extension.requires(packageName, '1.0.0', 5)
then:
extension.dependencies.size() == 1
Dependency dep = extension.dependencies[0]
dep.packageName == packageName
dep.version == '1.0.0'
dep.flag == 5
}
def "Cannot define required package name containing comma without version and flag"() {
given:
String packageName = 'myPackage,something'
when:
extension.requires(packageName)
then:
Throwable t = thrown(IllegalArgumentException)
}
def "Cannot define required package name containing comma with version and flag"() {
given:
String packageName = 'myPackage,something'
when:
extension.requires(packageName, '1.0.0', 5)
then:
Throwable t = thrown(IllegalArgumentException)
}
}

View file

@ -0,0 +1,113 @@
package org.xbib.gradle.plugin.rpm
import org.gradle.tooling.BuildLauncher
import org.gradle.tooling.GradleConnector
import org.gradle.tooling.ProjectConnection
import java.util.concurrent.TimeUnit
class ToolingApiGradleHandleFactory implements GradleHandleFactory {
private final boolean fork
private final String version
private final Integer daemonMaxIdleTimeInSeconds
ToolingApiGradleHandleFactory(boolean fork, String version, Integer daemonMaxIdleTimeInSeconds = null) {
this.fork = fork
this.version = version
this.daemonMaxIdleTimeInSeconds = daemonMaxIdleTimeInSeconds
}
@Override
GradleHandle start(File projectDir, List<String> arguments, List<String> jvmArguments = []) {
GradleConnector connector = createGradleConnector(projectDir)
boolean forkedProcess = isForkedProcess()
connector.embedded(!forkedProcess)
if (daemonMaxIdleTimeInSeconds != null) {
connector.daemonMaxIdleTime(daemonMaxIdleTimeInSeconds, TimeUnit.SECONDS)
}
ProjectConnection connection = connector.connect();
BuildLauncher launcher = createBuildLauncher(connection, arguments, jvmArguments)
createGradleHandle(connection, launcher, forkedProcess)
}
private GradleConnector createGradleConnector(File projectDir) {
GradleConnector connector = GradleConnector.newConnector();
connector.forProjectDirectory(projectDir);
configureGradleVersion(connector, projectDir)
connector
}
private void configureGradleVersion(GradleConnector connector, File projectDir) {
if (version != null) {
connector.useGradleVersion(version)
} else {
configureWrapperDistributionIfUsed(connector, projectDir)
}
}
private static void configureWrapperDistributionIfUsed(GradleConnector connector, File projectDir) {
File target = projectDir.absoluteFile
while (target != null) {
URI distribution = prepareDistributionURI(target)
if (distribution) {
connector.useDistribution(distribution)
return
}
target = target.parentFile
}
}
private static URI prepareDistributionURI(File target) {
File propertiesFile = new File(target, "gradle/wrapper/gradle-wrapper.properties")
if (propertiesFile.exists()) {
Properties properties = new Properties()
propertiesFile.withInputStream {
properties.load(it)
}
URI source = new URI(properties.getProperty("distributionUrl"))
return source.getScheme() == null ? (new File(propertiesFile.getParentFile(), source.getSchemeSpecificPart())).toURI() : source;
}
return null
}
private boolean isForkedProcess() {
fork
}
private static BuildLauncher createBuildLauncher(ProjectConnection connection, List<String> arguments,
List<String> jvmArguments) {
BuildLauncher launcher = connection.newBuild();
launcher.withArguments(arguments as String[]);
launcher.setJvmArguments(jvmArguments as String[])
launcher
}
private GradleHandle createGradleHandle(ProjectConnection connection, BuildLauncher launcher, boolean forkedProcess) {
GradleHandleBuildListener toolingApiBuildListener =
new ToolingApiBuildListener(connection)
BuildLauncherBackedGradleHandle buildLauncherBackedGradleHandle =
new BuildLauncherBackedGradleHandle(launcher, forkedProcess)
buildLauncherBackedGradleHandle.registerBuildListener(toolingApiBuildListener)
buildLauncherBackedGradleHandle
}
private class ToolingApiBuildListener implements GradleHandleBuildListener {
private final ProjectConnection connection
ToolingApiBuildListener(ProjectConnection connection) {
this.connection = connection
}
@Override
void buildStarted() {
}
@Override
void buildFinished() {
connection.close()
}
}
}

View file

@ -0,0 +1,12 @@
package org.xbib.gradle.plugin.rpm
/**
* Hold additional response data, that is only available
*/
class ToolingExecutionResult extends DefaultExecutionResult {
ToolingExecutionResult(Boolean success, String standardOutput, String standardError,
List<MinimalExecutedTask> executedTasks, Throwable failure) {
super(success, standardOutput, standardError, executedTasks, failure)
}
}

View file

@ -0,0 +1,35 @@
package org.xbib.gradle.plugin.rpm.validation
import spock.lang.Specification
import spock.lang.Unroll
class RpmPackageNameAttributeValidatorTest extends Specification {
RpmPackageNameAttributeValidator validator = new RpmPackageNameAttributeValidator()
@Unroll
def "verifies #description: '#attribute'"() {
when:
boolean valid = validator.validate(attribute)
then:
valid == result
where:
attribute | result | description
'a25b' | true | 'valid package name with mixed alphanumeric characters'
'my.awesome.package' | true | 'package with dot characters'
'my-awesome-package' | true | 'package with dash characters'
'my_awesome_package' | true | 'package with underscore characters'
'My-Awesome-Package' | true | 'package with upper case characters'
'abc^' | false | 'package name with an invalid character'
}
def "provide error message"() {
when:
String errorMessage = validator.getErrorMessage('abc^')
then:
errorMessage == "Invalid package name 'abc^' - a valid package name must only contain [a-zA-Z0-9-._+]"
}
}

View file

@ -0,0 +1,41 @@
package org.xbib.gradle.plugin.rpm.validation
import org.gradle.api.InvalidUserDataException
import org.xbib.gradle.plugin.rpm.ProjectSpec
import org.xbib.gradle.plugin.rpm.Rpm
class RpmTaskPropertiesValidatorIntegrationTest extends ProjectSpec {
RpmTaskPropertiesValidator validator = new RpmTaskPropertiesValidator()
def setup() {
project.apply plugin: 'org.xbib.gradle.plugin.rpm'
}
def 'can execute Rpm task with valid version and package name'() {
given:
Rpm rpmTask = project.task('buildRpm', type: Rpm) {
packageName = 'can-execute-rpm-task-with-valid-version'
}
when:
validator.validate(rpmTask)
then:
noExceptionThrown()
}
def 'executing a Rpm task with invalid package name throws exception'() {
given:
Rpm rpmTask = project.task('buildRpm', type: Rpm) {
packageName = 'abc^'
}
when:
validator.validate(rpmTask)
then:
Throwable t = thrown(InvalidUserDataException)
t.message == "Invalid package name 'abc^' - a valid package name must only contain [a-zA-Z0-9-._+]"
}
}

15
gradle.properties Normal file
View file

@ -0,0 +1,15 @@
group = org.xbib
name = rpm
version = 1.0.0
bouncycastle.version = 1.57
xbib-archive.version = 0.0.1
ant.version = 1.10.1
log4j.version = 2.8.2
junit.version = 4.12
wagon.version = 2.12
groovy.version = 2.4.11
spock-core.version = 1.1-groovy-2.4
xbib-guice.version = 4.0.4
maven.version = 3.5.0
mvel.version = 2.3.2.Final

8
gradle/ext.gradle Normal file
View file

@ -0,0 +1,8 @@
ext {
user = 'xbib'
projectName = 'rpm'
projectDescription = 'Java 8 RPM implementation with plugins for Ant, Maven, Gradle'
scmUrl = 'https://github.com/xbib/rpm'
scmConnection = 'scm:git:git://github.com/xbib/rpm.git'
scmDeveloperConnection = 'scm:git:git://github.com/xbib/rpm.git'
}

67
gradle/publish.gradle Normal file
View file

@ -0,0 +1,67 @@
task xbibUpload(type: Upload) {
configuration = configurations.archives
uploadDescriptor = true
repositories {
if (project.hasProperty('xbibUsername')) {
mavenDeployer {
configuration = configurations.wagon
repository(url: uri('sftp://xbib.org/repository')) {
authentication(userName: xbibUsername, privateKey: xbibPrivateKey)
}
}
}
}
}
task sonatypeUpload(type: Upload) {
configuration = configurations.archives
uploadDescriptor = true
repositories {
if (project.hasProperty('ossrhUsername')) {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
repository(url: uri(ossrhReleaseUrl)) {
authentication(userName: ossrhUsername, password: ossrhPassword)
}
snapshotRepository(url: uri(ossrhSnapshotUrl)) {
authentication(userName: ossrhUsername, password: ossrhPassword)
}
pom.project {
name projectName
description projectDescription
packaging 'jar'
inceptionYear '2017'
url scmUrl
organization {
name 'xbib'
url 'http://xbib.org'
}
developers {
developer {
id user
name 'Jörg Prante'
email 'joergprante@gmail.com'
url 'https://github.com/jprante'
}
}
scm {
url scmUrl
connection scmConnection
developerConnection scmDeveloperConnection
}
licenses {
license {
name 'The Apache License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
}
}
}
}
}
nexusStaging {
packageGroup = "org.xbib"
}

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,6 @@
#Wed Oct 04 23:29:00 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.2-all.zip

172
gradlew vendored Executable file
View file

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || 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
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
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=$((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
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
gradlew.bat vendored Normal file
View file

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
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
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%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
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

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,72 @@
configurations {
mavenEmbedder
}
dependencies {
compile project(':rpm-core')
compile "org.mvel:mvel2:${project.property('mvel.version')}"
compile "org.apache.ant:ant:${project.property('ant.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:3.5'
testCompile "org.apache.maven:maven-core:${project.property('maven.version')}"
testCompile "org.apache.maven:maven-plugin-api:${project.property('maven.version')}"
testCompile 'org.apache.maven.plugin-tools:maven-plugin-annotations:3.5'
mavenEmbedder "org.apache.maven:maven-embedder:${project.property('maven.version')}"
mavenEmbedder 'org.slf4j:slf4j-simple:1.7.5'
mavenEmbedder 'org.apache.maven.wagon:wagon-http:2.12:shaded'
mavenEmbedder 'org.apache.maven.wagon:wagon-provider-api:2.12'
mavenEmbedder 'org.eclipse.aether:aether-connector-basic:1.0.2.v20150114'
mavenEmbedder 'org.eclipse.aether:aether-transport-wagon:1.0.2.v20150114'
}
test {
testLogging {
showStandardStreams = false
exceptionFormat = 'full'
}
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', '../config/maven/repo-settings.xml',
'--file', "${buildDir}/pom.xml",
"org.apache.maven.plugins:maven-plugin-plugin:3.5: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,323 @@
<?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="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="groups" value="com.google,android,junit,net,org,java,javax"/>
<!-- This ensures that static imports go first. -->
<property name="option" value="top"/>
<property name="tokens" value="STATIC_IMPORT, IMPORT"/>
</module>
<!--
JAVADOC CHECKS
-->
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="protected"/>
<property name="severity" value="warning"/>
<property name="allowMissingJavadoc" value="true"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
<property name="allowUndeclaredRTE" 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="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 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>

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,
getDirectives(), owner, group);
}
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,46 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.Assert.assertEquals;
import org.junit.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.Before;
import org.xbib.maven.plugin.rpm.mojo.PackageRpmMojo;
import java.io.File;
/**
*
*/
public class RpmLinkTest extends RpmBaseObjectTest {
private RpmLink rpmLink;
@Before
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.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
/**
*
*/
public class RpmPackageAssociationTest {
private RpmPackageAssociation association;
@Before
public void setUp() {
association = new RpmPackageAssociation();
}
@Test
public void nameAccessors() {
assertEquals(null, association.getName());
association.setName("testname");
assertEquals("testname", association.getName());
}
@Test
public void unassignedVersion() {
assertEquals(null, association.getVersion());
assertEquals(null, association.getMinVersion());
assertEquals(null, association.getMaxVersion());
}
@Test
public void latestVersion() {
association.setVersion(null);
assertEquals(null, association.getVersion());
assertEquals(null, association.getMinVersion());
assertEquals(null, association.getMaxVersion());
association.setVersion("");
assertEquals(null, association.getVersion());
assertEquals(null, association.getMinVersion());
assertEquals(null, association.getMaxVersion());
association.setVersion("RELEASE");
assertEquals(null, association.getVersion());
assertEquals(null, association.getMinVersion());
assertEquals(null, association.getMaxVersion());
}
@Test
public void specificVersion() {
association.setVersion("1.2.3");
assertEquals("1.2.3", association.getVersion());
assertEquals(null, association.getMinVersion());
assertEquals(null, association.getMaxVersion());
}
@Test
public void minVersionRange() {
association.setVersion("[1.2.3,)");
assertEquals(null, association.getVersion());
assertEquals("1.2.3", association.getMinVersion());
assertEquals(null, association.getMaxVersion());
}
@Test
public void maxVersionRange() {
association.setVersion("[,1.2.3)");
assertEquals(null, association.getVersion());
assertEquals(null, association.getMinVersion());
assertEquals("1.2.3", association.getMaxVersion());
}
@Test
public void minMaxVersionRange() {
association.setVersion("[1.2.3,1.2.5)");
assertEquals(null, association.getVersion());
assertEquals("1.2.3", association.getMinVersion());
assertEquals("1.2.5", association.getMaxVersion());
}
}

View file

@ -0,0 +1,136 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.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,153 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
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.Before;
import org.junit.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;
@Before
public void setUp() throws Exception {
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("build");
}
@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("");
assertEquals(null, rpmFileRule.getDestination());
rpmFileRule.setDestination(null);
assertEquals(null, 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%sbuild", 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(63, files.length);
}
@Test(expected = PathOutsideBuildPathException.class)
public void testListFilesOutsideBuildPath() throws RpmException {
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(63, files.length);
assertEquals(94, builder.getContents().size());
}
}

View file

@ -0,0 +1,410 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.apache.maven.model.Build;
import org.apache.maven.project.MavenProject;
import org.junit.Before;
import org.junit.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;
@Before
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%sbuild", 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() {
assertEquals(null, rpmPackage.getUrl());
rpmPackage.setUrl("http://www.example.com/foo");
assertEquals("http://www.example.com/foo", rpmPackage.getUrl());
}
@Test
public void groupAccessors() {
assertEquals(null, rpmPackage.getGroup());
rpmPackage.setGroup("group/subgroup");
assertEquals("group/subgroup", rpmPackage.getGroup());
}
@Test
public void licenseAccessors() {
assertEquals(null, rpmPackage.getLicense());
rpmPackage.setLicense("license");
assertEquals("license", rpmPackage.getLicense());
}
@Test
public void summaryAccessors() {
assertEquals(null, rpmPackage.getSummary());
rpmPackage.setSummary("summary");
assertEquals("summary", rpmPackage.getSummary());
}
@Test
public void descriptionAccessors() {
assertEquals(null, rpmPackage.getDescription());
rpmPackage.setDescription("description");
assertEquals("description", rpmPackage.getDescription());
}
@Test
public void distributionAccessors() {
assertEquals(null, 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(expected = UnknownArchitectureException.class)
public void architectureInvalidException() throws UnknownArchitectureException {
rpmPackage.setArchitecture("NONEXISTENT");
}
@Test(expected = UnknownArchitectureException.class)
public void architectureBlankException() throws UnknownArchitectureException {
rpmPackage.setArchitecture("");
}
@Test(expected = UnknownArchitectureException.class)
public void architectureNullException() throws UnknownArchitectureException {
rpmPackage.setArchitecture(null);
}
@Test
public void operatingSystemAccessors() throws UnknownOperatingSystemException {
assertEquals(Os.LINUX, rpmPackage.getOperatingSystem());
rpmPackage.setOperatingSystem("LINUX390");
assertEquals(Os.LINUX390, rpmPackage.getOperatingSystem());
}
@Test(expected = UnknownOperatingSystemException.class)
public void operatingSystemInvalidException() throws UnknownOperatingSystemException {
rpmPackage.setOperatingSystem("NONEXISTENT");
}
@Test(expected = UnknownOperatingSystemException.class)
public void operatingSystemBlankException() throws UnknownOperatingSystemException {
rpmPackage.setOperatingSystem("");
}
@Test(expected = UnknownOperatingSystemException.class)
public void operatingSystemNullException() throws UnknownOperatingSystemException {
rpmPackage.setOperatingSystem(null);
}
@Test
public void buildHostNameAccessors() throws Exception {
assertNotNull(rpmPackage.getBuildHostName());
rpmPackage.setBuildHostName("buildhost");
assertEquals("buildhost", rpmPackage.getBuildHostName());
}
@Test
public void packagerAccessors() {
assertEquals(null, rpmPackage.getPackager());
rpmPackage.setPackager("packager");
assertEquals("packager", rpmPackage.getPackager());
}
@Test
public void attachAccessors() {
assertEquals(true, rpmPackage.isAttach());
rpmPackage.setAttach(false);
assertEquals(false, rpmPackage.isAttach());
}
@Test
public void classifierAccessors() {
assertEquals(null, 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");
// pre transaction
assertEquals(null, rpmPackage.getPreTransactionScriptPath());
rpmPackage.setPreTransactionScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPreTransactionScriptPath());
assertEquals(null, rpmPackage.getPreTransactionProgram());
rpmPackage.setPreTransactionProgram("/bin/sh");
assertEquals("/bin/sh", rpmPackage.getPreTransactionProgram());
// pre install
assertEquals(null, rpmPackage.getPreInstallScriptPath());
rpmPackage.setPreInstallScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPreInstallScriptPath());
assertEquals(null, rpmPackage.getPreInstallProgram());
rpmPackage.setPreInstallProgram("/bin/sh");
assertEquals("/bin/sh", rpmPackage.getPreInstallProgram());
assertEquals(null, rpmPackage.getPostInstallScriptPath());
rpmPackage.setPostInstallScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPostInstallScriptPath());
assertEquals(null, rpmPackage.getPostInstallProgram());
rpmPackage.setPostInstallProgram("/bin/sh");
assertEquals("/bin/sh", rpmPackage.getPostInstallProgram());
assertEquals(null, rpmPackage.getPreUninstallScriptPath());
rpmPackage.setPreUninstallScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPreUninstallScriptPath());
assertEquals(null, rpmPackage.getPreUninstallProgram());
rpmPackage.setPreUninstallProgram("/bin/sh");
assertEquals("/bin/sh", rpmPackage.getPreUninstallProgram());
assertEquals(null, rpmPackage.getPostUninstallScriptPath());
rpmPackage.setPostUninstallScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPostUninstallScriptPath());
assertEquals(null, rpmPackage.getPostUninstallProgram());
rpmPackage.setPostUninstallProgram("/bin/sh");
assertEquals("/bin/sh", rpmPackage.getPostUninstallProgram());
assertEquals(null, rpmPackage.getPostTransactionScriptPath());
rpmPackage.setPostTransactionScriptPath(scriptFile);
assertEquals(scriptFile, rpmPackage.getPostTransactionScriptPath());
assertEquals(null, 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() {
assertEquals(null, rpmPackage.getSigningKey());
rpmPackage.setSigningKey("key");
assertEquals("key", rpmPackage.getSigningKey());
assertEquals(null, rpmPackage.getSigningKeyId());
rpmPackage.setSigningKeyId(0L);
assertEquals(new Long(0L), rpmPackage.getSigningKeyId());
assertEquals(null, 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());
assertEquals(true, 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());
assertEquals(true, 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());
assertEquals(true, 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());
assertEquals(true, 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());
assertEquals(true, new File(rpmFileName).exists());
}
}

View file

@ -0,0 +1,62 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.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;
@Before
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,50 @@
package org.xbib.maven.plugin.rpm;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.junit.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,172 @@
package org.xbib.maven.plugin.rpm.mojo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.apache.maven.model.Build;
import org.apache.maven.model.License;
import org.apache.maven.project.MavenProject;
import org.junit.Before;
import org.junit.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;
@Before
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");
//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 (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%sbuild", testOutputPath, File.separator));
mojo.scanMasterFiles();
Set<String> masterFiles = mojo.getMasterFiles();
assertEquals(65, 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.Before;
import org.junit.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;
@Before
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%sbuild", 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,112 @@
package org.xbib.maven.plugin.rpm.mojo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.apache.maven.model.Build;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.junit.Before;
import org.junit.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;
@Before
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("uk.co.codezen");
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%sbuild", 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();
assertEquals(true, 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(expected = MojoExecutionException.class)
public void packageRpmMissedFiles() throws MojoExecutionException {
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(expected = MojoExecutionException.class)
public void packageRpmNoFilesPackaged() throws MojoExecutionException {
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,2 @@
@{project.artifactId}
@{project.version}

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