diff --git a/src/main/java/rife/bld/BaseProject.java b/src/main/java/rife/bld/BaseProject.java index 042ae23..40a13e8 100644 --- a/src/main/java/rife/bld/BaseProject.java +++ b/src/main/java/rife/bld/BaseProject.java @@ -664,7 +664,42 @@ public class BaseProject extends BuildExecutor { if (rife2Agent_ == null) { return null; } - return new File(libRuntimeDirectory(), rife2Agent_.toFileName()); + + var directory = libRuntimeDirectory(); + var logical = rife2Agent_.toFileName(); + + // for a released version the on-disk name matches the dependency exactly + if (!rife2Agent_.version().isSnapshot()) { + return new File(directory, logical); + } + + // snapshot artifacts keep their resolved, timestamped names on disk, so + // the logical name with the SNAPSHOT qualifier won't exist; locate the + // resolved file by matching that qualifier against the timestamp part, + // e.g. rife2-1.10.0-SNAPSHOT-agent.jar resolves to a file like + // rife2-1.10.0-20240101.120000-1-agent.jar + var marker = logical.toUpperCase().indexOf(SNAPSHOT_QUALIFIER); + if (marker >= 0) { + var prefix = logical.substring(0, marker); + var suffix = logical.substring(marker + SNAPSHOT_QUALIFIER.length()); + var matches = directory.listFiles((dir, name) -> + name.length() > prefix.length() + suffix.length() && + name.startsWith(prefix) && name.endsWith(suffix)); + if (matches != null && matches.length > 0) { + // when several resolved snapshots are present, pick the most + // recent one; timestamped names sort chronologically + var latest = matches[0]; + for (var candidate : matches) { + if (candidate.getName().compareTo(latest.getName()) > 0) { + latest = candidate; + } + } + return latest; + } + } + + // fall back to the logical name if no resolved file could be found + return new File(directory, logical); } /** diff --git a/src/test/java/rife/bld/TestBaseProject.java b/src/test/java/rife/bld/TestBaseProject.java index 263861b..98c9f09 100644 --- a/src/test/java/rife/bld/TestBaseProject.java +++ b/src/test/java/rife/bld/TestBaseProject.java @@ -324,4 +324,55 @@ class TestBaseProject { ); } } + + @Nested + @DisplayName("getRife2AgentFile()") + class Rife2AgentFileTest { + @Test + @DisplayName("null when the agent isn't used") + void nullWhenUnused() { + assertNull(project.getRife2AgentFile()); + } + + @Test + @DisplayName("released version uses the exact logical name") + void releasedVersion() throws Exception { + project.useRife2Agent(project.version(1, 9, 1)); + var expected = new File(project.libRuntimeDirectory(), "rife2-1.9.1-agent.jar"); + Files.createFile(expected.toPath()); + assertEquals(expected, project.getRife2AgentFile()); + } + + @Test + @DisplayName("snapshot version resolves the timestamped file, ignoring look-alikes") + void snapshotResolvesTimestamped() throws Exception { + project.useRife2Agent(project.version(1, 10, 0, "SNAPSHOT")); + var dir = project.libRuntimeDirectory(); + var agent = new File(dir, "rife2-1.10.0-20240101.120000-1-agent.jar"); + Files.createFile(agent.toPath()); + // neither the main jar nor the agent sources jar may be picked + Files.createFile(new File(dir, "rife2-1.10.0-20240101.120000-1.jar").toPath()); + Files.createFile(new File(dir, "rife2-1.10.0-20240101.120000-1-agent-sources.jar").toPath()); + assertEquals(agent, project.getRife2AgentFile()); + } + + @Test + @DisplayName("snapshot version picks the most recent resolved file") + void snapshotPicksMostRecent() throws Exception { + project.useRife2Agent(project.version(1, 10, 0, "SNAPSHOT")); + var dir = project.libRuntimeDirectory(); + Files.createFile(new File(dir, "rife2-1.10.0-20240101.120000-1-agent.jar").toPath()); + var newest = new File(dir, "rife2-1.10.0-20240202.130000-1-agent.jar"); + Files.createFile(newest.toPath()); + assertEquals(newest, project.getRife2AgentFile()); + } + + @Test + @DisplayName("snapshot version falls back to the logical name when nothing is resolved") + void snapshotFallsBack() { + project.useRife2Agent(project.version(1, 10, 0, "SNAPSHOT")); + var logical = new File(project.libRuntimeDirectory(), "rife2-1.10.0-SNAPSHOT-agent.jar"); + assertEquals(logical, project.getRife2AgentFile()); + } + } }