"What is this file called cool-app.jar?"
If you had to answer a question like this, you would probably answer something like
"It is a (zip) file that contains the main (i.e. not test) java classes of cool-app."
Or, the same using iwant:
"Well, what are the java classes, then?"
"They are bytecode compiled from the main java files of cool-app."
"And what are the java files?"
"They are text files written and maintained by the developers."
The answers here are examples of declarative definitions. They answer to questions that start with what by describing file content. The focus is in in nouns.
One of the main principles of iwant is that build script authors and users declare what they want. The question of how, the imperative part, or the verbs, belongs to developers of iwant and its plugins.If only it wasn't so difficult to know what to want...
In the java snippets above we can see two kinds of objects: Sources and Targets.
Generally, in the context of building, a source is a file that is directly edited by the developers of the project. And a target is a file that is (automatically) derived from other files. (Note that this differs from the compiler terminology, where compilers consume sources and produce binaries. Using the build terminology, the "source" files consumed by a compiler may actually be targets, if they have been generated by a code generator.)
In other words, Sources are written by iwant users only, Targets by iwant only.
In iwant terminology Sources and Targets are both called Paths. So, an iwant Target is a Path with content derived from other Paths. The other Paths are called the ingredients of the Target.
For example, in the snippets above we can see that the definition of coolAppMainClasses refers to coolAppMainJava, so the latter is an ingredient to the former.
The declarative, referentially transparent nice graph of objects is a simple and powerful model that makes lazy concurrent building possible.
Unfortunately, the real world is more complex.
iwant can only guarantee correct lazy building, if it has full control over the files it has generated. But this is not always possible.
A remotely running deployment of an application is an example of such a build artifact. The remote machine may have crashed or some administrator may have made modifications. So even if none of the ingredients have been modified, iwant cannot know if files need to be transferred again or the application restarted.
One option is to just use iwant to define a script/program that does the deployment. The script is fully under iwant control, and can be refreshed and rerun whenever the user thinks it is needed.
But iwant also supports side-effects directly. A side-effect is a piece of code that is executed every time the user requests it, unlike target code that is only executed if needed.
These two concepts, Target and SideEffect, are so different in nature, that both the API and the user interface of iwant make a very clear distinction between them, so there will be no surprises to the users.
This concludes the introduction of the most important concepts. It is all still very abstract, so let's see all of them in action in the following chapters, starting from the very beginning.