Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements to standalone header #1903

Merged
merged 8 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# usethis (development version)

* `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).
Expand Down
29 changes: 22 additions & 7 deletions R/import-standalone-obj-type.R
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
# Standalone file: do not edit by hand
# Source: <https://github.com/r-lib/rlang/blob/main/R/standalone-obj-type.R>
# Source: https://github.com/r-lib/rlang/blob/HEAD/R/standalone-obj-type.R
# Generated by: usethis::use_standalone("r-lib/rlang", "obj-type")
# ----------------------------------------------------------------------
#
# ---
# repo: r-lib/rlang
# file: standalone-obj-type.R
# last-updated: 2022-10-04
# last-updated: 2024-02-14
# license: https://unlicense.org
# imports: rlang (>= 1.1.0)
# ---
#
# ## Changelog
#
# 2024-02-14:
# - `obj_type_friendly()` now works for S7 objects.
#
# 2023-05-01:
# - `obj_type_friendly()` now only displays the first class of S3 objects.
#
# 2023-03-30:
# - `stop_input_type()` now handles `I()` input literally in `arg`.
#
# 2022-10-04:
# - `obj_type_friendly(value = TRUE)` now shows numeric scalars
# literally.
Expand Down Expand Up @@ -65,7 +75,7 @@ obj_type_friendly <- function(x, value = TRUE) {
if (inherits(x, "quosure")) {
type <- "quosure"
} else {
type <- paste(class(x), collapse = "/")
type <- class(x)[[1L]]
}
return(sprintf("a <%s> object", type))
}
Expand Down Expand Up @@ -261,19 +271,19 @@ vec_type_friendly <- function(x, length = FALSE) {
#' Return OO type
#' @param x Any R object.
#' @return One of `"bare"` (for non-OO objects), `"S3"`, `"S4"`,
#' `"R6"`, or `"R7"`.
#' `"R6"`, or `"S7"`.
#' @noRd
obj_type_oo <- function(x) {
if (!is.object(x)) {
return("bare")
}

class <- inherits(x, c("R6", "R7_object"), which = TRUE)
class <- inherits(x, c("R6", "S7_object"), which = TRUE)

if (class[[1]]) {
"R6"
} else if (class[[2]]) {
"R7"
"S7"
} else if (isS4(x)) {
"S4"
} else {
Expand Down Expand Up @@ -315,10 +325,15 @@ stop_input_type <- function(x,
if (length(what)) {
what <- oxford_comma(what)
}
if (inherits(arg, "AsIs")) {
format_arg <- identity
} else {
format_arg <- cli$format_arg
}

message <- sprintf(
"%s must be %s, not %s.",
cli$format_arg(arg),
format_arg(arg),
what,
obj_type_friendly(x, value = show_value)
)
Expand Down
3 changes: 2 additions & 1 deletion R/import-standalone-types-check.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Standalone file: do not edit by hand
# Source: <https://github.com/r-lib/rlang/blob/main/R/standalone-types-check.R>
# Source: https://github.com/r-lib/rlang/blob/HEAD/R/standalone-types-check.R
# Generated by: usethis::use_standalone("r-lib/rlang", "types-check")
# ----------------------------------------------------------------------
#
# ---
Expand Down
18 changes: 15 additions & 3 deletions R/use_standalone.R
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ use_standalone <- function(repo_spec, file = NULL, ref = NULL, host = NULL) {
dest_path <- path("R", as_standalone_dest_file(file))

lines <- read_github_file(repo_spec, path = src_path, ref = ref, host = host)
lines <- c(standalone_header(repo_spec, src_path), lines)
lines <- c(standalone_header(repo_spec, src_path, ref, host), lines)
write_over(proj_path(dest_path), lines, overwrite = TRUE)

dependencies <- standalone_dependencies(lines, path)
Expand Down Expand Up @@ -156,10 +156,22 @@ as_standalone_dest_file <- function(file) {
gsub("standalone-", "import-standalone-", file)
}

standalone_header <- function(repo_spec, path) {
standalone_header <- function(repo_spec, path, ref = NULL, host = NULL) {
ref_string <- ref %||% "HEAD"
host_string <- host %||% "https://github.com"
source_comment <-
glue("# Source: {host_string}/{repo_spec}/blob/{ref_string}/{path}")
Copy link
Member

@jennybc jennybc Jul 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works better in Positron to not surround this with <>, i.e. the automatic hyperlink detection copes better with this form.


path_string <- path_ext_remove(sub("^standalone-", "", path_file(path)))
ref_string <- if (is.null(ref)) "" else glue(', ref = "{ref}"')
host_string <- if (is.null(host) || host == "https://github.com") "" else glue(', host = "{host}"')
Copy link
Member

@jennybc jennybc Jul 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only include host if it's something other than github.com. Only include ref if the user explicitly did so.

code_hint <- glue('usethis::use_standalone("{repo_spec}", "{path_string}"{ref_string}{host_string})')
generated_comment <- glue('# Generated by: {code_hint}')

c(
"# Standalone file: do not edit by hand",
glue("# Source: <https://github.com/{repo_spec}/blob/main/{path}>"),
source_comment,
generated_comment,
paste0("# ", strrep("-", 72 - 2)),
"#"
)
Expand Down
76 changes: 66 additions & 10 deletions tests/testthat/_snaps/use_standalone.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,69 @@
# standalone_header() works with various inputs

Code
standalone_header("OWNER/REPO", "R/standalone-foo.R")
Output
[1] "# Standalone file: do not edit by hand"
[2] "# Source: https://github.com/OWNER/REPO/blob/HEAD/R/standalone-foo.R"
[3] "# Generated by: usethis::use_standalone(\"OWNER/REPO\", \"foo\")"
[4] "# ----------------------------------------------------------------------"
[5] "#"

---

Code
standalone_header("OWNER/REPO", "R/standalone-foo.R", ref = "blah")
Output
[1] "# Standalone file: do not edit by hand"
[2] "# Source: https://github.com/OWNER/REPO/blob/blah/R/standalone-foo.R"
[3] "# Generated by: usethis::use_standalone(\"OWNER/REPO\", \"foo\", ref = \"blah\")"
[4] "# ----------------------------------------------------------------------"
[5] "#"

---

Code
standalone_header("OWNER/REPO", "R/standalone-foo.R", host = "https://github.com")
Output
[1] "# Standalone file: do not edit by hand"
[2] "# Source: https://github.com/OWNER/REPO/blob/HEAD/R/standalone-foo.R"
[3] "# Generated by: usethis::use_standalone(\"OWNER/REPO\", \"foo\")"
[4] "# ----------------------------------------------------------------------"
[5] "#"

---

Code
standalone_header("OWNER/REPO", "R/standalone-foo.R", host = "https://github.acme.com")
Output
[1] "# Standalone file: do not edit by hand"
[2] "# Source: https://github.acme.com/OWNER/REPO/blob/HEAD/R/standalone-foo.R"
[3] "# Generated by: usethis::use_standalone(\"OWNER/REPO\", \"foo\", host = \"https://github.acme.com\")"
[4] "# ----------------------------------------------------------------------"
[5] "#"

---

Code
standalone_header("OWNER/REPO", "R/standalone-foo.R", ref = "blah", host = "https://github.com")
Output
[1] "# Standalone file: do not edit by hand"
[2] "# Source: https://github.com/OWNER/REPO/blob/blah/R/standalone-foo.R"
[3] "# Generated by: usethis::use_standalone(\"OWNER/REPO\", \"foo\", ref = \"blah\")"
[4] "# ----------------------------------------------------------------------"
[5] "#"

---

Code
standalone_header("OWNER/REPO", "R/standalone-foo.R", ref = "blah", host = "https://github.acme.com")
Output
[1] "# Standalone file: do not edit by hand"
[2] "# Source: https://github.acme.com/OWNER/REPO/blob/blah/R/standalone-foo.R"
[3] "# Generated by: usethis::use_standalone(\"OWNER/REPO\", \"foo\", ref = \"blah\", host = \"https://github.acme.com\")"
[4] "# ----------------------------------------------------------------------"
[5] "#"

# can offer choices

Code
Expand All @@ -12,16 +78,6 @@
! `file` is absent, but must be supplied.
i Possible options are cli, downstream-deps, lazyeval, lifecycle, linked-version, obj-type, purrr, rlang, s3-register, sizes, types-check, vctrs, or zeallot.

# header provides useful summary

Code
standalone_header("r-lib/usethis", "R/standalone-test.R")
Output
[1] "# Standalone file: do not edit by hand"
[2] "# Source: <https://github.com/r-lib/usethis/blob/main/R/standalone-test.R>"
[3] "# ----------------------------------------------------------------------"
[4] "#"

# can extract imports

Code
Expand Down
35 changes: 31 additions & 4 deletions tests/testthat/test-use_standalone.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
test_that("standalone_header() works with various inputs", {
expect_snapshot(
standalone_header("OWNER/REPO", "R/standalone-foo.R")
)
expect_snapshot(
standalone_header("OWNER/REPO", "R/standalone-foo.R", ref = "blah")
)
expect_snapshot(
standalone_header(
"OWNER/REPO", "R/standalone-foo.R", host = "https://github.com"
)
)
expect_snapshot(
standalone_header(
"OWNER/REPO", "R/standalone-foo.R", host = "https://github.acme.com"
)
)
expect_snapshot(
standalone_header(
"OWNER/REPO", "R/standalone-foo.R",
ref = "blah", host = "https://github.com"
)
)
expect_snapshot(
standalone_header(
"OWNER/REPO", "R/standalone-foo.R",
ref = "blah", host = "https://github.acme.com"
)
)
})

test_that("can import standalone file with dependencies", {
skip_if_offline("github.com")
create_local_package()
Expand Down Expand Up @@ -40,10 +71,6 @@ test_that("can offer choices", {
})
})

test_that("header provides useful summary", {
expect_snapshot(standalone_header("r-lib/usethis", "R/standalone-test.R"))
})

test_that("can extract dependencies", {
extract_deps <- function(deps) {
out <- standalone_dependencies(c("# ---", deps, "# ---"), "test.R")
Expand Down
Loading