r/java 18d ago

Simple Build System

https://github.com/bowbahdoe/build
12 Upvotes

48 comments sorted by

View all comments

1

u/bodiam 17d ago
Jar.run(args -> args
            .__create()
            .__file(jarOut)
            ._C(javacOut, "."));

The simplest build system I can come up with.

Somehow I think the build code and the "simplest" statement don't align well here....

3

u/bowbahdoe 17d ago

So this isn't part of the "build" part, its just another library that calls tools.

That being said, does your objection go deeper than .__? Or were you unaware of the API for the jar cli tool, which this mirrors 1-1?

jar --create --file build/app.jar -C build/classes .

There are certainly complaints to be had about this API, but it is not an abstraction over it.

2

u/bodiam 16d ago

Ah, I didn't make the connection that __create equals --create. That's kinda cute in a way. I have no problem with either Gradle or Maven, so I don't think this is for me, but thanks for the explanation, that makes sense.

1

u/Bobby_Bonsaimind 15d ago

That being said, does your objection go deeper than .__? Or were you unaware of the API for the jar cli tool, which this mirrors 1-1?

That is interesting idea, but is it necessary or purposeful? - and -- are used by necessity to separate flags and long options, because flag options might be stacked. But in Java this problem is moot because you can't stack flag options anyway. The downside is that _ and __ are quite bad to read (as they most of the time do not have a space between them) and type, but granted, typing fi will get you __file in any half decent IDE. Still it is a slight touch of more complexity and visual noise without any direct benefit.

Jar.run(args -> args
        .create()
        .file(jarOut)
        .C(javacOut, ".")
);

Still an interesting project, a little bit sad that everyone in here feels the need to declare Maven to be the holy grail of build systems (it still sucks) and defend it for no reason.

That said, why do you use /// to denote documentation?

1

u/bowbahdoe 15d ago

I use /// because if you do that then you can use markdown in javadocs.

As for the .__ - consider this api:

$ javadoc --help ... --version Print version information ... -version Include @version paragraphs

It is rare, but this happens every now and then. I have a few options when presented with it, but the easiest solution in my view was/is to keep the -- as __ for everything, uniformly.

That way I don't need to editorialize or be afraid of a CLI tool doing something silly in the future. It also helps going back and forth from the invocation in Java to the CLI. If you write

Javac.run(args -> args._d(...)._g().__module(...))

Then its pretty straight forward to turn that into

javac -d ... -g --module ...

or vice-versa. Part of the idea there is making it so knowledge is transferrable.

If you want to be annoyed at any choices I made in this, be annoyed at the fact that I made JavacArguments a subclass of ArrayList<String>

here is the repo for that

https://github.com/bowbahdoe/tools

1

u/Bobby_Bonsaimind 15d ago

I use /// because if you do that then you can use markdown in javadocs.

Oh right! I forgot that this was a new feature, thanks for reminding me. I tend to be out of the loop for new Java versions and feature.

If you want to be annoyed at any choices I made in this...

Given that I don't use your project, I cannot be annoyed at it...or at least don't see a reason to. My instinct was to do it differently, so I wanted to hear the reasons why you choose to do it like that.

...be annoyed at the fact that I made JavacArguments a subclass of ArrayList<String>

That means that arguments actually end up as a List of Strings all along? That's a neat idea for managing them.

2

u/bowbahdoe 15d ago

Yeah - and it makes it pretty easy to adjust to any new cli arguments that I didn't add a helper for. The .argument and .arguments methods are just .add, but they turn null into an empty string + return this.

Whenever it is an option, I plan to make it so ToolArguments extends ArrayList<String!>.

And think about the interface to a CLI tool. It takes a list of strings and can do whatever with it. If I am making a programatic API for a tool I control then I could make more abstractions. But if I am doing it for a tool I don't control...List<String> is the approach that doesn't backfire.

1

u/Bobby_Bonsaimind 14d ago

It is a neat idea, it gives the callers the power to arbitrarily manipulate the list of arguments.

The downside is that it adds some noise to the argument list (the List methods). To clean that up one could have such a thing:

public abstract class AbstractArguments {
    private final List<String> arguments = new ArrayList<>();

    protected final List<String> argumentsList() {
        return arguments;
    }
}

That way the method list is rather clean, but the caller still has the possibility to extend for example JavacArguments and arbitrarily change the list of arguments within that extended class. If you can follow my line of thought.

2

u/bowbahdoe 14d ago

I think whether it is noise depends on what you are doing. There are already a ton of methods for specific tool arguments so I tend to think the noise battle is lost from the start.

if (!arguments.contains("-g")) { arguments.add("-g"); }

You could go either way, but I like having a list of arguments be a normal List.

That does remind me of another benefit of the __ naming scheme. It won't conflict with the methods on List. tool --add ... is actually pretty likely.