Fork me on GitHub
#java
<
2022-01-17
>
emccue22:01:35

So for those following the saga of me trying to present tools.deps in a way that is oriented toward java projects for an audience of 0 - how would people feel about this syntax

jproject javac --class-path ,,, -d target/classes 
jproject javac --module-path ,,, -d target/classes 
jproject -A:build javac --module-path ,,, -d target/classes 
Which would translate effectively to
javac --class-path $(clj -Spath) -d target/classes
javac --module-path $(clj -Spath) -d target/classes 
javac --module-path $(clj -A:build -Spath) -d target/classes

emccue22:01:31

Basically the hint i took from bach was that there is a somewhat sensible workflow with standard java tools to compile a modular project, so i’m leaning into supporting the ToolProvider SPI from the command line

Available in every alias
-------------------------
jar          create an archive for classes and resources, and manipulate or restore individual classes or resources from an archive
javac        read Java declarations and compile them into class files
javadoc      generate HTML pages of API documentation from Java source files
javap        disassemble one or more class files
jdeps        launch the Java class dependency analyzer
jlink        assemble and optimize a set of modules and their dependencies into a custom runtime image
jmod         create JMOD files and list the content of existing JMOD files
jpackage     tool for packaging self-contained Java applications

Available in :google-java-format
-------------------------
google-java-format

Available in :jreleaser
-------------------------
jreleaser    release automation tool for Java projects.

Available in :junit
-------------------------
junit        launches the JUnit Platform from the console
With the thought that a build program can get a basis object and invoke these tools to do most of its work

emccue22:01:47

so those invocations would look kinda like

var basis = Basis.builder().alias("junit").build();
var javac = ToolProvider.findFirst("javac").orElseThrow();
var javacRunResult = javac.run(
    System.out, 
    System.err,
    List.of(
        "--class-path",
        basis.path(),
        "-g",
        "-d",
        "target/classes"
    )
);
if (javacRunResult != 0) {
    System.exit(javacRunResult);
}
// more code here

emccue22:01:51

and the reason i would want that vs the api that tool.build provides is that a java project might want to use --module-path instead of class-path

emccue22:01:26

and if have a CLI that directly exposes tools, you could write a jar file that if its in the alias you get run, compile, build, etc - all the modern conveniences you can get from assuming a project layout or structure (like “only modules” or “everything follows the src/main/java, etc structure”)

emccue22:01:16

but not every tool would be uniform in how it takes the computed dependency path, hence the idea of just having people write ,,,

emccue23:01:52

at which point the only thing I would really be taking from tools.build is the uberjar shortcut - the basis comes from tools deps and the rest of it - file system utils, git utils - isn’t that crucial

emccue23:01:20

so i could make a few artifacts • one that depends on tools.deps and provides a Basis class • one that depends on the Basis class and provides a sub-interface of ToolProvider that would let tools optionally give more info to jproject

public interface ProjectToolProvider extends ToolProvider {
    // Can be used in lieu of hard coded dep information
    String description();
    // alleviate the need for that ,,, hack if the tool can make do without it
    Optional<ToolProvider> inBasis(Basis basis);
}
• An executable CLI built with graalvm that has tools.deps and all this tool resolution logic • an uberjar helper that depends on Basis • An example build program that could be subclassed/copy pasted that does basic stuff (maybe 1 for module-like projects, one where the end goal is an uberjar) • An example set of build tools that you can plug in as your build program in the CLI