Search code examples
rpathrepositorycran

Expand path to actual subdirectory containing packages for local repositories


Is there a function that expands the path to the actual subdirectory containing package binaries (or whatever the equivalent under Linux and Mac OS is called) given the URL-like path to a local repository's root directory in an OS-independent manner?

Due Dilligence

Related Links

Suppose you have a repository under L:/my_repo:

path.repo <- "L:/my_repo"

MS Windows requires a certain subdirectory structure:

path.sub  <- file.path("bin/windows/contrib", paste(version$major, 
    gsub("(?<=\\d)\\.\\d", "", version$minor, perl=TRUE), sep=".")
)

Actually create the repository:

dir.create(file.path(path.repo, path.sub), recursive=TRUE, showWarnings=FALSE)

Once a package binary exists in the repository, the repository's index needs to be created:

setwd(file.path(path.repo, path.sub))
tools::write_PACKAGES(".", type="win.binary")

After that, the repository is good to go and you could install its packages via

install.packages("mypackage", repos=file.path("file://", path.repo))

So far, so good. I'd like to create a function that automatically copies a package binary to my local repository once the package binary has been built. In order to do so, I guess I need to retrieve the path to the actual directory containing the binaries and the two index files (PACKAGES' andPACKAGES.gz`). And that should happen in an OS-independent way in order to make it as generic as possible.

Of course I could search for the index files via

unique(dirname(grep("PACKAGE*", list.files(path.repo, recursive=TRUE, 
    full.names=TRUE), value=TRUE)))

But I wonder if there's a better way.


Solution

  • This is what I came up so far. It borrows from the code in contrib.url():

    expandPathRepos=function(
        path,
        type="win.binary",
        vsn=paste(version$major, gsub("(?<=\\d)\\.\\d", "", 
            version$minor, perl=TRUE), sep="."), 
        ...
    ) {
        if (!type %in% c("source", "mac.binary", "win.binary")) {
            stop(paste("Invalid type: '", type, "'", sep=""))
        }
        out <- switch(unlist(type), 
            source=paste(gsub("/$", "", path), 
                "src", "contrib", sep = "/"), 
            mac.binary=paste(gsub("/$", "", path), "bin", "macosx", 
                mac.subtype, "contrib", ver, sep="/"), 
            win.binary=paste(gsub("/$", "", path), 
                "bin", "windows", "contrib", vsn, sep = "/")
        )
        return(out)
    }
    
    expandPathRepos(path="L:/R")
    [1] "L:/R/bin/windows/contrib/2.14"
    

    Any other ideas?