-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcreate-component.qmd
More file actions
229 lines (181 loc) · 7.4 KB
/
Copy pathcreate-component.qmd
File metadata and controls
229 lines (181 loc) · 7.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
---
title: Create a new component
description: Building a reproducible Viash component.
order: 1
---
{{< include ../../_includes/_language_chooser.qmd >}}
```{r setup, include=FALSE}
repo_path <- system("git rev-parse --show-toplevel", intern = TRUE)
source(paste0(repo_path, "/_includes/_r_helper.R"))
source(paste0(repo_path, "/guide/component/_language_examples.R"))
temp_dir <- tempfile("create_new_component")
dir.create(temp_dir, recursive = TRUE, showWarnings = FALSE)
on.exit(unlink(temp_dir, recursive = TRUE), add = TRUE)
# create tempdir with files
langs <- langs %>%
mutate(
label = gsub("#", "\\\\#", label),
config_path = paste0(temp_dir, "/", id, "/", basename(example_config)),
script_path = paste0(temp_dir, "/", id, "/", basename(example_script))
)
pwalk(langs, function(id, label, example_config, example_script, config_path, script_path, ...) {
# create dir
dir.create(paste0(temp_dir, "/", id), recursive = TRUE, showWarnings = FALSE)
file.copy(example_config, config_path)
file.copy(example_script, script_path)
})
```
A Viash component can be translated into one or more engines: Native, Docker; and one or more runners: Executable, Nextflow. Each of these engines and runners result in a different artifact:
* [Native engine](/reference/config/engines/native/#): a single executable is generated which runs natively on the host system. This assumes all dependencies are already installed by the user and is therefore not reproducible. Requirements: Bash.
* [Docker engine](/reference/config/engines/docker/#): a single executable is generated but it runs inside a Docker container instead. The Docker engine specification can help you install custom dependencies and will take care of auto-mounting input/output files. Requirements: Bash, Docker.
* [Executable runner](/reference/config/runners/executable/#): a bash script is generated and can be run directly. The executable runner supports both the native and docker engine.
* [Nextflow runner](/reference/config/runners/nextflow/#): a Nextflow module which can be used as a standalone workflow or as a module in a larger workflow. Requirements: Nextflow and a containerization engine (e.g. Docker, Singularity, Podman).
Below we will create our first Viash component using any of the languages natively supported by Viash.
## Create a script
When creating a new Viash component, you can write a new script or use a pre-existing script.
Below is a script that simply copies an input file to an output destination.
::: {.panel-tabset}
```{r create-script, echo=FALSE, output="asis"}
pwalk(langs, function(id, label, example_script, ...) {
qrt(
"## {% label %}
|
|Create a new file named `{% basename(example_script) %}` and copy the following content inside of it.
|This script will copy an input file to an output destination.
|
|```{% id %}
|{% paste(readr::read_lines(example_script), collapse = '\n') %}
|```
|")
})
```
:::
:::{.callout-note}
The `par` variable(s) appear to be hard coded, but they're not! When running this script with Viash, Viash will strip away the section between `VIASH START` and `VIASH END`, and replace it with parameter values at runtime. The values included in this script are thus entirely for development and debugging purposes. More information on how this works will be given in [Variables and meta-variables](variables.qmd).
:::
## Create a config
A [Viash config file](/reference/config/#) is a YAML file that describes the functionality of a component as well as the engine(s) and runner(s) it targets.
::: {.panel-tabset}
```{r create-config, echo=FALSE, output="asis"}
pwalk(langs, function(id, label, example_config, ...) {
qrt(
"## {% label %}
|
|Create a file named `{% basename(example_config) %}` and add the contents below based on your chosen scripting language.
|
|```yaml
|{% paste(readr::read_lines(example_config), collapse = '\n |') %}
|```
|")
})
```
:::
Here's a breakdown of the different sections:
* `name`: The name of the component.
* `description`: A description of what the component does
* `arguments`: The input and output parameters of the script.
* `resources`: References to all necessary files and folders to make the component work.
* `engines`: Lists which engines a component can target (i.e. Native or Docker).
* `runners`: Lists which runners a component can utilize (i.e. Executable or Nextflow).
## Run the component
That's it! With these two steps, you created your first component.
Next, you can use the [`viash run`](/reference/cli/run.qmd) command to test whether it actually works as intended.
::: {.panel-tabset}
```{r viash-run, echo=FALSE, output="asis"}
pwalk(langs, function(id, label, config_path, script_path, ...) {
qrt(
"## {% label %}
|You can call use the component's `--help` functionality to get an overview its parameters and descriptions.
|
|```{bash run-help}
|viash run config.vsh.yaml -- --help
|```
|
|As expected, this component has an `--input` and `--output` parameter. You can execute the component by providing values for these parameters.
|
|```{bash run-io}
|viash run config.vsh.yaml -- --input config.vsh.yaml --output foo.txt
|```
|", .dir = paste0(temp_dir, "/", id))
})
```
:::
:::{.callout-note}
The double dash (`--`) between the viash command and the arguments is used to signify the end of the arguments passed to Viash and the start of those passed to the script. If you forgot to add these, you'll get an error similar to this:
```{bash error=TRUE}
viash run config.vsh.yaml \
--input foo.txt \
--output bar.txt
```
:::
## Build an executable
We will now turn the Viash component into an executable.
Use the [viash build](/reference/cli/build.qmd) command to generate an executable.
::: {.panel-tabset}
```{r echo=FALSE, output="asis"}
pwalk(langs, function(id, label, config_path, script_path, ...) {
qrt(
"## {% label %}
|
|```{bash build-example}
|viash build config.vsh.yaml --output target
|```
|
|This will generate an executable in the `target/` directory:
|
|```{bash view-tree}
|tree
|```
|",
.dir = paste0(temp_dir, "/", id)
)
})
```
:::
## Displaying the help text
It's often useful to know what arguments an executable expects before trying to run it.
::: {.panel-tabset}
```{r echo=FALSE, output="asis"}
pwalk(langs, function(id, label, ...) {
qrt(
"## {% label %}
|To display its documentation, run the executable with just the `--help` argument:
|
|```{bash exec-help}
|target/example_{%id%} --help
|```
|",
.dir = paste0(temp_dir, "/", id)
)
})
```
:::
This executable takes a file as input and will create an output file.
## Running the executable
Running an executable is the same as any other executable on your system.
::: {.panel-tabset}
```{r viash-run-dont-worry-this-takes-a-long-time, echo=FALSE, output="asis"}
pwalk(langs, function(id, label, ...) {
exec <- paste0("target/my_copy_", id)
# generate markdown
qrt(
"## {% label %}
|
|You can run the executable by providing a value for `--input` and `--output`:
|
|```{bash exec-run}
|target/example_{%id%} --input config.vsh.yaml --output output.txt
|```
|
|This results in the following output:
|
|```{bash ls-dir}
|ls -l
|```
|",
.dir = paste0(temp_dir, "/", id)
)
})
```
:::
{{< include ../../_includes/_prune_all_images.qmd >}}