From p@u|john32 @end|ng |rom gm@||@com  Thu Feb 14 20:02:12 2019
From: p@u|john32 @end|ng |rom gm@||@com (Paul Johnson)
Date: Thu, 14 Feb 2019 13:02:12 -0600
Subject: [Rd] Proposed function file.backup
Message-ID: <CAErODj8VTDF-XYR4H1Bq34q9p-tsJaL_ni9iKHBA6+hT=AL5wg@mail.gmail.com>

Dear R Core:

In the kutils package, I wrote a function that is so handy that I would
like to ask you put it in R itself.

file.backup() will look at a file, find its last modification time, and
create a new backup with a name that appends YYYYMMDD-HHMM to the file
name. So now, whenever I worry that running write.csv or saving a graph
might destroy something valuable, I use an idiom like

fn <- "filename.csv"
file.backup(fn)
write.csv(fn)

So If "filename.csv" already exists, it will get a backup copy.  If an old
backup version exists, the function doesn't re-copy.  In my workflow, this
is very convenient and it could be integrated with other R file writers
that have overwrite as a parameter.  If overwrite could be set as "backup"
instead of TRUE or FALSE, it would be convenient.

I sincerely hope you will consider it:

##' Create a backup version of a file by renaming it.
##'
##' Inserts the date-time of the most recent modification at the
##' end of the file name, before the extension.
##'
##' Return is the new file name that was created, using whatever
##' path information was provided in the file's original name. However,
##' the fullpath argument can be set to TRUE, so a path with the
##' full directory name will be created and returned.
##'
##' @param name A character string for the name of the file.
##' @param fullpath Return the full directory path to the
##'     file. Default FALSE, return only the file name.
##' @param keep.old If FALSE (default), rename the file. Otherwise, keep
old copy.
##' @param verbose If TRUE, list the files in the output directory
##' @author Shadi Pirhosseinloo <shadi@@ku.edu> Paul Johnson <pauljohn@@
ku.edu>
##' @return The name of the newly created file.
##' @importFrom tools file_ext
##' @importFrom tools file_path_sans_ext
##' @export
##' @examples
##' tdir <- tempdir()
##' owd <- getwd()
##'
##' setwd(tdir)
##' system("touch test.1.txt")
##' system("touch test.2.txt")
##' system("touch test.3.txt")
##' system("touch test.4.txt")
##' system("touch test.5.txt")
##' ## note: no extension next
##' system("touch test.6")
##' list.files()
##' file.backup("test.1.txt")
##' file.backup("test.2.txt", fullpath=TRUE)
##' list.files()
##' setwd(owd)
##' file.backup(file.path(tdir, "test.3.txt"))
##' ## Next should be same path because input had a full path
##' file.backup(file.path(tdir, "test.4.txt"), fullpath=TRUE)
##' file.backup(file.path(tdir, "test.5.txt"), fullpath = TRUE, verbose =
TRUE)
##' file.backup(file.path(tdir, "test.6"))
file.backup <- function(name, fullpath = FALSE, keep.old = FALSE, verbose =
FALSE){
    if(!file.exists(name)){
        MESSG <- paste("file", name, "does not exist. No backup created.")
        warning(MESSG)
        return(NULL)
    }
    dir.source <- dirname(normalizePath(name))

    date_cr <- base::format(base::file.info(name)$mtime, "%Y%m%d-%H%M")
    ext_name <- tools::file_ext(name)
    noext_name <- tools::file_path_sans_ext(name)
    new_name <- paste0(noext_name, "-", date_cr,
                       if(!ext_name == "") {paste0( ".", ext_name)})

    ## Abort if new file name already exists
    if (file.exists(new_name)){
        MESSG <- paste("backup file already exists. No new backup created.")
        warning(MESSG)
        return(new_name)
    }
    ret <- if(keep.old){
               file.copy(name, new_name, recursive = TRUE, overwrite = TRUE,
                         copy.mode = TRUE, copy.date = TRUE)
           }else{
               file.rename(name, new_name)
           }
    if(!ret) {
        MESSG <- paste("file.rename(", name, ",", new_name, "failed")
        stop(MESSG)
    }
    if(verbose){
        cat("Full file list of directory:", dir.source, "\n")
        print(list.files(dir.source))
        cat("End of file list\n")
    }
    if(fullpath){
        new_name_fullpath <- normalizePath(new_name)
        return(new_name_fullpath)
    }

    ## else, give back adjusted with same path information it had
    new_name
}







-- 
Paul E. Johnson   http://pj.freefaculty.org
Director, Center for Research Methods and Data Analysis http://crmda.ku.edu

To write to me directly, please address me at pauljohn at ku.edu.

	[[alternative HTML version deleted]]



[Rd] Proposed function file.backup
Paul Johnson