Next: Defining a Workflow, Previous: Defining a Process, Up: Top [Contents][Index]
Code Snippets
The Guix Workflow Language is embedded in Guile Scheme, so it makes sense to use Scheme to define the work that a process should perform. Sometimes it may be more convenient, though, to express the procedure in a different language, such as GNU R, Python, or maybe even in Bash.
The GWL provides special syntax for embedding code snippets. The
special syntax is provided in the (gwl sugar)
module, and is
loaded by default. Here is an example of a process that runs an
embedded Bash shell script:
process run-bash
packages "bash"
# bash { echo "hello from bash!" }
Notice how the “procedure” field name was not used here, because the code snippet came last. This cuts down on boilerplate.
Code snippets are introduced with # interpreter {
, where
interpreter
is the command line for running an interpreter, such
as /bin/bash -c
. Code snippets must end with a closing brace,
}
.
Make sure that the package inputs include a package providing the
interpreter. For convenience we provide the special interpreters
bash
, R
, and python
, so that you don’t have to
specify a more complicated command line. When no interpreter is
provided the generic shell interpreter /bin/sh
will be used:
process run-sh
# { echo "hello from a shell!" }
Within code snippets a special syntax is supported for accessing
variables. Any uninterrupted value enclosed in double braces is
considered a reference to a variable, which may also be the name of
other process fields. In the following example, the shell snippet
refers to the name
and inputs
fields of the current
process:
process run-bash
packages "bash"
inputs
. "a"
. "b"
. "c"
# bash {
echo "The name of this process: {{name}}."
echo "The data inputs are: {{inputs}}."
}
You can even access named or tagged values in lists. In the following
example, the shell snippet refers to only selected values of the
inputs
field of the current process:
process run-bash
packages "bash"
inputs
. "a"
. mine: "b"
. "c"
. yours: "d"
# bash {
echo "This is mine: {{inputs:mine}}, and this is yours: {{inputs:yours}}."
}
As expected, this will output the following text when run:
This is mine: b, and this is yours: d.
You can also access tagged sub-lists with the ::
accessor:
process frobnicate
packages "frobnicator"
inputs
. genome: "hg19.fa"
. samples: "a" "b" "c"
outputs
. "result"
# {
frobnicate -g {{inputs:genome}} --files {{inputs::samples}} > {{outputs}}
}
This process will cause the following command to be executed:
frobnicate -g hg19.fa --files a b c > result
If these two ways to access elements of a list are not enough, we
recommend defining a variable using pick
(Useful procedures and macros).
In the following example we define a variable second-sample
inside of the procedure
field to hold the second of the inputs
after the keyword samples:
, i.e. the string the
. We can
then refer to that variable by name in the code snippet.
process foo
inputs
. "something"
. samples: "in" "the" "way"
procedure
define second-sample
pick second samples: inputs
# { echo {{second-sample}} }
You can also access process meta data through environment variables. The following variables may be set:
-
_GWL_PROCESS_NAME
-
_GWL_PROCESS_SYNOPSIS
-
_GWL_PROCESS_DESCRIPTION
-
_GWL_PROCESS_INPUTS
-
_GWL_PROCESS_OUTPUT_PATH
-
_GWL_PROCESS_OUTPUTS
-
_GWL_PROCESS_COMPLEXITY_TIME
-
_GWL_PROCESS_COMPLEXITY_SPACE
-
_GWL_PROCESS_COMPLEXITY_THREADS
-
_GWL_PROCESS_VALUES
Next: Defining a Workflow, Previous: Defining a Process, Up: Top [Contents][Index]