-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Replace groovy script with FreeMarker template engine #2669
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
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
1af1b29
Replace groovy script with FreeMarker template engine
mlvandijk 5b52815
Update CHANGELOG.md
mlvandijk 488f276
Cleanup
mlvandijk 1eb8445
More cleanup
mlvandijk 9ade4d3
Write classes to target/codegen-classes to avoid conflicts
mpkorstanje 5694410
Put all code gen steps in the same id
mpkorstanje 610242f
Don't expose freemarker as a dependency
mpkorstanje 4c0f2e9
Fix relative path problems
mpkorstanje b576dfd
Clean up
mpkorstanje 0924349
Merge remote-tracking branch 'origin/main' into codegen
mpkorstanje 616ab9b
Clean up'
mpkorstanje 2e54d72
Clean up'
mpkorstanje 8bf5c45
More clean up
mpkorstanje c81b317
More clean up
mpkorstanje 3aea8ab
More clean up
mpkorstanje 8680834
Merge remote-tracking branch 'origin/main' into codegen
mpkorstanje 16bf7f5
Move gherkin and messages version into bom
mpkorstanje File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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,142 @@ | ||
import freemarker.template.Configuration; | ||
import freemarker.template.Template; | ||
import freemarker.template.TemplateException; | ||
import freemarker.template.TemplateExceptionHandler; | ||
import io.cucumber.gherkin.GherkinDialect; | ||
import io.cucumber.gherkin.GherkinDialectProvider; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.text.Normalizer; | ||
import java.util.Arrays; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
import java.util.Locale; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
import static java.nio.file.Files.newBufferedWriter; | ||
import static java.nio.file.StandardOpenOption.CREATE; | ||
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; | ||
|
||
/* This class generates the cucumber-java Interfaces and package-info | ||
* based on the languages and keywords from the GherkinDialectProvider | ||
* using the FreeMarker template engine and provided templates. | ||
*/ | ||
public class GenerateI18n { | ||
|
||
// The generated files for and Emoij do not compile :( | ||
private static final List<String> unsupported = Arrays.asList("em", "en-tx"); | ||
|
||
public static void main(String[] args) throws Exception { | ||
if (args.length != 2) { | ||
throw new IllegalArgumentException("Usage: <baseDirectory> <packagePath>"); | ||
} | ||
|
||
DialectWriter dialectWriter = new DialectWriter(args[0], args[1]); | ||
|
||
// Generate annotation files for each dialect | ||
GherkinDialectProvider dialectProvider = new GherkinDialectProvider(); | ||
dialectProvider.getLanguages() | ||
.stream() | ||
.map(dialectProvider::getDialect) | ||
.filter(Optional::isPresent) | ||
.map(Optional::get) | ||
.filter(dialect -> !unsupported.contains(dialect.getLanguage())) | ||
.forEach(dialectWriter::writeDialect); | ||
} | ||
|
||
static class DialectWriter { | ||
private final Template templateSource; | ||
private final Template packageInfoSource; | ||
private final String baseDirectory; | ||
private final String packagePath; | ||
|
||
DialectWriter(String baseDirectory, String packagePath) throws IOException { | ||
this.baseDirectory = baseDirectory; | ||
this.packagePath = packagePath; | ||
|
||
Configuration cfg = new Configuration(Configuration.VERSION_2_3_21); | ||
cfg.setClassForTemplateLoading(GenerateI18n.class, "templates"); | ||
cfg.setDefaultEncoding("UTF-8"); | ||
cfg.setLocale(Locale.US); | ||
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); | ||
|
||
templateSource = cfg.getTemplate("annotation.java.ftl"); | ||
packageInfoSource = cfg.getTemplate("package-info.ftl"); | ||
} | ||
|
||
void writeDialect(GherkinDialect dialect) { | ||
writeKeyWordAnnotations(dialect); | ||
writePackageInfo(dialect); | ||
} | ||
|
||
private void writeKeyWordAnnotations(GherkinDialect dialect) { | ||
dialect.getStepKeywords().stream() | ||
.filter(it -> !it.contains(String.valueOf('*'))) | ||
.filter(it -> !it.matches("^\\d.*")) | ||
.distinct() | ||
.forEach(keyword -> writeKeyWordAnnotation(dialect, keyword)); | ||
} | ||
|
||
private void writeKeyWordAnnotation(GherkinDialect dialect, String keyword) { | ||
String normalizedLanguage = getNormalizedLanguage(dialect); | ||
String normalizedKeyword = getNormalizedKeyWord(keyword); | ||
|
||
Map<String, String> binding = new LinkedHashMap<>(); | ||
binding.put("lang", normalizedLanguage); | ||
binding.put("kw", normalizedKeyword); | ||
|
||
Path path = Paths.get(baseDirectory, packagePath, normalizedLanguage, normalizedKeyword + ".java"); | ||
|
||
if (Files.exists(path)) { | ||
// Haitian has two translations that only differ by case - Sipozeke and SipozeKe | ||
// Some file systems are unable to distinguish between them and | ||
// overwrite the other one :-( | ||
return; | ||
} | ||
|
||
try { | ||
Files.createDirectories(path.getParent()); | ||
templateSource.process(binding, newBufferedWriter(path, CREATE, TRUNCATE_EXISTING)); | ||
} catch (IOException | TemplateException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private static String getNormalizedKeyWord(String keyword) { | ||
return normalize(keyword.replaceAll("[\\s',!\u00AD]", "")); | ||
} | ||
|
||
private static String normalize(CharSequence s) { | ||
return Normalizer.normalize(s, Normalizer.Form.NFC); | ||
} | ||
|
||
private void writePackageInfo(GherkinDialect dialect) { | ||
String normalizedLanguage = getNormalizedLanguage(dialect); | ||
String languageName = dialect.getName(); | ||
if (!dialect.getName().equals(dialect.getNativeName())) { | ||
languageName += " - " + dialect.getNativeName(); | ||
} | ||
|
||
Map<String, String> binding = new LinkedHashMap<>(); | ||
binding.put("normalized_language", normalizedLanguage); | ||
binding.put("language_name", languageName); | ||
|
||
Path path = Paths.get(baseDirectory, packagePath, normalizedLanguage, "package-info.java"); | ||
|
||
try { | ||
Files.createDirectories(path.getParent()); | ||
packageInfoSource.process(binding, newBufferedWriter(path, CREATE, TRUNCATE_EXISTING)); | ||
} catch (IOException | TemplateException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private static String getNormalizedLanguage(GherkinDialect dialect) { | ||
return dialect.getLanguage().replaceAll("[\\s-]", "_").toLowerCase(); | ||
} | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.