---
title: "CWL syntax" 
type: docs
weight: 1
---

```{r style, echo = FALSE, results = 'asis'}
BiocStyle::markdown()
options(width=80, max.print=1000)
knitr::opts_chunk$set(
    eval=as.logical(Sys.getenv("KNITR_EVAL", "TRUE")),
    cache=as.logical(Sys.getenv("KNITR_CACHE", "TRUE")), 
    tidy.opts=list(width.cutoff=80), tidy=TRUE)
```

```{r setup, echo=FALSE, message=FALSE, warning=FALSE}
suppressPackageStartupMessages({
    library(systemPipeR)
})
```

For complete documentation, please check the CommandLineTools documentation [here](https://www.commonwl.org/v1.2/CommandLineTool.html) 
and [here](https://www.commonwl.org/v1.2/Workflow.html) for Workflows and the user guide [here](https://www.commonwl.org/user_guide/). 
CWL command-line specifications are written in [YAML](http://yaml.org/) format.

In CWL, files with the extension `.cwl` define the parameters of a chosen 
command-line step or workflow, while files with the extension `.yml` define 
the input variables of command-line steps. 

### CWL `CommandLineTool`

`CommandLineTool` by CWL definition is a standalone process, with no interaction 
if other programs, execute a program, and produce output. 

Let's explore the `*.cwl` file: 

```{r}
dir_path <- system.file("extdata/cwl", package = "systemPipeR")
cwl <- yaml::read_yaml(file.path(dir_path, "example/example.cwl"))
```

- The `cwlVersion` component shows the CWL specification version used by the document. 
- The `class` component shows this document describes a `CommandLineTool.`
Note that CWL has another `class`, called `Workflow` which represents a union of one 
or more command-line tools together. 

```{r}
cwl[1:2]
```

- `baseCommand` component provides the name of the software that we desire to execute.

```{r}
cwl[3]
```

- The `inputs` section provides the input information to run the tool. Important 
components of this section are: 
    - `id`: each input has an id describing the input name;
    - `type`: describe the type of input value (string, int, long, float, double, 
    File, Directory or Any);
    - `inputBinding`: It is optional. This component indicates if the input 
    parameter should appear on the command-line. If this component is missing 
    when describing an input parameter, it will not appear in the command-line 
    but can be used to build the command-line.

```{r}
cwl[4]
```

- The `outputs` section should provide a list of the expected outputs after running the command-line tools. Important 
components of this section are: 
    - `id`: each input has an id describing the output name;
    - `type`: describe the type of output value (string, int, long, float, double, 
    File, Directory, Any or `stdout`);
    - `outputBinding`: This component defines how to set the outputs values. The `glob` component will define the name of the output value. 

```{r}
cwl[5]
```

- `stdout`: component to specify a `filename` to capture standard output.
Note here we are using a syntax that takes advantage of the inputs section, 
using results_path parameter and also the `SampleName` to construct the output `filename.` 

```{r}
cwl[6]
```

### CWL `Workflow`

`Workflow` class in CWL is defined by multiple process steps, where can have 
interdependencies between the steps, and the output for one step can be used as 
input in the further steps.

```{r}
cwl.wf <- yaml::read_yaml(file.path(dir_path, "example/workflow_example.cwl"))
```

- The `cwlVersion` component shows the CWL specification version used by the document. 
- The `class` component shows this document describes a `Workflow`.

```{r}
cwl.wf[1:2]
```

- The `inputs` section describes the inputs of the workflow.

```{r}
cwl.wf[3]
```

- The `outputs` section describes the outputs of the workflow.

```{r}
cwl.wf[4]
```

- The `steps` section describes the steps of the workflow. In this simple example, 
we demonstrate one step.

```{r}
cwl.wf[5]
```

### CWL Input Parameter 

Next, let's explore the *.yml* file, which provide the input parameter values for all
the components we describe above. 

For this simple example, we have three parameters defined:

```{r}
yaml::read_yaml(file.path(dir_path, "example/example_single.yml"))
```

Note that if we define an input component in the *.cwl* file, this value needs 
to be also defined here in the *.yml* file. 

### Reference
