Skip to content

Commit

Permalink
Fix idempotency of roxygenize() for packages using multi-line @rawNam…
Browse files Browse the repository at this point in the history
…espace (#1573)

Fixes #1572
  • Loading branch information
MichaelChirico authored Jan 22, 2024
1 parent a3e3908 commit b5e882a
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
.Rproj.user
/.Rhistory

tests/testthat/testthat-problems.rds

## Qt Creator
*.pro
*.pro.user
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# roxygen2 (development version)

* `@family` lists are now ordered more carefully, "foo1" comes after "foo" (#1563, @krlmlr).
* Re-runs of `namespace_roclet()` fixed for packages using multi-line `@rawNamespace` directives (#1572, @MichaelChirico).

* `@importFrom` works again for quoted non-syntactic names, e.g.
`@importFrom magrittr "%>%"` or ``@importFrom rlang `:=` ``, after being broken
Expand Down
7 changes: 5 additions & 2 deletions R/namespace.R
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ update_namespace_imports <- function(base_path) {
}

lines <- c(namespace_imports(base_path), namespace_exports(NAMESPACE))
results <- c(made_by("#"), sort_c(unique(lines)))
results <- c(made_by("#"), sort_c(unique(trimws(lines))))
write_if_different(NAMESPACE, results, check = TRUE)

invisible()
Expand Down Expand Up @@ -109,12 +109,15 @@ namespace_imports_blocks <- function(srcref) {
}))
}

# NB: this is designed as the conjugate of namespace_imports(), so also
# includes @rawNamespace entries which may/may not also include import directives.
namespace_exports <- function(path) {
parsed <- as.list(parse(path, keep.source = TRUE))

is_import_directive <- function(x) is_call(x, import_directives)
export_lines <- attr(parsed, "srcref")[!map_lgl(parsed, is_import_directive)]
unlist(lapply(export_lines, as.character))
# Each multiline directives are a single element so they're sorted correctly
unlist(lapply(export_lines, function(x) paste(as.character(x), collapse = "\n")))
}

# NAMESPACE generation ----------------------------------------------------
Expand Down
19 changes: 18 additions & 1 deletion tests/testthat/test-namespace.R
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,17 @@ test_that("rawNamespace inserted unchanged", {
expect_equal(out, "xyz\n abc")
})

test_that("rawNamespace does not break idempotency", {
test_pkg <- test_path("testRawNamespace")
NAMESPACE <- file.path(test_pkg, "NAMESPACE")

lines_orig <- read_lines(NAMESPACE)

expect_no_error(roxygenize(test_pkg, namespace_roclet()))

# contents unchanged
expect_equal(read_lines(NAMESPACE), lines_orig)
})

# @evalNamespace ----------------------------------------------------------

Expand Down Expand Up @@ -391,7 +402,13 @@ test_that("can extract non-imports from namespace preserving source", {
"export(b)"
)
path <- withr::local_tempfile(lines = lines)
expect_equal(namespace_exports(path), lines[c(1:3, 5)])
expect_equal(
namespace_exports(path),
c(
paste(lines[1:3], collapse = "\n"),
lines[5L]
)
)
})

test_that("invalid imports generate correct declarations", {
Expand Down
9 changes: 9 additions & 0 deletions tests/testthat/testRawNamespace/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Package: testRawNamespace
Title: Check that re-running on multi-line @rawNamespace directive is OK
License: GPL-2
Description: testRawNamespace.
Author: Hadley <[email protected]>
Maintainer: Hadley <[email protected]>
Encoding: UTF-8
Version: 0.1
RoxygenNote: 7.3.0.9000
10 changes: 10 additions & 0 deletions tests/testthat/testRawNamespace/NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Generated by roxygen2: do not edit by hand


if (TRUE) {
import(grDevices)
} else {
import(methods)
}
import(graphics)
import(utils)
9 changes: 9 additions & 0 deletions tests/testthat/testRawNamespace/R/a.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#' @import graphics
#' @rawNamespace
#' if (TRUE) {
#' import(grDevices)
#' } else {
#' import(methods)
#' }
#' @import utils
NULL

0 comments on commit b5e882a

Please sign in to comment.