-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit efc985d
Showing
12 changed files
with
329 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
Package: rfold | ||
Type: Package | ||
Title: Working with many R Folders Within an R Package | ||
Version: 0.1.0 | ||
Authors@R: | ||
person(given = "Mohamed El Fodil", | ||
family = "Ihaddaden", | ||
role = c("aut", "cre"), | ||
email = "ihaddaden.fodeil@gmail.com") | ||
Description: | ||
Allows developers to work with many R folders inside a package. It offers functionalities to transfer R scripts (saved outside the R folder) into | ||
the R folder while making additional checks. | ||
License: MIT + file LICENSE | ||
Encoding: UTF-8 | ||
Imports: cli (>= 3.6.1), fs (>= 1.5.0), here (>= 1.0.1), usethis (>= | ||
2.0.1) | ||
RoxygenNote: 7.1.1 | ||
Suggests: testthat (>= 3.0.0) | ||
Config/testthat/edition: 3 | ||
NeedsCompilation: no | ||
Packaged: 2023-11-01 22:37:29 UTC; Administrateur | ||
Author: Mohamed El Fodil Ihaddaden [aut, cre] | ||
Maintainer: Mohamed El Fodil Ihaddaden <ihaddaden.fodeil@gmail.com> | ||
Repository: CRAN | ||
Date/Publication: 2023-11-02 15:50:02 UTC |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
YEAR: 2023 | ||
COPYRIGHT HOLDER: rfold authors |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
3680a516b6ed0be936a838738de0db71 *DESCRIPTION | ||
ce7c21a851fc05d855d30ded2dd4dca4 *LICENSE | ||
818722a25944f8f44c044f54cb89f6cd *NAMESPACE | ||
5793a5608b1f247fa72d16e10bb303a9 *NEWS.md | ||
7453e420754cad0e8d5d7d3e7d719e3a *R/main.R | ||
b4844025274abe17014899b8352c7388 *README.md | ||
90189bfb82ebe81e65db92e71a32854a *man/figures/figure1.png | ||
e631da678fd55a6dd635e12a7f6a7bac *man/figures/figure2.png | ||
9f02da1d16599452a48c616fe75b2bd6 *man/rfold.Rd | ||
e6cfab9a5c250596a1a122da5f026ace *tests/testthat.R | ||
7510abeeea816f2d7cb19640d08536f5 *tests/testthat/test-main.R |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Generated by roxygen2: do not edit by hand | ||
|
||
export(rfold) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# rfold 0.1.0 | ||
|
||
# rfold 0.0.1 | ||
|
||
* Added a `NEWS.md` file to track changes to the package. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
|
||
.get_files_that_are_not_in_r_folder <- function(folders_to_ignore) { | ||
|
||
r_folder_exists <- unname(fs::dir_exists(here::here("R"))) | ||
|
||
if (!r_folder_exists) { | ||
message("R folder does not exist, creating it") | ||
fs::dir_create(here::here("R")) | ||
} | ||
|
||
r_folders <- list.dirs(here::here("R")) | ||
|
||
if (length(r_folders) > 1) { | ||
stop("Looks like you've folders insider your R folder, please inspect") | ||
} | ||
|
||
all_r_files <- fs::dir_ls( | ||
path = ".", | ||
regexp = "\\.R$|\\.r$", | ||
recurse = TRUE | ||
) | ||
|
||
tmp_df <- data.frame( | ||
r_files = all_r_files, | ||
dir_name = dirname(all_r_files), | ||
row.names = NULL, | ||
stringsAsFactors = FALSE | ||
) | ||
|
||
r_files_without_dir <- tmp_df[tmp_df$dir_name == ".", ] | ||
|
||
if (nrow(r_files_without_dir) > 0) { | ||
stop( | ||
"The following .R files are on the top-level | ||
of the package and don't have a parent directory, please inspect: ", | ||
toString(r_files_without_dir$r_files) | ||
) | ||
} | ||
|
||
folders_to_be_ignored <- c("R", "tests", "tests/testthat", folders_to_ignore) | ||
|
||
r_files_not_in_r_dir_df <- tmp_df[!tmp_df$dir_name %in% folders_to_be_ignored, ] | ||
|
||
r_files_not_in_r_dir <- r_files_not_in_r_dir_df$r_files | ||
|
||
r_check_folder <- grepl(".Rcheck/", x = r_files_not_in_r_dir) | ||
|
||
r_files_not_in_r_dir <- r_files_not_in_r_dir[!r_check_folder] | ||
|
||
if (length(r_files_not_in_r_dir) == 0) { | ||
cli::cli_alert_warning( | ||
"No R files available outside of the R directory, nothing to do" | ||
) | ||
return(character(0)) | ||
} | ||
|
||
r_files_names_not_in_r_dir <- basename(r_files_not_in_r_dir) | ||
|
||
dupli <- duplicated(r_files_names_not_in_r_dir) | ||
|
||
duplicated_files <- r_files_names_not_in_r_dir[dupli] | ||
|
||
if (length(duplicated_files) > 0) { | ||
stop( | ||
"The following file(s) are duplicated across your package: ", | ||
toString(duplicated_files) | ||
) | ||
} | ||
|
||
r_files_not_in_r_dir | ||
|
||
} | ||
|
||
|
||
#' Transfer .R files into the R directory | ||
#' | ||
#' @return called for the side effect of transferring all R files | ||
# available inside a project into the R folder | ||
#' @param folders_to_ignore a string vector of plain names folders that should be ignored | ||
#' where transferring .R files into the main R folder (for example a dev folder). Defaults to NULL | ||
#' | ||
#' @param script_name_prefix characters string of length 1 that will be appended to the start of the .R scripts when transferring them to the R folder. Defaults to 'DO_NOT_EDIT', set it to NULL for no appending | ||
#' | ||
#' @export | ||
#' | ||
|
||
rfold <- function( | ||
folders_to_ignore = NULL, | ||
script_name_prefix = "DO_NOT_EDIT_" | ||
) { | ||
|
||
if (length(script_name_prefix) > 1) { | ||
stop("script_name_prefix must be of length 1") | ||
} | ||
|
||
if (is.null(script_name_prefix)) { | ||
script_name_prefix <- "" | ||
} | ||
|
||
if (!is.null(folders_to_ignore)) { | ||
dir_exist <- dir.exists(folders_to_ignore) | ||
|
||
if (!any(dir_exist)) { | ||
dir_no_exist <- folders_to_ignore[!dir_exist] | ||
stop("The following directories do not exist. Can't ignore them: ", dir_no_exist) | ||
|
||
} | ||
} | ||
|
||
r_files <- .get_files_that_are_not_in_r_folder(folders_to_ignore) | ||
|
||
if (length(r_files) == 0) { | ||
return(invisible(NULL)) | ||
} | ||
|
||
dir_components <- unique(unlist(strsplit(r_files, "/"))) | ||
|
||
dir_components <- dir_components[!grepl("\\.R$", dir_components)] | ||
|
||
usethis::use_build_ignore(dir_components) | ||
|
||
r_files_string <- paste(toString(r_files), collapse = ", ") | ||
|
||
cli::cli_alert_info( | ||
"Copying the following R files with prefix '{script_name_prefix}' into the R folder: {r_files_string}" | ||
) | ||
|
||
file_names <- basename(r_files) | ||
|
||
new_file_names <- paste0(script_name_prefix, file_names) | ||
|
||
fs::file_copy( | ||
path = r_files, | ||
new_path = here::here("R", new_file_names), | ||
overwrite = TRUE | ||
) | ||
|
||
for (i in seq_along(new_file_names)) { | ||
|
||
script_to_consider <- here::here("R", new_file_names[i]) | ||
|
||
existing_script_content <- readLines(script_to_consider) | ||
|
||
comment <- "# GENERATED BY RFOLD: DO NOT EDIT BY HAND ####" | ||
|
||
if (length(existing_script_content) == 0) { | ||
writeLines(comment, con = script_to_consider) | ||
next() | ||
} | ||
|
||
if (existing_script_content[1] == comment) { | ||
next() | ||
} | ||
|
||
new_content <- c( | ||
comment, | ||
existing_script_content, | ||
comment | ||
) | ||
|
||
writeLines(new_content, con = script_to_consider) | ||
} | ||
|
||
cli::cli_alert_success("Success") | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
|
||
<!-- README.md is generated from README.Rmd. Please edit that file --> | ||
|
||
# rfold | ||
|
||
<!-- badges: start --> | ||
<!-- badges: end --> | ||
|
||
The goal of the `rfold` package is to allow `R` developers to work with | ||
many `R` directories within an `R` package. A considerable limitation | ||
regarding `R` packages development, is that one cannot create other | ||
directories/sub directories (other than the `R` directory) and bind them | ||
to the package ecosystem. | ||
|
||
Using `rfold`, you can create as many directories/sub directories | ||
(**outside of your `R` directory**). | ||
|
||
The `rfold()` function will list all the `.R` scripts available outside | ||
of the `R` folder, assign their names to `.Rbuildignore` file and | ||
transfer them within the main `R` directory, giving you all the | ||
flexibility you need to organize your package into many | ||
directories/sub-directories. | ||
|
||
## Installation | ||
|
||
You can install the development version of `rfold` with: | ||
|
||
``` r | ||
remotes::install_github("feddelegrand7/rfold") | ||
``` | ||
|
||
## Usage | ||
|
||
Just use `rfold::rfold()` before building or documenting your package | ||
and you’re all set. | ||
|
||
## Example | ||
|
||
Suppose that within this package, I would decide to have the following | ||
structure: | ||
|
||
![](man/figures/figure1.png) | ||
|
||
Running `rfold::rfold()`, all the external (external to the `R` folder) | ||
`.R` scripts will be moved within the `R` folder: | ||
|
||
``` r | ||
rfold::rfold() | ||
``` | ||
|
||
As such, I’ll get now the following structure: | ||
|
||
![](man/figures/figure2.png) | ||
|
||
Notice, that script names that will be transferred to the `R` folder | ||
have their name prefixed with the character `DO_NOT_EDIT`. You can tweak | ||
this feature or deactivate it using the `script_name_suffix` parameter | ||
of the `rfold()` function. | ||
|
||
The following comment will also be inserted at the top of each script | ||
transferred into the R folder: **\# GENERATED BY FOLD: DO NOT EDIT BY | ||
HAND \####** | ||
|
||
There’s another parameter available, called `folders_to_ignore` which | ||
allows you to ignore certain directories (for example `dev` directory) | ||
when running the `rfold` function. | ||
|
||
Note also that `devtools::build()` and `devtools::document()` will only | ||
consider the scripts available within your `R` folder. | ||
|
||
## Code of Conduct | ||
|
||
Please note that the rfold project is released with a [Contributor Code | ||
of | ||
Conduct](https://contributor-covenant.org/version/2/0/CODE_OF_CONDUCT.html). | ||
By contributing to this project, you agree to abide by its terms. |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
library(testthat) | ||
library(rfold) | ||
|
||
test_check("rfold") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
testthat::test_that("rfold works as expected", { | ||
|
||
testthat::expect_error( | ||
object = { | ||
rfold::rfold(folders_to_ignore = "dont_exist") | ||
}, | ||
regexp = "The following directories do not exist. Can't ignore them: dont_exist" | ||
) | ||
|
||
testthat::expect_error( | ||
object = { | ||
rfold::rfold(script_name_prefix = c("pref1", "pref2")) | ||
}, | ||
regexp = "script_name_prefix must be of length 1" | ||
) | ||
|
||
}) |