davsclaus commented on code in PR #27862:
URL: https://github.com/apache/camel/pull/27862#discussion_r4279986447
##########
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/AuthoringTools.java:
##########
@@ -1070,13 +1070,117 @@ private static void putFileNotes(JsonObject result,
String file, String content)
}
}
+ private static final Pattern JAVA_PACKAGE =
Pattern.compile("^\\s*package\\s+([\\w.]+)\\s*;", Pattern.MULTILINE);
+
+ /** The package a Java source declares, or the empty string for none. */
+ static String javaPackage(String content) {
+ Matcher m = content != null ? JAVA_PACKAGE.matcher(content) : null;
+ return m != null && m.find() ? m.group(1) : "";
+ }
+
+ /**
+ * The other files of the project with the name of the file. Folders that
hold no sources of the app are left out:
+ * dot folders, build output and test sources.
+ */
+ private static List<Path> sameNamedFiles(Path dir, Path path) {
+ Path root = dir.toAbsolutePath().normalize();
+ Path self = path.toAbsolutePath().normalize();
+ String name = self.getFileName().toString();
+ List<Path> found = new ArrayList<>();
+ try {
+ Files.walkFileTree(root, EnumSet.noneOf(FileVisitOption.class),
12, new SimpleFileVisitor<>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path d,
BasicFileAttributes attrs) {
+ String n = d.getFileName() != null ?
d.getFileName().toString() : "";
+ String relative =
root.relativize(d).toString().replace('\\', '/');
+ if (!d.equals(root) && (n.startsWith(".") ||
"target".equals(n) || "build".equals(n)
+ || "node_modules".equals(n) ||
"src/test".equals(relative) || relative.endsWith("/src/test"))) {
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path f, BasicFileAttributes
attrs) {
+ if (attrs.isRegularFile() &&
name.equals(f.getFileName().toString())
+ && !self.equals(f.toAbsolutePath().normalize())) {
+ found.add(f);
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ } catch (IOException e) {
+ // best effort: without the list the write goes ahead as before
+ }
+ return found;
+ }
+
+ /**
+ * The file of the project that already defines the class a new Java
source would define (the same package and
+ * name), relative to the project directory, or null. Asked to change a
class of a camel run project, whose sources
+ * sit next to the routes, a model wrote a second copy under src/main/java
instead, 7 times out of 11 in a benchmark
+ * (CAMEL-25673): two classes of the same name, of which the runtime uses
one, while the change is in the other.
+ */
+ static String fileOfSameClass(Path dir, Path path, String content) {
+ String pkg = javaPackage(content);
+ Path root = dir.toAbsolutePath().normalize();
+ for (Path other : sameNamedFiles(dir, path)) {
+ if (pkg.equals(javaPackage(read(other)))) {
Review Comment:
Right, the search was best effort but the read was not. Fixed in
cce6313c50d4: a candidate that cannot be read is skipped, so it never refuses
the write.
_Claude Code on behalf of @davsclaus._
##########
dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/AuthoringTools.java:
##########
@@ -1070,13 +1070,117 @@ private static void putFileNotes(JsonObject result,
String file, String content)
}
}
+ private static final Pattern JAVA_PACKAGE =
Pattern.compile("^\\s*package\\s+([\\w.]+)\\s*;", Pattern.MULTILINE);
+
+ /** The package a Java source declares, or the empty string for none. */
+ static String javaPackage(String content) {
+ Matcher m = content != null ? JAVA_PACKAGE.matcher(content) : null;
+ return m != null && m.find() ? m.group(1) : "";
+ }
+
+ /**
+ * The other files of the project with the name of the file. Folders that
hold no sources of the app are left out:
+ * dot folders, build output and test sources.
+ */
+ private static List<Path> sameNamedFiles(Path dir, Path path) {
+ Path root = dir.toAbsolutePath().normalize();
+ Path self = path.toAbsolutePath().normalize();
+ String name = self.getFileName().toString();
+ List<Path> found = new ArrayList<>();
+ try {
+ Files.walkFileTree(root, EnumSet.noneOf(FileVisitOption.class),
12, new SimpleFileVisitor<>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path d,
BasicFileAttributes attrs) {
+ String n = d.getFileName() != null ?
d.getFileName().toString() : "";
+ String relative =
root.relativize(d).toString().replace('\\', '/');
+ if (!d.equals(root) && (n.startsWith(".") ||
"target".equals(n) || "build".equals(n)
+ || "node_modules".equals(n) ||
"src/test".equals(relative) || relative.endsWith("/src/test"))) {
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path f, BasicFileAttributes
attrs) {
+ if (attrs.isRegularFile() &&
name.equals(f.getFileName().toString())
+ && !self.equals(f.toAbsolutePath().normalize())) {
+ found.add(f);
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ } catch (IOException e) {
+ // best effort: without the list the write goes ahead as before
+ }
+ return found;
+ }
+
+ /**
+ * The file of the project that already defines the class a new Java
source would define (the same package and
+ * name), relative to the project directory, or null. Asked to change a
class of a camel run project, whose sources
+ * sit next to the routes, a model wrote a second copy under src/main/java
instead, 7 times out of 11 in a benchmark
+ * (CAMEL-25673): two classes of the same name, of which the runtime uses
one, while the change is in the other.
+ */
+ static String fileOfSameClass(Path dir, Path path, String content) {
+ String pkg = javaPackage(content);
+ Path root = dir.toAbsolutePath().normalize();
+ for (Path other : sameNamedFiles(dir, path)) {
+ if (pkg.equals(javaPackage(read(other)))) {
+ return
root.relativize(other.toAbsolutePath().normalize()).toString().replace('\\',
'/');
+ }
+ }
+ return null;
+ }
+
+ /**
+ * A note when a new beans.yaml or application.properties has the name of
a file the project already has in another
+ * folder: two files of that name are easy to mix up (CAMEL-25673). Null
for any other file, or when there is none.
+ */
+ static String sameNamedConfigNote(Path dir, Path path) {
+ String name = path.getFileName().toString();
+ boolean config = "application.properties".equals(name)
+ || name.startsWith("application-") &&
name.endsWith(".properties")
Review Comment:
Done in cce6313c50d4.
_Claude Code on behalf of @davsclaus._
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]