1 # Convert a package with custom sub-folders to a valid CRAN package
2 # @param inPath Input path: location of the package to flatten
3 # @param outPath Output path: location of the package to create
4 .pkgdev.tocran = function(inPath, outPath) {
6 # Gather all R source files (no tests)
8 forbiddenPath = file.path(inPath,"R","tests")
9 for (fileOrDir in list.files(file.path(inPath,"R"),full.names=TRUE)) {
10 if (fileOrDir != forbiddenPath) {
11 if (file.info(fileOrDir)$isdir) {
14 list.files(fileOrDir,pattern="\\.[RrSsq]$",
15 recursive=TRUE,full.names=TRUE))
17 else fullPathRfiles = c(fullPathRfiles, fileOrDir)
20 # Truncate paths: only suffix in pkgname/R/suffix is useful
22 paste(inPath,.Platform$file.sep,"R",.Platform$file.sep,sep=''),
27 # Transform rFiles until no folder separator can be found
28 rFiles = fullPathRfiles
29 while (length(grep(.Platform$file.sep,rFiles)) > 0) {
30 rFiles = lowerFileDepth(rFiles)
33 # Create and fill every non-sensible folder on output path
34 unlink(outPath, recursive=TRUE) #in case of [TODO: warn user]
35 dir.create(outPath, showWarnings=FALSE)
37 for (fileOrDir in list.files(inPath)) {
38 if (fileOrDir != forbiddenPath) {
39 if (file.info(file.path(inPath,fileOrDir))$isdir) {
40 dir.create(file.path(outPath,fileOrDir), showWarnings=FALSE, recursive=TRUE)
41 file.copy(file.path(inPath,fileOrDir), file.path(outPath),recursive=TRUE)
43 else file.copy(file.path(inPath,fileOrDir), file.path(outPath))
47 # Prepare R folder (empty for the moment)
48 dir.create( file.path(outPath,"R") )
50 # Copy "flattened" files to R/
51 for (i in 1:length(rFiles)) {
52 file.copy( file.path(inPath,"R",fullPathRfiles[i]),
53 file.path(outPath,"R",rFiles[i]) )
56 # Optional processing if /src is present
57 if (file.exists(file.path(inPath,"src"))) {
59 # Gather all C code files (NOT including headers; no tests)
61 forbiddenPath = file.path(inPath,"src","tests")
62 for (fileOrDir in list.files(file.path(inPath,"src"),full.names=TRUE)) {
63 if (fileOrDir != forbiddenPath) {
64 if (file.info(fileOrDir)$isdir) {
67 list.files(fileOrDir,pattern="\\.[Cc]$",
68 recursive=TRUE,full.names=TRUE))
70 else cCodeFiles = c(cCodeFiles, fileOrDir)
73 # Truncate paths: only suffix in pkgname/R/suffix is useful
75 paste(inPath,.Platform$file.sep,"src",.Platform$file.sep,sep=''),
80 # Add a 'Makevars' file under src/ to allow compilation by R CMD INSTALL
82 paste("SOURCES","=",paste(cCodeFiles,sep='',collapse=' '),"\n",sep=' '),
83 paste("OBJECTS","=","$(SOURCES:.c=.o)","\n",sep=' '),
85 writeLines(makevars, file.path(outPath,"src","Makevars"))
89 # NOTE: rule = sort according to first subfolder, then place 1 for the first ...etc;
90 # for example tr1/tr2/tr3/file.c --> tr2/tr3/file_1.c --> tr3/file_12.c ...etc
91 lowerFileDepth = function(files) {
93 # Sort files according to their prefix paths
94 sortedFiles = sort(files, index.return=TRUE)
96 # Truncate paths if required
99 for (i in 1:length(files)) {
100 if (length(grep(.Platform$file.sep, sortedFiles$x[i], fixed=TRUE)) > 0) {
101 prefix = strsplit(sortedFiles$x[i], c(.Platform$file.sep))[[1]][1]
102 if (prefix != lastFolder) {
103 folderKount = folderKount + 1
106 sortedFiles$x[i] = paste(
108 substr(sortedFiles$x[i],nchar(prefix)+2,nchar(sortedFiles$x[i])-2),
109 #add [sub-]folder identifier
111 #add suffix (.R, .r ...) de
112 substr(sortedFiles$x[i],nchar(sortedFiles$x[i])-1,nchar(sortedFiles$x[i])),
117 # Return transformed files list ranked as in input (unsorted)
118 for (i in 1:length(files)) {
119 files[ sortedFiles$ix[i] ] = sortedFiles$x[i]