R/dockerBuildAllTags.R

Defines functions dockerBuildAllTags

Documented in dockerBuildAllTags

#' Build all Docker tags
#'
#' @export
#' @note Updated 2023-03-28.
#'
#' @param local `character(1)`.
#' Docker image repository directory.
#'
#' @param remote `character(1)`.
#' Remote Docker image repository URL (e.g. ECR or DockerHub).
#'
#' @param days `numeric(1)`.
#' Number of days to allow since last build.
#'
#' @param force `logical(1)`.
#' Force rebuild.
#'
#' @return Invisible `logical(1)`.
#'
#' @examples
#' ## > local <- file.path(
#' ## >     "~",
#' ## >     "monorepo",
#' ## >     "docker",
#' ## >     "acidgenomics",
#' ## >     "koopa"
#' ## > )
#' ## > remote <- "public.ecr.aws/acidgenomics/koopa"
#' ## > dockerBuildAllTags(local = local, remote = remote)
dockerBuildAllTags <-
    function(local,
             remote,
             days = 2L,
             force = FALSE) {
        assert(
            isADir(local),
            isString(remote),
            isNumber(days),
            isFlag(force)
        )
        alert(sprintf("Building all tags: {.var %s}.", remote))
        ## Build tags in desired order, using "build.txt" file.
        buildFile <- file.path(local, "build.txt")
        if (file.exists(buildFile)) {
            tags <- readLines(buildFile)
            ## Ensure we ignore comments here.
            keep <- grepl(pattern = "^[a-z0-9_.-]+$", x = tags)
            tags <- tags[keep]
            assert(isCharacter(tags))
        } else {
            ## Or build alphabetically (default).
            tags <- sort(list.dirs(
                path = local,
                full.names = FALSE,
                recursive = FALSE
            ))
        }
        if (length(tags) > 1L) {
            ## Build "latest" tag automatically at the end.
            tags <- setdiff(tags, "latest")
        }
        assert(hasLength(tags))
        ## Build the versioned images, defined by `Dockerfile` in the
        ## subdirectories.
        invisible(Map(
            tag = tags,
            MoreArgs = list(
                "local" = local,
                "remote" = remote
            ),
            f = function(tag, local, remote) {
                local <- file.path(local, tag)
                remote <- paste0(remote, ":", tag)
                alert(sprintf(
                    fmt = paste(
                        "Building {.var %s} at {.path %s}."
                    ),
                    remote, local
                ))
                if (isFALSE(force)) {
                    if (isTRUE(
                        tryCatch(
                            expr = {
                                isDockerBuildRecent(
                                    image = remote,
                                    days = days
                                )
                            },
                            error = function(e) {
                                FALSE
                            }
                        )
                    )) {
                        alertInfo(sprintf(
                            "{.var %s} was built recently.",
                            remote
                        ))
                        return(TRUE)
                    }
                }
                shell(
                    command = koopa(),
                    args = c(
                        "app", "docker", "build",
                        "--local", local,
                        "--remote", remote
                    ),
                    print = TRUE
                )
            }
        ))
        invisible(TRUE)
    }
acidgenomics/r-koopa documentation built on Oct. 31, 2023, 9:21 a.m.