Demonstrating features of the iwant build system
Java Shell C++ Python
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
common-resources 2 modules, distro target for running main Apr 20, 2017
iwant-demo-cli/src upgraded joulu to package-renamed version Jul 3, 2018
iwant-demo-math-lib/src 2 modules, distro target for running main Apr 20, 2017


A multi-module project that demonstrates features of the iwant build system

Quick start: Studying the code with Eclipse

After cloning this repository, cd to it and type your first wish to shell (remember that tab is your friend - oh, and you are expected to have bash and other standard unix tools in your path, as well as a Java SDK):


Note how you don't need to install or configure anything. A small amount of bootstrapping code will ensure you have the correct version of iwant serving your build wishes.

As this is the first wish, it forces the iwant bootstrapper to bootstrap iwant and generate more wishes. Use tab again and issue the next wish:


Note that we have to start with an exceptional way of using iwant: we wished for a side-effect, a mutation to the system. Most of the time we wish for targets instead, but since Eclipse dictates the location of its settings files and owns them, we have to be imperative here.

Now that you have the Eclipse settings generated, you can import the projects to Eclipse. (Don't copy them to the workspace, just import.)

Modules iwant-demo-wsdef and iwant-demo-wsdefdef define the build, and the rest of the modules are production modules. Your first entrypoint to the build is (Use shift-ctrl-T to open it with Eclipse.) It defines the actual build module. The entrypoint to the build, defined as string here, is From that you can navigate your way with ctrl-click.

Note how you can study how the build is defined by utilizing the Java type system and Eclipse navigation features instead of reading documentation and following loosely typed references and conventions.

Studying test coverage (aka "running the tests")

When you have finished your initial study of the code you can make your next wish to get a test coverage report and pipe it to a browser:

as-iwant-demo-developer/with/bash/iwant/target/jacoco-report-all/as-path | xargs -r chrome

Or, if you prefer fancier use of xargs, open the browser directly to the correct file:

as-iwant-demo-developer/with/bash/iwant/target/jacoco-report-all/as-path | xargs -r -Ixxx chrome xxx/index.html

Note how you didn't tell iwant to run tests. In fact, if you run the command again, it wont' run them because you didn't change the code coverage by touching anything. Even the methods of that define the target, jacocoReportAll and jacocoReport, don't mention anything imperative like running tests but just define nouns related to the report you are after.

Also note how all progress output of refreshing a target is printed to stderr, not stdout, so the output of the wish, the path of the target, is the only thing that goes to the next process in the pipeline - xargs and chrome in this case.

(Building and) running the application

To see the contents of the application cli distribution and to run it issue the following commands:

as-iwant-demo-developer/with/bash/iwant/target/cli-distro/as-path | xargs -r find
as-iwant-demo-developer/with/bash/iwant/target/cli-distro/as-path && as-iwant-demo-developer/.i-cached/target/cli-distro/

Note how easily includes all runtime dependencies of the application in the lib directory of the distribution.

Follow the error message of the application. For example, to print the first 4 prime numbers, type:

as-iwant-demo-developer/with/bash/iwant/target/cli-distro/as-path && as-iwant-demo-developer/.i-cached/target/cli-distro/ --primes 4

Using code to build during build: code generation

The cli demonstrates usage of a generated javabean, GeneratedBean, with the following command:

as-iwant-demo-developer/with/bash/iwant/target/cli-distro/as-path && as-iwant-demo-developer/.i-cached/target/cli-distro/ --generatedbean "new value"

See how defines generatedJavaBeansJava.jar as a jar of classes compiled from java files generated by a custom target,

The code generator is defined in a module that is not only built by the build system but also used by it during build. That's why it is defined very early, by and included as a dependency to the iwant-demo-wsdef module that defines most of the build.

Cache validity of a custom target

Note how declares the ingredients it needs for generating the java files. It not only declares the source file (generated-javabeans/beans.txt) it consumes as an ingredient, but also its own java file and the classpath location that contains the code generator, JavaBeanGenerator.class.

This makes sure the target will be refreshed if you touch any of the declared ingredients.

Try this by how touching generated-javabeans/beans.txt, or causes a refresh of the target generatedJavaBeansJava.classes when requesting for example for target cli-distro.

Also note how the target is not refreshed if none of its ingredients has changed.

Static code analysis with findbugs

You can get a findbugs report by running:

as-iwant-demo-developer/with/bash/iwant/target/findbugs-report/as-path | xargs -r -Ixxx chrome xxx/findbugs-report/findbugs-report.html

Code style and formatting

The project demonstrates customizing the code style policy for its modules in method commonSettings. The policies are defined in

The module iwant-demo-sloppy-legacy uses exceptional code formatting and style settings.

Note how easily you can enforce a zero tolerance of warnings even in a project with below-standard legacy code by relaxing opinionated default settings where needed.

Simple module compiled from sources from github

joulu unsigned-byte is a simple depencencyless module. The method jouluUnsignedByte of defines it as a java binary module compiled from sources downloaded from github.

To use it from the cli run

as-iwant-demo-developer/with/bash/iwant/target/cli-distro/as-path && as-iwant-demo-developer/.i-cached/target/cli-distro/ -u 3

Note how easy and natural it is to reuse code that hasn't even been "officially" published to a (maven) binary repository.

Case: gcc, static and dynamic linking, code generation (Anteru's build-systems example)

Anteru compares several build systems in his Build systems blog. He hosts the example project at bitbucket.

To be honest iwant is heavy for very simple (non-java) projects, because it requires some bootstrapping overhead (the wsdefdef and wsdef java modules) and, in practice, a heavy IDE for editing the build.

But as demonstrates, the actual target definitions of Anteru's example project are reasonably dry. (And the bigger the project, the drier it can be made with the power of Java and object oriented programming.)

To try out the example executable run

as-iwant-demo-developer/with/bash/iwant/target/anteru-build-systems-example/as-path && as-iwant-demo-developer/.i-cached/target/anteru-build-systems-example/

Note how the target is refreshed even when you make a trivial change to any shell command that defines a target. Even GNU make that otherwise is a very fine example of a declarative lazy build system falls for cache invalidation here.

Also note how easy it is to not only define parts of the application but also a full distribution directory with a run script.


There is a lot more you can do with iwant. Why don't you tell me what you want demonstrated next? Maybe challenge iwant with something that is especially difficult for other build systems. Or especially easy for them, for comparison. Or fork this project and do it yourself! Don't hesitate to ask for help.

- Ville Oikarinen (firstname at lastname dot org)

(author of iwant)