Skip to content
Skip to breadcrumbs
Skip to header menu
Skip to action menu
Skip to quick search
Quick Search
Browse
Pages
Blog
Labels
Attachments
Mail
Advanced
What’s New
Space Directory
Feed Builder
Keyboard Shortcuts
Confluence Gadgets
Log In
Sign Up
Dashboard
Groovy
Copy Page
You are not logged in. Any changes you make will be marked as
anonymous
. You may want to
Log In
if you already have an account. You can also
Sign Up
for a new account.
This page is being edited by
.
Paragraph
Paragraph
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Preformatted
Quote
Bold
Italic
Underline
More colours
Strikethrough
Subscript
Superscript
Monospace
Clear Formatting
Bullet list
Numbered list
Outdent
Indent
Align left
Align center
Align right
Link
Table
Insert
Insert Content
Image
Link
Attachment
Symbol
Emoticon
Wiki Markup
Horizontal rule
tinymce.confluence.insert_menu.macro_desc
Info
JIRA Issue
Status
Gallery
Tasklist
Table of Contents
Other Macros
Page Layout
No Layout
Two column (simple)
Two column (simple, left sidebar)
Two column (simple, right sidebar)
Three column (simple)
Two column
Two column (left sidebar)
Two column (right sidebar)
Three column
Three column (left and right sidebars)
Undo
Redo
Find/Replace
Keyboard Shortcuts Help
<p>I think the biggest challenge for our build system is how to implement multiproject builds. It is likely that most of users will do multiproject builds.</p> <h3>Vision</h3> <ul> <li>Gant enables DRY for multiproject builds. This is were Ant has massively failed so far.</li> <li>Gant offers an intuitive way to write a multiproject build.</li> <li>Gant offers out of the box functionality for standard Java build tasks, which will grow from release to release.</li> <li>Gant offers maximum flexibility for customization. This is were Maven has massively failed.</li> </ul> <h3>Directory structure for multiproject builds</h3> <p>I think it is good to be very flexible regarding the possible directory structures. For Steven's use case it was good enough to assume that all projects are toplevel folders of the root folder. But there are many situations were this structure is not expressive enough and therefore should not be imposed.</p> <p>In my last project we had a structure like:</p> <ul> <li>shared</li> <li>client</li> <li>...</li> <li>services <ul> <li>services-shared</li> <li>service1</li> <li>...</li> <li>serviceN</li> </ul> </li> </ul> <p>And I'm sure there are much more complicated project structures out there which can't be changed or people don't want to change them. I propose to have only one assumption. There is a root folder were we (might) have a top level buildfile and all projects folder must be contained somewhere in this root folder.</p> <h3>Determining the projects to be build</h3> <p>Even if I do not consider pathological cases, automatically determining the projects to be build is not easy or at least not cheap. The rule would be that everything is a project which contains a buildfile. If we look at the projects layout described in the section above (nested projects), we would have to scan many, many folders to look for the buildfiles (e.g. src/main/java/org/codehaus/.....). We could try to be smart and have the policy not to look in folders with name src. But the name src is just a convention and could be changed by the user. We could read the configuration of a found project first and then continue our search. But there might be some folder in a project with many files and subfolder which just sits there (e.g. not in use any longer but people don't want to delete it). For every build that is triggered we would have to scan this folder to look for buildfiles. I think an easy way out of this problem is that people have to declare the projects to be build in a top level build file. This has also the advantage to have a static file containing the projects layout.</p> <h2>Implementation</h2> <p>I've been thinking a lot about this in the last days. I think I have a solution I'm happy with now. It is very much inspired from looking at the code of buildr.</p> <h3>Endresult</h3> <p>After processing all the build scripts, our new Gant will produce one classic Gant build script (im memory). So the complete multiproject build is finally described by exactly one flat list of targets which are related by dependency relations.</p> <h3>How to get there</h3> <p>Every subproject is represented by an instance of a Project object. This Project object is amongst other things a container for target object. For each Project object we create a set of default target instances (e.g. compile, test, ...) which we add to the Project object. Every Project must have a unique name (parent-project-name + project-name). The target instances of a Project object have the name: project-name+target-name.</p> <h3>Customization of the default targets</h3> <p>The default targets are not simple target objects. I think about creating for example a class Compile which extendss the class Target. That means the compile target is a target but also a special compile object, that offers methods for customization and of course the action for actually doing the compile.</p> <p>In our build script we could write for example <code>target("compile").with classpath</code>. Or even better <code>compile.with classpath</code>.</p> <h3>Adding new behavior</h3> <p>For this feature I guess we have to extend the classic Gant a little bit. We might make it a bit more Rakish. Basically I have two additional methods for a target in mind:</p> <ul> <li>target("compile").dependsOn(otherTarget1, otherTarget2, ...)</li> <li>target("compile").addAction { ... }</li> </ul> <p>To add behavior we can now either create a new target in our build script and make a default target dependent on it. Or we can simply add behavior to an existing target, which gets executed after the default behavior is executed.</p> <p>When I talk about the build script I have in mind that every subproject has its build script. That means the behavior changes described above only apply to the build of this particular subproject. If we want a more general change, we have a couple of possibilities. In the build script of a parent project we can say:</p> <ul> <li>something like this.getChildren().each(add behavior)</li> <li>addRecursiveTarget(target)</li> </ul> <h3>Interproject dependencies</h3> <p>I think we don't have to explicitly declare them. If there is such a dependency, it means somewhere in the build script of the project that depends on the other project, it refers to this other project anyway. For example <code>compile.with project("otherProject").classpath</code>.</p> <h3>Conclusions</h3> <p>Of course there are many details to hammer out. But I'm confident enough now to start implementing something based on the above ideas if we all think this makes sense.</p>
Please type the word appearing in the picture.
Attachments
Labels
Location
Watch this page
< Edit
Preview >
Loading…
Save
Cancel
Next hint
search
attachments
weblink
advanced