Usually the task described here can be done with BashEvaluate or PythonEvaluate. However a component with well named inputs, outputs and parameters increases legibility of AndurilScript. The method may be extended to other languages in the future, as it is not too difficult.
Assume the command that needs to be run in a pipeline is as follows, after the script resides on the PATH:
runtraph.py -i traph_anduril_test_case/tophat_out/accepted_hits.bam -o myTraphOut -l 76
Already this simple line has many moving parts, i.e. file names and parameters, that may be generalized as inputs, outputs and parameters in an Anduril component.
A version of this script formatted in a more general way is a bit more elaborate, but can be run as a self-contained script. As such it can both be used to test itself and to create a new component in Anduril.
#!/bin/bash
#FILTEROUT
# Define inputs and outputs for the usage example
PATH=$PATH:/opt/Traph # Path to Traph installation
input_fragments="traph_anduril_test_case/tophat_out/accepted_hits.bam"
output_folder="traph_output"
parameter_readLength="76"
parameter_options=""
# The actual script that will become the component's main script.
# The variables will be substituted to refer to anything that the user passes in.
# Notice that runtraph.py can be found automatically from the PATH at this point.
#FILTERIN
runtraph.py -i "${input_fragments}" -o "${output_folder}" -l "${parameter_readLength}" ${parameter_options}
There are two odd comment lines in this script - namely the FILTER* lines. They are special instructions used for component generation, telling the lines between the lines to be ignored in the actual component - after all, the variable and input file values should not be fixed.
The names of the inputs, outputs and parameters can be parsed with the anduril-component-generate utility, which is used as follows:
anduril-component-generate myScript.sh NewTraphComponent
The tool automatically rewrites the header section of your script to produce a script for the component. This means you can use any of the functions demonstrated in the templates under anduril's doc/templates directory, such as access arrays and read CSV files.
This will create a new component directory called NewTraphComponent with a component.xml, and use the unfiltered portion of the input script myScript.sh as its main script, called main.bash. Of course the component.xml will have dummy values for the author and documentation fields. The command can be run repeatedly with the same directory, so if you edit the component.xml, all values will be remembered, but only the changed inputs, outputs and parameters will be added with new dummy values.
As a technical detail, for bash scripts the variables should be written like "${input_fragments}", to avoid any possible ambiguity with whitespace, quoting internal to the variable values, and variable name clashes. For Python, just use input_fragments. Check anduril-component-generate's documentation which you can view with the --help flag.
Notice the generic "options" parameter which is by default empty, so that the user can pass in any flags they wish, without needing to explicitly define them in the component's interface.
The input, output and parameter types will be initialized with generic defaults. Arrays are not supported. These features may be added in the future.
The final script looks like this:
#!/bin/bash
# running functions.sh also sets logfile and errorfile.
source "$ANDURIL_HOME/bash/functions.sh"
export_command
tempdir=$( gettempdir ) # nice to have it always since it's the scratch disk
runtraph.py -i "${input_fragments}" -o "${output_folder}" -l "${parameter_readLength}" ${parameter_options}
The component.xml looks like:
<?xml version='1.0' encoding='utf-8'?>
<component>
<name>Komponentti</name>
<version>0.1</version>
<doc>FIXME: Undocumented</doc>
<author email="FIXME">FIXME</author>
<category>External</category>
<launcher type="bash">
<argument name="file" value="main.bash" />
</launcher>
<requires URL="http://www.gnu.org/software/bash/" type="manual">bash</requires>
<inputs>
<input name="fragments" type="BinaryFile">
<doc>FIXME: Undocumented</doc>
</input>
</inputs>
<outputs>
<output name="folder" type="BinaryFile">
<doc>FIXME: Undocumented</doc>
</output>
</outputs>
<parameters>
<parameter name="readLength" type="string">
<doc>FIXME: Undocumented</doc>
</parameter>
<parameter name="options" type="string">
<doc>FIXME: Undocumented</doc>
</parameter>
</parameters>
</component>