Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow excluding files from property replacement #211

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

* Support excluding files from property replacement.

## Version 2.13.0

* Support escaping placeholders with backslash e.g. `\${MY_ENV_VAR}` will no longer be expanded
Expand Down
51 changes: 48 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ that the correct docker image is used. An example snippet:
## Configuration

| Property | Default | Description |
|---|---|---|
|---|--|---|
| chartName | The Maven `artifactId` | The name of the chart |
| chartVersion | `${project.model.version}` | The version of the chart |
| chartRepoUrl | `null` | The URL of the Chart repository where dependencies are required from and where charts should be published to |
Expand All @@ -95,6 +95,8 @@ that the correct docker image is used. An example snippet:
| extraValuesFiles | None | a list of additional values files that can be generated dynamically and will be merged with the values.yaml during [Package](#package). |
| outputFile | target/test-classes/helm.yaml | output file for [template goal](#template) |
| deployAtEnd | `false` | If true, the helm chart is deployed at the end of a multi-module Maven build. This option does not make sense for single-module Maven projects. |
| propertyReplacement | Empty | Structure to configure property replacement performed on the chart files |
| propertyReplacement.exclusions | Empty | List of file extensions that should be excluded from property replacement. The expressions are by default glob expressions |

## Goals

Expand Down Expand Up @@ -131,11 +133,11 @@ To use the `deployAtEnd` functionality it's mandatory to put the Helm Maven Plug
<plugin>
<groupId>com.deviceinsight.helm</groupId>
<artifactId>helm-maven-plugin</artifactId>
<version>2.11.1</version>
<version>2.14.0</version>
<configuration>
<chartName>my-chart</chartName>
<chartRepoUrl>https://charts.helm.sh/stable</chartRepoUrl>
<helmVersion>3.5.2</helmVersion>
<helmVersion>3.13.0</helmVersion>
<strictLint>true</strictLint>
<valuesFile>src/test/helm/my-chart/values.yaml</valuesFile>
<deployAtEnd>true</deployAtEnd>
Expand All @@ -155,6 +157,49 @@ To use the `deployAtEnd` functionality it's mandatory to put the Helm Maven Plug
</build>
```

### Exclude files from property replacement

To exclude files from property replacement, you can use the `propertyReplacement` configuration.
Any `exclusion` matching will exclude the file from property replacement.
By default, glob expressions are used.
You can also use regular expressions by prefixing the expression with `regex`.

```xml
<build>
<plugins>
...
<plugin>
<groupId>com.deviceinsight.helm</groupId>
<artifactId>helm-maven-plugin</artifactId>
<version>2.14.0</version>
<configuration>
<chartName>my-chart</chartName>
<chartRepoUrl>https://charts.helm.sh/stable</chartRepoUrl>
<helmVersion>3.13.0</helmVersion>
<strictLint>true</strictLint>
<valuesFile>src/test/helm/my-chart/values.yaml</valuesFile>
<propertyReplacement>
<exclusions>
<exclusion>**/grafana-dashboards/**/*.json</exclusion>
<exclusion>regex:.*/grafana-dashboards/.*\.json</exclusion>
</exclusions>
</propertyReplacement>
</configuration>
<executions>
<execution>
<goals>
<goal>package</goal>
<goal>lint</goal>
<goal>template</goal>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
```

## Troubleshooting

1. _**Problem**_
Expand Down
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<gitflow-maven-plugin.version>1.20.0</gitflow-maven-plugin.version>
<nexus-staging-maven-plugin.version>1.6.13</nexus-staging-maven-plugin.version>
<maven-gpg-plugin.version>3.1.0</maven-gpg-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -238,6 +239,11 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
</plugins>
</build>

Expand Down
6 changes: 4 additions & 2 deletions src/main/kotlin/com/deviceinsight/helm/PackageMojo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class PackageMojo : ResolveHelmMojo(), ServerAuthentication {

companion object {
private val PLACEHOLDER_REGEX = Regex("""(\\?)\$\{(.*?)}""")
private val SUBSTITUTED_EXTENSIONS = setOf("json", "tpl", "yml", "yaml")
}

@Component(role = SecDispatcher::class, hint = "default")
Expand Down Expand Up @@ -79,6 +78,9 @@ class PackageMojo : ResolveHelmMojo(), ServerAuthentication {
@Parameter(property = "extraValuesFiles")
private val extraValuesFiles: List<String> = emptyList()

@Parameter(property = "propertyReplacement")
private val propertyReplacement = PropertyReplacement()

@Throws(MojoExecutionException::class)
override fun execute() {

Expand Down Expand Up @@ -164,7 +166,7 @@ class PackageMojo : ResolveHelmMojo(), ServerAuthentication {
parentFile.mkdirs()
}

if (!SUBSTITUTED_EXTENSIONS.contains(file.extension.lowercase())) {
if (!propertyReplacement.isPropertyReplacementCandidate(file)) {
file.copyTo(targetFile, true)
return@onEach
}
Expand Down
35 changes: 35 additions & 0 deletions src/main/kotlin/com/deviceinsight/helm/PropertyReplacement.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.deviceinsight.helm

import org.apache.maven.plugins.annotations.Parameter
import java.io.File
import java.nio.file.FileSystems
import java.nio.file.PathMatcher

class PropertyReplacement {

@Parameter(property = "exclusions")
var exclusions: List<String> = emptyList()

private val exclusionPatchMatchers = lazy { exclusions.toPathMatchers() }

companion object {
private val SUBSTITUTED_EXTENSIONS = setOf("json", "tpl", "yml", "yaml")
private val PATH_MATCHER_PATTERN = Regex("^(glob|regex):.*$")
}

fun isPropertyReplacementCandidate(file: File): Boolean {
val extension = file.extension.lowercase()
return SUBSTITUTED_EXTENSIONS.contains(extension)
&& file.doesNotMatchAnyExclusion()
}

private fun File.doesNotMatchAnyExclusion() = exclusionPatchMatchers.value.none { it.matches(this.toPath()) }

private fun List<String>.toPathMatchers(): List<PathMatcher> = this
.map { prependGlobIfMissing(it) }
.map { FileSystems.getDefault().getPathMatcher(it) }

private fun prependGlobIfMissing(path: String): String = if (PATH_MATCHER_PATTERN.matches(path)) path else "glob:$path"

}

35 changes: 35 additions & 0 deletions src/test/kotlin/com/deviceinsight/helm/PropertyReplacementTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.deviceinsight.helm

import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import java.io.File

class PropertyReplacementTest {

@ParameterizedTest
@ValueSource(strings = ["test.txt", "test.xml"])
fun `isPropertyReplacementCandidate should return false if file extension is not in inclusion list`(filename: String) {
val file = File(filename)
val propertyReplacement = PropertyReplacement()
assertThat(propertyReplacement.isPropertyReplacementCandidate(file)).isFalse
}

@ParameterizedTest
@ValueSource(strings = ["test.json", "test.tpl", "test.yml", "test.yaml"])
fun `isPropertyReplacementCandidate should return true if file extension is in inclusion list`(filename: String) {
val file = File(filename)
val propertyReplacement = PropertyReplacement()
assertThat(propertyReplacement.isPropertyReplacementCandidate(file)).isTrue
}

@ParameterizedTest
@ValueSource(strings = ["dashboards/test.json", "templates/test.json", "templates/default/test.json"])
fun `isPropertyReplacementCandidate should return false if file matches exclusion pattern`(filename: String) {
val file = File(filename)
val propertyReplacement = PropertyReplacement()
propertyReplacement.exclusions =
listOf("regex:dashboards/.*\\.json", "glob:templates/*.json", "templates/**/*.json")
assertThat(propertyReplacement.isPropertyReplacementCandidate(file)).isFalse
}
}
Loading