-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
An option to record and dump all used build time config options and a
Maven goal that compares the recorded build config from the previous build to the current config before building an application Co-authored-by: Robert Stupp <[email protected]> (cherry picked from commit 01eedec)
- Loading branch information
1 parent
1b9a4c4
commit 3747c0d
Showing
16 changed files
with
943 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
...yment/src/main/java/io/quarkus/deployment/configuration/tracker/ConfigTrackingConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package io.quarkus.deployment.configuration.tracker; | ||
|
||
import java.nio.file.Path; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.regex.Pattern; | ||
|
||
import io.quarkus.runtime.annotations.ConfigPhase; | ||
import io.quarkus.runtime.annotations.ConfigRoot; | ||
import io.quarkus.util.GlobUtil; | ||
import io.smallrye.config.ConfigMapping; | ||
import io.smallrye.config.WithDefault; | ||
|
||
/** | ||
* Configuration options for application build time configuration usage tracking | ||
* and dumping. | ||
*/ | ||
@ConfigMapping(prefix = "quarkus.config-tracking") | ||
@ConfigRoot(phase = ConfigPhase.BUILD_TIME) | ||
public interface ConfigTrackingConfig { | ||
|
||
/** | ||
* Whether configuration dumping is enabled | ||
*/ | ||
@WithDefault("false") | ||
boolean enabled(); | ||
|
||
/** | ||
* Directory in which the configuration dump should be stored. | ||
* If not configured the {@code .quarkus} directory under the project directory will be used. | ||
*/ | ||
Optional<Path> directory(); | ||
|
||
/** | ||
* File in which the configuration dump should be stored. If not configured, the {@link #filePrefix} and | ||
* {@link #fileSuffix} will be used to generate the final file name. | ||
* If the configured file path is absolute, the {@link #directory} option will be ignored. Otherwise, | ||
* the path will be considered relative to the {@link #directory}. | ||
*/ | ||
Optional<Path> file(); | ||
|
||
/** | ||
* File name prefix. This option will be ignored in case {@link #file} is configured. | ||
*/ | ||
@WithDefault("quarkus") | ||
String filePrefix(); | ||
|
||
/** | ||
* File name suffix. This option will be ignored in case {@link #file} is configured. | ||
*/ | ||
@WithDefault("-config-dump") | ||
String fileSuffix(); | ||
|
||
/** | ||
* A list of config properties that should be excluded from the report. | ||
* GLOB patterns could be used instead of property names. | ||
*/ | ||
Optional<List<String>> exclude(); | ||
|
||
/** | ||
* Translates the value of {@link #exclude} to a list of {@link java.util.regex.Pattern}. | ||
* | ||
* @return list of patterns created from {@link #exclude} | ||
*/ | ||
default List<Pattern> getExcludePatterns() { | ||
return toPatterns(exclude()); | ||
} | ||
|
||
/** | ||
* A list of config properties whose values should be hashed in the report. | ||
* The values will be hashed using SHA-512 algorithm. | ||
* GLOB patterns could be used instead of property names. | ||
*/ | ||
Optional<List<String>> hashOptions(); | ||
|
||
/** | ||
* Translates the value of {@link #hashOptions()} to a list of {@link java.util.regex.Pattern}. | ||
* | ||
* @return list of patterns created from {@link #hashOptions()} | ||
*/ | ||
default List<Pattern> getHashOptionsPatterns() { | ||
return toPatterns(hashOptions()); | ||
} | ||
|
||
static List<Pattern> toPatterns(Optional<List<String>> globs) { | ||
if (globs.isEmpty()) { | ||
return List.of(); | ||
} | ||
var list = globs.get(); | ||
final List<Pattern> patterns = new ArrayList<>(list.size()); | ||
for (var s : list) { | ||
patterns.add(Pattern.compile(GlobUtil.toRegexPattern(s))); | ||
} | ||
return patterns; | ||
} | ||
|
||
/** | ||
* Whether to use a {@code ~} as an alias for user home directory in path values | ||
*/ | ||
@WithDefault("true") | ||
boolean useUserHomeAliasInPaths(); | ||
} |
89 changes: 89 additions & 0 deletions
89
.../src/main/java/io/quarkus/deployment/configuration/tracker/ConfigTrackingInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package io.quarkus.deployment.configuration.tracker; | ||
|
||
import static io.smallrye.config.SecretKeys.doLocked; | ||
|
||
import java.nio.file.Path; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
import jakarta.annotation.Priority; | ||
|
||
import org.eclipse.microprofile.config.Config; | ||
|
||
import io.quarkus.deployment.configuration.BuildTimeConfigurationReader; | ||
import io.quarkus.runtime.LaunchMode; | ||
import io.smallrye.config.ConfigSourceInterceptor; | ||
import io.smallrye.config.ConfigSourceInterceptorContext; | ||
import io.smallrye.config.ConfigValue; | ||
import io.smallrye.config.Priorities; | ||
|
||
/** | ||
* Build configuration interceptor that records all the configuration options | ||
* and their values that are read during the build. | ||
*/ | ||
@Priority(Priorities.APPLICATION) | ||
public class ConfigTrackingInterceptor implements ConfigSourceInterceptor { | ||
|
||
/** | ||
* A writer that persists collected configuration options and their values to a file | ||
*/ | ||
public interface ConfigurationWriter { | ||
void write(ConfigTrackingConfig config, BuildTimeConfigurationReader.ReadResult configReadResult, | ||
LaunchMode launchMode, Path buildDirectory); | ||
} | ||
|
||
/** | ||
* Provides an immutable map of options that were read during the build. | ||
*/ | ||
public interface ReadOptionsProvider { | ||
|
||
/** | ||
* An immutable map of options read during the build. | ||
* | ||
* @return immutable map of options read during the build | ||
*/ | ||
Map<String, String> getReadOptions(); | ||
} | ||
|
||
private boolean enabled; | ||
// it's a String value map to be able to represent null (not configured) values | ||
private Map<String, String> readOptions = Map.of(); | ||
private final ReadOptionsProvider readOptionsProvider = new ReadOptionsProvider() { | ||
@Override | ||
public Map<String, String> getReadOptions() { | ||
return Collections.unmodifiableMap(readOptions); | ||
} | ||
}; | ||
|
||
/** | ||
* Initializes the configuration tracker | ||
* | ||
* @param config configuration instance | ||
*/ | ||
public void configure(Config config) { | ||
enabled = config.getValue("quarkus.config-tracking.enabled", boolean.class); | ||
if (enabled) { | ||
readOptions = new ConcurrentHashMap<>(); | ||
} | ||
} | ||
|
||
@Override | ||
public ConfigValue getValue(ConfigSourceInterceptorContext context, String name) { | ||
if (!enabled) { | ||
return context.proceed(name); | ||
} | ||
final ConfigValue configValue = doLocked(() -> context.proceed(name)); | ||
readOptions.put(name, ConfigTrackingValueTransformer.asString(configValue)); | ||
return configValue; | ||
} | ||
|
||
/** | ||
* Read options orvipder. | ||
* | ||
* @return read options provider | ||
*/ | ||
public ReadOptionsProvider getReadOptionsProvider() { | ||
return readOptionsProvider; | ||
} | ||
} |
Oops, something went wrong.