Created
September 25, 2017 15:03
-
-
Save adamretter/ce5407cb8a2f97b9d891760e4c72c2ef to your computer and use it in GitHub Desktop.
XQuery to display the dependencies tree of an Ant target
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(:~ | |
: 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 <[email protected]> | |
:) | |
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}"/> | |
, | |
for $extern in $target/(ant | antcall) | |
return | |
if(local-name($extern) eq "ant")then | |
element ant { | |
$extern/@* | |
} | |
else if(local-name($extern) eq "antcall")then | |
<antcall name="{$extern/@target}"/> | |
else() | |
} | |
</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) | |
, | |
$target/(ant | antcall) | |
} | |
}; | |
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) | |
, | |
$expanded/(ant | antcall) | |
} | |
}; | |
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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment