4

I found this question:

How can I get a list of build targets in Ant?

What I'd like to know: Is there a way to get a list of targets, together with their depends-on values? We have a large build.xml file and the way it's currently written the presence or absence of a description doesn't really tell me much as to whether a target is a main target or an "other" target.

Running ant 1.8.1, this is an initial bit of due diligence as I prepare to upgrade to Gradle so I need to figure out which targets are truly the "high level" targets and which ones are "supporting" targets.

Note I work in a locked-down environment so downloading third-party software or ant extensions is not an option.

Additional Note If this level of detail is not possible in ant, that is a valid answer as well

Community
  • 1
  • 1
StormeHawke
  • 5,987
  • 5
  • 45
  • 73

2 Answers2

8

In Ant 1.8.2 and above, use the -d flag to print debug info:

ant -p -d <your main build file>

and you'll get details like this:

 javadoc
   depends on: resolve
 javadoc.distribute
 latest-ivy
 package
   depends on: -maybe-package-by-bom, -maybe-package-by-spec, -maybe-package-for-dc

The -d flag will also print the "other" targets (those without descriptions) that aren't printed by ant -p, along with their dependencies.

gareth_bowles
  • 20,760
  • 5
  • 52
  • 82
  • What version of ant does your answer apply to? This does nothing different than running `ant -p -v` for me in 1.8.1, which doesn't list any dependencies – StormeHawke Oct 17 '13 at 21:56
  • 1
    I have 1.8.2 and get very different output from ant -p -d versus ant -p -v. – gareth_bowles Oct 17 '13 at 22:04
  • 2
    @StormeHawke: with Ant 1.9.1 I also get a nice dependency tree (using `-p -d`) –  Oct 17 '13 at 22:30
  • 1
    Ahha. From http://archive.apache.org/dist/ant/RELEASE-NOTES-apache-ant-1.8.2.html: "The project help (-p option in the command line) will now print the dependencies of the targets in debug mode (-d on the command line)". Looks like I'm stuck since I'm not allowed to update Ant in my locked-down build environment. If you'll note that your answer only applies to 1.8.2 and above, I'll mark your answer as accepted – StormeHawke Oct 18 '13 at 14:22
  • Thanks, @StormeHawke - sorry, I thought that feature had been in Ant forever. – gareth_bowles Oct 18 '13 at 16:33
  • If you're allowed to get copies of your build files, it wouldn't be hard to copy them somewhere on your local machine and install a newer version of Ant to get the dependency data. – gareth_bowles Oct 18 '13 at 16:41
  • Unfortunately we're not even allowed to update our local machines. No unapproved software downloads. Thanks though :) – StormeHawke Oct 18 '13 at 16:57
0

If you want a recursive tree listing, you can use this XQuery script with Saxon:

(:~
 : XQuery to display the dependencies of an Ant target.
 :
 : There are two modes of operation:
 :   1) Display all targets and immediate dependencies, specified by $project-file
 :   2) Show a tree of a single targets dependencies, this happens when $target-name is set as well.
 :
 : External parameters:
 :  $project-file The initial Ant file to start parsing from (imports will be expanded)
 :  $target-name If specified we examine only a single target and produce a tree of all dependencies (recursively)
 :  $show-file Whether the file path of the dependency should be shown
 : 
 : Example Usage: java -cp Saxon-HE-9.7.0-18.jar net.sf.saxon.Query -q:ant-show-deps.xqy \!indent=yes project-file=file:/Users/are/exist-git/build.xml target-name=installer show-file=true
 :
 : If you don't want to specify the $target-name you can pass ?target-name=\(\) to Saxon on the command line.
 :
 : @author Adam Retter
 :)
xquery version "1.0";

declare variable $project-file external;
declare variable $target-name as xs:string? external;
declare variable $show-file as xs:boolean external;

declare function local:expand-import-targets($file as xs:string) as element(target)* {
    local:expand-import-targets($file, ())
};

declare function local:expand-import-targets($file as xs:string, $visited as xs:string*) as element(target)* {
    let $path := local:resolve($file, $visited[1])
    return
        if(not($visited = $path))then
            let $imported-project := doc($path)/project
            return
            (
                for $target in $imported-project/target
                return
              <target name="{$target/@name}" file="{$path}">
                  {
                  for $dependency in tokenize(replace($target/@depends, '\s+', ''), ',')
                  return
                      <dependency name="{$dependency}"/>
                  }
              </target>
                ,
                for $import in $imported-project/import
                return
                    local:expand-import-targets($import/@file, ($path, $visited))
            )
        else()
};

declare function local:resolve($file as xs:string, $prev-file as xs:string?) {
    if(not($prev-file))then
        $file
    else if(starts-with($file, "/") or starts-with($file, "file:/"))then
        $file
    else
        resolve-uri($file, $prev-file)
};

declare function local:target-tree($target-name as xs:string, $targets as element(target)*) as element(target)? {
    let $target := $targets[@name eq $target-name]
    return
        element target {
            $target/@name,
            if($show-file)then
                $target/@file
            else(),
            for $dependency in $target/dependency
            return
                local:expand-dependency($dependency/@name, $targets)
        }
};

declare function local:expand-dependency($dependency-name as xs:string, $targets as element(target)*) {
    for $expanded in $targets[@name eq $dependency-name]
    return
        element dependency {
            $expanded/@name,
            if($show-file)then
                $expanded/@file
            else(),
            for $sub-dependency in $expanded/dependency
            return
                local:expand-dependency($sub-dependency/@name, $targets)
        }
};

let $targets := local:expand-import-targets($project-file)
return
    if($target-name)then
        local:target-tree($target-name, $targets)
    else
        <targets>
        {
            for $target in $targets
            order by $target/@name
            return $target
        }
        </targets>
adamretter
  • 3,885
  • 2
  • 23
  • 43