Skip to content

Commit d044576

Browse files
authored
Add localization bundling to Maven CSS compilation (#4040)
* Add localization support to CSS compilation * Ensure plugin tests job provisions CN1 binaries * Fix mojo test setup for MavenProject
1 parent 68b9e43 commit d044576

File tree

3 files changed

+217
-1
lines changed

3 files changed

+217
-1
lines changed

.github/workflows/pr.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,21 @@ jobs:
4949
cd maven
5050
mvn clean verify -DunitTests=true -pl core-unittests -am -Dmaven.javadoc.skip=true -Plocal-dev-javase
5151
cd ..
52+
- name: Prepare Codename One binaries for Maven plugin tests
53+
run: |
54+
set -euo pipefail
55+
rm -rf maven/target/cn1-binaries
56+
git clone --depth=1 --filter=blob:none https://github.com/codenameone/cn1-binaries maven/target/cn1-binaries
57+
- name: Run Maven plugin tests
58+
working-directory: maven
59+
env:
60+
CN1_BINARIES: ${{ github.workspace }}/maven/target/cn1-binaries
61+
run: |
62+
mvn -B -Dmaven.javadoc.skip=true \
63+
-DunitTests=true \
64+
-Dcodename1.platform=javase \
65+
-Dcn1.binaries="${CN1_BINARIES}" \
66+
-pl codenameone-maven-plugin -am -Plocal-dev-javase test
5267
- name: Generate static analysis HTML summaries
5368
if: ${{ always() }}
5469
env:

maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/CompileCSSMojo.java

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,61 @@ protected File findCSSDirectory() {
7070
if (themeCss.exists()) {
7171
return cssSibling;
7272
}
73-
73+
7474
}
7575
return null;
7676
}
7777

