Skip to content

Commit

Permalink
Assume git users can undo (r-lib#1424)
Browse files Browse the repository at this point in the history
* Assume git users can undo

Fixes r-lib#1376

* Add an option

* Change name; document in vignette

* Apply suggestions from code review

Co-authored-by: Jennifer (Jenny) Bryan <[email protected]>

* Improve `can_overwrite()` behaviour re: active project

* Note this change in principles.md

* Update NEWS and setup vignette to reflect implementation

* Missing word

Co-authored-by: Jennifer (Jenny) Bryan <[email protected]>
  • Loading branch information
hadley and jennybc authored Apr 19, 2021
1 parent 2577ab5 commit 0d181f6
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 10 deletions.
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# usethis (development version)

* `"usethis.overwrite"` is a new option. When set to `TRUE`, usethis overwrites
an existing file without asking for user confirmation if the file is inside
a Git repo. The normal Git workflow makes it easy to see and selectively
accept/discard any proposed changes. This behaviour is strictly opt-in
(#1376).

* `use_lifecycle()` now imports `lifecycle::deprecated()` (#1419).

* `use_code_of_conduct()` now requires a `contact` argument to supply contact
Expand Down
12 changes: 12 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ can_overwrite <- function(path) {
return(TRUE)
}

if (getOption("usethis.overwrite", FALSE)) {
# don't activate a project
# don't assume `path` is in the active project
if (is_in_proj(path) && uses_git()) { # path is in active project
return(TRUE)
}
if (possibly_in_proj(path) && # path is some other project
with_project(proj_find(path), uses_git(), quiet = TRUE)) {
return(TRUE)
}
}

if (is_interactive()) {
ui_yeah("Overwrite pre-existing file {ui_path(path)}?")
} else {
Expand Down
12 changes: 7 additions & 5 deletions principles.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,15 @@ Two opposing mindsets:
- Everything should refer to the active project, unless there's a specific reason not to.

Ideally, the exported file writing helpers would not make direct reference to the active project.
But we are violating this somewhat.
However, we violate this, with due care, when it benefits us:

`write_utf8()` potentially consults the project `path` lives in re: line ending.
So its implementation takes care to respect that, but also to not change the active project.
- `write_utf8()` potentially consults the project in which `path` lives in re: line ending.
So its implementation takes care to respect that, but also to not change the active project.

Likewise, `write_union()` uses the active project, if such exists, to create a humane path in its message.
It also actively avoids activating or changing the project.
- `write_over()` (`can_overwrite()`, really) does same, except in that case we're determining whether `path` is within a Git repo.

- `write_union()` uses the active project, if such exists, to create a humane path in its message.
It also actively avoids activating or changing the project.

Git/GitHub helpers generally assume we're working on the Git repo that is also the active project.
These are unexported.
Expand Down
69 changes: 65 additions & 4 deletions tests/testthat/test-write.R
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,71 @@ test_that("write_over() writes a de novo file", {
expect_identical(read_utf8(tmp), letters[1:3])
})

test_that("write_over() leaves file 'as is'", {
tmp <- file_temp()
test_that("write_over() leaves file 'as is' (outside of a project)", {
local_interactive(FALSE)
tmp <- withr::local_file(file_temp())

writeLines(letters[1:3], tmp)

before <- read_utf8(tmp)
write_over(tmp, letters[1:3], quiet = TRUE)
expect_identical(before, read_utf8(tmp))
write_over(tmp, letters[4:6], quiet = TRUE)
expect_identical(read_utf8(tmp), before)

# usethis.overwrite shouldn't matter for a file outside of a project
withr::with_options(
list(usethis.overwrite = TRUE),
{
write_over(tmp, letters[4:6], quiet = TRUE)
expect_identical(read_utf8(tmp), before)
}
)
})

test_that("write_over() works in active project", {
local_interactive(FALSE)
create_local_project()

tmp <- proj_path("foo.txt")
writeLines(letters[1:3], tmp)

before <- read_utf8(tmp)
write_over(tmp, letters[4:6], quiet = TRUE)
expect_identical(read_utf8(tmp), before)

use_git()
withr::with_options(
list(usethis.overwrite = TRUE),
{
write_over(tmp, letters[4:6], quiet = TRUE)
expect_identical(read_utf8(tmp), letters[4:6])
}
)
})

test_that("write_over() works for a file in a project that is not active", {
local_interactive(FALSE)
owd <- getwd()
proj <- create_local_project()
use_git()

tmp <- proj_path("foo.txt")
writeLines(letters[1:3], tmp)

withr::local_dir(owd)
local_project(NULL)
expect_false(proj_active())

tmp <- path(proj, "foo.txt")
before <- read_utf8(tmp)
write_over(tmp, letters[4:6], quiet = TRUE)
expect_identical(read_utf8(tmp), before)

withr::with_options(
list(usethis.overwrite = TRUE),
{
write_over(tmp, letters[4:6], quiet = TRUE)
expect_identical(read_utf8(tmp), letters[4:6])
}
)
expect_false(proj_active())
})
7 changes: 6 additions & 1 deletion vignettes/articles/usethis-setup.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ Certain options are consulted by usethis and allow you to set personal defaults:
console.
* `usethis.destdir`: a default directory to use in `create_from_github()` and
`use_course()`.
* `usethis.overwrite`: if `TRUE`, usethis overwrites an existing file without
asking for user confirmation if the file is inside a Git repo. The rationale
is that the normal Git workflow makes it easy to see and selectively
accept/discard any proposed changes.

Define any of these options in your `.Rprofile`, which can be opened for editing via `usethis::edit_r_profile()`. Here is example code:

Expand All @@ -86,7 +90,8 @@ options(
),
Version = "0.0.0.9000"
),
usethis.destdir = "~/the/place/where/I/keep/my/R/projects"
usethis.destdir = "~/the/place/where/I/keep/my/R/projects",
usethis.overwrite = TRUE
)
```

Expand Down

0 comments on commit 0d181f6

Please sign in to comment.