From 00341c170f2b099580f7c612f6b2816d9e1bd37e Mon Sep 17 00:00:00 2001 From: "Jennifer (Jenny) Bryan" Date: Sat, 27 Jul 2024 16:03:45 -0700 Subject: [PATCH 01/21] Refactor tidy_unzip() (#2028) * Refactor tidy_unzip() Fixes #1961, closes #1962. Analyzing the above gave me a new/different understanding of common ZIP file organization structures. I think I've got a better heuristic for setting `exdir`. * Add NEWS bullet --- NEWS.md | 2 + R/course.R | 34 +-- tests/testthat/ref/README.Rmd | 192 +++++++++++--- tests/testthat/ref/README.md | 285 +++++++++++++++------ tests/testthat/ref/foo-explicit-parent.zip | Bin 0 -> 348 bytes tests/testthat/ref/foo-implicit-parent.zip | Bin 0 -> 212 bytes tests/testthat/ref/foo-loose-regular.zip | Bin 204 -> 0 bytes tests/testthat/ref/foo-no-parent.zip | Bin 0 -> 204 bytes tests/testthat/ref/foo-not-loose.zip | Bin 348 -> 0 bytes tests/testthat/ref/yo-explicit-parent.zip | Bin 0 -> 876 bytes tests/testthat/ref/yo-implicit-parent.zip | Bin 0 -> 742 bytes tests/testthat/ref/yo-loose-regular.zip | Bin 718 -> 0 bytes tests/testthat/ref/yo-no-parent.zip | Bin 0 -> 718 bytes tests/testthat/ref/yo-not-loose.zip | Bin 876 -> 0 bytes tests/testthat/test-course.R | 148 ++++++++--- 15 files changed, 496 insertions(+), 165 deletions(-) create mode 100644 tests/testthat/ref/foo-explicit-parent.zip create mode 100644 tests/testthat/ref/foo-implicit-parent.zip delete mode 100644 tests/testthat/ref/foo-loose-regular.zip create mode 100644 tests/testthat/ref/foo-no-parent.zip delete mode 100644 tests/testthat/ref/foo-not-loose.zip create mode 100644 tests/testthat/ref/yo-explicit-parent.zip create mode 100644 tests/testthat/ref/yo-implicit-parent.zip delete mode 100644 tests/testthat/ref/yo-loose-regular.zip create mode 100644 tests/testthat/ref/yo-no-parent.zip delete mode 100644 tests/testthat/ref/yo-not-loose.zip diff --git a/NEWS.md b/NEWS.md index 8626eb1d7..3f7a8051e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # usethis (development version) +* `use_zip()` and `use_course()` are equipped to handle a ZIP where the parent folder is implicit (@burnsal, #1961). + * `use_test_helper()` is a new function to create a test helper file (@olivroy, #1822). * `use_cpp11()` makes it easier to update `NAMESPACE` (@pachadotdev, #1921). diff --git a/R/course.R b/R/course.R index 772743717..2713568dc 100644 --- a/R/course.R +++ b/R/course.R @@ -360,15 +360,15 @@ tidy_unzip <- function(zipfile, cleanup = FALSE) { ## DropBox ZIP files often include lots of hidden R, RStudio, and Git files filenames <- filenames[keep_lgl(filenames)] - td <- top_directory(filenames) - loose_parts <- is.na(td) - - if (loose_parts) { + parents <- path_before_slash(filenames) + unique_parents <- unique(parents) + if (length(unique_parents) == 1 && unique_parents != "") { + target <- path(base_path, unique_parents) + utils::unzip(zipfile, files = filenames, exdir = base_path) + } else { + # there is no parent; archive contains loose parts target <- path_ext_remove(zipfile) utils::unzip(zipfile, files = filenames, exdir = target) - } else { - target <- path(base_path, td) - utils::unzip(zipfile, files = filenames, exdir = base_path) } ui_bullets(c( "v" = "Unpacking ZIP file into {.path {pth(target, base_path)}} @@ -398,7 +398,7 @@ tidy_unzip <- function(zipfile, cleanup = FALSE) { } } - invisible(target) + invisible(unclass(target)) } #' @rdname use_course_details @@ -525,15 +525,17 @@ keep_lgl <- function(file, !grepl(ignores, file, perl = TRUE) } -top_directory <- function(filenames) { - in_top <- path_dir(filenames) == "." - unique_top <- unique(filenames[in_top]) - is_directory <- grepl("/$", unique_top) - if (length(unique_top) > 1 || !is_directory) { - NA_character_ - } else { - unique_top +path_before_slash <- function(filepath) { + f <- function(x) { + parts <- strsplit(x, "/", fixed = TRUE)[[1]] + if (length(parts) > 1 || grepl("/", x)) { + parts[1] + } else { + "" + } } + purrr::map_chr(filepath, f) + } content_type <- function(h) { diff --git a/tests/testthat/ref/README.Rmd b/tests/testthat/ref/README.Rmd index d02b4e6d4..d95bafab6 100644 --- a/tests/testthat/ref/README.Rmd +++ b/tests/testthat/ref/README.Rmd @@ -14,66 +14,169 @@ library(fs) ## Different styles of ZIP file -Examples based on foo folder found here. +usethis has an unexported function `tidy_unzip()`, which is used under the hood in `use_course()` and `use_zip()`. +It is a wrapper around `utils::unzip()` that uses some heuristics to choose a good value for `exdir`, which is the "the directory to extract files to." +Why do we do this? +Because it's really easy to _not_ get the desired result when unpacking a ZIP archive. + +Common aggravations: + +* Instead of the unpacked files being corraled within a folder, they explode as "loose parts" into the current working directory. Too little nesting. +* The unpacked files are contained in a folder, but that folder itself is contained inside another folder. Too much nesting. + +`tidy_unzip()` tries to get the nesting just right. + +Why doesn't unzipping "just work"? +Because the people who make `.zip` files make lots of different choices when they actually create the archive and these details aren't baked in, i.e. a successful roundtrip isn't automatic. +It usually requires some peeking inside the archive and adjusting the unpack options. + +This README documents specific `.zip` situations that we anticipate. + +## Explicit parent folder + +Consider the foo folder: ```{bash} tree foo ``` -### Not Loose Parts, a.k.a. GitHub style +Zip it up like so: + +```{bash, eval = FALSE} +zip -r foo-explicit-parent.zip foo/ +``` + +This is the type of ZIP file that we get from GitHub via links of the forms and . + +Inspect it in the shell: + +```{bash} +unzip -Z1 foo-explicit-parent.zip +``` + +Or from R: + +```{r} +foo_files <- unzip("foo-explicit-parent.zip", list = TRUE) +with( + foo_files, + data.frame(Name = Name, dirname = path_dir(Name), basename = path_file(Name)) +) +``` + +Note that the folder `foo/` is explicitly included and all of the files are contained in it (in this case, just one file). + +## Implicit parent folder + +Consider the foo folder: + +```{bash} +tree foo +``` -This is the structure of ZIP files yielded by GitHub via links of the forms and . +Zip it up like so: ```{bash, eval = FALSE} -zip -r foo-not-loose.zip foo/ +zip -r foo-implicit-parent.zip foo/* ``` -Notice that everything is packaged below one top-level directory. +Note the use of `foo/*`, as opposed to `foo` or `foo/`. +This type of ZIP file was reported in . +The example given there is . + +Inspect our small example in the shell: + +```{bash} +unzip -Z1 foo-implicit-parent.zip +``` + +Or from R: ```{r} -foo_not_loose_files <- unzip("foo-not-loose.zip", list = TRUE) +foo_files <- unzip("foo-implicit-parent.zip", list = TRUE) with( - foo_not_loose_files, + foo_files, data.frame(Name = Name, dirname = path_dir(Name), basename = path_file(Name)) ) ``` -### Loose Parts, the Regular Way +Note that `foo/` is not included and its (original) existence is just implicit in the relative path to, e.g., +`foo/file.txt`. + +Here's a similar look at the example from issue #1961: + +```bash +~/rrr/usethis/tests/testthat/ref % unzip -l ~/Downloads/Species\ v2.3.zip +Archive: /Users/jenny/Downloads/Species v2.3.zip + Length Date Time Name +--------- ---------- ----- ---- + 1241 04-27-2023 09:16 species_v2/label_encoder.txt +175187560 04-06-2023 15:13 species_v2/model_arch.pt +174953575 04-14-2023 12:28 species_v2/model_weights.pth +--------- ------- +350142376 3 files +``` + +Note also that the implicit parent folder `species_v2` is not the base of the ZIP file name `Species v2.3.zip`. -This is the structure of many ZIP files I've seen, just in general. +## No parent + +Consider the foo folder: + +```{bash} +tree foo +``` + +Zip it up like so: ```{bash, eval = FALSE} -cd foo -zip ../foo-loose-regular.zip * -cd .. +(cd foo && zip -r ../foo-no-parent.zip .) ``` -All the files are packaged in the ZIP archive as "loose parts", i.e. there is no explicit top-level directory. +Note that we are zipping everything in a folder from *inside* the folder. + +Inspect our small example in the shell: + +```{bash} +unzip -Z1 foo-no-parent.zip +``` + +Or from R: ```{r} -foo_loose_regular_files <- unzip("foo-loose-regular.zip", list = TRUE) +foo_files <- unzip("foo-no-parent.zip", list = TRUE) with( - foo_loose_regular_files, + foo_files, data.frame(Name = Name, dirname = path_dir(Name), basename = path_file(Name)) ) ``` -### Loose Parts, the DropBox Way +All the files are packaged in the ZIP archive as "loose parts", i.e. there is no explicit or implicit top-level directory. + +## No parent, the DropBox Variation This is the structure of ZIP files yielded by DropBox via links of this form . I can't figure out how to even do this with zip locally, so I had to create an example on DropBox and download it. Jim Hester reports it is possible with `archive::archive_write_files()`. -It's basically like the "loose parts" above, except it includes a spurious top-level directory `"/"`. +It's basically like the "no parent" example above, except it includes a spurious top-level directory `"/"`. + +Inspect our small example in the shell: + +```{bash} +unzip -Z1 foo-loose-dropbox.zip +``` + +Or from R: ```{r} # curl::curl_download( # "https://www.dropbox.com/sh/5qfvssimxf2ja58/AABz3zrpf-iPYgvQCgyjCVdKa?dl=1", # destfile = "foo-loose-dropbox.zip" # ) -foo_loose_dropbox_files <- unzip("foo-loose-dropbox.zip", list = TRUE) +foo_files <- unzip("foo-loose-dropbox.zip", list = TRUE) with( - foo_loose_dropbox_files, + foo_files, data.frame(Name = Name, dirname = path_dir(Name), basename = path_file(Name)) ) ``` @@ -87,43 +190,50 @@ mapname: conversion of failed inflating: file.txt ``` -So this is a pretty odd ZIP packing strategy. But we need to plan for it. +which indicates some tripping over the `/`. +Only `file.txt` is left behind. -## Subdirs only at top-level +This is a pretty odd ZIP packing strategy. But we need to plan for it. -Let's make sure we detect loose parts (or not) when the top-level has only directories, not files. +## Only subdirectories -Example based on the yo directory here: +For testing purposes, we also want an example where all the files are inside subdirectories. + +Examples based on the yo directory here: ```{bash} tree yo ``` -```{bash, eval = FALSE} -zip -r yo-not-loose.zip yo/ -``` - -```{r} -(yo_not_loose_files <- unzip("yo-not-loose.zip", list = TRUE)) -top_directory(yo_not_loose_files$Name) -``` +Zip it up, in all the usual ways: ```{bash, eval = FALSE} -cd yo -zip -r ../yo-loose-regular.zip * -cd .. +zip -r yo-explicit-parent.zip yo/ +zip -r yo-implicit-parent.zip yo/* +(cd yo && zip -r ../yo-no-parent.zip .) ``` -```{r} -(yo_loose_regular_files <- unzip("yo-loose-regular.zip", list = TRUE)) -top_directory(yo_loose_regular_files$Name) -``` +Again, I couldn't create the DropBox variant locally, so I did it by downloading from DropBox. -```{r} +```{r eval = FALSE} # curl::curl_download( # "https://www.dropbox.com/sh/afydxe6pkpz8v6m/AADHbMZAaW3IQ8zppH9mjNsga?dl=1", # destfile = "yo-loose-dropbox.zip" # ) -(yo_loose_dropbox_files <- unzip("yo-loose-dropbox.zip", list = TRUE)) -top_directory(yo_loose_dropbox_files$Name) +``` + +Inspect each in the shell: + +```{bash} +unzip -Z1 yo-explicit-parent.zip +``` + +```{bash} +unzip -Z1 yo-implicit-parent.zip +``` +```{bash} +unzip -Z1 yo-no-parent.zip +``` +```{bash} +unzip -Z1 yo-loose-dropbox.zip ``` diff --git a/tests/testthat/ref/README.md b/tests/testthat/ref/README.md index cc301f187..b25b9c00e 100644 --- a/tests/testthat/ref/README.md +++ b/tests/testthat/ref/README.md @@ -4,39 +4,72 @@ ZIP file structures ``` r devtools::load_all("~/rrr/usethis") #> ℹ Loading usethis -#> x unloadNamespace("usethis") failed because another loaded package needs it -#> ℹ Forcing unload. If you encounter problems, please restart R. library(fs) ``` ## Different styles of ZIP file -Examples based on foo folder found here. +usethis has an unexported function `tidy_unzip()`, which is used under +the hood in `use_course()` and `use_zip()`. It is a wrapper around +`utils::unzip()` that uses some heuristics to choose a good value for +`exdir`, which is the “the directory to extract files to.” Why do we do +this? Because it’s really easy to *not* get the desired result when +unpacking a ZIP archive. + +Common aggravations: + +- Instead of the unpacked files being corraled within a folder, they + explode as “loose parts” into the current working directory. Too + little nesting. +- The unpacked files are contained in a folder, but that folder itself + is contained inside another folder. Too much nesting. + +`tidy_unzip()` tries to get the nesting just right. + +Why doesn’t unzipping “just work”? Because the people who make `.zip` +files make lots of different choices when they actually create the +archive and these details aren’t baked in, i.e. a successful roundtrip +isn’t automatic. It usually requires some peeking inside the archive and +adjusting the unpack options. + +This README documents specific `.zip` situations that we anticipate. + +## Explicit parent folder + +Consider the foo folder: ``` bash tree foo -#> foo +#> foo #> └── file.txt -#> -#> 0 directories, 1 file +#> +#> 1 directory, 1 file +``` + +Zip it up like so: + +``` bash +zip -r foo-explicit-parent.zip foo/ ``` -### Not Loose Parts, a.k.a. GitHub style +This is the type of ZIP file that we get from GitHub via links of the +forms and +. -This is the structure of ZIP files yielded by GitHub via links of the -forms and -. +Inspect it in the shell: ``` bash -zip -r foo-not-loose.zip foo/ +unzip -Z1 foo-explicit-parent.zip +#> foo/ +#> foo/file.txt ``` -Notice that everything is packaged below one top-level directory. +Or from R: ``` r -foo_not_loose_files <- unzip("foo-not-loose.zip", list = TRUE) +foo_files <- unzip("foo-explicit-parent.zip", list = TRUE) with( - foo_not_loose_files, + foo_files, data.frame(Name = Name, dirname = path_dir(Name), basename = path_file(Name)) ) #> Name dirname basename @@ -44,30 +77,115 @@ with( #> 2 foo/file.txt foo file.txt ``` -### Loose Parts, the Regular Way +Note that the folder `foo/` is explicitly included and all of the files +are contained in it (in this case, just one file). + +## Implicit parent folder -This is the structure of many ZIP files I’ve seen, just in general. +Consider the foo folder: ``` bash -cd foo -zip ../foo-loose-regular.zip * -cd .. +tree foo +#> foo +#> └── file.txt +#> +#> 1 directory, 1 file ``` -All the files are packaged in the ZIP archive as “loose parts”, -i.e. there is no explicit top-level directory. +Zip it up like so: + +``` bash +zip -r foo-implicit-parent.zip foo/* +``` + +Note the use of `foo/*`, as opposed to `foo` or `foo/`. This type of ZIP +file was reported in . The +example given there is +. + +Inspect our small example in the shell: + +``` bash +unzip -Z1 foo-implicit-parent.zip +#> foo/file.txt +``` + +Or from R: + +``` r +foo_files <- unzip("foo-implicit-parent.zip", list = TRUE) +with( + foo_files, + data.frame(Name = Name, dirname = path_dir(Name), basename = path_file(Name)) +) +#> Name dirname basename +#> 1 foo/file.txt foo file.txt +``` + +Note that `foo/` is not included and its (original) existence is just +implicit in the relative path to, e.g., `foo/file.txt`. + +Here’s a similar look at the example from issue \#1961: + +``` bash +~/rrr/usethis/tests/testthat/ref % unzip -l ~/Downloads/Species\ v2.3.zip +Archive: /Users/jenny/Downloads/Species v2.3.zip + Length Date Time Name +--------- ---------- ----- ---- + 1241 04-27-2023 09:16 species_v2/label_encoder.txt +175187560 04-06-2023 15:13 species_v2/model_arch.pt +174953575 04-14-2023 12:28 species_v2/model_weights.pth +--------- ------- +350142376 3 files +``` + +Note also that the implicit parent folder `species_v2` is not the base +of the ZIP file name `Species v2.3.zip`. + +## No parent + +Consider the foo folder: + +``` bash +tree foo +#> foo +#> └── file.txt +#> +#> 1 directory, 1 file +``` + +Zip it up like so: + +``` bash +(cd foo && zip -r ../foo-no-parent.zip .) +``` + +Note that we are zipping everything in a folder from *inside* the +folder. + +Inspect our small example in the shell: + +``` bash +unzip -Z1 foo-no-parent.zip +#> file.txt +``` + +Or from R: ``` r -foo_loose_regular_files <- unzip("foo-loose-regular.zip", list = TRUE) +foo_files <- unzip("foo-no-parent.zip", list = TRUE) with( - foo_loose_regular_files, + foo_files, data.frame(Name = Name, dirname = path_dir(Name), basename = path_file(Name)) ) #> Name dirname basename #> 1 file.txt . file.txt ``` -### Loose Parts, the DropBox Way +All the files are packaged in the ZIP archive as “loose parts”, +i.e. there is no explicit or implicit top-level directory. + +## No parent, the DropBox Variation This is the structure of ZIP files yielded by DropBox via links of this form . I can’t @@ -77,21 +195,31 @@ with `archive::archive_write_files()`. -It’s basically like the “loose parts” above, except it includes a +It’s basically like the “no parent” example above, except it includes a spurious top-level directory `"/"`. +Inspect our small example in the shell: + +``` bash +unzip -Z1 foo-loose-dropbox.zip +#> / +#> file.txt +``` + +Or from R: + ``` r # curl::curl_download( # "https://www.dropbox.com/sh/5qfvssimxf2ja58/AABz3zrpf-iPYgvQCgyjCVdKa?dl=1", # destfile = "foo-loose-dropbox.zip" # ) -foo_loose_dropbox_files <- unzip("foo-loose-dropbox.zip", list = TRUE) +foo_files <- unzip("foo-loose-dropbox.zip", list = TRUE) with( - foo_loose_dropbox_files, + foo_files, data.frame(Name = Name, dirname = path_dir(Name), basename = path_file(Name)) ) #> Name dirname basename -#> 1 / / +#> 1 / / #> 2 file.txt . file.txt ``` @@ -103,72 +231,79 @@ result: mapname: conversion of failed inflating: file.txt -So this is a pretty odd ZIP packing strategy. But we need to plan for -it. +which indicates some tripping over the `/`. Only `file.txt` is left +behind. + +This is a pretty odd ZIP packing strategy. But we need to plan for it. -## Subdirs only at top-level +## Only subdirectories -Let’s make sure we detect loose parts (or not) when the top-level has -only directories, not files. +For testing purposes, we also want an example where all the files are +inside subdirectories. -Example based on the yo directory here: +Examples based on the yo directory here: ``` bash tree yo -#> yo -#> ├── subdir1 +#> yo +#> ├── subdir1 #> │   └── file1.txt -#> └── subdir2 +#> └── subdir2 #> └── file2.txt -#> -#> 2 directories, 2 files +#> +#> 3 directories, 2 files ``` +Zip it up, in all the usual ways: + ``` bash -zip -r yo-not-loose.zip yo/ +zip -r yo-explicit-parent.zip yo/ +zip -r yo-implicit-parent.zip yo/* +(cd yo && zip -r ../yo-no-parent.zip .) ``` +Again, I couldn’t create the DropBox variant locally, so I did it by +downloading from DropBox. + ``` r -(yo_not_loose_files <- unzip("yo-not-loose.zip", list = TRUE)) -#> Name Length Date -#> 1 yo/ 0 2018-01-11 15:48:00 -#> 2 yo/subdir1/ 0 2018-01-11 15:48:00 -#> 3 yo/subdir1/file1.txt 42 2018-01-11 15:48:00 -#> 4 yo/subdir2/ 0 2018-01-11 15:49:00 -#> 5 yo/subdir2/file2.txt 42 2018-01-11 15:49:00 -top_directory(yo_not_loose_files$Name) -#> [1] "yo/" +# curl::curl_download( +# "https://www.dropbox.com/sh/afydxe6pkpz8v6m/AADHbMZAaW3IQ8zppH9mjNsga?dl=1", +# destfile = "yo-loose-dropbox.zip" +# ) ``` +Inspect each in the shell: + ``` bash -cd yo -zip -r ../yo-loose-regular.zip * -cd .. +unzip -Z1 yo-explicit-parent.zip +#> yo/ +#> yo/subdir2/ +#> yo/subdir2/file2.txt +#> yo/subdir1/ +#> yo/subdir1/file1.txt ``` -``` r -(yo_loose_regular_files <- unzip("yo-loose-regular.zip", list = TRUE)) -#> Name Length Date -#> 1 subdir1/ 0 2018-01-11 15:48:00 -#> 2 subdir1/file1.txt 42 2018-01-11 15:48:00 -#> 3 subdir2/ 0 2018-01-11 15:49:00 -#> 4 subdir2/file2.txt 42 2018-01-11 15:49:00 -top_directory(yo_loose_regular_files$Name) -#> [1] NA +``` bash +unzip -Z1 yo-implicit-parent.zip +#> yo/subdir1/ +#> yo/subdir1/file1.txt +#> yo/subdir2/ +#> yo/subdir2/file2.txt ``` -``` r -# curl::curl_download( -# "https://www.dropbox.com/sh/afydxe6pkpz8v6m/AADHbMZAaW3IQ8zppH9mjNsga?dl=1", -# destfile = "yo-loose-dropbox.zip" -# ) -(yo_loose_dropbox_files <- unzip("yo-loose-dropbox.zip", list = TRUE)) -#> Name Length Date -#> 1 / 0 2018-01-11 23:57:00 -#> 2 subdir1/file1.txt 42 2018-01-11 23:57:00 -#> 3 subdir2/file2.txt 42 2018-01-11 23:57:00 -#> 4 subdir1/ 0 2018-01-11 23:57:00 -#> 5 subdir2/ 0 2018-01-11 23:57:00 -top_directory(yo_loose_dropbox_files$Name) -#> [1] NA +``` bash +unzip -Z1 yo-no-parent.zip +#> subdir2/ +#> subdir2/file2.txt +#> subdir1/ +#> subdir1/file1.txt +``` + +``` bash +unzip -Z1 yo-loose-dropbox.zip +#> / +#> subdir1/file1.txt +#> subdir2/file2.txt +#> subdir1/ +#> subdir2/ ``` diff --git a/tests/testthat/ref/foo-explicit-parent.zip b/tests/testthat/ref/foo-explicit-parent.zip new file mode 100644 index 0000000000000000000000000000000000000000..ac7c2abd21ae7dd00e7c00d8cd16cf3dc3a067b1 GIT binary patch literal 348 zcmWIWW@h1H00HTYUlCvilwe_yVMxo**AEThWMD33Sds?D72FJrEZ-Oz7+6Gr>H<)7 zi@g0?uLcwaVIHXNw9K4Ty^@L&xG5DNlTc0ZR7lKKfGJcc&&W*9P{_$FOD$H&%qz}J zNmT$jgDb$Bkx7mjms=&Et`=Z;>j+{(T+Rx0IjVi=CZW0;ViM4Y3`-jApeDf_7aD@g SL{>JCtxP~T2S~31aToyjgF-+6 literal 0 HcmV?d00001 diff --git a/tests/testthat/ref/foo-implicit-parent.zip b/tests/testthat/ref/foo-implicit-parent.zip new file mode 100644 index 0000000000000000000000000000000000000000..0c0a13431c26d6f286faf8edeb9e77b7ab6cdc3c GIT binary patch literal 212 zcmWIWW@h1H00HTYUlAg2|JJJk*&xirAj6QBpRb>mnUktlQc)5b!pXo~%CID@0*Fg1 zxEUB(zA-W|u!sQFdMYI5D!>#flxJinXDH-kmZcUeWabrTrlcx>4B`s#W@M6M#$}rX m&>RK^pot7i8bK^nyICQ2quCqa&B_K+%Ls%)KspD+VE_O?Q!V}g literal 0 HcmV?d00001 diff --git a/tests/testthat/ref/foo-loose-regular.zip b/tests/testthat/ref/foo-loose-regular.zip deleted file mode 100644 index 92e8cc7529dd67b4b19f0aadd1e6dae4ed1d037c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 204 zcmWIWW@h1H00Fi@Z6A@hf9utNY!K#PkYPy6%t_TNsVE5z;bdUuUJ)KuyDL1Zw1S&~ zk>x8R0|Sc)P@ShjVy*&Ap+b2^W^#r?PG(tZu|j5Eab`-YLRx;lK39M@Ba<96E}JBP n<}fe-O=MWo2x7sE3k_j~*o$UofHx}}NF5^(`T^+-5QhN(Pp~N{ diff --git a/tests/testthat/ref/foo-no-parent.zip b/tests/testthat/ref/foo-no-parent.zip new file mode 100644 index 0000000000000000000000000000000000000000..11756785f9043874a5e0a826857392d7079e8fd5 GIT binary patch literal 204 zcmWIWW@h1H00HTYUlAg2|JJJk*&xipAj6QBnUktlQc)5b!pXo~%CID@0*Fg1xEUB( zzA-W|u!sQFc`794D!>#flxJinXDH-kmZcUeWabrTrlcyQ<>%{j1$Z+u$uZ-yNdjmN l0|U@Rh9!+47R11vdjD%U4DQ1{M*Z zx&XLtHlS{iw}0!^fTAGG1J#|DnUktlQc(gng?mMK)GDA!Xr_27B<3o>6e^TwWF}`Q zO-jiuG9tl{Z8y%OXaS7|VG&eA(lT>Wjr2+?O5jea067cQNuCOcxe9QVItn@Y z$%!SYDGEucIr-%ZK>xs;#6_gz4M}kPuj_Mdu{z#RALJxMq8$%biPQ0h`as7sGRZOH ziZ}^q6bdlBbp$cN(Z~voM%3`aXAn07vO%^GgJ9to8bX|bs1XV=5SV@#mNYh@8VHXx zVoe5WhXYin{sM}_qZ$-}#5ol;`jDM!4|Fk-fk=^w%VbtIklR>+a6VA)c94%50IXfF AYybcN literal 0 HcmV?d00001 diff --git a/tests/testthat/ref/yo-implicit-parent.zip b/tests/testthat/ref/yo-implicit-parent.zip new file mode 100644 index 0000000000000000000000000000000000000000..853ad1ee220e33da86b6a5e1c17936f9cdbfe7cf GIT binary patch literal 742 zcmWIWW@h1H00HTYUlCvil;CENVW`a4FD^|=$t*I|4-MgDU@m1?k_N^V+zgB?-xwJf zSVVxz15gb4b$za_7Ely~MNkb%%gjkN)GMhdftywVG7;4@Pld!>1-MEbg`E84#FEq$ zg{0J+{Bi{(CvlW7AKGBDrx9vQ zesW?-YKlTqYEFK+LS?=_%spHPOBHcC+X&+9cZ8g+0yJUUjWa2j&Nk8qImQU?>@NhI z4OWTM*+%+6XEQR%G2;qv324X*FuZjHF=4(94Pk|ZK1RqROv4O&h-tuBVp!7Xgk%~# ze8I+oVgiq`n4yd8$n9`rL17JaBq*%$n1&hB$d3GpWExVq1C0fRJBG2WY(Vu4EI{Z5 K^kg2$qYMC#ZI^KX diff --git a/tests/testthat/ref/yo-no-parent.zip b/tests/testthat/ref/yo-no-parent.zip new file mode 100644 index 0000000000000000000000000000000000000000..24a7b85656d9b31e97a14c6b54de8985f779e0c6 GIT binary patch literal 718 zcmWIWW@h1H00HTYUlCvil;B{HVJI$5O35rT(hm*cWMD33Sds?D72FJrEZ-Oz7+6Gr zY6DPA*mmPgiWX25gawgINXyJgHPS1oD1jSQ0WuENC{KmNTm`sF9fh3y?7g}N9_A)IYUg0p{JpKFWhY(ssJV+@IQHdrN2XB+ARoz2K3$BZky zC7}KgV0h~YV#0hI8o~+p3DPzlmP&Ue3LZ* literal 0 HcmV?d00001 diff --git a/tests/testthat/ref/yo-not-loose.zip b/tests/testthat/ref/yo-not-loose.zip deleted file mode 100644 index 5681a0cc71d4292ed518666cc49a62df7109a441..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 876 zcmWIWW@h1H00GH5Z67cLN-#6XFjVI2hlX%6FhBYp9@Y3GJgT&Un}Lz#D;Onr3c@=Hk+%l*}SSh#@x!8NvlLEF7Re-D1QOLkF2{pa;&i-`KG5-uOmfV)B2EGtg#rw39YIWRG_pdX5zR_u zgD@iz*&thpL9p-(4FMVmic&lVVn!&$Kw$b|Skl;pY9Kt)z$SyD7mvx9QHJc)U&tnd wA`s|QPz2&J5HtFaooWwsF+A;{L?+N=ED;&t&B_LJ0|P4%&Ijt<4)QSr0KiMO0{{R3 diff --git a/tests/testthat/test-course.R b/tests/testthat/test-course.R index 0dff96f88..987a64fbb 100644 --- a/tests/testthat/test-course.R +++ b/tests/testthat/test-course.R @@ -83,27 +83,121 @@ test_that("tidy_download() works", { ## tidy_unzip ---- -test_that("tidy_unzip() deals with loose parts, reports unpack destination", { - tmp <- file_temp(ext = ".zip") - fs::file_copy(test_file("yo-loose-regular.zip"), tmp) - dest <- tidy_unzip(tmp) - loose_regular_files <- fs::path_file(fs::dir_ls(dest, recurse = TRUE)) - fs::dir_delete(dest) - - tmp <- file_temp(ext = ".zip") - fs::file_copy(test_file("yo-loose-dropbox.zip"), tmp) - dest <- tidy_unzip(tmp) - loose_dropbox_files <- fs::path_file(fs::dir_ls(dest, recurse = TRUE)) - fs::dir_delete(dest) - - tmp <- file_temp(ext = ".zip") - fs::file_copy(test_file("yo-not-loose.zip"), tmp) - dest <- tidy_unzip(tmp) - not_loose_files <- fs::path_file(fs::dir_ls(dest, recurse = TRUE)) - fs::dir_delete(dest) - - expect_identical(loose_regular_files, loose_dropbox_files) - expect_identical(loose_dropbox_files, not_loose_files) +test_that("tidy_unzip(): explicit parent, file example", { + local_interactive(FALSE) + + zipfile <- withr::local_tempfile(fileext = ".zip") + file_copy(test_file("foo-explicit-parent.zip"), zipfile) + dest <- tidy_unzip(zipfile) + withr::defer(dir_delete(dest)) + expect_equal(path_file(dest), "foo") + + explicit_parent_files <- path_file(dir_ls(dest, recurse = TRUE)) + expect_equal(explicit_parent_files, "file.txt") +}) + +test_that("tidy_unzip(): explicit parent, folders example", { + local_interactive(FALSE) + files <- c("subdir1", "file1.txt", "subdir2", "file2.txt") + + zipfile <- withr::local_tempfile(fileext = ".zip") + file_copy(test_file("yo-explicit-parent.zip"), zipfile) + dest <- tidy_unzip(zipfile) + withr::defer(dir_delete(dest)) + expect_equal(path_file(dest), "yo") + + explicit_parent_files <- path_file(dir_ls(dest, recurse = TRUE)) + expect_setequal(explicit_parent_files, files) +}) + +test_that("tidy_unzip(): implicit parent, file example", { + local_interactive(FALSE) + + zipfile <- withr::local_tempfile(fileext = ".zip") + file_copy(test_file("foo-implicit-parent.zip"), zipfile) + dest <- tidy_unzip(zipfile) + withr::defer(dir_delete(dest)) + expect_equal(path_file(dest), "foo") + + implicit_parent_files <- path_file(dir_ls(dest, recurse = TRUE)) + expect_equal(implicit_parent_files, "file.txt") +}) + +test_that("tidy_unzip(): implicit parent, folders example", { + local_interactive(FALSE) + files <- c("subdir1", "file1.txt", "subdir2", "file2.txt") + + zipfile <- withr::local_tempfile(fileext = ".zip") + file_copy(test_file("yo-implicit-parent.zip"), zipfile) + dest <- tidy_unzip(zipfile) + withr::defer(dir_delete(dest)) + expect_equal(path_file(dest), "yo") + + implicit_parent_files <- path_file(dir_ls(dest, recurse = TRUE)) + expect_setequal(implicit_parent_files, files) +}) + +test_that("tidy_unzip(): no parent, file example", { + local_interactive(FALSE) + + zipfile <- withr::local_tempfile(fileext = ".zip") + file_copy(test_file("foo-no-parent.zip"), zipfile) + dest <- tidy_unzip(zipfile) + withr::defer(dir_delete(dest)) + expect_equal(path_file(dest), path_ext_remove(path_file(zipfile))) + + no_parent_files <- path_file(dir_ls(dest, recurse = TRUE)) + expect_setequal(no_parent_files, "file.txt") +}) + +test_that("tidy_unzip(): no parent, folders example", { + local_interactive(FALSE) + files <- c("subdir1", "file1.txt", "subdir2", "file2.txt") + + zipfile <- withr::local_tempfile(fileext = ".zip") + file_copy(test_file("yo-no-parent.zip"), zipfile) + dest <- tidy_unzip(zipfile) + withr::defer(dir_delete(dest)) + expect_equal(path_file(dest), path_ext_remove(path_file(zipfile))) + + no_parent_files <- path_file(dir_ls(dest, recurse = TRUE)) + expect_setequal(no_parent_files, files) +}) + +test_that("tidy_unzip(): DropBox, file example", { + local_interactive(FALSE) + + zipfile <- withr::local_tempfile(fileext = ".zip") + file_copy(test_file("foo-loose-dropbox.zip"), zipfile) + dest <- tidy_unzip(zipfile) + withr::defer(dir_delete(dest)) + expect_equal(path_file(dest), path_ext_remove(path_file(zipfile))) + + loose_dropbox_files <- path_file(dir_ls(dest, recurse = TRUE)) + expect_setequal(loose_dropbox_files, "file.txt") +}) + +test_that("tidy_unzip(): DropBox, folders example", { + local_interactive(FALSE) + files <- c("subdir1", "file1.txt", "subdir2", "file2.txt") + + zipfile <- withr::local_tempfile(fileext = ".zip") + file_copy(test_file("yo-loose-dropbox.zip"), zipfile) + dest <- tidy_unzip(zipfile) + withr::defer(dir_delete(dest)) + expect_equal(path_file(dest), path_ext_remove(path_file(zipfile))) + + loose_dropbox_files <- path_file(dir_ls(dest, recurse = TRUE)) + expect_setequal(loose_dropbox_files, files) +}) + +test_that("path_before_slash() works", { + expect_equal(path_before_slash(""), "") + expect_equal(path_before_slash("/"), "") + expect_equal(path_before_slash("a/"), "a") + expect_equal(path_before_slash("a/b"), "a") + expect_equal(path_before_slash("a/b/c"), "a") + expect_equal(path_before_slash("a/b/c/"), "a") }) ## helpers ---- @@ -260,15 +354,3 @@ test_that("keep_lgl() keeps and drops correct files", { ) expect_false(any(keep_lgl(droppers))) }) - -test_that("top_directory() identifies a unique top directory (or not)", { - ## there is >= 1 file at top-level or >1 directories - expect_identical(top_directory("a"), NA_character_) - expect_identical(top_directory(c("a/", "b")), NA_character_) - expect_identical(top_directory(c("a/", "b/")), NA_character_) - - ## there are no files at top-level and exactly 1 directory - expect_identical(top_directory("a/"), "a/") - expect_identical(top_directory(c("a/", "a/b")), "a/") - expect_identical(top_directory(c("a/", "a/b", "a/c")), "a/") -}) From 5cde0da04944223aaa2e5434b125b6013cf915e7 Mon Sep 17 00:00:00 2001 From: olivroy <52606734+olivroy@users.noreply.github.com> Date: Sun, 28 Jul 2024 12:35:20 -0400 Subject: [PATCH 02/21] Tickle git pane with `pr_finish()` (#2010) --- R/pr.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/pr.R b/R/pr.R index 9a202232b..c486d37b7 100644 --- a/R/pr.R +++ b/R/pr.R @@ -532,6 +532,7 @@ pr_forget <- function() pr_clean(mode = "forget") pr_clean <- function(number = NULL, target = c("source", "primary"), mode = c("finish", "forget")) { + withr::defer(rstudio_git_tickle()) mode <- match.arg(mode) repo <- git_repo() tr <- target_repo(github_get = NA, role = target, ask = FALSE) From 97d1218e87b2419db084f15831e387ddf5ed2ca2 Mon Sep 17 00:00:00 2001 From: olivroy <52606734+olivroy@users.noreply.github.com> Date: Sun, 28 Jul 2024 14:48:59 -0400 Subject: [PATCH 03/21] Add badge when updating coverage action (#2009) * Add badge when updating coverage action * Tweaks --------- Co-authored-by: Jenny Bryan --- R/github-actions.R | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/R/github-actions.R b/R/github-actions.R index e2c2d5f88..91bf90bd8 100644 --- a/R/github-actions.R +++ b/R/github-actions.R @@ -124,10 +124,12 @@ use_github_action <- function(name = NULL, ui_bullets(c("_" = "Learn more at {.url {readme}}.")) } - badge <- badge %||% is_check_action(url) - if (badge) { + if (badge %||% is_check_action(url)) { use_github_actions_badge(path_file(save_as)) } + if (badge %||% is_coverage_action(url)) { + use_codecov_badge(target_repo_spec()) + } invisible(new) } @@ -167,6 +169,10 @@ is_check_action <- function(url) { grepl("^check-", path_file(url)) } +is_coverage_action <- function(url) { + grepl("test-coverage", path_file(url)) +} + #' Generates a GitHub Actions badge #' #' Generates a GitHub Actions badge and that's all. This exists primarily for From a1da375189384b8706d85948876696f04b27a11b Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Sun, 28 Jul 2024 12:21:28 -0700 Subject: [PATCH 04/21] Advance/move another deprecation --- R/badge.R | 10 ---------- R/usethis-deprecated.R | 20 ++++++++++++++++++-- man/badges.Rd | 3 --- man/git_branch_default.Rd | 5 ++--- man/use_rscloud_badge.Rd | 14 ++++++++++++++ tests/testthat/_snaps/badge.md | 18 +----------------- tests/testthat/test-badge.R | 16 +--------------- 7 files changed, 36 insertions(+), 50 deletions(-) create mode 100644 man/use_rscloud_badge.Rd diff --git a/R/badge.R b/R/badge.R index b97bf08d1..1427a207d 100644 --- a/R/badge.R +++ b/R/badge.R @@ -165,16 +165,6 @@ use_posit_cloud_badge <- function(url) { invisible(TRUE) } -#' @rdname badges -#' @export -use_rscloud_badge <- function(url) { - lifecycle::deprecate_warn( - "2.2.0", "use_rscloud_badge()", - "use_posit_cloud_badge()" - ) - use_posit_cloud_badge(url) -} - has_badge <- function(href) { readme_path <- proj_path("README.md") if (!file_exists(readme_path)) { diff --git a/R/usethis-deprecated.R b/R/usethis-deprecated.R index 588f78619..56241f176 100644 --- a/R/usethis-deprecated.R +++ b/R/usethis-deprecated.R @@ -3,15 +3,31 @@ #' @description #' `r lifecycle::badge("deprecated")` #' -#' * `git_branch_default()` has been replaced by [git_default_branch()]. +#' `git_branch_default()` has been replaced by [git_default_branch()]. #' #' @keywords internal #' @export git_branch_default <- function() { - lifecycle::deprecate_soft("2.1.0", "git_branch_default()", "git_default_branch()") + lifecycle::deprecate_warn("2.1.0", "git_branch_default()", "git_default_branch()") git_default_branch() } +#' Deprecated badge function +#' +#' @description +#' `r lifecycle::badge("deprecated")` +#' +#' `use_rscloud_badge()` has been replaced by [use_posit_cloud_badge()]. +#' +#' @keywords internal +#' @export +use_rscloud_badge <- function(url) { + lifecycle::deprecate_stop( + "2.2.0", "use_rscloud_badge()", + "use_posit_cloud_badge()" + ) +} + #' Deprecated tidyverse functions #' #' @description diff --git a/man/badges.Rd b/man/badges.Rd index 831a574c1..b69ea32b5 100644 --- a/man/badges.Rd +++ b/man/badges.Rd @@ -8,7 +8,6 @@ \alias{use_lifecycle_badge} \alias{use_binder_badge} \alias{use_posit_cloud_badge} -\alias{use_rscloud_badge} \title{README badges} \usage{ use_badge(badge_name, href, src) @@ -22,8 +21,6 @@ use_lifecycle_badge(stage) use_binder_badge(ref = git_default_branch(), urlpath = NULL) use_posit_cloud_badge(url) - -use_rscloud_badge(url) } \arguments{ \item{badge_name}{Badge name. Used in error message and alt text} diff --git a/man/git_branch_default.Rd b/man/git_branch_default.Rd index 42d5395de..f7b1bf112 100644 --- a/man/git_branch_default.Rd +++ b/man/git_branch_default.Rd @@ -8,8 +8,7 @@ git_branch_default() } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} -\itemize{ -\item \code{git_branch_default()} has been replaced by \code{\link[=git_default_branch]{git_default_branch()}}. -} + +\code{git_branch_default()} has been replaced by \code{\link[=git_default_branch]{git_default_branch()}}. } \keyword{internal} diff --git a/man/use_rscloud_badge.Rd b/man/use_rscloud_badge.Rd new file mode 100644 index 000000000..5d352b81b --- /dev/null +++ b/man/use_rscloud_badge.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/usethis-deprecated.R +\name{use_rscloud_badge} +\alias{use_rscloud_badge} +\title{Deprecated badge function} +\usage{ +use_rscloud_badge(url) +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + +\code{use_rscloud_badge()} has been replaced by \code{\link[=use_posit_cloud_badge]{use_posit_cloud_badge()}}. +} +\keyword{internal} diff --git a/tests/testthat/_snaps/badge.md b/tests/testthat/_snaps/badge.md index a212bab6b..9546db429 100644 --- a/tests/testthat/_snaps/badge.md +++ b/tests/testthat/_snaps/badge.md @@ -7,7 +7,7 @@ ! `stage` must be one of "experimental", "stable", "superseded", or "deprecated", not "eperimental". i Did you mean "experimental"? -# use_rscloud_badge() handles bad and good input +# use_posit_cloud_badge() handles bad and good input Code use_posit_cloud_badge() @@ -31,19 +31,3 @@ Error in `use_posit_cloud_badge()`: x `usethis::use_posit_cloud_badge()` requires a link to an existing Posit Cloud project of the form "https://posit.cloud/content/" or "https://posit.cloud/spaces//content/". ---- - - Code - use_rscloud_badge("https://rstudio.cloud/content/123") - Condition - Error in `use_posit_cloud_badge()`: - x `usethis::use_posit_cloud_badge()` requires a link to an existing Posit Cloud project of the form "https://posit.cloud/content/" or "https://posit.cloud/spaces//content/". - ---- - - Code - use_rscloud_badge("https://posit.cloud/project/123") - Condition - Error in `use_posit_cloud_badge()`: - x `usethis::use_posit_cloud_badge()` requires a link to an existing Posit Cloud project of the form "https://posit.cloud/content/" or "https://posit.cloud/spaces//content/". - diff --git a/tests/testthat/test-badge.R b/tests/testthat/test-badge.R index e90d05f56..6c9b8057d 100644 --- a/tests/testthat/test-badge.R +++ b/tests/testthat/test-badge.R @@ -21,27 +21,13 @@ test_that("use_binder_badge() needs a github repository", { expect_error(use_binder_badge(), class = "usethis_error_bad_github_remote_config") }) -test_that("use_rscloud_badge() handles bad and good input", { +test_that("use_posit_cloud_badge() handles bad and good input", { create_local_project() expect_snapshot(use_posit_cloud_badge(), error = TRUE) expect_snapshot(use_posit_cloud_badge(123), error = TRUE) expect_snapshot(use_posit_cloud_badge("http://posit.cloud/123"), error = TRUE) expect_no_error(use_posit_cloud_badge("https://posit.cloud/content/123")) expect_no_error(use_posit_cloud_badge("https://posit.cloud/spaces/123/content/123")) - - lifecycle::expect_deprecated( - use_rscloud_badge("https://posit.cloud/spaces/123/content/123") - ) - - withr::local_options(lifecycle_verbosity = "quiet") - expect_snapshot( - use_rscloud_badge("https://rstudio.cloud/content/123"), - error = TRUE - ) - expect_snapshot( - use_rscloud_badge("https://posit.cloud/project/123"), - error = TRUE - ) }) test_that("use_badge() does nothing if badge seems to pre-exist", { From 1b911ce943fcd19499cfb82af84b37cb97b1da72 Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Sun, 28 Jul 2024 12:51:20 -0700 Subject: [PATCH 05/21] Update a URL --- R/issue.R | 4 ++-- man/issue-this.Rd | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/R/issue.R b/R/issue.R index a4b0e6085..9e4b2e44f 100644 --- a/R/issue.R +++ b/R/issue.R @@ -7,8 +7,8 @@ #' by the tidyverse team. #' #' * `issue_close_community()` closes an issue, because it's not a bug report or -#' feature request, and points the author towards RStudio Community as a -#' better place to discuss usage (). +#' feature request, and points the author towards Posit Community as a +#' better place to discuss usage (). #' #' * `issue_reprex_needed()` labels the issue with the "reprex" label and #' gives the author some advice about what is needed. diff --git a/man/issue-this.Rd b/man/issue-this.Rd index 7486ddc4d..eb490fbee 100644 --- a/man/issue-this.Rd +++ b/man/issue-this.Rd @@ -22,8 +22,8 @@ with large numbers of issues, particularly motivated by the challenges faced by the tidyverse team. \itemize{ \item \code{issue_close_community()} closes an issue, because it's not a bug report or -feature request, and points the author towards RStudio Community as a -better place to discuss usage (\url{https://community.rstudio.com}). +feature request, and points the author towards Posit Community as a +better place to discuss usage (\url{https://forum.posit.co}). \item \code{issue_reprex_needed()} labels the issue with the "reprex" label and gives the author some advice about what is needed. } From 822e5905f64ca5157c27d956f77b1c6a32957cbb Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Sun, 28 Jul 2024 12:52:03 -0700 Subject: [PATCH 06/21] Update form of codecov URL Learned about this from urlchecker --- R/coverage.R | 2 +- README.Rmd | 2 +- README.md | 12 ++++++------ tests/testthat/_snaps/coverage.md | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/R/coverage.R b/R/coverage.R index 2406cd8bd..6a6332513 100644 --- a/R/coverage.R +++ b/R/coverage.R @@ -44,7 +44,7 @@ use_covr_ignore <- function(files) { } use_codecov_badge <- function(repo_spec) { - url <- glue("https://codecov.io/gh/{repo_spec}") + url <- glue("https://app.codecov.io/gh/{repo_spec}") img <- glue("https://codecov.io/gh/{repo_spec}/graph/badge.svg") use_badge("Codecov test coverage", url, img) } diff --git a/README.Rmd b/README.Rmd index ed3b4ac0a..e033dc312 100644 --- a/README.Rmd +++ b/README.Rmd @@ -20,7 +20,7 @@ knitr::opts_chunk$set( [![CRAN status](https://www.r-pkg.org/badges/version/usethis)](https://CRAN.R-project.org/package=usethis) [![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) [![.github/workflows/R-CMD-check](https://github.com/r-lib/usethis/actions/workflows/.github/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-lib/usethis/actions/workflows/.github/workflows/R-CMD-check.yaml) -[![Codecov test coverage](https://codecov.io/gh/r-lib/usethis/graph/badge.svg)](https://codecov.io/gh/r-lib/usethis) +[![Codecov test coverage](https://codecov.io/gh/r-lib/usethis/graph/badge.svg)](https://app.codecov.io/gh/r-lib/usethis) usethis is a workflow package: it automates repetitive tasks that arise during project setup and development, both for R packages and non-package projects. diff --git a/README.md b/README.md index b865cb055..f78de71dd 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ status](https://www.r-pkg.org/badges/version/usethis)](https://CRAN.R-project.or stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) [![.github/workflows/R-CMD-check](https://github.com/r-lib/usethis/actions/workflows/.github/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-lib/usethis/actions/workflows/.github/workflows/R-CMD-check.yaml) [![Codecov test -coverage](https://codecov.io/gh/r-lib/usethis/graph/badge.svg)](https://codecov.io/gh/r-lib/usethis) +coverage](https://codecov.io/gh/r-lib/usethis/graph/badge.svg)](https://app.codecov.io/gh/r-lib/usethis) usethis is a workflow package: it automates repetitive tasks that arise @@ -61,8 +61,8 @@ library(usethis) # Create a new package ------------------------------------------------- path <- file.path(tempdir(), "mypkg") create_package(path) -#> ✔ Creating '/tmp/RtmpMuqeSm/mypkg/'. -#> ✔ Setting active project to "/private/tmp/RtmpMuqeSm/mypkg". +#> ✔ Creating '/tmp/Rtmpyt1hd6/mypkg/'. +#> ✔ Setting active project to "/private/tmp/Rtmpyt1hd6/mypkg". #> ✔ Creating 'R/'. #> ✔ Writing 'DESCRIPTION'. #> Package: mypkg @@ -75,13 +75,13 @@ create_package(path) #> license #> Encoding: UTF-8 #> Roxygen: list(markdown = TRUE) -#> RoxygenNote: 7.3.1 +#> RoxygenNote: 7.3.2 #> ✔ Writing 'NAMESPACE'. #> ✔ Setting active project to "". # only needed since this session isn't interactive proj_activate(path) -#> ✔ Setting active project to "/private/tmp/RtmpMuqeSm/mypkg". -#> ✔ Changing working directory to '/tmp/RtmpMuqeSm/mypkg/' +#> ✔ Setting active project to "/private/tmp/Rtmpyt1hd6/mypkg". +#> ✔ Changing working directory to '/tmp/Rtmpyt1hd6/mypkg/' # Modify the description ---------------------------------------------- use_mit_license("My Name") diff --git a/tests/testthat/_snaps/coverage.md b/tests/testthat/_snaps/coverage.md index c849622be..df963ad75 100644 --- a/tests/testthat/_snaps/coverage.md +++ b/tests/testthat/_snaps/coverage.md @@ -8,6 +8,6 @@ i Badge link will only be printed to screen. [ ] Copy and paste the following lines into 'README': - [![Codecov test coverage](https://codecov.io/gh/OWNER/REPO/graph/badge.svg)](https://codecov.io/gh/OWNER/REPO) + [![Codecov test coverage](https://codecov.io/gh/OWNER/REPO/graph/badge.svg)](https://app.codecov.io/gh/OWNER/REPO) From 37a428b96b93cd928e1938dda8f2dd479ad4815a Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Sun, 28 Jul 2024 13:27:51 -0700 Subject: [PATCH 07/21] Polish NEWS --- NEWS.md | 73 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/NEWS.md b/NEWS.md index 3f7a8051e..58e984fee 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,34 +1,6 @@ # usethis (development version) -* `use_zip()` and `use_course()` are equipped to handle a ZIP where the parent folder is implicit (@burnsal, #1961). - -* `use_test_helper()` is a new function to create a test helper file (@olivroy, #1822). - -* `use_cpp11()` makes it easier to update `NAMESPACE` (@pachadotdev, #1921). - -* `pr_merge_main()` now offers the choice to not open the files with merge conflicts (@olivroy, #1720). - -* `edit_rstudio_snippets()` now accepts yaml snippets (@olivroy, #1941). - -* `use_standalone()` inserts an improved header that includes the code needed to - update the standalone file (@krlmlr, #1903). - -* `use_release_issue()` and `use_upkeep()` behave better when the user has a - fork. The user is asked just once to choose between `origin` and `upstream` as - the target repo (#2023). - -* The README templates now recommend [pak](https://pak.r-lib.org) instead of - devtools for package installation (@olivroy, #1723). - -* `use_github()` now knows that you can reuse the name of an earlier repo that - has since been renamed (@ateucher, #1893). - -* `use_git()` no longer asks if you want to restart RStudio when using Positron. - -* `use_test()` and `use_r()` now work when you are in `tests/testthat/_snaps/{foo}.md` (@olivroy, #1988). - -* The URLs baked into the badge generated by `use_coverage(type = "codecov")` - no longer specify a branch (#2008). +## Transition to cli package for UI * The `ui_*()` functions have been marked as [superseded](https://lifecycle.r-lib.org/articles/stages.html#superseded). @@ -39,13 +11,9 @@ superior option. There is a cli vignette about how to make this transition: `vignette("usethis-ui", package = "cli")`. - usethis no longer uses the `ui_*()` functions internally, in favor of new cli-based helpers that are not exported. -* `usethis::use_version()` now tolerates empty / blank lines preceding the - first section title in the package NEWS file. (#1976) - ## Deprecated function and argument removal We are removing functions and arguments that were deprecated as of usethis @@ -83,6 +51,45 @@ Function arguments that are removed: * `use_github_links(auth_token =, host =)` * `use_github_release(host =, auth_token =)` +## Other changes + +* `use_zip()` and `use_course()` are equipped to handle a ZIP where the parent + folder is implicit (@burnsal, #1961). + +* `use_test_helper()` is a new function to create a test helper file + (@olivroy, #1822). + +* `use_cpp11()` makes it easier to update `NAMESPACE` (@pachadotdev, #1921). + +* `pr_merge_main()` now offers the choice to not open the files with merge + conflicts (@olivroy, #1720). + +* `edit_rstudio_snippets()` now accepts yaml snippets (@olivroy, #1941). + +* `use_standalone()` inserts an improved header that includes the code needed to + update the standalone file (@krlmlr, #1903). + +* `use_release_issue()` and `use_upkeep()` behave better when the user has a + fork. The user is asked just once to choose between `origin` and `upstream` as + the target repo (#2023). + +* The README templates now recommend [pak](https://pak.r-lib.org) instead of + devtools for package installation (@olivroy, #1723). + +* `use_github()` now knows that you can reuse the name of an earlier repo that + has since been renamed (@ateucher, #1893). + +* `use_git()` no longer asks if you want to restart RStudio when using Positron. + +* `use_test()` and `use_r()` now work when you are in + `tests/testthat/_snaps/{foo}.md` (@olivroy, #1988). + +* The URLs baked into the badge generated by `use_coverage(type = "codecov")` + are updated and no longer specify a branch(#2008). + +* `usethis::use_version()` now tolerates empty lines preceding the + first section title in the package NEWS file. (#1976) + # usethis 2.2.3 * Patch release with changes to `.Rd` files requested by CRAN. From 4b3bc178ce7d237ed241635695caf4f22f822171 Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Sun, 28 Jul 2024 13:50:58 -0700 Subject: [PATCH 08/21] Get rid of Travis CI mentions Saw this on win-builder, which alerted me to this stuff even still being here. The Travis CI functions have been removed. Found the following (possibly) invalid URLs: URL: https://www.travis-ci.com/ From: man/browse-this.Rd Status: Error Message: Maximum (10) redirects followed --- R/browse.R | 3 --- man/browse-this.Rd | 3 --- 2 files changed, 6 deletions(-) diff --git a/R/browse.R b/R/browse.R index 726a97950..71888aeed 100644 --- a/R/browse.R +++ b/R/browse.R @@ -9,7 +9,6 @@ #' DESCRIPTION file is sought first in the local package library and then #' on CRAN. #' * Fixed templates: -#' - Travis CI: `https://travis-ci.{EXT}/{OWNER}/{PACKAGE}` #' - Circle CI: `https://circleci.com/gh/{OWNER}/{PACKAGE}` #' - CRAN landing page: `https://cran.r-project.org/package={PACKAGE}` #' - GitHub mirror of a CRAN package: `https://github.com/cran/{PACKAGE}` @@ -29,8 +28,6 @@ #' issue. #' * `browse_github_pulls()`: Visits the GitHub Pull Request index or one #' specific pull request. -#' * `browse_travis()`: Visits the project's page on -#' [Travis CI](https://www.travis-ci.com/). #' * `browse_circleci()`: Visits the project's page on #' [Circle CI](https://circleci.com). #' * `browse_cran()`: Visits the package on CRAN, via the canonical URL. diff --git a/man/browse-this.Rd b/man/browse-this.Rd index 5b474f32a..0057dba6c 100644 --- a/man/browse-this.Rd +++ b/man/browse-this.Rd @@ -47,7 +47,6 @@ DESCRIPTION file is sought first in the local package library and then on CRAN. \item Fixed templates: \itemize{ -\item Travis CI: \verb{https://travis-ci.\{EXT\}/\{OWNER\}/\{PACKAGE\}} \item Circle CI: \verb{https://circleci.com/gh/\{OWNER\}/\{PACKAGE\}} \item CRAN landing page: \verb{https://cran.r-project.org/package=\{PACKAGE\}} \item GitHub mirror of a CRAN package: \verb{https://github.com/cran/\{PACKAGE\}} @@ -70,8 +69,6 @@ in the source repo or your fork. issue. \item \code{browse_github_pulls()}: Visits the GitHub Pull Request index or one specific pull request. -\item \code{browse_travis()}: Visits the project's page on -\href{https://www.travis-ci.com/}{Travis CI}. \item \code{browse_circleci()}: Visits the project's page on \href{https://circleci.com}{Circle CI}. \item \code{browse_cran()}: Visits the package on CRAN, via the canonical URL. From 7b262bb9cc13bf04ed1272eca4fd6daab74ba332 Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Sun, 28 Jul 2024 15:05:15 -0700 Subject: [PATCH 09/21] revdepcheck::cloud_check() The main run has one laggard: ``` > revdepcheck::cloud_status() [0/1/217/0 - 218] 01:28:52 ``` I don't know an easy way to tell what this 1 package is. In the meantime, I'm starting a new job to recheck scaper on R 4.4.0, because that seems to be the problem there. --- cran-comments.md | 37 +++++++++++-- revdep/README.md | 16 ++++-- revdep/cran.md | 17 ++++-- revdep/failures.md | 61 ++++++++++++++++++++- revdep/problems.md | 134 ++++++++++++++++++++++++++++++++++++++------- 5 files changed, 231 insertions(+), 34 deletions(-) diff --git a/cran-comments.md b/cran-comments.md index 44b7bf32e..de5560446 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,8 +1,35 @@ -This is a patch release in response to a 2024-01-22 email from Kurt Hornik about -check NOTEs related to Rd \usage sections. I have eliminated the NOTEs. - -I did NOT rerun reverse dependency checks for this patch release. - ## R CMD check results 0 errors | 0 warnings | 0 notes + +## revdepcheck results + +We checked 217 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. + + * We saw 3 new problems + * We failed to check 1 packages + +Issues with CRAN packages are summarised below. + +### New problems + +* circle + This package makes reference to a function that is now removed from usethis. + This function has been hard-deprecated (i.e. throws an error with advice on + how to update) since usethis v2.2.0, released in December 2020. + I have opened an issue in circle's GitHub repository. + +* exampletestr + This package has a brittle test that checks for exact wording of an error + message originating in usethis. + That test fails because usethis's error message has changed slightly. + I have opened an issue in exampletestr's GitHub repository. + +* pharmaverseadam + I saw the NOTE about the installed package size being large. + I believe this is spurious/random as I don't see how this could be related to + usethis. + +### Failed to check + +* scaper (NA) diff --git a/revdep/README.md b/revdep/README.md index 1ecf9100a..23b2f2eba 100644 --- a/revdep/README.md +++ b/revdep/README.md @@ -1,8 +1,16 @@ # Revdeps -## New problems (1) +## Failed to check (1) -|package |version |error |warning |note | -|:-------|:-------|:------|:-------|:----| -|[cffr](problems.md#cffr)|0.5.0 |__+1__ | | | +|package |version |error |warning |note | +|:-------|:-------|:-----|:-------|:----| +|scaper |0.1.0 |1 | | | + +## New problems (3) + +|package |version |error |warning |note | +|:---------------|:-------|:--------|:-------|:------| +|[circle](problems.md#circle)|0.7.2 |1 |__+1__ | | +|[exampletestr](problems.md#exampletestr)|1.7.1 |1 __+1__ | | | +|[pharmaverseadam](problems.md#pharmaverseadam)|1.0.0 | | |__+1__ | diff --git a/revdep/cran.md b/revdep/cran.md index 633030f13..3b19c4fbf 100644 --- a/revdep/cran.md +++ b/revdep/cran.md @@ -1,15 +1,24 @@ ## revdepcheck results -We checked 181 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. +We checked 217 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. - * We saw 1 new problems - * We failed to check 0 packages + * We saw 3 new problems + * We failed to check 1 packages Issues with CRAN packages are summarised below. ### New problems (This reports the first line of each new failure) -* cffr +* circle + checking dependencies in R code ... WARNING + +* exampletestr checking tests ... ERROR +* pharmaverseadam + checking installed package size ... NOTE + +### Failed to check + +* scaper (NA) diff --git a/revdep/failures.md b/revdep/failures.md index 9a2073633..64892937f 100644 --- a/revdep/failures.md +++ b/revdep/failures.md @@ -1 +1,60 @@ -*Wow, no problems at all. :)* \ No newline at end of file +# scaper + +
+ +* Version: 0.1.0 +* GitHub: NA +* Source code: https://github.com/cran/scaper +* Date/Publication: 2023-10-19 07:20:02 UTC +* Number of recursive dependencies: 161 + +Run `revdepcheck::cloud_details(, "scaper")` for more info + +
+ +## In both + +* checking whether package ‘scaper’ can be installed ... ERROR + ``` + Installation failed. + See ‘/tmp/workdir/scaper/new/scaper.Rcheck/00install.out’ for details. + ``` + +## Installation + +### Devel + +``` +* installing *source* package ‘scaper’ ... +** package ‘scaper’ successfully unpacked and MD5 sums checked +** using staged installation +** R +** inst +** byte-compile and prepare package for lazy loading +Error in loadNamespace(j <- i[[1L]], c(lib.loc, .libPaths()), versionCheck = vI[[j]]) : + namespace ‘Matrix’ 1.5-4.1 is already loaded, but >= 1.6.4 is required +Calls: ... namespaceImportFrom -> asNamespace -> loadNamespace +Execution halted +ERROR: lazy loading failed for package ‘scaper’ +* removing ‘/tmp/workdir/scaper/new/scaper.Rcheck/scaper’ + + +``` +### CRAN + +``` +* installing *source* package ‘scaper’ ... +** package ‘scaper’ successfully unpacked and MD5 sums checked +** using staged installation +** R +** inst +** byte-compile and prepare package for lazy loading +Error in loadNamespace(j <- i[[1L]], c(lib.loc, .libPaths()), versionCheck = vI[[j]]) : + namespace ‘Matrix’ 1.5-4.1 is already loaded, but >= 1.6.4 is required +Calls: ... namespaceImportFrom -> asNamespace -> loadNamespace +Execution halted +ERROR: lazy loading failed for package ‘scaper’ +* removing ‘/tmp/workdir/scaper/old/scaper.Rcheck/scaper’ + + +``` diff --git a/revdep/problems.md b/revdep/problems.md index d9ef6a546..c61bc2482 100644 --- a/revdep/problems.md +++ b/revdep/problems.md @@ -1,14 +1,55 @@ -# cffr +# circle
-* Version: 0.5.0 -* GitHub: https://github.com/ropensci/cffr -* Source code: https://github.com/cran/cffr -* Date/Publication: 2023-05-05 12:00:02 UTC -* Number of recursive dependencies: 71 +* Version: 0.7.2 +* GitHub: https://github.com/ropensci/circle +* Source code: https://github.com/cran/circle +* Date/Publication: 2022-08-24 07:50:02 UTC +* Number of recursive dependencies: 76 -Run `revdepcheck::cloud_details(, "cffr")` for more info +Run `revdepcheck::cloud_details(, "circle")` for more info + +
+ +## Newly broken + +* checking dependencies in R code ... WARNING + ``` + Missing or unexported object: ‘usethis::github_token’ + ``` + +## In both + +* checking running R code from vignettes ... ERROR + ``` + Errors in running code in vignettes: + when running code in ‘circle.Rmd’ + ... + + > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") + + > knitr::include_graphics("../man/figures/user-key.png") + + When sourcing ‘circle.R’: + Error: Cannot find the file(s): "../man/figures/user-key.png" + Execution halted + + ‘circle.Rmd’ using ‘UTF-8’... failed + ‘tic.Rmd’ using ‘UTF-8’... OK + ``` + +# exampletestr + +
+ +* Version: 1.7.1 +* GitHub: https://github.com/rorynolan/exampletestr +* Source code: https://github.com/cran/exampletestr +* Date/Publication: 2023-06-11 03:10:02 UTC +* Number of recursive dependencies: 97 + +Run `revdepcheck::cloud_details(, "exampletestr")` for more info
@@ -16,23 +57,76 @@ Run `revdepcheck::cloud_details(, "cffr")` for more info * checking tests ... ERROR ``` + Running ‘spelling.R’ Running ‘testthat.R’ Running the tests in ‘tests/testthat.R’ failed. - Last 13 lines of output: - 'test-write_citation.R:46:3', 'test-write_citation.R:111:3' - - ══ Failed tests ════════════════════════════════════════════════════════════════ - ── Failure ('test-cff_to_bibtex.R:416:3'): Errors ────────────────────────────── - `b <- cff_to_bibtex("testthat")` produced warnings. + Complete output: + > library(testthat) + > library(exampletestr) + > + > get_os <- function() { + + sysinf <- Sys.info() + + if (!is.null(sysinf)) { + ... + 6. └─exampletestr:::extract_examples("detect", tempdir(check = TRUE)) + 7. └─usethis::local_project(path = pkg_dir, quiet = TRUE) + 8. └─usethis::proj_set(path = path, force = force) + 9. └─usethis:::ui_abort(...) + 10. └─cli::cli_abort(...) + 11. └─rlang::abort(...) - [ FAIL 1 | WARN 10 | SKIP 110 | PASS 311 ] - Deleting unused snapshots: - • write_bib/append.bib - • write_bib/ascii.bib - • write_bib/noext.bib - • write_citation/append - • write_citation/noext + [ FAIL 1 | WARN 0 | SKIP 0 | PASS 27 ] Error: Test failures Execution halted ``` +## In both + +* checking running R code from vignettes ... ERROR + ``` + Errors in running code in vignettes: + when running code in ‘one-file-at-a-time.Rmd’ + ... + > knitr::opts_knit$set(root.dir = paste0(tempdir(), + + "/", "tempkg")) + + > usethis::proj_set(".") + + When sourcing ‘one-file-at-a-time.R’: + Error: ✖ Path '/tmp/RtmpGIYvQt/file132af710168/vignettes/' does not appear to + ... + + When sourcing ‘whole-package.R’: + Error: ✖ Path '/tmp/RtmpauCurR/file133f1dd70a93/vignettes/' does not appear to + be inside a project or package. + ℹ Read more in the help for `usethis::proj_get()`. + Execution halted + + ‘one-file-at-a-time.Rmd’ using ‘UTF-8’... failed + ‘one-function-at-a-time.Rmd’ using ‘UTF-8’... OK + ‘whole-package.Rmd’ using ‘UTF-8’... failed + ``` + +# pharmaverseadam + +
+ +* Version: 1.0.0 +* GitHub: https://github.com/pharmaverse/pharmaverseadam +* Source code: https://github.com/cran/pharmaverseadam +* Date/Publication: 2024-07-01 09:30:02 UTC +* Number of recursive dependencies: 120 + +Run `revdepcheck::cloud_details(, "pharmaverseadam")` for more info + +
+ +## Newly broken + +* checking installed package size ... NOTE + ``` + installed size is 7.9Mb + sub-directories of 1Mb or more: + data 7.5Mb + ``` + From 632e106e4b561dfa802106444fb9824073fce993 Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Sun, 28 Jul 2024 16:01:38 -0700 Subject: [PATCH 10/21] Update revdep results revdepcheck::cloud_check(revdep_packages = c("scaper", "pharmaverseadam"), r_version = "4.4.0") --- cran-comments.md | 13 ++-------- revdep/failures.md | 61 +--------------------------------------------- revdep/problems.md | 24 ------------------ 3 files changed, 3 insertions(+), 95 deletions(-) diff --git a/cran-comments.md b/cran-comments.md index de5560446..6df713ca7 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -6,8 +6,8 @@ We checked 217 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. - * We saw 3 new problems - * We failed to check 1 packages + * We saw 2 new problems + * We failed to check 0 packages Issues with CRAN packages are summarised below. @@ -24,12 +24,3 @@ Issues with CRAN packages are summarised below. message originating in usethis. That test fails because usethis's error message has changed slightly. I have opened an issue in exampletestr's GitHub repository. - -* pharmaverseadam - I saw the NOTE about the installed package size being large. - I believe this is spurious/random as I don't see how this could be related to - usethis. - -### Failed to check - -* scaper (NA) diff --git a/revdep/failures.md b/revdep/failures.md index 64892937f..9a2073633 100644 --- a/revdep/failures.md +++ b/revdep/failures.md @@ -1,60 +1 @@ -# scaper - -
- -* Version: 0.1.0 -* GitHub: NA -* Source code: https://github.com/cran/scaper -* Date/Publication: 2023-10-19 07:20:02 UTC -* Number of recursive dependencies: 161 - -Run `revdepcheck::cloud_details(, "scaper")` for more info - -
- -## In both - -* checking whether package ‘scaper’ can be installed ... ERROR - ``` - Installation failed. - See ‘/tmp/workdir/scaper/new/scaper.Rcheck/00install.out’ for details. - ``` - -## Installation - -### Devel - -``` -* installing *source* package ‘scaper’ ... -** package ‘scaper’ successfully unpacked and MD5 sums checked -** using staged installation -** R -** inst -** byte-compile and prepare package for lazy loading -Error in loadNamespace(j <- i[[1L]], c(lib.loc, .libPaths()), versionCheck = vI[[j]]) : - namespace ‘Matrix’ 1.5-4.1 is already loaded, but >= 1.6.4 is required -Calls: ... namespaceImportFrom -> asNamespace -> loadNamespace -Execution halted -ERROR: lazy loading failed for package ‘scaper’ -* removing ‘/tmp/workdir/scaper/new/scaper.Rcheck/scaper’ - - -``` -### CRAN - -``` -* installing *source* package ‘scaper’ ... -** package ‘scaper’ successfully unpacked and MD5 sums checked -** using staged installation -** R -** inst -** byte-compile and prepare package for lazy loading -Error in loadNamespace(j <- i[[1L]], c(lib.loc, .libPaths()), versionCheck = vI[[j]]) : - namespace ‘Matrix’ 1.5-4.1 is already loaded, but >= 1.6.4 is required -Calls: ... namespaceImportFrom -> asNamespace -> loadNamespace -Execution halted -ERROR: lazy loading failed for package ‘scaper’ -* removing ‘/tmp/workdir/scaper/old/scaper.Rcheck/scaper’ - - -``` +*Wow, no problems at all. :)* \ No newline at end of file diff --git a/revdep/problems.md b/revdep/problems.md index c61bc2482..3051c2622 100644 --- a/revdep/problems.md +++ b/revdep/problems.md @@ -106,27 +106,3 @@ Run `revdepcheck::cloud_details(, "exampletestr")` for more info ‘one-function-at-a-time.Rmd’ using ‘UTF-8’... OK ‘whole-package.Rmd’ using ‘UTF-8’... failed ``` - -# pharmaverseadam - -
- -* Version: 1.0.0 -* GitHub: https://github.com/pharmaverse/pharmaverseadam -* Source code: https://github.com/cran/pharmaverseadam -* Date/Publication: 2024-07-01 09:30:02 UTC -* Number of recursive dependencies: 120 - -Run `revdepcheck::cloud_details(, "pharmaverseadam")` for more info - -
- -## Newly broken - -* checking installed package size ... NOTE - ``` - installed size is 7.9Mb - sub-directories of 1Mb or more: - data 7.5Mb - ``` - From 0fcc5c15759a2f6a0f67000dc4862a57a2f01c2d Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Sun, 28 Jul 2024 16:06:54 -0700 Subject: [PATCH 11/21] Increment version number to 3.0.0 --- DESCRIPTION | 2 +- NEWS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 1b915cec1..de757465c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: usethis Title: Automate Package and Project Setup -Version: 2.2.3.9000 +Version: 3.0.0 Authors@R: c( person("Hadley", "Wickham", , "hadley@posit.co", role = "aut", comment = c(ORCID = "0000-0003-4757-117X")), diff --git a/NEWS.md b/NEWS.md index 58e984fee..fcd0887ea 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# usethis (development version) +# usethis 3.0.0 ## Transition to cli package for UI From 0024a85f0c43bea08198431a6b8d9448a58d5cf2 Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Mon, 29 Jul 2024 05:34:28 -0700 Subject: [PATCH 12/21] Increment version number to 3.0.0.9000 --- DESCRIPTION | 2 +- NEWS.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index de757465c..e779235bf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: usethis Title: Automate Package and Project Setup -Version: 3.0.0 +Version: 3.0.0.9000 Authors@R: c( person("Hadley", "Wickham", , "hadley@posit.co", role = "aut", comment = c(ORCID = "0000-0003-4757-117X")), diff --git a/NEWS.md b/NEWS.md index fcd0887ea..cef413ee4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,5 @@ +# usethis (development version) + # usethis 3.0.0 ## Transition to cli package for UI From 22b3bd0eb3b1ecd5258a8d59d99d449e3f62ee6a Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Mon, 29 Jul 2024 05:57:04 -0700 Subject: [PATCH 13/21] Fix this bullet list --- R/course.R | 14 +++++++------- man/zip-utils.Rd | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/R/course.R b/R/course.R index 2713568dc..ddfbb8cb3 100644 --- a/R/course.R +++ b/R/course.R @@ -11,13 +11,13 @@ #' @param url Link to a ZIP file containing the materials. To reduce the chance #' of typos in live settings, these shorter forms are accepted: #' -#' * GitHub repo spec: "OWNER/REPO". Equivalent to -#' `https://github.com/OWNER/REPO/DEFAULT_BRANCH.zip`. -#' * bit.ly or rstd.io shortlinks: "bit.ly/xxx-yyy-zzz" or "rstd.io/foofy". -#' The instructor must then arrange for the shortlink to point to a valid -#' download URL for the target ZIP file. The helper -#' [create_download_url()] helps to create such URLs for GitHub, DropBox, -#' and Google Drive. +#' * GitHub repo spec: "OWNER/REPO". Equivalent to +#' `https://github.com/OWNER/REPO/DEFAULT_BRANCH.zip`. +#' * bit.ly or rstd.io shortlinks: "bit.ly/xxx-yyy-zzz" or "rstd.io/foofy". +#' The instructor must then arrange for the shortlink to point to a valid +#' download URL for the target ZIP file. The helper +#' [create_download_url()] helps to create such URLs for GitHub, DropBox, +#' and Google Drive. #' @param destdir Destination for the new folder. Defaults to the location #' stored in the global option `usethis.destdir`, if defined, or to the user's #' Desktop or similarly conspicuous place otherwise. diff --git a/man/zip-utils.Rd b/man/zip-utils.Rd index fbb0b7747..2e569ce3b 100644 --- a/man/zip-utils.Rd +++ b/man/zip-utils.Rd @@ -17,15 +17,15 @@ use_zip( \arguments{ \item{url}{Link to a ZIP file containing the materials. To reduce the chance of typos in live settings, these shorter forms are accepted: - -\if{html}{\out{
}}\preformatted{* GitHub repo spec: "OWNER/REPO". Equivalent to - `https://github.com/OWNER/REPO/DEFAULT_BRANCH.zip`. -* bit.ly or rstd.io shortlinks: "bit.ly/xxx-yyy-zzz" or "rstd.io/foofy". - The instructor must then arrange for the shortlink to point to a valid - download URL for the target ZIP file. The helper - [create_download_url()] helps to create such URLs for GitHub, DropBox, - and Google Drive. -}\if{html}{\out{
}}} +\itemize{ +\item GitHub repo spec: "OWNER/REPO". Equivalent to +\verb{https://github.com/OWNER/REPO/DEFAULT_BRANCH.zip}. +\item bit.ly or rstd.io shortlinks: "bit.ly/xxx-yyy-zzz" or "rstd.io/foofy". +The instructor must then arrange for the shortlink to point to a valid +download URL for the target ZIP file. The helper +\code{\link[=create_download_url]{create_download_url()}} helps to create such URLs for GitHub, DropBox, +and Google Drive. +}} \item{destdir}{Destination for the new folder. Defaults to the location stored in the global option \code{usethis.destdir}, if defined, or to the user's From 6aee0d0aafc29c8f5a59b7881ea2ff6e1293fe47 Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Mon, 29 Jul 2024 07:53:51 -0700 Subject: [PATCH 14/21] Use the actual function name --- NEWS.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index cef413ee4..a698b8d7a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -71,9 +71,9 @@ Function arguments that are removed: * `use_standalone()` inserts an improved header that includes the code needed to update the standalone file (@krlmlr, #1903). -* `use_release_issue()` and `use_upkeep()` behave better when the user has a - fork. The user is asked just once to choose between `origin` and `upstream` as - the target repo (#2023). +* `use_release_issue()` and `use_upkeep_issue()` behave better when the user has + a fork. The user is asked just once to choose between `origin` and `upstream` + as the target repo (#2023). * The README templates now recommend [pak](https://pak.r-lib.org) instead of devtools for package installation (@olivroy, #1723). From 1047825c052c000222dc5ade79c867961a47558f Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Tue, 30 Jul 2024 14:25:08 -0700 Subject: [PATCH 15/21] Get rid of a duplicate badge --- README.Rmd | 1 - README.md | 9 ++++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/README.Rmd b/README.Rmd index e033dc312..35d75aa9b 100644 --- a/README.Rmd +++ b/README.Rmd @@ -19,7 +19,6 @@ knitr::opts_chunk$set( [![R-CMD-check](https://github.com/r-lib/usethis/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-lib/usethis/actions/workflows/R-CMD-check.yaml) [![CRAN status](https://www.r-pkg.org/badges/version/usethis)](https://CRAN.R-project.org/package=usethis) [![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) -[![.github/workflows/R-CMD-check](https://github.com/r-lib/usethis/actions/workflows/.github/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-lib/usethis/actions/workflows/.github/workflows/R-CMD-check.yaml) [![Codecov test coverage](https://codecov.io/gh/r-lib/usethis/graph/badge.svg)](https://app.codecov.io/gh/r-lib/usethis) diff --git a/README.md b/README.md index f78de71dd..2dc670044 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ status](https://www.r-pkg.org/badges/version/usethis)](https://CRAN.R-project.org/package=usethis) [![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) -[![.github/workflows/R-CMD-check](https://github.com/r-lib/usethis/actions/workflows/.github/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-lib/usethis/actions/workflows/.github/workflows/R-CMD-check.yaml) [![Codecov test coverage](https://codecov.io/gh/r-lib/usethis/graph/badge.svg)](https://app.codecov.io/gh/r-lib/usethis) @@ -61,8 +60,8 @@ library(usethis) # Create a new package ------------------------------------------------- path <- file.path(tempdir(), "mypkg") create_package(path) -#> ✔ Creating '/tmp/Rtmpyt1hd6/mypkg/'. -#> ✔ Setting active project to "/private/tmp/Rtmpyt1hd6/mypkg". +#> ✔ Creating '/tmp/RtmpCJHMlj/mypkg/'. +#> ✔ Setting active project to "/private/tmp/RtmpCJHMlj/mypkg". #> ✔ Creating 'R/'. #> ✔ Writing 'DESCRIPTION'. #> Package: mypkg @@ -80,8 +79,8 @@ create_package(path) #> ✔ Setting active project to "". # only needed since this session isn't interactive proj_activate(path) -#> ✔ Setting active project to "/private/tmp/Rtmpyt1hd6/mypkg". -#> ✔ Changing working directory to '/tmp/Rtmpyt1hd6/mypkg/' +#> ✔ Setting active project to "/private/tmp/RtmpCJHMlj/mypkg". +#> ✔ Changing working directory to '/tmp/RtmpCJHMlj/mypkg/' # Modify the description ---------------------------------------------- use_mit_license("My Name") From e195e1fe433f6404392fca9ff60506678faa5671 Mon Sep 17 00:00:00 2001 From: Jenny Bryan Date: Mon, 5 Aug 2024 11:10:20 -0700 Subject: [PATCH 16/21] Test less about the the GHA config files These tests started failing after some changes in r-lib/actions and it feels like we are testing too much about the content of the YAML here. --- tests/testthat/test-github-actions.R | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/testthat/test-github-actions.R b/tests/testthat/test-github-actions.R index a42de3f4a..ff2523862 100644 --- a/tests/testthat/test-github-actions.R +++ b/tests/testthat/test-github-actions.R @@ -102,10 +102,6 @@ test_that("use_github_action() accepts a name", { expect_proj_dir(".github/workflows") expect_proj_file(".github/workflows/R-CMD-check.yaml") - yml <- yaml::yaml.load_file(proj_path(".github/workflows/R-CMD-check.yaml")) - expect_identical(yml$name, "R-CMD-check") - expect_named(yml$jobs, "R-CMD-check") - readme_lines <- read_utf8(proj_path("README.md")) expect_match(readme_lines, "R-CMD-check", all = FALSE) @@ -129,9 +125,6 @@ test_that("use_tidy_github_actions() configures the full check and pr commands", expect_proj_file(".github/workflows/R-CMD-check.yaml") yml <- yaml::yaml.load_file(proj_path(".github/workflows/R-CMD-check.yaml")) - expect_identical(yml$name, "R-CMD-check") - expect_named(yml$jobs, "R-CMD-check") - size_build_matrix <- length(yml[["jobs"]][["R-CMD-check"]][["strategy"]][["matrix"]][["config"]]) expect_gte(size_build_matrix, 6) # release, r-devel, 4 previous versions From 1f6d511cda0960f9edd0d822b9906214b45681f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Mon, 5 Aug 2024 20:16:51 +0200 Subject: [PATCH 17/21] Use latest GHA workflows (#2033) --- .github/workflows/R-CMD-check.yaml | 6 +++--- .github/workflows/pkgdown.yaml | 2 +- .github/workflows/pr-commands.yaml | 6 +++++- .github/workflows/test-coverage.yaml | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index c9494bd09..258243b9c 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -10,7 +10,7 @@ on: pull_request: branches: [main, master] -name: R-CMD-check +name: R-CMD-check.yaml permissions: read-all @@ -27,8 +27,8 @@ jobs: - {os: macos-latest, r: 'release'} - {os: windows-latest, r: 'release'} - # use 4.1 to check with rtools40's older compiler - - {os: windows-latest, r: '4.1'} + # use 4.0 or 4.1 to check with rtools40's older compiler + - {os: windows-latest, r: 'oldrel-4'} - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} - {os: ubuntu-latest, r: 'release'} diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index c9f0165d4..4bbce7508 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -9,7 +9,7 @@ on: types: [published] workflow_dispatch: -name: pkgdown +name: pkgdown.yaml permissions: read-all diff --git a/.github/workflows/pr-commands.yaml b/.github/workflows/pr-commands.yaml index d1f765096..2edd93f27 100644 --- a/.github/workflows/pr-commands.yaml +++ b/.github/workflows/pr-commands.yaml @@ -4,7 +4,7 @@ on: issue_comment: types: [created] -name: Commands +name: pr-commands.yaml permissions: read-all @@ -15,6 +15,8 @@ jobs: runs-on: ubuntu-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write steps: - uses: actions/checkout@v4 @@ -52,6 +54,8 @@ jobs: runs-on: ubuntu-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 054ad014c..8e8e73007 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -6,7 +6,7 @@ on: pull_request: branches: [main, master] -name: test-coverage +name: test-coverage.yaml permissions: read-all From 792cdd054190ce2bf9cd5b9a8461805a08e92f42 Mon Sep 17 00:00:00 2001 From: Cynthia Huang <29718979+cynthiahqy@users.noreply.github.com> Date: Thu, 15 Aug 2024 09:57:18 -0700 Subject: [PATCH 18/21] Remove link from tidy-dev-day label (#2037) Fixes #2022 --- R/github-labels.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/github-labels.R b/R/github-labels.R index 7da4f1d80..f17fecb71 100644 --- a/R/github-labels.R +++ b/R/github-labels.R @@ -301,7 +301,7 @@ tidy_label_descriptions <- function() { "good first issue :heart:" = "good issue for first-time contributors", "help wanted :heart:" = "we'd love your help!", "breaking change :skull_and_crossbones:" = "API change likely to affect existing code", - "tidy-dev-day :nerd_face:" = "Tidyverse Developer Day rstd.io/tidy-dev-day" + "tidy-dev-day :nerd_face:" = "Tidyverse Developer Day" ) } From fa847b5941e6acf94fcc9a7ac01d3307ba8f79db Mon Sep 17 00:00:00 2001 From: Jon Harmon Date: Thu, 15 Aug 2024 11:03:30 -0700 Subject: [PATCH 19/21] Dots in rename (#2038) * Check uncommitted before renaming files. Fixes #1969. After digging into this a little, I think making sure everything is committed is enough. use_r() won't create a file with a `.` in it, so, unless you want to let this snowball, I think the check is enough. * Only remove `.R` extensions from old/new. * Don't use shorthand for function definition. * Use older anonymous function syntax in more places --------- Co-authored-by: Jenny Bryan --- R/rename-files.R | 12 +++++++++--- man/rename_files.Rd | 2 +- tests/testthat/test-rename-files.R | 27 +++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/R/rename-files.R b/R/rename-files.R index 5f71605b8..f3cd21141 100644 --- a/R/rename-files.R +++ b/R/rename-files.R @@ -12,13 +12,19 @@ #' This is a potentially dangerous operation, so you must be using Git in #' order to use this function. #' -#' @param old,new Old and new file names (with or without extensions). +#' @param old,new Old and new file names (with or without `.R` extensions). #' @export rename_files <- function(old, new) { check_uses_git() + challenge_uncommitted_changes( + msg = " + There are uncommitted changes and we're about to bulk-rename files. It is \\ + highly recommended to get into a clean Git state before bulk-editing files", + untracked = TRUE + ) - old <- path_ext_remove(old) - new <- path_ext_remove(new) + old <- sub("\\.R$", "", old) + new <- sub("\\.R$", "", new) # R/ ------------------------------------------------------------------------ r_old_path <- proj_path("R", old, ext = "R") diff --git a/man/rename_files.Rd b/man/rename_files.Rd index fb5396a3c..39ca1b8a5 100644 --- a/man/rename_files.Rd +++ b/man/rename_files.Rd @@ -7,7 +7,7 @@ rename_files(old, new) } \arguments{ -\item{old, new}{Old and new file names (with or without extensions).} +\item{old, new}{Old and new file names (with or without \code{.R} extensions).} } \description{ \itemize{ diff --git a/tests/testthat/test-rename-files.R b/tests/testthat/test-rename-files.R index 86b89d5c6..cdfef3906 100644 --- a/tests/testthat/test-rename-files.R +++ b/tests/testthat/test-rename-files.R @@ -1,5 +1,19 @@ +test_that("checks uncommitted files", { + create_local_package() + expect_error(rename_files("foo", "bar"), class = "usethis_error") + + git_init() + use_r("foo", open = FALSE) + expect_error( + rename_files("foo", "bar"), + "uncommitted changes", + class = "usethis_error" + ) +}) + test_that("renames R and test and snapshot files", { create_local_package() + local_mocked_bindings(challenge_uncommitted_changes = function(...) invisible()) git_init() use_r("foo", open = FALSE) @@ -18,6 +32,7 @@ test_that("renames R and test and snapshot files", { test_that("renames src/ files", { create_local_package() + local_mocked_bindings(challenge_uncommitted_changes = function(...) invisible()) git_init() use_src() @@ -35,6 +50,7 @@ test_that("renames src/ files", { test_that("strips context from test file", { create_local_package() + local_mocked_bindings(challenge_uncommitted_changes = function(...) invisible()) git_init() use_testthat() @@ -54,6 +70,7 @@ test_that("strips context from test file", { test_that("rename paths in test file", { create_local_package() + local_mocked_bindings(challenge_uncommitted_changes = function(...) invisible()) git_init() use_testthat() @@ -65,3 +82,13 @@ test_that("rename paths in test file", { lines <- read_utf8(proj_path("tests", "testthat", "test-bar.R")) expect_equal(lines, "test-bar.txt") }) + +test_that("does not remove non-R dots in filename", { + create_local_package() + local_mocked_bindings(challenge_uncommitted_changes = function(...) invisible()) + git_init() + + file_create(proj_path("R/foo.bar.R")) + rename_files("foo.bar", "baz.qux") + expect_proj_file("R/baz.qux.R") +}) From 716fb14329971fc53c527d46c4d6c3f367bae181 Mon Sep 17 00:00:00 2001 From: Thomas Wells Date: Thu, 15 Aug 2024 11:24:06 -0700 Subject: [PATCH 20/21] suppress git_protocol message in git_sitrep (#2039) * suppress git_protocol message in git_sitrep `git_protocol()` sets a default *and* messages the user if the option isn't already set. This message looks confusing in the output for `git_sitrep()`. This commit suppresses that messsage. * replace suppressMessages() with ui_silence() --- R/git.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/git.R b/R/git.R index b821b2a80..f7f01b681 100644 --- a/R/git.R +++ b/R/git.R @@ -357,7 +357,7 @@ git_sitrep <- function(tool = c("git", "github"), if (!vaccinated) { ui_bullets(c("i" = "See {.fun usethis::git_vaccinate} to learn more.")) } - kv_line("Default Git protocol", git_protocol()) + kv_line("Default Git protocol", ui_silence(git_protocol())) kv_line("Default initial branch name", init_default_branch) } From 0e20668f8bd16db9b17e104568a53aea5e66a17c Mon Sep 17 00:00:00 2001 From: "Jennifer (Jenny) Bryan" Date: Thu, 15 Aug 2024 11:37:38 -0700 Subject: [PATCH 21/21] Fix wording (#2041) Fixes #2036 --- R/pipe.R | 2 +- man/use_pipe.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/pipe.R b/R/pipe.R index d59436c64..dd36544cb 100644 --- a/R/pipe.R +++ b/R/pipe.R @@ -1,7 +1,7 @@ #' Use magrittr's pipe in your package #' #' Does setup necessary to use magrittr's pipe operator, `%>%` in your package. -#' This function requires the use roxygen. +#' This function requires the use of \pkg{roxygen2}. #' * Adds magrittr to "Imports" in `DESCRIPTION`. #' * Imports the pipe operator specifically, which is necessary for internal #' use. diff --git a/man/use_pipe.Rd b/man/use_pipe.Rd index 8558fdb3c..eee140aa0 100644 --- a/man/use_pipe.Rd +++ b/man/use_pipe.Rd @@ -13,7 +13,7 @@ roxygen directive is added, if possible, or otherwise instructions are given.} } \description{ Does setup necessary to use magrittr's pipe operator, \verb{\%>\%} in your package. -This function requires the use roxygen. +This function requires the use of \pkg{roxygen2}. \itemize{ \item Adds magrittr to "Imports" in \code{DESCRIPTION}. \item Imports the pipe operator specifically, which is necessary for internal