R/touch.R

Defines functions .touch2 touch2 .touch touch

Documented in touch touch2

#' Mock the Unix \command{touch} Utility
#'
#' Creating files or ensuring that their file modification times change.
#' @param ... Paths to files.
#' @family file utilities
#' @return The Paths to the files touched.
#' @export
#' @examples
#' file1 <- tempfile()
#' file2 <- tempfile()
#' touch(file1, file2)
#' t1 <- file.mtime(file1, file2)
#' touch(file2)
#' t2 <- file.mtime(file1, file2)
#' t1 < t2
#' file <- file.path(tempfile(), "path", "not", "there.txt")
#' touch(file)
#' file.exists(file)
touch <- function(...) {
    paths <- list(...)
    lapply(paths, .touch)
    return(invisible(unlist(paths)))
}
.touch <- function(path) {
    if (!file.exists(path)) {
        if (!dir.exists(dirname(path))) dir.create(dirname(path),
                                                   recursive = TRUE)
        cat("# This file was generated by fritools::touch()", file = path)
    } else {
        tmp <- tempfile()
        on.exit(unlink(tmp))
        file.copy(path, tmp)
        if (file.mtime(tmp) <= file.mtime(path)) Sys.sleep(2)
        file.copy(tmp, path, overwrite = TRUE)
    }
}

#' @description \code{touch2} is an alternate - yet not faster - implementation.
#' @rdname touch
#' @export
#'
touch2 <- function(...) {
    # I tought I could save time (file.copy and file.mtime can digest multiple
    # paths) by using an index, but it didn't work out.
    paths <- unlist(list(...))
    idx <- file.exists(paths)
    if (any(idx)) {
        tmp <- replicate(sum(idx), tempfile())
        on.exit(unlink(tmp))
        file.copy(paths[idx], tmp)
        if (any(file.mtime(tmp) <= file.mtime(paths[idx]))) Sys.sleep(2)
        file.copy(tmp, paths[idx], overwrite = TRUE)
    }
    invisible(sapply(paths[!idx], .touch2))
    return(invisible(unlist(paths)))
}
.touch2 <- function(path) {
    if (!dir.exists(dirname(path))) dir.create(dirname(path),
                                               recursive = TRUE)
    cat("# This file was generated by fritools::touch()", file = path)
}

Try the fritools package in your browser

Any scripts or data that you put into this service are public.

fritools documentation built on Nov. 19, 2023, 1:06 a.m.