mirror of
https://github.com/rife2/bld
synced 2026-08-05 07:07:48 +02:00
Compare commits
No commits in common. "b9577c225666e67d3ef342e638339ad640c584ba" and "c005bf42d2ef5556f4a85225b305037d11321276" have entirely different histories.
b9577c2256
...
c005bf42d2
2
core
2
core
|
|
@ -1 +1 @@
|
||||||
Subproject commit eaa498c55de76d2fa0280ffd592353bcd1aaaac6
|
Subproject commit fb2e5022e5c1d125e45227b49076c2b200763986
|
||||||
|
|
@ -11,8 +11,6 @@ import rife.bld.operations.*;
|
||||||
import rife.tools.FileUtils;
|
import rife.tools.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
@ -927,40 +925,14 @@ public class BaseProject extends BuildExecutor {
|
||||||
* <p>
|
* <p>
|
||||||
* If the local dependency points to a directory, it will be scanned for jar files.
|
* If the local dependency points to a directory, it will be scanned for jar files.
|
||||||
*
|
*
|
||||||
* @param path the file system path (absolute or relative to the {@link #workDirectory})
|
* @param path the file system path of the local dependency
|
||||||
* of the local dependency
|
|
||||||
* @since 1.5.2
|
* @since 1.5.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public LocalDependency local(String path) {
|
public LocalDependency local(String path) {
|
||||||
return new LocalDependency(path);
|
return new LocalDependency(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a local dependency instance.
|
|
||||||
* <p>
|
|
||||||
* If the local dependency points to a directory, it will be scanned for jar files.
|
|
||||||
*
|
|
||||||
* @param path the file system path (absolute or relative to the {@link #workDirectory})
|
|
||||||
* of the local dependency
|
|
||||||
* @since 2.4.0
|
|
||||||
*/
|
|
||||||
public LocalDependency local(Path path) {
|
|
||||||
return new LocalDependency(path.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a local dependency instance.
|
|
||||||
* <p>
|
|
||||||
* If the local dependency points to a directory, it will be scanned for jar files.
|
|
||||||
*
|
|
||||||
* @param path the file system path (absolute or relative to the {@link #workDirectory})
|
|
||||||
* of the local dependency
|
|
||||||
* @since 2.4.0
|
|
||||||
*/
|
|
||||||
public LocalDependency local(File path) {
|
|
||||||
return new LocalDependency(path.getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new module instance.
|
* Creates a new module instance.
|
||||||
*
|
*
|
||||||
|
|
@ -1104,40 +1076,14 @@ public class BaseProject extends BuildExecutor {
|
||||||
* <p>
|
* <p>
|
||||||
* If the local module points to a directory, it will be scanned for jar files.
|
* If the local module points to a directory, it will be scanned for jar files.
|
||||||
*
|
*
|
||||||
* @param path the file system path (absolute or relative to the {@link #workDirectory})
|
* @param path the file system path of the local module
|
||||||
* of the local module
|
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public LocalModule localModule(String path) {
|
public LocalModule localModule(String path) {
|
||||||
return new LocalModule(path);
|
return new LocalModule(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a local module instance.
|
|
||||||
* <p>
|
|
||||||
* If the local module points to a directory, it will be scanned for jar files.
|
|
||||||
*
|
|
||||||
* @param path the file system path (absolute or relative to the {@link #workDirectory})
|
|
||||||
* of the local module
|
|
||||||
* @since 2.4.0
|
|
||||||
*/
|
|
||||||
public LocalModule localModule(Path path) {
|
|
||||||
return new LocalModule(path.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a local module instance.
|
|
||||||
* <p>
|
|
||||||
* If the local module points to a directory, it will be scanned for jar files.
|
|
||||||
*
|
|
||||||
* @param path the file system path (absolute or relative to the {@link #workDirectory})
|
|
||||||
* of the local module
|
|
||||||
* @since 2.4.0
|
|
||||||
*/
|
|
||||||
public LocalModule localModule(File path) {
|
|
||||||
return new LocalModule(path.getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Project directories
|
* Project directories
|
||||||
*/
|
*/
|
||||||
|
|
@ -1996,25 +1942,14 @@ public class BaseProject extends BuildExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addLocalJars(List<File> jars, String path) {
|
private void addLocalJars(List<File> jars, String path) {
|
||||||
var local_path = Path.of(path);
|
var local_file = new File(workDirectory(), path);
|
||||||
if (!local_path.isAbsolute()) {
|
if (local_file.exists()) {
|
||||||
local_path = workDirectory().toPath().resolve(path);
|
if (local_file.isDirectory()) {
|
||||||
}
|
var local_jar_files = FileUtils.getFileList(local_file.getAbsoluteFile(), INCLUDED_JARS, EXCLUDED_JARS);
|
||||||
|
jars.addAll(new ArrayList<>(local_jar_files.stream().map(file -> new File(local_file, file)).toList()));
|
||||||
if (!Files.exists(local_path)) {
|
} else {
|
||||||
if (verbose()) {
|
jars.add(local_file);
|
||||||
System.err.println("Invalid local dependency or module path, skipped: " + path);
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Files.isDirectory(local_path)) {
|
|
||||||
var local_jar_files = FileUtils.getFileList(local_path.toFile(), INCLUDED_JARS, EXCLUDED_JARS);
|
|
||||||
for (var jar : local_jar_files) {
|
|
||||||
jars.add(local_path.resolve(jar).toFile());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
jars.add(local_path.toFile());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,327 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2026 Erik C. Thauvin (https://erik.thauvin.net/)
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
|
||||||
*/
|
|
||||||
package rife.bld;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.*;
|
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
|
||||||
import rife.bld.dependencies.Scope;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
class TestBaseProject {
|
|
||||||
private static Method ADD_LOCAL_JARS;
|
|
||||||
@TempDir
|
|
||||||
Path tempDir;
|
|
||||||
private BaseProject project;
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
static void initReflection() throws Exception {
|
|
||||||
ADD_LOCAL_JARS = BaseProject.class.getDeclaredMethod("addLocalJars", List.class, String.class);
|
|
||||||
ADD_LOCAL_JARS.setAccessible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void beforeEach() {
|
|
||||||
project = new BaseProject();
|
|
||||||
project.workDirectory = tempDir.toFile();
|
|
||||||
project.createProjectStructure();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void invokeAddLocalJars(List<File> jars, String path) throws Exception {
|
|
||||||
ADD_LOCAL_JARS.invoke(project, jars, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
@DisplayName("local(Path) and local(File)")
|
|
||||||
class LocalDependencyTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("local(Path) relative should resolve via workDirectory")
|
|
||||||
void localPathRelative() throws Exception {
|
|
||||||
var jar = Files.createFile(tempDir.resolve("a.jar"));
|
|
||||||
var dep = project.local(Path.of("a.jar"));
|
|
||||||
|
|
||||||
assertAll(
|
|
||||||
() -> assertNotNull(dep, "local(Path) should not return null"),
|
|
||||||
() -> assertEquals("a.jar", dep.path(), "relative Path should be kept as-is")
|
|
||||||
);
|
|
||||||
|
|
||||||
project.dependencies().scope(Scope.compile).include(dep);
|
|
||||||
assertTrue(project.compileClasspathJars().stream()
|
|
||||||
.anyMatch(f -> f.getAbsolutePath().equals(jar.toFile().getAbsolutePath())),
|
|
||||||
"compileClasspathJars should resolve relative path against workDirectory");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("local(Path) absolute should be kept absolute")
|
|
||||||
void localPathAbsolute() throws Exception {
|
|
||||||
var jar = Files.createFile(tempDir.resolve("abs.jar"));
|
|
||||||
var dep = project.local(jar);
|
|
||||||
|
|
||||||
assertAll(
|
|
||||||
() -> assertNotNull(dep, "local(Path) absolute should not return null"),
|
|
||||||
() -> assertEquals(jar.toString(), dep.path(), "absolute Path should be kept absolute")
|
|
||||||
);
|
|
||||||
|
|
||||||
project.dependencies().scope(Scope.compile).include(dep);
|
|
||||||
assertTrue(project.compileClasspathJars().stream()
|
|
||||||
.anyMatch(f -> f.getName().equals("abs.jar")),
|
|
||||||
"compileClasspathJars should include absolute Path dependency");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("local(File) relative file should be kept as-is")
|
|
||||||
void localFileRelative() {
|
|
||||||
var dep = project.local(new File("b.jar"));
|
|
||||||
|
|
||||||
assertAll(
|
|
||||||
() -> assertNotNull(dep, "local(File) should not return null"),
|
|
||||||
() -> assertEquals("b.jar", dep.path(), "relative File should be kept as-is")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("local(Path) absolute outside the project should resolve")
|
|
||||||
void localPathAbsoluteOutsideProject(@TempDir Path otherDir) throws Exception {
|
|
||||||
var jar = Files.createFile(otherDir.resolve("outside.jar"));
|
|
||||||
project.dependencies().scope(Scope.compile).include(project.local(jar));
|
|
||||||
|
|
||||||
assertTrue(project.compileClasspathJars().stream()
|
|
||||||
.anyMatch(f -> f.getAbsolutePath().equals(jar.toFile().getAbsolutePath())),
|
|
||||||
"compileClasspathJars should include an absolute path outside the project");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("local(File) absolute file")
|
|
||||||
void localFileAbsolute() throws Exception {
|
|
||||||
var jar = Files.createFile(tempDir.resolve("c.jar"));
|
|
||||||
var dep = project.local(jar.toFile());
|
|
||||||
|
|
||||||
assertAll(
|
|
||||||
() -> assertNotNull(dep, "local(File) absolute should not return null"),
|
|
||||||
() -> assertEquals(jar.toFile().getAbsolutePath(), dep.path(),
|
|
||||||
"absolute File should be kept absolute")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("local(File) directory should scan jars excluding sources/javadoc")
|
|
||||||
void localFileDirectory() throws Exception {
|
|
||||||
var dir = Files.createDirectory(tempDir.resolve("libs-dep-filter"));
|
|
||||||
Files.createFile(dir.resolve("one.jar"));
|
|
||||||
Files.createFile(dir.resolve("one-sources.jar"));
|
|
||||||
Files.createFile(dir.resolve("one-JAVADOC.jar"));
|
|
||||||
|
|
||||||
var dep = project.local(dir.toFile());
|
|
||||||
project.dependencies().scope(Scope.compile).include(dep);
|
|
||||||
|
|
||||||
var cp = project.compileClasspathJars();
|
|
||||||
assertAll(
|
|
||||||
() -> assertTrue(cp.stream().anyMatch(
|
|
||||||
f -> f.getName().equals("one.jar")), "regular jar should be included"),
|
|
||||||
() -> assertFalse(cp.stream().anyMatch(f -> f.getName().equals("one-sources.jar")),
|
|
||||||
"sources jar should be excluded (case-insensitive)"),
|
|
||||||
() -> assertFalse(cp.stream().anyMatch(
|
|
||||||
f -> f.getName().toLowerCase().contains("javadoc")),
|
|
||||||
"javadoc jar should be excluded")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("local(Path) and local(String) should behave same")
|
|
||||||
void parityWithStringOverload() throws Exception {
|
|
||||||
Files.createFile(tempDir.resolve("parity.jar"));
|
|
||||||
|
|
||||||
var fromString = project.local("parity.jar");
|
|
||||||
var fromPath = project.local(Path.of("parity.jar"));
|
|
||||||
var fromFile = project.local(new File("parity.jar"));
|
|
||||||
|
|
||||||
assertAll(
|
|
||||||
() -> assertEquals(fromString.path(), fromPath.path(),
|
|
||||||
"String and Path overloads should have same path()"),
|
|
||||||
() -> assertEquals(fromString.path(), fromFile.path(),
|
|
||||||
"String and File overloads should have same path()")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
@DisplayName("addLocalJars - private implementation")
|
|
||||||
class LocalJarsTest {
|
|
||||||
@Test
|
|
||||||
@DisplayName("should add relative file path")
|
|
||||||
void relativeFile() throws Exception {
|
|
||||||
Files.createFile(tempDir.resolve("my.jar"));
|
|
||||||
var jars = new ArrayList<File>();
|
|
||||||
invokeAddLocalJars(jars, "my.jar");
|
|
||||||
assertEquals(1, jars.size(), "relative file that exists should be added");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("should add absolute file path")
|
|
||||||
void absoluteFile() throws Exception {
|
|
||||||
var jar = Files.createFile(tempDir.resolve("abs2.jar"));
|
|
||||||
var jars = new ArrayList<File>();
|
|
||||||
invokeAddLocalJars(jars, jar.toAbsolutePath().toString());
|
|
||||||
assertEquals(1, jars.size(), "absolute file that exists should be added");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("should resolve relative to workDirectory")
|
|
||||||
void relativeToWorkDirectory() throws Exception {
|
|
||||||
var sub = Files.createDirectory(tempDir.resolve("sub"));
|
|
||||||
var jar = Files.createFile(sub.resolve("x.jar"));
|
|
||||||
var jars = new ArrayList<File>();
|
|
||||||
invokeAddLocalJars(jars, "sub/x.jar");
|
|
||||||
assertEquals(jar.toFile().getAbsoluteFile(), jars.get(0).getAbsoluteFile(),
|
|
||||||
"should resolve against workDirectory");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("should scan directory for jars only")
|
|
||||||
void directoryScansJars() throws Exception {
|
|
||||||
var libDir = Files.createDirectory(tempDir.resolve("libs-jars-scan"));
|
|
||||||
Files.createFile(libDir.resolve("a.jar"));
|
|
||||||
Files.createFile(libDir.resolve("b.jar"));
|
|
||||||
Files.createFile(libDir.resolve("not-a-jar.txt"));
|
|
||||||
var jars = new ArrayList<File>();
|
|
||||||
invokeAddLocalJars(jars, "libs-jars-scan");
|
|
||||||
assertEquals(2, jars.size(), "should only include .jar files");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("should exclude -sources and -javadoc jars in directory")
|
|
||||||
void directoryExcludesSourcesAndJavadoc() throws Exception {
|
|
||||||
var libDir = Files.createDirectory(tempDir.resolve("libs2-filter"));
|
|
||||||
Files.createFile(libDir.resolve("foo.jar"));
|
|
||||||
Files.createFile(libDir.resolve("foo-sources.jar"));
|
|
||||||
Files.createFile(libDir.resolve("foo-javadoc.jar"));
|
|
||||||
var jars = new ArrayList<File>();
|
|
||||||
invokeAddLocalJars(jars, "libs2-filter");
|
|
||||||
assertAll(
|
|
||||||
() -> assertEquals(1, jars.size(), "should filter out -sources and -javadoc"),
|
|
||||||
() -> assertEquals("foo.jar", jars.get(0).getName(), "only foo.jar should remain")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
@DisplayName("integration via public classpath methods")
|
|
||||||
class Integration {
|
|
||||||
@Test
|
|
||||||
@DisplayName("compileClasspathJars should include local file dependency")
|
|
||||||
void viaCompileClasspath() throws Exception {
|
|
||||||
var myJar = Files.createFile(tempDir.resolve("custom.jar"));
|
|
||||||
project.dependencies().scope(Scope.compile).include(project.local("custom.jar"));
|
|
||||||
var classpath = project.compileClasspathJars();
|
|
||||||
assertTrue(classpath.stream().anyMatch(
|
|
||||||
f -> f.getAbsolutePath().equals(myJar.toFile().getAbsolutePath())),
|
|
||||||
"compileClasspathJars should include local file dependency");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
@DisplayName("verbose branch")
|
|
||||||
class VerboseBranch {
|
|
||||||
@BeforeEach
|
|
||||||
void enableVerbose() {
|
|
||||||
project = new BaseProject() {
|
|
||||||
@Override
|
|
||||||
public boolean verbose() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
project.workDirectory = tempDir.toFile();
|
|
||||||
project.createProjectStructure();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("should skip non-existent path without throwing, even verbose")
|
|
||||||
void nonExistentPathSkipped() {
|
|
||||||
var jars = new ArrayList<File>();
|
|
||||||
assertDoesNotThrow(() -> invokeAddLocalJars(jars, "does-not-exist-verbose"),
|
|
||||||
"should not throw for missing path");
|
|
||||||
assertTrue(jars.isEmpty(), "non-existent path should be skipped");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
@DisplayName("localModule(Path) and localModule(File)")
|
|
||||||
class LocalModuleTest {
|
|
||||||
@Test
|
|
||||||
@DisplayName("localModule(Path) relative")
|
|
||||||
void localModulePathRelative() {
|
|
||||||
var mod = project.localModule(Path.of("mod.jar"));
|
|
||||||
assertAll(
|
|
||||||
() -> assertNotNull(mod, "should not return null"),
|
|
||||||
() -> assertEquals("mod.jar", mod.path(), "relative path kept as-is")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("localModule(Path) absolute")
|
|
||||||
void localModulePathAbsolute() throws Exception {
|
|
||||||
var jar = Files.createFile(tempDir.resolve("modAbs.jar"));
|
|
||||||
var mod = project.localModule(jar);
|
|
||||||
assertAll(
|
|
||||||
() -> assertNotNull(mod, "should not return null"),
|
|
||||||
() -> assertEquals(jar.toString(), mod.path(), "absolute path kept absolute")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("localModule(File) absolute")
|
|
||||||
void localModuleFileAbsolute() throws Exception {
|
|
||||||
var jar = Files.createFile(tempDir.resolve("mod2.jar"));
|
|
||||||
var mod = project.localModule(jar.toFile());
|
|
||||||
assertAll(
|
|
||||||
() -> assertNotNull(mod, "should not return null"),
|
|
||||||
() -> assertEquals(jar.toFile().getAbsolutePath(), mod.path(),
|
|
||||||
"absolute File should be kept absolute")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("localModule(File) directory scan")
|
|
||||||
void localModuleFileDirectory() throws Exception {
|
|
||||||
var dir = Files.createDirectory(tempDir.resolve("mods-filter"));
|
|
||||||
Files.createFile(dir.resolve("m1.jar"));
|
|
||||||
Files.createFile(dir.resolve("m1-javadoc.jar"));
|
|
||||||
|
|
||||||
var mod = project.localModule(dir.toFile());
|
|
||||||
project.dependencies().scope(Scope.compile).include(mod);
|
|
||||||
|
|
||||||
var mp = project.compileModulePathJars();
|
|
||||||
assertAll(
|
|
||||||
() -> assertTrue(mp.stream().anyMatch(f -> f.getName().equals("m1.jar")),
|
|
||||||
"regular jar should be in module path"),
|
|
||||||
() -> assertFalse(mp.stream().anyMatch(f -> f.getName().contains("javadoc")),
|
|
||||||
"javadoc jar should be excluded")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@DisplayName("all three overloads are consistent")
|
|
||||||
void overloadsConsistent() throws Exception {
|
|
||||||
Files.createFile(tempDir.resolve("cons.jar"));
|
|
||||||
|
|
||||||
var s = project.localModule("cons.jar");
|
|
||||||
var p = project.localModule(Path.of("cons.jar"));
|
|
||||||
var f = project.localModule(new File("cons.jar"));
|
|
||||||
|
|
||||||
assertAll(
|
|
||||||
() -> assertEquals(s.path(), p.path(), "String and Path overloads equal"),
|
|
||||||
() -> assertEquals(s.path(), f.path(), "String and File overloads equal")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue