diff --git a/.github/workflows/R-CMD-check-devel.yaml b/.github/workflows/R-CMD-check-devel.yaml index e418968..7ee535f 100644 --- a/.github/workflows/R-CMD-check-devel.yaml +++ b/.github/workflows/R-CMD-check-devel.yaml @@ -74,7 +74,7 @@ jobs: run: | remotes::install_deps(dependencies = TRUE, upgrade = "always") # remotes::install_cran("rcmdcheck") - remotes::install_github("rundel/parsermd", upgrade = "always") + remotes::install_github("ThinkR-open/lightparser", upgrade = "always") shell: Rscript {0} # - name: Setup tmate session diff --git a/DESCRIPTION b/DESCRIPTION index 003e529..90dedf4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: fusen Title: Build a Package from Rmarkdown Files -Version: 0.5.2.9000 +Version: 0.6.0 Authors@R: c( person("Sebastien", "Rochette", , "sebastien@thinkr.fr", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-1565-9313")), @@ -24,9 +24,9 @@ Imports: devtools, glue, here (>= 1.0.0), + lightparser, magrittr, methods, - parsermd (>= 0.1.0), roxygen2, stats, stringi, @@ -48,6 +48,8 @@ Suggests: withr VignetteBuilder: knitr +Remotes: + ThinkR-open/lightparser Config/fusen/version: 0.5.2.9000 Config/Needs/website: ThinkR-open/thinkrtemplate Config/testthat/edition: 3 diff --git a/NAMESPACE b/NAMESPACE index aad4832..50d8d18 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -27,13 +27,10 @@ importFrom(devtools,check) importFrom(glue,glue) importFrom(magrittr,"%>%") importFrom(methods,formalArgs) -importFrom(parsermd,as_tibble) -importFrom(parsermd,parse_rmd) -importFrom(parsermd,rmd_get_chunk) -importFrom(parsermd,rmd_node_code) importFrom(stats,na.omit) importFrom(stats,setNames) importFrom(stringi,stri_trans_general) +importFrom(tibble,as_tibble) importFrom(tibble,tibble) importFrom(tools,file_path_sans_ext) importFrom(utils,getFromNamespace) diff --git a/NEWS.md b/NEWS.md index 8e54780..45d71b1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,10 @@ -# fusen (development version) +# fusen 0.6.0 + +## Breaking changes + +- {fusen} now relies on {lightparser} instead of {parsermd} to parse flat file. This allows to avoid installation problems with {parsermd}, which is not updated anymore. As {lightparser} is lighter, this may have unattended effects on specific flat file cases. Please report any issue you may encounter. (#233) + +## New features - Allow `organisation` in `init_share_on_github()` to send to a GitHub organisation - Fix `load_flat_functions()` to work with VSCode diff --git a/R/inflate-utils.R b/R/inflate-utils.R index 1f98472..479969c 100644 --- a/R/inflate-utils.R +++ b/R/inflate-utils.R @@ -19,11 +19,10 @@ regex_extract_fun_name <- paste( #' Parse function code as tibble and get positions #' @param x One row out of function parsed tibble -#' @importFrom parsermd rmd_node_code #' @noRd parse_fun <- function(x) { # x <- rmd_fun[3,] - code <- unlist(rmd_node_code(x[["ast"]])) + code <- unlist(x[["code"]]) # Clean extra space between #' and @ code <- gsub(pattern = "#'\\s*@", "#' @", code) @@ -276,7 +275,7 @@ parse_test <- function(x, pkg, relative_flat_file) { # x <- rmd_test[1,] #' Add examples in function code #' @param parsed_tbl tibble of a parsed Rmd #' @param fun_code R code of functions in Rmd as character -#' @importFrom parsermd rmd_node_code +#' @importFrom tibble as_tibble #' @noRd add_fun_code_examples <- function(parsed_tbl, fun_code) { # Example in separate chunk @@ -323,9 +322,8 @@ add_fun_code_examples <- function(parsed_tbl, fun_code) { if (nrow(rmd_ex) != 0) { # Group rmd_ex for the same function - rmd_ex$rmd_ex_code <- lapply(1:nrow(rmd_ex), function(x) { - rmd_node_code(rmd_ex[x, ][["ast"]]) - }) + rmd_ex$rmd_ex_code <- rmd_ex[["code"]] + rmd_ex_group <- group_code(df = rmd_ex, group_col = "fun_name", code_col = "rmd_ex_code") # Get example code @@ -353,7 +351,6 @@ add_fun_code_examples <- function(parsed_tbl, fun_code) { # Remove if example is empty fun_code[["example"]] <- lapply(fun_code[["example"]], function(example) { - # example <- fun_code[["example"]][[1]] example <- gsub("^#' $", "#'", example) # clean empty lines if (length(example) == 0) { @@ -370,32 +367,37 @@ add_fun_code_examples <- function(parsed_tbl, fun_code) { }) # Add to function code - fun_code[["code_example"]] <- lapply(seq_len(nrow(fun_code)), function(x) { - fun_code_x <- fun_code[x, ] - if (is.na(fun_code_x[["fun_name"]])) { - return( - unlist(fun_code_x[["code"]]) - ) - } + fun_code[["code_example"]] <- lapply( + seq_len(nrow(fun_code)), + function(x) { + fun_code_x <- fun_code[x, ] + if (is.na(fun_code_x[["fun_name"]])) { + return( + unlist(fun_code_x[["code"]]) + ) + } - end_skeleton <- ifelse(is.na(fun_code_x[["example_pos_start"]]), - fun_code_x[["example_pos_end"]], - fun_code_x[["example_pos_start"]] - 1 - ) + end_skeleton <- ifelse(is.na(fun_code_x[["example_pos_start"]]), + fun_code_x[["example_pos_end"]], + fun_code_x[["example_pos_start"]] - 1 + ) - all_fun_code <- stats::na.omit(c( - # begin - if (!is.na(end_skeleton)) { - unlist(fun_code_x[["code"]])[1:end_skeleton] - }, - # examples - unlist(fun_code_x[["example"]]), - # end - unlist(fun_code_x[["code"]])[ - (fun_code_x[["example_pos_end"]] + 1):length(unlist(fun_code_x[["code"]])) - ] - )) - }) + all_fun_code <- stats::na.omit(c( + # begin + if (!is.na(end_skeleton)) { + unlist(fun_code_x[["code"]])[1:end_skeleton] + }, + # examples + unlist(fun_code_x[["example"]]), + # end + unlist(fun_code_x[["code"]])[ + (fun_code_x[["example_pos_end"]] + 1): + length(unlist(fun_code_x[["code"]])) + ] + )) + return(all_fun_code) + } + ) # Clean double #' due to dontrun fun_code[["code_example"]] <- lapply(fun_code[["code_example"]], function(example) { diff --git a/R/inflate.R b/R/inflate.R index b4fad73..2cf0a99 100644 --- a/R/inflate.R +++ b/R/inflate.R @@ -28,7 +28,6 @@ regex_example <- paste(regex_example_vec, collapse = "|") #' For example, you can do `inflate(check = TRUE, quiet = TRUE)`, where `quiet` is #' passed to `devtools::check()`. #' -#' @importFrom parsermd parse_rmd as_tibble #' @importFrom utils getFromNamespace #' @importFrom glue glue #' @importFrom methods formalArgs @@ -206,35 +205,28 @@ inflate <- function(pkg = ".", flat_file, roxygen2::roxygenise(pkg) } - parsed_flat_file <- parse_rmd(flat_file) - parsed_tbl <- as_tibble(parsed_flat_file) + parsed_tbl <- lightparser::split_to_tbl(flat_file) + + parsed_tbl$order <- seq_len(nrow(parsed_tbl)) - parsed_tbl$order <- 1:nrow(parsed_tbl) # Set start for group variables ---- - parsed_tbl$options <- parsermd::rmd_get_options(parsed_tbl) + parsed_tbl$options <- parsed_tbl$params + # Get filename option in chunk parsed_tbl$chunk_filename <- unlist( lapply( parsed_tbl[["options"]], function(x) { - ifelse(is.null(x[["filename"]]), + ifelse(!is.list(x) || is.null(x[["filename"]]), NA_character_, gsub('"', "", x[["filename"]]) ) } ) ) # Define sec_title to group functions in same R file - sec_title <- paste(parsed_tbl[["sec_h1"]], - parsed_tbl[["sec_h2"]], - sep = "-" - ) - - if (length(sec_title) != 0) { - parsed_tbl$sec_title <- sec_title - } else { - parsed_tbl$sec_title <- "fake-section-title" - } + parsed_tbl$sec_title <- parsed_tbl$section + parsed_tbl$sec_title[is.na(parsed_tbl$sec_title)] <- "fake-section-title" # Get flat file path relative to package root # To be inserted in "DO NOT EDIT" comments @@ -410,7 +402,6 @@ create_functions_all <- function(parsed_tbl, fun_code, pkg, relative_flat_file) #' Get function names ---- #' @param parsed_tbl tibble of a parsed Rmd -#' @importFrom parsermd rmd_get_chunk #' @noRd get_functions_tests <- function(parsed_tbl) { which_parsed_fun <- which(!is.na(parsed_tbl$label) & @@ -424,7 +415,6 @@ get_functions_tests <- function(parsed_tbl) { # At least one function fun_code <- lapply(seq_len(nrow(rmd_fun)), function(x) parse_fun(rmd_fun[x, ])) fun_code <- do.call("rbind", fun_code) - fun_code$sec_h1 <- rmd_fun[["sec_h1"]] fun_code$sec_title <- rmd_fun[["sec_title"]] } else if (length(which_parsed_tests) != 0) { # Some tests but no function at all @@ -486,7 +476,6 @@ create_r_files <- function(fun_code, pkg, relative_flat_file) { #' @param pkg Path to package #' @param relative_flat_file Path to the flat file to show in R scripts #' -#' @importFrom parsermd rmd_node_code #' #' @noRd create_tests_files <- function(parsed_tbl, pkg, relative_flat_file) { @@ -510,7 +499,6 @@ create_tests_files <- function(parsed_tbl, pkg, relative_flat_file) { } # Group code by file_name - rmd_test[["code"]] <- rmd_node_code(rmd_test[["ast"]]) rmd_test <- group_code(rmd_test, group_col = "file_name", code_col = "code") # Filter if code is still empty after code grouped @@ -584,45 +572,23 @@ create_vignette <- function(parsed_tbl, pkg, relative_flat_file, vignette_name, regex_functions ), collapse = "|") vignette_tbl <- parsed_tbl[ - !(grepl(not_in_vignette, parsed_tbl[["label"]]) | - grepl("rmd_yaml_list", parsed_tbl[["type"]])), + !( + grepl(not_in_vignette, parsed_tbl[["label"]]) | + grepl("yaml", parsed_tbl[["type"]]) + ), ] - flat_yaml <- parsed_tbl[grepl("rmd_yaml_list", parsed_tbl[["type"]]), ] - # Make chunk names unique - # vignette_tbl[["label"]][grepl("unnamed", vignette_tbl[["label"]])] <- - # gsub("unnamed-", "parsermd-", vignette_tbl[["label"]][grepl("unnamed", vignette_tbl[["label"]])]) - # is.na(vignette_tbl[["label"]]) & vignette_tbl[["type"]] == "rmd_chunk", - # gsub("[.]+", "-", make.names(vignette_name)), - # vignette_tbl[["label"]]) - # - # vignette_tbl[["label"]] <- make.unique(vignette_tbl[["label"]], sep = "-") - # # /!\ Not re-used in as_document(), this must be in ast - - # ast <- vignette_tbl[["ast"]][[21]] - - # To correct for {parsermd} unnamed attribution - fix_unnamed_chunks <- function(ast) { - if (inherits(ast, "rmd_chunk") && grepl("unnamed-chunk-", ast[["name"]])) { - ast[["name"]] <- gsub("unnamed-", "parsermd-", ast[["name"]]) - } - ast - } - - ast_class <- class(vignette_tbl[["ast"]]) - vignette_tbl[["ast"]] <- lapply(vignette_tbl[["ast"]], fix_unnamed_chunks) - class(vignette_tbl[["ast"]]) <- ast_class + flat_yaml <- parsed_tbl[grepl("yaml", parsed_tbl[["type"]]), ] # File to save cleaned_vignette_name <- asciify_name(vignette_name) vignette_file <- file.path("vignettes", paste0(cleaned_vignette_name, ".Rmd")) # Yaml info - yaml_options <- flat_yaml[["ast"]][[1]] + yaml_options <- flat_yaml$params[[1]] # Vignette # Copied from usethis::use_vignette() to allow to not open vignette created usethis::use_package("knitr", "Suggests") - # desc <- desc::desc(file = usethis::proj_get()) desc <- desc::desc(file = pkg) desc$set("VignetteBuilder", "knitr") desc$write() @@ -647,7 +613,7 @@ create_vignette <- function(parsed_tbl, pkg, relative_flat_file, vignette_name, if (nrow(vignette_tbl) != 0) { lines <- c( lines, - parsermd::as_document(vignette_tbl) + lightparser::combine_tbl_to_file(vignette_tbl) ) } diff --git a/R/load_flat_functions.R b/R/load_flat_functions.R index e81d395..9709ef1 100644 --- a/R/load_flat_functions.R +++ b/R/load_flat_functions.R @@ -39,15 +39,15 @@ load_flat_functions <- function(flat_file, envir = globalenv()) { ) } - parsed_flat_file <- parse_rmd(flat_file) - parsed_tbl <- as_tibble(parsed_flat_file) + parsed_tbl <- lightparser::split_to_tbl(flat_file) + which_parsed_fun <- which( !is.na(parsed_tbl$label) & grepl(regex_functions, parsed_tbl$label) ) - if (nrow(parsed_tbl) > 0) { - content <- unlist(rmd_node_code(parsed_tbl[which_parsed_fun, ][["ast"]])) + if (nrow(parsed_tbl) > 0 && length(which_parsed_fun) > 0) { + content <- unlist(parsed_tbl[which_parsed_fun, ][["code"]]) eval(parse(text = content), envir) diff --git a/README.Rmd b/README.Rmd index a419129..eead808 100644 --- a/README.Rmd +++ b/README.Rmd @@ -195,6 +195,7 @@ Similarly, the {fusen} package uses a flat Rmd template, that you fill in a spec - Thanks to Deemah who asked me to go further 'Rmd first' after my presentation at useR 2019 in Toulouse: ['The "Rmd first" method: when projects start with documentation'](https://github.com/statnmap/prez/blob/master/2019-07_useR_Toulouse.pdf) (Video on Youtube: https://youtu.be/cB1BCxFbhtk). - Thanks to @rundel and its package {parsermd} who helped me get back in this project with ease : https://github.com/rundel/parsermd + + Now replaced with {lightparser} : https://github.com/ThinkR-open/lightparser - Thanks to the [ThinkR team](https://rtask.thinkr.fr) who adopted this package for its daily production. ## Code of Conduct diff --git a/README.md b/README.md index 318b354..7aa05e8 100644 --- a/README.md +++ b/README.md @@ -67,39 +67,43 @@ remotes::install_github("ThinkR-open/fusen") > *Full documentation for the development version is here: > * -## You are one Rmd away from building a package! +## You are one Rmd away from building a package\! *{fusen} is all about correctly separating and naming chunks.* -- Create a new directory / new project with - - RStudio template: File \> New Project \> New directory \> Package - using {fusen} - -- Choose the template - - Choose the template `teaching` the first time to see how {fusen} - works, - - Choose the template `full` the second time to answer most of your - questions - - - *Or command line: - `create_fusen("path/to/new/project", template = "teaching")`* -- Open the “dev/flat_teaching.Rmd” to start setting up the package -- In this flat Rmd template, run the first chunks named `description` - asking to describe your package and license it - - They look like these lines of code: + - Create a new directory / new project with + - RStudio template: File \> New Project \> New directory \> + Package using {fusen} + + - Choose the template + - Choose the template `teaching` the first time to see how {fusen} + works, + - Choose the template `full` the second time to answer most of + your questions + + - *Or command line: `create_fusen("path/to/new/project", template + = "teaching")`* + - Open the “dev/flat\_teaching.Rmd” to start setting up the package + - In this flat Rmd template, run the first chunks named `description` + asking to describe your package and license it + - They look like these lines of code: + + ``` r fill_description(fields = list(Title = "My Awesome Package")) usethis::use_mit_license("John Doe") ``` -- Write your analysis and functionalities following the Rmd template - - You probably develop them with a few examples and tests - - *For the first time, you can let the code as is, this is already the - content for a working package* -- Run the following code to **transform the flat Rmd as an inflated - package** - - This will open the vignette created + - Write your analysis and functionalities following the Rmd template + - You probably develop them with a few examples and tests + - *For the first time, you can let the code as is, this is already + the content for a working package* + - Run the following code to **transform the flat Rmd as an inflated + package** + - This will open the vignette created + + ``` r fusen::inflate( @@ -109,27 +113,34 @@ fusen::inflate( ) ``` -- Share it on a website on GitHub + - Share it on a website on GitHub + + ``` r fusen::init_share_on_github() ``` -**That’s it! You built a package! A documented and tested package!** -**You even have a website for it!** +**That’s it\! You built a package\! A documented and tested +package\!** +**You even have a website for it\!** Let’s test it now: -- Install your package locally + - Install your package locally + + ``` r remotes::install_local() ``` -- Restart your R session to clean environment - - You can restart your RStudio session to let appear the “Build” tab - panel -- Test functions of your package + - Restart your R session to clean environment + - You can restart your RStudio session to let appear the “Build” + tab panel + - Test functions of your package + + ``` r my.package::my_median(1:12) @@ -140,21 +151,21 @@ my.package::my_median(1:12) As I said earlier, this is all about using the correct split and name for your chunks. -- Follow the `"dev/flat_template.Rmd"` template to write your - documentation and build your functions and test your examples. - - Chunk named `function` gets the code of a function - - Chunk named `example` gets the code for examples of using the - function. This will be used for function `@examples` and will be - kept for the vignette. - - As chunk names should be unique in the future vignette, you can - add function names like `example-myfunction`, - `example-myotherfunction`, … - - Chunk named `tests` gets the code for unit testing - - Chunk named `development` gets the code for development purposes, - usually only used once like {usethis} functions -- **Inflate** the flat Rmd template to transform it as a package with - functions, unit tests and the current Rmd transformed as a vignette. - And check. + - Follow the `"dev/flat_template.Rmd"` template to write your + documentation and build your functions and test your examples. + - Chunk named `function` gets the code of a function + - Chunk named `example` gets the code for examples of using the + function. This will be used for function `@examples` and will be + kept for the vignette. + - As chunk names should be unique in the future vignette, you + can add function names like `example-myfunction`, + `example-myotherfunction`, … + - Chunk named `tests` gets the code for unit testing + - Chunk named `development` gets the code for development + purposes, usually only used once like {usethis} functions + - **Inflate** the flat Rmd template to transform it as a package with + functions, unit tests and the current Rmd transformed as a vignette. + And check. *Note that the `"flat*.Rmd"` files created with templates `full` and `teaching` are indeed working examples that can directly be inflated.* @@ -169,11 +180,12 @@ for your chunks. There is a dedicated vignette to answer this: -- **Option 1**: Modifications are only added to the “flat_template.Rmd” - file, which then is inflated to update all packages files -- **Option 2**: Modifications are realized in the package files - directly, and the “flat_template.Rmd” file must be protected from any - use. + - **Option 1**: Modifications are only added to the + “flat\_template.Rmd” file, which then is inflated to update all + packages files + - **Option 2**: Modifications are realized in the package files + directly, and the “flat\_template.Rmd” file must be protected from + any use. > Advice : Use git as soon as possible, this will avoid losing your work > if you made some modifications in the wrong place @@ -187,12 +199,12 @@ some unit tests to verify the outputs. This is even more true if you follow this guide : [‘Rmd first’: When development starts with documentation](https://rtask.thinkr.fr/when-development-starts-with-documentation/) After that, you need to move your functions and scripts in the correct -place. Let {fusen} do that for you! +place. Let {fusen} do that for you\! *{fusen} is first addressed to people who never wrote a package before* but know how to write a Rmarkdown file. Understanding package infrastructure and correctly settling it can be frightening. This -package may help them do the first step! +package may help them do the first step\! *{fusen} is also addressed to more advanced developers who are fed up with switching* between R files, tests files, vignettes. In particular, @@ -201,27 +213,27 @@ tests in multiple places. Here, you can do it in one place. No risk to forget one. Think also about code review: everything related to one function is at the same place. -## Q&A : All tips and tricks of a {fusen} template - -- Can I be lazy in names used? -- Can I knit the content of the flat template ? -- How to declare packages with library() for the future vignette ? -- How to include examples that cannot be run ? -- Document your internal datasets in a function chunk as usual -- How to ignore some chunks ? -- How to create a vignette with different title and Index Entry? -- How not to create a vignette ? -- How to get a pre-filled template for a specific function name ? -- How to Inflate multiple flat files ? -- How to store multiple functions in a unique R file ? -- How to read dataset that I usually put in “tests/testthat/” for my - unit tests? -- Can I load all functions of the current flat file during development - without having to `inflate()`? -- Can I inflate a Quarto qmd file? -- Can I use {fusen} with {golem}? - -=\> See vignette Tips and Tricks: +## Q\&A : All tips and tricks of a {fusen} template + + - Can I be lazy in names used? + - Can I knit the content of the flat template ? + - How to declare packages with library() for the future vignette ? + - How to include examples that cannot be run ? + - Document your internal datasets in a function chunk as usual + - How to ignore some chunks ? + - How to create a vignette with different title and Index Entry? + - How not to create a vignette ? + - How to get a pre-filled template for a specific function name ? + - How to Inflate multiple flat files ? + - How to store multiple functions in a unique R file ? + - How to read dataset that I usually put in “tests/testthat/” for my + unit tests? + - Can I load all functions of the current flat file during development + without having to `inflate()`? + - Can I inflate a Quarto qmd file? + - Can I use {fusen} with {golem}? + +\=\> See vignette Tips and Tricks: ## Why is this package named {fusen} ? @@ -237,23 +249,25 @@ in a specific way so that at the end, you can magically `inflate()` it to let a nice package appear.
- -Click here to fold your {fusen}… - - + + Click here to fold your +{fusen}… +
## Acknowledgments -- Thanks to Deemah who asked me to go further ‘Rmd first’ after my - presentation at useR 2019 in Toulouse: [‘The “Rmd first” method: when - projects start with - documentation’](https://github.com/statnmap/prez/blob/master/2019-07_useR_Toulouse.pdf) - (Video on Youtube: ). -- Thanks to @rundel and its package {parsermd} who helped me get back in - this project with ease : -- Thanks to the [ThinkR team](https://rtask.thinkr.fr) who adopted this - package for its daily production. + - Thanks to Deemah who asked me to go further ‘Rmd first’ after my + presentation at useR 2019 in Toulouse: [‘The “Rmd first” method: + when projects start with + documentation’](https://github.com/statnmap/prez/blob/master/2019-07_useR_Toulouse.pdf) + (Video on Youtube: ). + - Thanks to @rundel and its package {parsermd} who helped me get back + in this project with ease : + - Now replaced with {lightparser} : + + - Thanks to the [ThinkR team](https://rtask.thinkr.fr) who adopted + this package for its daily production. ## Code of Conduct diff --git a/dev/dev_history.R b/dev/dev_history.R index ea35586..86d5f1e 100644 --- a/dev/dev_history.R +++ b/dev/dev_history.R @@ -132,8 +132,8 @@ attachment::att_amend_desc( chameleon::create_pkg_desc_file(out.dir = "inst", source = c("archive"), to = "html") thinkridentity::create_pkg_biblio_file_thinkr() -# Update parsermd -remotes::install_github("rundel/parsermd") +# Update lightparser +remotes::install_github("ThinkR-open/lightparser") # Utils for dev ---- devtools::install(upgrade = "never") # devtools::load_all() @@ -202,7 +202,6 @@ Sys.setenv("FUSEN_TEST_PUBLISH" = "FALSE") # Test no output generated in the user files # pkgload::load_all(export_all = FALSE) # remotes::install_github("ropensci-review-tools/autotest") -# debugonce(autotest:::rm_not_parseable) # Run examples in interactive mode too devtools::run_examples() @@ -250,7 +249,6 @@ rhub::check_for_cran(show_status = FALSE) # docker pull rhub/debian-clang-devel # docker run -ti rhub/debian-clang-devel bash # docker run -v /mnt/Data/github/ThinkR-open/fusen:/home/root/toto -ti rhub/debian-clang-devel bash -# debugonce(rhub::local_check_linux) rhub::local_check_linux(image = "rhub/debian-clang-devel") rhub::local_check_linux(image = "rhub/fedora-clang-devel") # a55df815-38f2-4854-a3bc-29cdcac878cc-2 diff --git a/dev/flat_clean_fusen_files.Rmd b/dev/flat_clean_fusen_files.Rmd index 8300acf..e03c4da 100644 --- a/dev/flat_clean_fusen_files.Rmd +++ b/dev/flat_clean_fusen_files.Rmd @@ -74,8 +74,6 @@ usethis::with_project(dummypackage, { open_vignette = FALSE ) ) - - # debugonce(inflate) }) ``` diff --git a/dev/flat_create_flat.Rmd b/dev/flat_create_flat.Rmd index 816e1b9..505e075 100644 --- a/dev/flat_create_flat.Rmd +++ b/dev/flat_create_flat.Rmd @@ -342,11 +342,19 @@ dir.create(dummypackage) # Add test_that("add dev_history template works", { withr::with_dir(dummypackage, { - dev_file_path <- expect_error(add_flat_template(pkg = dummypackage, template = "dev_history", open = FALSE), regexp = NA) + dev_file_path <- expect_error( + add_flat_template( + pkg = dummypackage, + template = "dev_history", + open = FALSE + ), + regexp = NA + ) expect_true(file.exists(dev_file_path)) usethis::with_project(dummypackage, { + # Extract and test the description chunk dev_lines <- readLines(dev_file_path) # Change path of project @@ -354,16 +362,27 @@ test_that("add dev_history template works", { "here::here()", # To correct for Windows path paste0('"', gsub("\\\\", "\\\\\\\\", dummypackage), '"'), dev_lines, - # paste0('"', newdir, '"'), dev_lines, fixed = TRUE ) - dev_parse <- parsermd::parse_rmd(dev_lines) + + devlines_file <- tempfile(pattern = "devlines") + cat(dev_lines, file = devlines_file, sep = "\n") + dev_parse <- lightparser::split_to_tbl(devlines_file) + file.remove(devlines_file) + desc_code <- tempfile("desc") - parsermd::rmd_select(dev_parse, "description")[[1]] %>% - parsermd::rmd_node_code() %>% - cat(., sep = "\n", file = desc_code) + + cat( + unlist( + dev_parse[which(dev_parse[["label"]] == "description"), ][["code"]] + ), + sep = "\n", + file = desc_code + ) + # Execute code expect_error(source(desc_code), regexp = NA) + file.remove(desc_code) }) expect_true(file.exists(file.path(dummypackage, "DESCRIPTION"))) expect_true(file.exists(file.path(dummypackage, "LICENSE"))) @@ -404,11 +423,23 @@ test_that("add dev_history template works with windows \\users path", { # paste0('"', newdir_uu, '"'), dev_lines, fixed = TRUE ) - dev_parse <- parsermd::parse_rmd(dev_lines) + + + devlines_file <- tempfile(pattern = "devlines") + cat(dev_lines, file = devlines_file, sep = "\n") + dev_parse <- lightparser::split_to_tbl(devlines_file) + file.remove(devlines_file) + desc_code <- tempfile("desc", fileext = ".R") - parsermd::rmd_select(dev_parse, "description")[[1]] %>% - parsermd::rmd_node_code() %>% - cat(., sep = "\n", file = desc_code) + + cat( + unlist( + dev_parse[which(dev_parse[["label"]] == "description"), ][["code"]] + ), + sep = "\n", + file = desc_code + ) + # Execute code expect_error(source(desc_code), regexp = NA) }) diff --git a/dev/flat_inflate_all.Rmd b/dev/flat_inflate_all.Rmd index 65b6613..badc92c 100644 --- a/dev/flat_inflate_all.Rmd +++ b/dev/flat_inflate_all.Rmd @@ -718,7 +718,6 @@ usethis::with_project(dummypackage, { ) # register everything - # debugonce(register_all_to_config) suppressMessages(register_all_to_config()) expect_message( diff --git a/dev/flat_register_config_file.Rmd b/dev/flat_register_config_file.Rmd index 6381e7f..148732c 100644 --- a/dev/flat_register_config_file.Rmd +++ b/dev/flat_register_config_file.Rmd @@ -354,8 +354,6 @@ flat_file <- dev_file[grepl("flat_", dev_file)] usethis::with_project(dummypackage, { test_that("check_not_registered_files returns message if empty", { expect_true(inherits(check_not_registered_files, "function")) - - # debugonce(check_not_registered_files) expect_message(check_not_registered_files(open = FALSE), "There are no files in the package") }) diff --git a/tests/testthat/test-add_flat_template.R b/tests/testthat/test-add_flat_template.R index 3ca5ca6..f59c8a6 100644 --- a/tests/testthat/test-add_flat_template.R +++ b/tests/testthat/test-add_flat_template.R @@ -63,11 +63,19 @@ dir.create(dummypackage) # Add test_that("add dev_history template works", { withr::with_dir(dummypackage, { - dev_file_path <- expect_error(add_flat_template(pkg = dummypackage, template = "dev_history", open = FALSE), regexp = NA) + dev_file_path <- expect_error( + add_flat_template( + pkg = dummypackage, + template = "dev_history", + open = FALSE + ), + regexp = NA + ) expect_true(file.exists(dev_file_path)) usethis::with_project(dummypackage, { + # Extract and test the description chunk dev_lines <- readLines(dev_file_path) # Change path of project @@ -75,16 +83,27 @@ test_that("add dev_history template works", { "here::here()", # To correct for Windows path paste0('"', gsub("\\\\", "\\\\\\\\", dummypackage), '"'), dev_lines, - # paste0('"', newdir, '"'), dev_lines, fixed = TRUE ) - dev_parse <- parsermd::parse_rmd(dev_lines) + + devlines_file <- tempfile(pattern = "devlines") + cat(dev_lines, file = devlines_file, sep = "\n") + dev_parse <- lightparser::split_to_tbl(devlines_file) + file.remove(devlines_file) + desc_code <- tempfile("desc") - parsermd::rmd_select(dev_parse, "description")[[1]] %>% - parsermd::rmd_node_code() %>% - cat(., sep = "\n", file = desc_code) + + cat( + unlist( + dev_parse[which(dev_parse[["label"]] == "description"), ][["code"]] + ), + sep = "\n", + file = desc_code + ) + # Execute code expect_error(source(desc_code), regexp = NA) + file.remove(desc_code) }) expect_true(file.exists(file.path(dummypackage, "DESCRIPTION"))) expect_true(file.exists(file.path(dummypackage, "LICENSE"))) @@ -125,11 +144,23 @@ test_that("add dev_history template works with windows \\users path", { # paste0('"', newdir_uu, '"'), dev_lines, fixed = TRUE ) - dev_parse <- parsermd::parse_rmd(dev_lines) + + + devlines_file <- tempfile(pattern = "devlines") + cat(dev_lines, file = devlines_file, sep = "\n") + dev_parse <- lightparser::split_to_tbl(devlines_file) + file.remove(devlines_file) + desc_code <- tempfile("desc", fileext = ".R") - parsermd::rmd_select(dev_parse, "description")[[1]] %>% - parsermd::rmd_node_code() %>% - cat(., sep = "\n", file = desc_code) + + cat( + unlist( + dev_parse[which(dev_parse[["label"]] == "description"), ][["code"]] + ), + sep = "\n", + file = desc_code + ) + # Execute code expect_error(source(desc_code), regexp = NA) }) diff --git a/tests/testthat/test-inflate-part1.R b/tests/testthat/test-inflate-part1.R index b39d64d..8de04ee 100644 --- a/tests/testthat/test-inflate-part1.R +++ b/tests/testthat/test-inflate-part1.R @@ -24,7 +24,7 @@ usethis::with_project(dummypackage, { ) ) - test_that("inflate() worked correctly", { + test_that("inflate - description is ok", { # Description with version expect_true(file.exists(file.path(dummypackage, "DESCRIPTION"))) desc <- desc::desc(file.path(dummypackage, "DESCRIPTION")) @@ -34,40 +34,47 @@ usethis::with_project(dummypackage, { as.character(version_line), as.character(utils::packageVersion(pkg = "fusen")) ) + }) + test_that("inflate - number of files is ok", { # Number of files expect_equal(length(list.files(file.path(dummypackage, "R"))), 11) expect_equal(length(list.files(file.path(dummypackage, "vignettes"))), 1) expect_equal(length(list.files(file.path(dummypackage, "tests", "testthat"))), 4) + }) + my_median_file <- file.path(dummypackage, "R", "my_median.R") + my_other_median_file <- file.path(dummypackage, "R", "my_other_median.R") + my_third_median_file <- file.path(dummypackage, "R", "my_third_median.R") + my_fourth_median_file <- file.path(dummypackage, "R", "my_fourth_median.R") + my_fifth_median_file <- file.path(dummypackage, "R", "my_fifth_median.R") + my_sixth_median_file <- file.path(dummypackage, "R", "my-sixth-median_function.R") + myuppercasefunctionfile <- file.path(dummypackage, "R", "myuppercasefunction.R") + my_noroxfunctionfile <- file.path(dummypackage, "R", "my_norox.R") + my_norox2functionfile <- file.path(dummypackage, "R", "my_norox2.R") + my_spacefunctionfile <- file.path(dummypackage, "R", "my_space.R") + my_space2functionfile <- file.path(dummypackage, "R", "my_space2.R") + + test_that("inflate - named R files exist", { # R files - my_median_file <- file.path(dummypackage, "R", "my_median.R") expect_true(file.exists(my_median_file)) - my_other_median_file <- file.path(dummypackage, "R", "my_other_median.R") expect_true(file.exists(my_other_median_file)) - my_third_median_file <- file.path(dummypackage, "R", "my_third_median.R") expect_true(file.exists(my_third_median_file)) - my_fourth_median_file <- file.path(dummypackage, "R", "my_fourth_median.R") expect_true(file.exists(my_fourth_median_file)) - my_fifth_median_file <- file.path(dummypackage, "R", "my_fifth_median.R") expect_true(file.exists(my_fifth_median_file)) - my_sixth_median_file <- file.path(dummypackage, "R", "my-sixth-median_function.R") expect_true(file.exists(my_sixth_median_file)) - myuppercasefunctionfile <- file.path(dummypackage, "R", "myuppercasefunction.R") expect_true(file.exists(myuppercasefunctionfile)) # Found with chunk named `fun` - my_noroxfunctionfile <- file.path(dummypackage, "R", "my_norox.R") expect_true(file.exists(my_noroxfunctionfile)) # Found with chunk named `fun-norox2` - my_norox2functionfile <- file.path(dummypackage, "R", "my_norox2.R") expect_true(file.exists(my_norox2functionfile)) # Found with chunk named `fun_space` - my_spacefunctionfile <- file.path(dummypackage, "R", "my_space.R") expect_true(file.exists(my_spacefunctionfile)) - my_space2functionfile <- file.path(dummypackage, "R", "my_space2.R") expect_true(file.exists(my_space2functionfile)) + }) + test_that("inflate - R files contents are ok", { # examples in R files my_median_lines <- readLines(my_median_file) expect_equal(my_median_lines[1], "# WARNING - Generated by {fusen} from dev/flat_full.Rmd: do not edit by hand") @@ -126,7 +133,9 @@ usethis::with_project(dummypackage, { expect_true(all(my_space2_lines[8:10] == c( "#' @noRd", "", "my_space2 <- function(x) {" ))) + }) + test_that("inflate - vignette is ok", { # vignette the_vignette <- file.path(dummypackage, "vignettes", "get-started.Rmd") expect_true(file.exists(the_vignette)) @@ -142,7 +151,9 @@ usethis::with_project(dummypackage, { # No dev chunks in the vignette expect_false(any(grepl("```{r dev}", vignette_lines, fixed = TRUE))) expect_false(any(grepl("```{r development-1", vignette_lines, fixed = TRUE))) + }) + test_that("inflate - tests files are ok", { # tests test_file <- file.path(dummypackage, "tests", "testthat", "test-my_median.R") expect_true(file.exists(test_file)) @@ -173,6 +184,9 @@ usethis::with_project(dummypackage, { expect_false(file.exists( file.path(dummypackage, "tests", "testthat", "test-my_space2.R") )) + }) + + test_that("inflate - namespace is ok", { # Namespace expect_true(file.exists(file.path(dummypackage, "NAMESPACE"))) }) @@ -217,38 +231,36 @@ unlink(file.path(dummypackage, "tests"), recursive = TRUE) unlink(file.path(dummypackage, "dev", "config_fusen.yaml"), recursive = TRUE) # Test no problem with special character in YAML ---- -if (packageVersion("parsermd") > "0.1.2") { - dummypackage.special <- tempfile("dummypackage.special") - dir.create(dummypackage.special) +dummypackage.special <- tempfile("dummypackage.special") +dir.create(dummypackage.special) - # {fusen} steps - fill_description(pkg = dummypackage.special, fields = list(Title = "Dummy Package")) - dev_file <- add_flat_template(pkg = dummypackage.special, overwrite = TRUE, open = FALSE) - flat_file <- dev_file[grepl("flat_", dev_file)] - - usethis::with_project(dummypackage.special, { - testfile <- "tests-templates/dev-template-tests-special-char.Rmd" - file.copy( - system.file(testfile, package = "fusen"), - flat_file, - overwrite = TRUE - ) +# {fusen} steps +fill_description(pkg = dummypackage.special, fields = list(Title = "Dummy Package")) +dev_file <- add_flat_template(pkg = dummypackage.special, overwrite = TRUE, open = FALSE) +flat_file <- dev_file[grepl("flat_", dev_file)] - suppressMessages( - inflate( - pkg = dummypackage.special, flat_file = flat_file, - vignette_name = "Get started", check = FALSE, - open_vignette = FALSE - ) +usethis::with_project(dummypackage.special, { + testfile <- "tests-templates/dev-template-tests-special-char.Rmd" + file.copy( + system.file(testfile, package = "fusen"), + flat_file, + overwrite = TRUE + ) + + suppressMessages( + inflate( + pkg = dummypackage.special, flat_file = flat_file, + vignette_name = "Get started", check = FALSE, + open_vignette = FALSE ) + ) - test_that("inflate with special yaml worked correctly", { - # R files - my_median_file <- file.path(dummypackage.special, "R", "my_median.R") - expect_true(file.exists(my_median_file)) - }) + test_that("inflate with special yaml worked correctly", { + # R files + my_median_file <- file.path(dummypackage.special, "R", "my_median.R") + expect_true(file.exists(my_median_file)) }) -} +}) # Test no attachment and no check when asked ---- unlink(file.path(dummypackage, "DESCRIPTION"), recursive = TRUE) @@ -411,7 +423,7 @@ usethis::with_project(dummypackage, { flat_file, overwrite = TRUE ) - test_that("inflate() output error duplicate label names for vignette", { + test_that("inflate() - {lightparser} fixes duplicate label names in vignette", { expect_error( suppressMessages( inflate( @@ -419,7 +431,8 @@ usethis::with_project(dummypackage, { vignette_name = "Get started", check = FALSE, open_vignette = FALSE ) - ) + ), + regexp = NA ) }) # Clean R, tests and vignettes @@ -560,7 +573,8 @@ if ( requireNamespace("rstudioapi") && rstudioapi::isAvailable() && rstudioapi::hasFun("navigateToFile") && - rstudioapi::hasFun("documentId") + rstudioapi::hasFun("documentId") && + rstudioapi::hasFun("documentClose") ) { print("Test with RStudio") # current position diff --git a/tests/testthat/test-inflate_all.R b/tests/testthat/test-inflate_all.R index 4514f98..6aee106 100644 --- a/tests/testthat/test-inflate_all.R +++ b/tests/testthat/test-inflate_all.R @@ -478,7 +478,6 @@ usethis::with_project(dummypackage, { ) # register everything - # debugonce(register_all_to_config) suppressMessages(register_all_to_config()) expect_message( diff --git a/tests/testthat/test-register_config_file.R b/tests/testthat/test-register_config_file.R index c0be3d5..7ebd670 100644 --- a/tests/testthat/test-register_config_file.R +++ b/tests/testthat/test-register_config_file.R @@ -11,8 +11,6 @@ flat_file <- dev_file[grepl("flat_", dev_file)] usethis::with_project(dummypackage, { test_that("check_not_registered_files returns message if empty", { expect_true(inherits(check_not_registered_files, "function")) - - # debugonce(check_not_registered_files) expect_message(check_not_registered_files(open = FALSE), "There are no files in the package") })