R/rule.R

Defines functions rule

Documented in rule

#' General creator of an instance of the S3 `rmake.rule` class
#'
#' Rule is an atomic element of the build process. It defines a set of `target` file names,
#' which are to be built with a given `build` command from a given set `depends` of files
#' that targets depend on, and which can be removed by a given `clean` command.
#'
#' If there is a need to group some rules together, one can assign them the same task identifier in
#' the `task` argument. Each rule may get assigned one or more tasks. Tasks may be then built
#' by executing `make task_name` on the command line, which forces to rebuild all rules assigned to the
#' task `'task_name'`. By default, all rules are assigned to task `all`,
#' which causes `make all` command to build everything.
#'
#' @param target A character vector of target file names that are created by the given build command
#' @param depends A character vector of file names the build command depends on
#' @param build A shell command that runs the build of the given target
#' @param clean A shell command that erases all files produced by the build command
#' @param task A character vector of parent task names. The mechanism of tasks allows to
#' group rules. Anything different from `'all'` will
#' cause creation of a new task depending on the given rule. Executing `make taskname`
#' will then force building of this rule.
#' @param phony Whether the rule has a `PHONY` (i.e. non-file) target. A rule should be marked with
#' `phony` if the target is not a file name that would be generated by the `build` commands.
#' E.g. `all` or `clean` are phony targets. Also all targets representing tasks (see `task` above) are phony.
#' @param type A string representing a type of a rule used e.g. while printing a rule in easily readable format.
#' For instance, [rRule()] uses `R`, [markdownRule()] uses `markdown` etc.
#' @return Instance of S3 class `rmake.rule`
#' @seealso [makefile()], [inShell()]
#' @author Michal Burda
#' @aliases rmake.rule
#' @examples
#' r <- rule(target='something.abc',
#'           depends=c('file.a', 'file.b', 'file.c'),
#'           build='myCompiler file.a file.b file.c -o something.abc',
#'           clean='$(RM) something.abc')
#'
#' # generate the content of a makefile (as character vector)
#' makefile(list(r))
#'
#' # generate to file
#' tmp <- tempdir()
#' makefile(list(r), file.path(tmp, "Makefile"))
#' @export
rule <- function(target, depends=NULL, build=NULL, clean=NULL, task='all', phony=FALSE, type='') {
  assert_that(is.character(type))
  assert_that(is.character(target))
  assert_that(is.null(depends) || is.character(depends))
  assert_that(is.null(build) || is.character(build))
  assert_that(is.null(clean) || is.character(clean))
  assert_that(is.character(task))
  assert_that(is.flag(phony))

  pattern <- target
  if (length(target) > 1) {
    if (!all(grepl('.', target, fixed=TRUE))) {
      stop('"." not found in all targets')
    }
    pattern <- sub('.', '%', target, fixed=TRUE)
  }

  structure(list(target=target,
                 pattern=pattern,
                 depends=unique(depends),
                 build=build,
                 clean=clean,
                 task=task,
                 phony=phony,
                 type=type),
            class='rmake.rule')
}
beerda/rmake documentation built on July 2, 2022, 6:24 p.m.