Add this to build.xml:
def u(x) {x.toString().replace("-", "_").replace(".", "_")}
new File("build.dot").text = """
digraph ant {
${project.targets.values().collect {target ->
target.dependencies.collect {dep ->
u(dep) + " -> " + u(target)
}.join("\n")
}.join("\n")}
}
"""
You will need to have the embeddable groovy-all.jar in Ant's classpath, e.g. in ~/.ant/lib/.
Then run "ant target-graph". It writes a build.dot file in the current directory.
Convert this into a picture using the GraphViz dot command:
dot -Tsvg -O build.dot
The results are surprisingly good.
Here's an example from the Apache commons-dbcp project:
I'm not going to show you the diagram I got for our system at work, the reason I wrote this script! The diagram is so big and complex, I was shocked. After being happy with Ant all these years, I think it's time to be getting serious about Gradle.
6 comments:
If you declare the taskdef classpath and taskdef separately
you don't have to put groovy in .ant/lib
If I am not mistaken, this will work only for that build.xml to which you are adding the groovy target. How about if I have a myriad of entangled build files, a ton of imports, and a universe of dependencies? This solution would be really practical if it worked for my situation.
I've used it with imported scripts.
Targets from imported scripts get their names prefixed with the 'name' attribute from the imported script.
So I have
where common-build has name "common", and in my diagram I get nodes "common.compile", "common.test" etc.
BTW my original version had trivial tag nesting issues with (not sure how that happened).
More importantly, you can improve the format of the result by using quotes around the node names, using:
target.dependencies.collect {dep ->
'"' + dep + '" -> "' + target + '"'
}.join("\n")
Argh, example is supposed to read
<import file="common-build.xml"/>
thank you John, I'll try to experiment with these solutions.
Vicki
Hi John what version of groovy are you using?
Post a Comment