--- title: "Build Rules" author: "Michal Burda" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Build Rules} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r br-setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 5 ) library(rmake) ``` ## Introduction This vignette describes the various types of build rules available in `rmake` for defining how targets are built from their dependencies. For information on project management (initialization, running builds, cleaning), see the [rmake Project Management](project-management.html) vignette. For advanced features like tasks and templates, see the [Tasks and Templates](tasks-and-templates.html) vignette. ## Common Rule Parameters All rule functions have the following common parameters: - `target` - Character vector of files to create - `depends` - Character vector of prerequisite files (optional) - `task` - Task name(s) for grouping (default: "all") - `params` - Parameters to pass to scripts (optional for some rules) Each rule executes in a separate R process (no shared state). Note: The `task` parameter is covered in detail in the [Tasks and Templates](tasks-and-templates.html) vignette, and the `params` parameter is explained in the parameterized execution section of that vignette. ## Pre-defined Rule Types ### rRule() Executes an R script using `Rscript`. The rule is triggered when any dependency or the script itself changes. ```{r rrule_sig, eval=FALSE} rRule(target, script, depends = NULL, params = list(), task = "all") ``` **Parameters:** - `target` - Name of the output file to be created - `script` - Name of the R script to execute - `depends` - Vector of file names that the script depends on, or `NULL` - `params` - List of R values that become available within the script in a `params` variable - `task` - Character vector of parent task names **Example:** ```{r rrule_ex, eval=FALSE} rRule(target = "output.rds", script = "process.R", depends = "input.csv") ``` ### markdownRule() Renders a document from R Markdown using `rmarkdown::render()`. ```{r markdown_sig, eval=FALSE} markdownRule(target, script, depends = NULL, format = "all", params = list(), task = "all") ``` **Parameters:** - `target` - Name of the output file to be created - `script` - Name of the R Markdown file to render - `depends` - Vector of file names that the markdown script depends on, or `NULL` - `format` - Output format specification (see below) - `params` - List of R values available within the script in a `params` variable - `task` - Character vector of parent task names **Format Options:** - `"all"` - All formats defined in the Rmd file - `"html_document"` - HTML web page - `"pdf_document"` - PDF document - `"word_document"` - Microsoft Word - `"odt_document"` - OpenDocument Text - `"rtf_document"` - Rich Text Format - `"md_document"` - Markdown - Vector of format names for multiple formats **Example:** ```{r markdown_ex, eval=FALSE} markdownRule(target = "report.pdf", script = "report.Rmd", depends = "data.rds", format = "pdf_document") ``` ### knitrRule() Executes knitr to create a text file using `knitr::knit()`. This is useful for processing Sweave-style documents (.Rnw files). ```{r knitr_sig, eval=FALSE} knitrRule(target, script, depends = NULL, params = list(), task = "all") ``` **Parameters:** - `target` - Name of the output file to be created - `script` - Name of the Rnw file to be rendered - `depends` - Vector of file names that the knitr script depends on, or `NULL` - `params` - List of R values available within the script in a `params` variable - `task` - Character vector of parent task names **Example:** ```{r knitr_ex, eval=FALSE} knitrRule(target = "report.tex", script = "report.Rnw", depends = c("data1.csv", "data2.csv")) ``` ### copyRule() Copies a file from one location to another. The rule executes `$(CP) depends[1] target`. ```{r copy_sig, eval=FALSE} copyRule(target, depends, task = "all") ``` **Parameters:** - `target` - Target file name to copy the file to - `depends` - Name of the file to copy from (only the first element is used) - `task` - Character vector of parent task names **Example:** ```{r copy_ex, eval=FALSE} copyRule(target = "backup/data.csv", depends = "data.csv") ``` ### depRule() Defines a dependency between targets without providing any execution script. This is useful when you want to specify that a target depends on another target but don't need to execute any command to build it. ```{r dep_sig, eval=FALSE} depRule(target, depends = NULL, task = "all") ``` **Parameters:** - `target` - Target file name that depends on `depends` - `depends` - Character vector of prerequisite file names - `task` - Character vector of parent task names **Example:** ```{r dep_ex, eval=FALSE} # Ensure all preprocessing is done before starting the analysis depRule(target = "analysis-ready", depends = c("data1.rds", "data2.rds", "data3.rds")) ``` ### subdirRule() Runs the make process in a subdirectory. The subdirectory is assumed to contain its own `Makefile`. This rule executes `make ` in the specified subdirectory. ```{r subdir_sig, eval=FALSE} subdirRule(target, depends = NULL, task = "all", targetTask = "all") ``` **Parameters:** - `target` - Name of the subdirectory - `depends` - Must be `NULL` - `task` - Character vector of parent task names - `targetTask` - What task to execute in the subdirectory (default: "all") **Example:** ```{r subdir_ex, eval=FALSE} subdirRule(target = "subproject", targetTask = "all") ``` ### offlineRule() Forces manual action within the build process. Shows a custom error message instructing the user to perform a task manually. This is useful when transformation requires manual intervention. ```{r offline_sig, eval=FALSE} offlineRule(target, message, depends = NULL, task = "all") ``` **Parameters:** - `target` - Name of the file to be created manually - `message` - Custom message to display to the user - `depends` - Vector of prerequisite file names, or `NULL` - `task` - Character vector of parent task names **Example:** ```{r offline_ex, eval=FALSE} offlineRule(target = "cleaned_data.csv", message = "Please manually clean data.csv and save as cleaned_data.csv", depends = "data.csv") ``` ## Custom Rules Create custom rules using the general `rule()` function: ```{r rule_sig, eval=FALSE} rule(target, depends = NULL, build = NULL, clean = NULL, task = "all", phony = FALSE) ``` **Arguments:** - `target` - Target file names - `depends` - Prerequisite file names - `build` - Shell commands to build targets - `clean` - Shell commands to clean targets - `task` - Task assignment - `phony` - Whether target is a non-file target (TRUE/FALSE) **Predefined Make Variables:** - `$(R)` - Path to Rscript binary - `$(RM)` - File deletion command - `$(CP)` - File copy command **Example with NodeJS:** ```{r rule_custom_ex, eval=FALSE} r <- rule(target = "test.json", depends = "test.js", build = "node test.js", clean = "$(RM) test.json") ``` **Define custom Make variables:** ```{r vars_ex, eval=FALSE} defaultVars["JS"] <- "/usr/bin/node" job <- list(rule(target = "test.json", depends = "test.js", build = "$(JS) test.js", clean = "$(RM) test.json")) ``` ### Using inShell() The `inShell()` function converts R expressions to shell commands: ```{r inshell_ex} inShell({ result <- 1 + 1; saveRDS(result, "result.rds") }) ``` **Example rule using inShell():** ```{r inshell_rule, eval=FALSE} rule(target = "result.rds", build = inShell({ result <- 1 + 1; saveRDS(result, "result.rds") }), clean = "$(RM) result.rds") ``` **Note:** Overuse of `inShell()` is not recommended. Prefer separate script files so Make can detect changes. ## Summary `rmake` provides a comprehensive set of rule types: - **rRule()**: Execute R scripts - **markdownRule()**: Render R Markdown documents - **knitrRule()**: Process knitr/Sweave documents - **copyRule()**: Copy files - **depRule()**: Define dependencies without execution - **subdirRule()**: Run make in subdirectories - **offlineRule()**: Require manual intervention - **rule()**: Create custom rules with shell commands ## See Also For more information on related topics, see these vignettes: - [Getting Started with rmake](getting-started.html): Introduction and basic usage - [rmake Project Management](project-management.html): Project initialization, running builds, and cleaning - [Tasks and Templates](tasks-and-templates.html): Advanced features including tasks, parameterized execution, and rule templates