Skip to content

Commit

Permalink
Use list of base directories for which intermediate directories shoul…
Browse files Browse the repository at this point in the history
…d be generated
  • Loading branch information
moedan committed Feb 26, 2024
1 parent a7a69a3 commit 2e22458
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 40 deletions.
141 changes: 141 additions & 0 deletions src/it/test19-intermediate-directories/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>de.dentrassi.maven.rpm.test</groupId>
<artifactId>test19</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Test Package #19</name>
<description>
Test explicitly adding and applying rules for implicitly created intermediate directories.
</description>

<url>http://dentrassi.de</url>

<organization>
<name>Jens Reimann</name>
<url>http://dentrassi.de</url>
</organization>

<licenses>
<license>
<name>Eclipse Public License - v 1.0</name>
<distribution>repo</distribution>
<url>https://www.eclipse.org/legal/epl-v10.html</url>
</license>
</licenses>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<skipSigning>true</skipSigning>
<!-- use a predictable timestamp -->
<project.build.outputTimestamp>2009-01-01T12:00:00+01:00</project.build.outputTimestamp>
</properties>

<build>

<plugins>
<plugin>
<groupId>de.dentrassi.maven</groupId>
<artifactId>rpm</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>rpm</goal>
</goals>
<configuration>
<attach>false</attach>
<group>Application/Misc</group>

<signature>
<keyId>${keyId}</keyId>
<keyringFile>${user.home}/.gnupg/secring.gpg</keyringFile>
<passphrase>${passphrase}</passphrase>
<hashAlgorithm>SHA1</hashAlgorithm>
<skip>${skipSigning}</skip>
</signature>

<generateIntermediateDirectories>
<baseDirectory>/etc/mycompany/myapp</baseDirectory>
<baseDirecotry>/opt/mycompany/myapp</baseDirecotry>
</generateIntermediateDirectories>

<rulesets>
<ruleset>
<id>my-default</id>
<rules>
<rule>
<when>
<prefix>/opt/mycompany</prefix>
</when>
<user>mygeneraluser</user>
<group>mygeneralgroup</group>
<mode>0111</mode>
</rule>
<rule>
<when>
<prefix>/opt/mycompany/myapp</prefix>
</when>
<user>myuser</user>
<group>mygroup</group>
<mode>0555</mode>
</rule>
<rule>
<when>
<prefix>/opt/mycompany/myapp</prefix>
<type>directory</type>
</when>
<mode>0777</mode>
</rule>
</rules>
</ruleset>
</rulesets>

<entries>
<entry>
<name>/opt/mycompany/myapp/a/b/c/foobar</name>
<file>${project.basedir}/src/main/data/foobar</file>
<ruleset>my-default</ruleset>
</entry>
<entry>
<name>/opt/mycompany/myapp</name>
<directory>true</directory>
<ruleset>my-default</ruleset>
</entry>
<entry>
<name>/etc/mycompany/myapp/defaults</name>
<directory>true</directory>
<ruleset>my-default</ruleset>
</entry>
<entry>
<name>/opt/mycompany/otherapp/a/b/c/foobar</name>
<file>${project.basedir}/src/main/data/foobar</file>
<ruleset>my-default</ruleset>
</entry>
</entries>

</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>sign</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<skipSigning>false</skipSigning>
</properties>
</profile>
</profiles>

</project>
Empty file.
24 changes: 24 additions & 0 deletions src/it/test19-intermediate-directories/verify.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
def dump() {
Process proc = ('rpm -q --dump -p ' + basedir + "/target/*.rpm").execute()
return proc.in.getText().trim()
}

def actual = dump()
println "Dump:\n" + actual

def expected = """\
/etc/mycompany/myapp 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040755 root root 0 0 0 X
/etc/mycompany/myapp/defaults 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040755 root root 0 0 0 X
/opt/mycompany/myapp 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/a 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/a/b 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/a/b/c 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/a/b/c/foobar 0 1230807600 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0100555 myuser mygroup 0 0 0 X
/opt/mycompany/otherapp/a/b/c/foobar 0 1230807600 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0100111 mygeneraluser mygeneralgroup 0 0 0 X""".stripIndent()

if (actual != expected) {
System.out.format("RPM dump doesn't match - actual:%n%s%nexpected:%n%s%n", actual, expected);
return false;
}

return true;
36 changes: 20 additions & 16 deletions src/main/java/de/dentrassi/rpm/builder/MissingDirectoryTracker.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@

