This topic tells you about the Application Accelerator InvokeFragment
transform in Tanzu Application Platform (commonly known as TAP).
The InvokeFragment
performs transformations defined in an imported Fragment, allowing re-use across accelerators.
engine{
InvokeFragment(FRAGMENT-NAME)
}
Where FRAGMENT-NAME
is the name of your fragment.
If, for example, the fragment my-fragment
is imported into the accelerator, which exposes the options it defines as options of the current accelerator, the following construct invokes my-fragment
:
InvokeFragment('my-fragment')
This passes all input files, depending where this invocation sits in the tree, to the invoked fragment. The invoked fragment can then manipulate the input files alongside its own files. The result of the invocation becomes the result of this transform.
At the point of invocation, all currently defined variables are made visible to the invoked fragment. Therefore, if it was import
-ed in the most straightforward manner, a fragment defining an option myOption
is defining an option named myOption
at the accelerator level, and the value provided by the user is visible at the time of invocation.
To override a value, or if an imported option has been exposed under a different name, or not at all, you can use a let
construct when using InvokeFragment
. This behaves as the Let transform: for the duration of the fragment invocation, the variables defined by let
now have their newly defined values. Outside the scope of the invocation, the regular model applies.
The set of files coming from the invoking accelerator and made visible to the fragment is the set of files that “reach” the point of invocation. For example, in the following case:
include: ["somedir/**"]
chain:
- type: InvokeFragment
reference: my-fragment
All files that the fragment invocation “sees” are files in the somedir/
subdirectory. If the my-fragment
has not been written accordingly, this can be problematic. Chances are that this re-usable fragment expects files to be present at the root of the project tree and work on them.
To better cope with this typical situation, the InvokeFragment
transform exposes the optional anchor
configuration property. Continuing with the earlier example, by using anchor: somedir
, then all files coming from the current accelerator are exposed as if their path
had the somedir/
prefix removed. When it comes to gathering the result of the invocation though, all resulting files are re-introduced with a prefix prepended to their path
(this applies to all files produced by the fragment, not just the ones originating from the accelerator).
The value of the anchor
property must not start nor end with a slash (/
) character.
The following is a full-featured example showing the interaction between the imports
section and InvokeFragment
:
accelerator:
name: my-accelerator
options:
- name: someOption
dataType: number
imports:
- name: my-fragment
Example accelerator.axl
:
engine {
Include({'...'})
T2()
InvokeFragment('my-fragment')
}
If my-fragment
is defined as follows:
accelerator:
name: my-fragment
options:
- name: indentationLevel
dataType: number
defaultValue: 2
transform:
chain:
- include: ["**/*.xml"]
- type: SomeTransform
...
Then users are presented with two options, someOption
and indentationLevel
, as if indentationLevel
was defined in the host accelerator.
Moreover, the behavior of the calling accelerator is exactly as if the body of the fragment transform was inserted in-place of InvokeFragment
:
accelerator:
name: my-accelerator
options:
- name: someOption
dataType: number
- name: indentationLevel
dataType: number
defaultValue: 2
Example accelerator.axl
:
engine {
Include({"...", "**/pom.xml". "**/*.xml"})
T1()
}
There are some scenarios to better clarify all configuration properties.
If you don’t want to use the value entered in the indentationLevel
option for the fragment but use the value provided for someOption
twice, you can rewrite the InvokeFragment
block as follows:
let indententationLevel in {
InvokeFragment('my-fragment')
}
Finally, if the invocation in the accelerator looks like this:
engine {
Include("...")
+ Include("**/README.md")
+ InvokeFragment('my-fragment')
}
Then there is no visible effect, because this is forwarding only README.md
files to the fragment and the fragment is itself filtering by *.xml
files.