78+
protected File findLocalizationDirectory() {
79+
if (project.getCompileSourceRoots() != null) {
80+
for (String dir : project.getCompileSourceRoots()) {
81+
File dirFile = new File(dir);
82+
File parent = dirFile.getParentFile();
83+
if (parent == null) {
84+
continue;
85+
}
86+
File localizationSibling = new File(parent, "l10n");
87+
if (hasLocalizationBundles(localizationSibling)) {
88+
return localizationSibling;
89+
}
90+
}
91+
}
92+
93+
File cn1ProjectDir = getCN1ProjectDir();
94+
if (cn1ProjectDir != null) {
95+
File defaultLocalization = new File(cn1ProjectDir, path("src", "main", "l10n"));
96+
if (hasLocalizationBundles(defaultLocalization)) {
97+
return defaultLocalization;
98+
}
99+
File rootLocalization = new File(cn1ProjectDir, "l10n");
100+
if (hasLocalizationBundles(rootLocalization)) {
101+
return rootLocalization;
102+
}
103+
}
104+
105+
return null;
106+
}
107+
108+
private boolean hasLocalizationBundles(File directory) {
109+
if (directory == null || !directory.isDirectory()) {
110+
return false;
111+
}
112+
File[] files = directory.listFiles();
113+
if (files == null) {
114+
return false;
115+
}
116+
for (File file : files) {
117+
if (file.isDirectory()) {
118+
if (hasLocalizationBundles(file)) {
119+
return true;
120+
}
121+
} else if (file.getName().endsWith(".properties")) {
122+
return true;
123+
}
124+
}
125+
return false;
126+
}
127+
78128
private void executeImpl(String themePrefix) throws MojoExecutionException, MojoFailureException {
79129
if (!isCN1ProjectDir()) {
80130
return;
@@ -201,6 +251,11 @@ private void executeImpl(String themePrefix) throws MojoExecutionException, Mojo
201251

202252
java.createArg().setValue("-merge");
203253
java.createArg().setFile(mergeFile);
254+
File localizationDir = findLocalizationDirectory();
255+
if (localizationDir != null) {
256+
java.createArg().setValue("-l");
257+
java.createArg().setFile(localizationDir);
258+
}
204259
int res = java.executeJava();
205260
if (res != 0) {
206261
throw new MojoExecutionException("An error occurred while compiling the CSS files. Inputs: "+inputs+", output: " + new File(project.getBuild().getOutputDirectory() + File.separator + themePrefix + "theme.res") +", merge file: "+mergeFile);
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package com.codename1.maven;
2+
3+
import org.apache.maven.model.Build;
4+
import org.apache.maven.plugin.logging.SystemStreamLog;
5+
import org.apache.maven.project.MavenProject;
6+
import org.apache.tools.ant.Project;
7+
import org.apache.tools.ant.taskdefs.Java;
8+
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.api.io.TempDir;
10+
11+
import java.io.File;
12+
import java.io.IOException;
13+
import java.nio.file.Files;
14+
import java.nio.file.Path;
15+
import java.util.ArrayList;
16+
import java.util.Arrays;
17+
import java.util.HashSet;
18+
import java.util.List;
19+
import java.util.Properties;
20+
21+
import static org.junit.jupiter.api.Assertions.assertEquals;
22+
import static org.junit.jupiter.api.Assertions.assertFalse;
23+
import static org.junit.jupiter.api.Assertions.assertTrue;
24+
25+
class CompileCSSMojoTest {
26+
27+
@Test
28+
void addsLocalizationDirectoryToDesignerInvocation(@TempDir Path tempDir) throws Exception {
29+
Path projectDir = setupProject(tempDir, true);
30+
TestCompileCSSMojo mojo = createMojo(projectDir);
31+
32+
mojo.executeImpl();
33+
34+
List<String> args = mojo.getRecordingJava().getCommandLineArguments();
35+
assertTrue(args.contains("-l"), "Expected -l argument when localization directory exists");
36+
int index = args.indexOf("-l");
37+
assertTrue(index >= 0 && index + 1 < args.size(), "Expected localization directory argument after -l");
38+
assertEquals(projectDir.resolve("src/main/l10n").toFile().getAbsolutePath(), args.get(index + 1));
39+
}
40+
41+
@Test
42+
void skipsLocalizationArgumentWhenDirectoryMissing(@TempDir Path tempDir) throws Exception {
43+
Path projectDir = setupProject(tempDir, false);
44+
TestCompileCSSMojo mojo = createMojo(projectDir);
45+
46+
mojo.executeImpl();
47+
48+
List<String> args = mojo.getRecordingJava().getCommandLineArguments();
49+
assertFalse(args.contains("-l"), "Did not expect -l argument without localization directory");
50+
}
51+
52+
private TestCompileCSSMojo createMojo(Path projectDir) throws IOException {
53+
MavenProject mavenProject = new MavenProject();
54+
mavenProject.setFile(projectDir.resolve("pom.xml").toFile());
55+
mavenProject.addCompileSourceRoot(projectDir.resolve("src/main/java").toString());
56+
Build build = new Build();
57+
build.setDirectory(projectDir.resolve("target").toString());
58+
build.setOutputDirectory(projectDir.resolve("target/classes").toString());
59+
mavenProject.setBuild(build);
60+
mavenProject.setArtifacts(new HashSet<>());
61+
62+
TestCompileCSSMojo mojo = new TestCompileCSSMojo(projectDir.resolve("designer.jar").toFile());
63+
mojo.project = mavenProject;
64+
mojo.antProject = new Project();
65+
mojo.antProject.setBaseDir(projectDir.toFile());
66+
mojo.antProject.init();
67+
mojo.pluginArtifacts = new ArrayList<>();
68+
mojo.properties = new Properties();
69+
mojo.properties.setProperty("codename1.cssTheme", "true");
70+
mojo.setLog(new SystemStreamLog());
71+
72+
return mojo;
73+
}
74+
75+
private Path setupProject(Path tempDir, boolean includeLocalization) throws IOException {
76+
Path projectDir = tempDir.resolve("project");
77+
Files.createDirectories(projectDir);
78+
Files.createDirectories(projectDir.resolve("src/main/java"));
79+
Path cssDir = Files.createDirectories(projectDir.resolve("src/main/css"));
80+
Files.write(cssDir.resolve("theme.css"), Arrays.asList("/* test css */"));
81+
Files.write(projectDir.resolve("codenameone_settings.properties"), Arrays.asList("codename1.cssTheme=true"));
82+
Files.createDirectories(projectDir.resolve("target/classes"));
83+
Files.createFile(projectDir.resolve("designer.jar"));
84+
Files.write(projectDir.resolve("pom.xml"), Arrays.asList(
85+
"<project xmlns=\"http://maven.apache.org/POM/4.0.0\"",
86+
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"",
87+
" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">",
88+
" <modelVersion>4.0.0</modelVersion>",
89+
" <groupId>com.codename1</groupId>",
90+
" <artifactId>test-project</artifactId>",
91+
" <version>1.0-SNAPSHOT</version>",
92+
"</project>"
93+
));
94+
95+
if (includeLocalization) {
96+
Path localizationDir = Files.createDirectories(projectDir.resolve("src/main/l10n"));
97+
Files.write(localizationDir.resolve("Messages.properties"), Arrays.asList("greeting=Hello"));
98+
}
99+
100+
return projectDir;
101+
}
102+
103+
private static class TestCompileCSSMojo extends CompileCSSMojo {
104+
private final File designerJar;
105+
private RecordingJava recordingJava;
106+
107+
private TestCompileCSSMojo(File designerJar) {
108+
this.designerJar = designerJar;
109+
}
110+
111+
@Override
112+
public Java createJava() {
113+
recordingJava = new RecordingJava();
114+
recordingJava.setProject(antProject);
115+
return recordingJava;
116+
}
117+
118+
@Override
119+
protected void setupCef() {
120+
// Skip CEF setup during tests.
121+
}
122+
123+
@Override
124+
protected File getDesignerJar() {
125+
return designerJar;
126+
}
127+
128+
RecordingJava getRecordingJava() {
129+
return recordingJava;
130+
}
131+
}
132+
133+
private static class RecordingJava extends Java {
134+
private List<String> commandLineArguments = new ArrayList<>();
135+
136+
@Override
137+
public int executeJava() {
138+
commandLineArguments = Arrays.asList(getCommandLine().getCommandline());
139+
return 0;
140+
}
141+
142+
List<String> getCommandLineArguments() {
143+
return commandLineArguments;
144+
}
145+
}
146+
}

0 commit comments

Comments
 (0)