public class MissingDirectoryTracker implements BuilderContextListener {

// keep track of explicit added directories
private final Set<String> explicitAddedDirectories;
// keep track of all missing directories which should be added after processing (without explicit added directories)
private final Map<String, FileInformationProvider<Object>> missingDirectories;
private final List<String> ignorePrefixes;
// base directories (prefixes) for which the intermediate directories should be generated
private final List<String> baseDirectories;

public MissingDirectoryTracker(List<String> ignorePrefixes) {
public MissingDirectoryTracker(List<String> baseDirectories) {
this.explicitAddedDirectories = new HashSet<>();
this.missingDirectories = new HashMap<>();
this.ignorePrefixes = ignorePrefixes;
this.baseDirectories = baseDirectories;
}

@Override
Expand All @@ -53,23 +56,25 @@ public void notifySymbolicLinkAdded(String targetName, FileInformationProvider<O
}

private void addMissingDirectoriesFromPath(String targetName, FileInformationProvider<Object> provider) {
for (String intermediateDirectory : getIntermediateDirectories(targetName)) {
if (!shouldDirectoryIgnored(intermediateDirectory) && !explicitAddedDirectories.contains(intermediateDirectory)) {
if (provider instanceof MojoFileInformationProvider) {
MojoFileInformationProvider mojoProvider = (MojoFileInformationProvider) provider;
missingDirectories.computeIfAbsent(intermediateDirectory, k -> new MojoFileInformationProvider(mojoProvider.getRulesetEval(), mojoProvider.getRuleId(), null, mojoProvider.getLogger(), mojoProvider.getTimestamp()));
if (provider instanceof MojoFileInformationProvider) {
MojoFileInformationProvider mojoProvider = (MojoFileInformationProvider) provider;

for (String intermediateDirectory : getIntermediateDirectories(targetName)) {
if (startsPathWithPrefix(intermediateDirectory) && !explicitAddedDirectories.contains(intermediateDirectory)) {
missingDirectories.computeIfAbsent(intermediateDirectory,
(String directory) -> new MojoFileInformationProvider(
mojoProvider.getRulesetEval(),
mojoProvider.getRuleId(),
null,
mojoProvider.getLogger(),
mojoProvider.getTimestamp()));
}
}
}
}

private boolean shouldDirectoryIgnored(String directory) {
for (String ignorePrefix : ignorePrefixes) {
if (ignorePrefix.startsWith(directory)) {
return true;
}
}
return false;
private boolean startsPathWithPrefix(String directory) {
return baseDirectories.stream().anyMatch(directory::startsWith);
}

public void addMissingIntermediateDirectoriesToContext(BuilderContext ctx) throws IOException {
Expand All @@ -90,5 +95,4 @@ private List<String> getIntermediateDirectories(String targetName) {
return intermediateDirectories;
}


}
51 changes: 27 additions & 24 deletions src/main/java/de/dentrassi/rpm/builder/RpmMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -208,28 +208,6 @@ public void setGenerateDefaultSourcePackage(final boolean generateDefaultSourceP
this.generateDefaultSourcePackage = generateDefaultSourcePackage;
}

/**
* Whether implicitly created intermediate directories should explicitly
* added to package.
* <p>
* If enabled, all from entries implicitly created intermediate directories
* are added as explicit entries to package. Also the rules with file
* information are applied to these directories.
* </p>
* <p>
* To exclude directories like {@code /usr} from being added, you have
* to add these as prefix property (see {@code prefixes}). Directories
* that match a whole prefix or a sub path of it, are not added.
* </p>
*/
@Parameter(property = "rpm.generateIntermediateDirectories", defaultValue = "true")
boolean generateIntermediateDirectories = true;

public void setGenerateIntermediateDirectories(final boolean generateIntermediateDirectories) {
this.generateIntermediateDirectories = generateIntermediateDirectories;
}


/**
* The prefix of the release if this is a snapshot build, will be suffixed
* with the snapshot build id
Expand Down Expand Up @@ -388,6 +366,31 @@ public void setGenerateIntermediateDirectories(final boolean generateIntermediat
@Parameter(property = "rpm.prefixes")
List<String> prefixes;

/**
* Base paths for which implicitly created intermediate directories should
* explicitly added to package.
*
* <pre>
* &lt;generateIntermediateDirectories&gt;
* &lt;baseDirectory&gt;/opt/mycompany/myapp&lt;/baseDirectory&gt;
* &lt;baseDirectory&gt;/etc/mycompany&lt;/baseDirectory&gt;
* &lt;/generateIntermediateDirectories&gt;
* </pre>
*
* <p>
* For given base directories, all from entries implicitly created
* intermediate directories are added as explicit entries to package.
* Also the rules with file information are applied to these added directories.
* </p>
* <p>
* To exclude directories like {@code /usr} from being added, you have
* to add these as prefix property (see {@code prefixes}). Directories
* that match a whole prefix or a sub path of it, are not added.
* </p>
*/
@Parameter(property = "rpm.generateIntermediateDirectories")
List<String> generateIntermediateDirectories;

/**
* The actual payload/file entries
* <p>
Expand Down Expand Up @@ -1100,7 +1103,7 @@ protected void fillPayload(final RpmBuilder builder) throws MojoFailureException
}

final ListenableBuilderContext ctx = new ListenableBuilderContext(builder.newContext());
final MissingDirectoryTracker missingDirectoryTracker = new MissingDirectoryTracker(this.prefixes);
final MissingDirectoryTracker missingDirectoryTracker = new MissingDirectoryTracker(this.generateIntermediateDirectories);
ctx.registerListener(missingDirectoryTracker);

this.logger.debug("Building payload:");
Expand All @@ -1118,7 +1121,7 @@ protected void fillPayload(final RpmBuilder builder) throws MojoFailureException
}

ctx.removeListener(missingDirectoryTracker);
if (generateIntermediateDirectories) {
if (!generateIntermediateDirectories.isEmpty()) {
missingDirectoryTracker.addMissingIntermediateDirectoriesToContext(ctx);
}
}
Expand Down

0 comments on commit 2e22458

Please sign in to comment.