Skip to content

Commit f56256a

Browse files
committed
MCP cgen_run tool: correctly set last modification time
1 parent e473ef2 commit f56256a

2 files changed

Lines changed: 37 additions & 0 deletions

File tree

cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/cgen/CgenRunTool.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,18 @@ public CgenRunResult run(String projectPath, String dataMapName) {
168168
}
169169
CgenConfiguration cgenConfig = configList.getAll().getFirst();
170170

171+
// Set the DataMap file's mtime as the timestamp so fileNeedUpdate() can detect DataMap changes correctly.
172+
if (dataMap.getConfigurationSource() != null) {
173+
try {
174+
Path dataMapFile = Path.of(dataMap.getConfigurationSource().getURL().toURI());
175+
cgenConfig.setTimestamp(Files.getLastModifiedTime(dataMapFile).toMillis());
176+
} catch (Exception e) {
177+
// URI conversion failed (e.g. non-file: URL) or some problems with file mtime read,
178+
// better to regen all, than silently fail.
179+
cgenConfig.setForce(true);
180+
}
181+
}
182+
171183
// Step 5 — destDir specified?
172184
Path destDir = cgenConfig.buildOutputPath();
173185
if (destDir == null) {

cayenne-mcp-server/src/test/java/org/apache/cayenne/mcp/tools/cgen/CgenRunIT.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.io.IOException;
2929
import java.nio.file.Files;
3030
import java.nio.file.Path;
31+
import java.nio.file.attribute.FileTime;
3132
import java.util.List;
3233

3334
import static org.junit.jupiter.api.Assertions.*;
@@ -117,6 +118,30 @@ public void subclassNotOverwrittenWhenMakePairsIsTrue() throws IOException {
117118
assertTrue(skipped >= 1, "At least one file (the existing subclass) should have been skipped");
118119
}
119120

121+
@Test
122+
public void regeneratesAfterDataMapChange() throws IOException {
123+
// First run — generates files
124+
CgenRunResult first = tool.run(projectFile.toString(), "PersonMap");
125+
assertEquals("generated", first.status());
126+
127+
// Bump the DataMap's mtime to be clearly newer than the generated files.
128+
// Use setLastModifiedTime rather than a wall-clock sleep to avoid
129+
// filesystem mtime granularity issues (Windows has 1-second resolution).
130+
long maxGeneratedMtime = first.files().stream()
131+
.mapToLong(e -> Path.of(e.path()).toFile().lastModified())
132+
.max()
133+
.orElseThrow();
134+
Path dataMapFile = tempDir.resolve("PersonMap.map.xml");
135+
Files.setLastModifiedTime(dataMapFile, FileTime.fromMillis(maxGeneratedMtime + 5_000L));
136+
137+
// Second run — must detect that the DataMap is newer than the generated files
138+
// and regenerate the superclass(es).
139+
CgenRunResult second = tool.run(projectFile.toString(), "PersonMap");
140+
assertEquals("generated", second.status(),
141+
"Expected regeneration after DataMap mtime was bumped past generated files");
142+
assertTrue(second.summary().filesWritten() > 0);
143+
}
144+
120145
private Path writeFixture(String mapName, String pkg, Path destDir, boolean makePairs) throws IOException {
121146

122147
// Project descriptor

0 commit comments

Comments
 (0)