Skip to content

Mhlidd/config inversion #9181

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

Draft
wants to merge 14 commits into
base: project/config_inversion
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ spotlessPredeclare {
}
}
apply from: "$rootDir/gradle/spotless.gradle"
apply from: "$rootDir/gradle/configInversionLinter.gradle"

def compileTask = tasks.register("compile")

Expand Down
37 changes: 37 additions & 0 deletions components/environment/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,45 @@ plugins {
id("com.gradleup.shadow")
}

sourceSets {
create("generator") {
java.srcDir("src/generator/java")
}
val main by getting {
java {
srcDir("build/generated/sources/supported")
}
}
}

dependencies {
"generatorImplementation"("com.fasterxml.jackson.core:jackson-databind:2.15.2")
"generatorImplementation"("org.slf4j:slf4j-api:1.7.36")
}

apply(from = "$rootDir/gradle/java.gradle")

val compileGeneratorJava = tasks.named("compileGeneratorJava")

val generateSupportedConfigurations by tasks.registering(JavaExec::class) {
// We can run the generator with the main sourceSet runtimeClasspath
dependsOn(compileGeneratorJava)
mainClass.set("datadog.environment.ParseSupportedConfigurations")
classpath = sourceSets["generator"].runtimeClasspath

val outputFile = layout.buildDirectory.file("generated/sources/supported/GeneratedSupportedConfigurations.java")
args("supported-configurations.json", outputFile.get().asFile.absolutePath)

doFirst {
outputFile.get().asFile.parentFile.mkdirs()
}
}
// Ensure Java compilation depends on the generated sources
sourceSets["main"].java.srcDir(layout.buildDirectory.dir("generated/sources/supported"))

tasks.named("compileJava") {
dependsOn(generateSupportedConfigurations)
}
/*
* Add an addition gradle configuration to be consumed by bootstrap only.
* "datadog.trace." prefix is required to be excluded from Jacoco instrumentation.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package datadog.environment;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ParseSupportedConfigurations {

public static void main(String[] args) {
String supportedConfigurationsFilename =
args[0]; // e.g., "resources/supported-configurations.json"
String generatedMappingPath = args[1]; // e.g.,
// "build/generated-sources/datadog/environment/GeneratedSupportedConfigurations.java"

String jsonString;
try {

InputStream in =
ParseSupportedConfigurations.class
.getClassLoader()
.getResourceAsStream(supportedConfigurationsFilename);
if (in == null) {
throw new IllegalArgumentException(
"Resource not found: " + supportedConfigurationsFilename);
}

ObjectMapper mapper = new ObjectMapper();
Map<String, Object> fileData = mapper.readValue(in, Map.class);

Map<String, List<String>> supported =
(Map<String, List<String>>) fileData.get("supportedConfigurations");
Map<String, List<String>> aliases = (Map<String, List<String>>) fileData.get("aliases");
Map<String, String> deprecated = (Map<String, String>) fileData.get("deprecations");

Map<String, String> aliasMapping = new HashMap<>();
for (Map.Entry<String, List<String>> entry : aliases.entrySet()) {
for (String alias : entry.getValue()) {
aliasMapping.put(alias, entry.getKey());
}
}
generateJavaFile(generatedMappingPath, supported.keySet(), aliases, aliasMapping, deprecated);
} catch (IOException e) {
throw new RuntimeException("Failed to read " + supportedConfigurationsFilename, e);
}
}

private static void generateJavaFile(
String outputPath,
Set<String> supported,
Map<String, List<String>> aliases,
Map<String, String> aliasMapping,
Map<String, String> deprecated)
throws IOException {
try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(Paths.get(outputPath)))) {
out.println("package datadog.environment;");
out.println();
out.println("import java.util.*;");
out.println();
out.println("public final class GeneratedSupportedConfigurations {");

// Supported set using Arrays.asList and HashSet
out.println(" public static final Set<String> SUPPORTED;");
out.println();

// ALIASES map
out.println(" public static final Map<String, List<String>> ALIASES;");
out.println();

// ALIAS_MAPPING map
out.println(" public static final Map<String, String> ALIAS_MAPPING;");
out.println();

// DEPRECATED map
out.println(" public static final Map<String, String> DEPRECATED;");
out.println();

// Static initializer block
out.println(" static {");

// Initialize SUPPORTED
out.print(" Set<String> supportedSet = new HashSet<>(Arrays.asList(");
Iterator<String> supportedIter = supported.iterator();
while (supportedIter.hasNext()) {
String key = supportedIter.next();
out.print("\"" + key + "\"");
if (supportedIter.hasNext()) {
out.print(", ");
}
}
out.println("));");
out.println(" SUPPORTED = Collections.unmodifiableSet(supportedSet);");
out.println();

// Initialize ALIASES
out.println(" Map<String, List<String>> aliasesMap = new HashMap<>();");
for (Map.Entry<String, List<String>> entry : aliases.entrySet()) {
out.printf(
" aliasesMap.put(\"%s\", Collections.unmodifiableList(Arrays.asList(%s)));\n",
entry.getKey(), quoteList(entry.getValue()));
}
out.println(" ALIASES = Collections.unmodifiableMap(aliasesMap);");
out.println();

// Initialize ALIAS_MAPPING
out.println(" Map<String, String> aliasMappingMap = new HashMap<>();");
for (Map.Entry<String, String> entry : aliasMapping.entrySet()) {
out.printf(" aliasMappingMap.put(\"%s\", \"%s\");\n", entry.getKey(), entry.getValue());
}
out.println(" ALIAS_MAPPING = Collections.unmodifiableMap(aliasMappingMap);");
out.println();

// Initialize DEPRECATED
out.println(" Map<String, String> deprecatedMap = new HashMap<>();");
for (Map.Entry<String, String> entry : deprecated.entrySet()) {
out.printf(" deprecatedMap.put(\"%s\", \"%s\");\n", entry.getKey(), entry.getValue());
}
out.println(" DEPRECATED = Collections.unmodifiableMap(deprecatedMap);");

out.println(" }"); // end static block
out.println("}"); // end class
}
}

private static String quoteList(List<String> list) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
sb.append("\"").append(list.get(i)).append("\"");
if (i < list.size() - 1) {
sb.append(", ");
}
}
return sb.toString();
}
}
Loading
Loading