From f3d5d124686527297be64b66577f0fd32cc1bcdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABlle=20Salmon?= Date: Thu, 18 Jan 2024 14:13:19 +0100 Subject: [PATCH] feat: add exercise featuring a merge conflict --- NAMESPACE | 1 + R/conflict.R | 75 +++++++++++++++++++++++++++++ _pkgdown.yml | 1 + inst/exo_conflict-Rprofile.R | 22 +++++++++ man/exo_conflict.Rd | 33 +++++++++++++ tests/testthat/_snaps/conflict.md | 9 ++++ tests/testthat/_snaps/create-all.md | 3 ++ tests/testthat/test-conflict.R | 7 +++ 8 files changed, 151 insertions(+) create mode 100644 R/conflict.R create mode 100644 inst/exo_conflict-Rprofile.R create mode 100644 man/exo_conflict.Rd create mode 100644 tests/testthat/_snaps/conflict.md create mode 100644 tests/testthat/test-conflict.R diff --git a/NAMESPACE b/NAMESPACE index b9269d5..a9a8bab 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,6 +5,7 @@ export(exo_bisect) export(exo_clean_dir) export(exo_committed_to_main) export(exo_committed_to_wrong) +export(exo_conflict) export(exo_latest_message) export(exo_one_small_change) export(exo_rebase_i) diff --git a/R/conflict.R b/R/conflict.R new file mode 100644 index 0000000..3ddca51 --- /dev/null +++ b/R/conflict.R @@ -0,0 +1,75 @@ +#' "Hey I'd like to see what merge conflicts look like!" +#' +#' @description +#' I made some work in a feature branch and want to merge it. +#' Meanwhile, the main branch advanced. +#' Unfortunately someone touched the same file as I did. +#' Now I need to fix a merge conflict! +#' +#' See also . +#' +#' +#' @inheritParams exo_one_small_change +#' +#' @section Git commands: +#' `git merge`. +#' @return The path to the new project +#' @export +#' +#' @examplesIf interactive() +#' parent_path <- withr::local_tempdir() +#' path <- exo_conflict(parent_path = parent_path) +exo_conflict <- function(parent_path) { + + path <- file.path(parent_path, "conflict") + + withr::local_options(usethis.quiet = TRUE) + + dir_create(path) + original_dir <- getwd() + + withr::local_dir(path) + gert::git_init() + + file.copy( + system.file("exo_conflict-Rprofile.R", package = "saperlipopette"), + ".Rprofile" + ) + + create_project(path = getwd()) + # Ignore Rproj that might otherwise get edited when we open the project + rproj <- fs::dir_ls(glob = "*.Rproj") + usethis::local_project(getwd(), force = TRUE) + usethis::use_git_ignore(rproj) + usethis::use_git_ignore(".Rprofile") + gert::git_add("*") + git_commit("First commit") + + new_script <- file.path("R", "script.R") + fs::file_create(new_script) + script_lines <- c("a <- 1", "b <- 2") + brio::write_lines(text = script_lines, path = new_script) + gert::git_add(new_script) + git_commit("feat: add script") + + + gert::git_branch_create("feature") + brio::write_lines(text = c("a <- 10", "b <- 2", "c <- 3"), path = new_script) + gert::git_add(new_script) + git_commit("feat: improve script") + + if ("main" %in% gert::git_branch_list()[["name"]]) { + gert::git_branch_checkout("main") + } else { + gert::git_branch_checkout("master") + } + brio::write_lines(text = c("a <- 11", "b <- 2"), path = new_script) + gert::git_add(new_script) + git_commit("feat: amend script") + + usethis::local_project(original_dir, force = TRUE) + + cli::cli_alert_info("Follow along in {path}!") + + return(path) +} diff --git a/_pkgdown.yml b/_pkgdown.yml index 8620eaa..30274fc 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -16,6 +16,7 @@ reference: contents: - exo_split_changes - exo_clean_dir + - exo_conflict - exo_rebase_i - exo_bisect - title: All exercises at once diff --git a/inst/exo_conflict-Rprofile.R b/inst/exo_conflict-Rprofile.R new file mode 100644 index 0000000..a8a6a26 --- /dev/null +++ b/inst/exo_conflict-Rprofile.R @@ -0,0 +1,22 @@ +if (file.exists("~/.Rprofile")) { + base::sys.source("~/.Rprofile", envir = environment()) +} + +cli::cli_alert_danger('"I want to merge feature into main."') +cli::cli_alert_danger("I will need to fix a merge conflict.") +cli::cli_alert_info("For more help use {.run tip()}") + +tip <- function() { + cli::cli_li( + items = c( + "Examine Git history.", + "{.code git merge feature} on the default branch", + "Edit R/script.R to the desired state, remove conflict markers.", + "{.code git add R/script.R}", + "{.code git commit}.", + "See the merge finalize, you might need to edit a commit message.", + "Examine Git history." + ) + ) + +} diff --git a/man/exo_conflict.Rd b/man/exo_conflict.Rd new file mode 100644 index 0000000..4186cf5 --- /dev/null +++ b/man/exo_conflict.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/conflict.R +\name{exo_conflict} +\alias{exo_conflict} +\title{"Hey I'd like to see what merge conflicts look like!"} +\usage{ +exo_conflict(parent_path) +} +\arguments{ +\item{parent_path}{Path where to create the exercise repo} +} +\value{ +The path to the new project +} +\description{ +I made some work in a feature branch and want to merge it. +Meanwhile, the main branch advanced. +Unfortunately someone touched the same file as I did. +Now I need to fix a merge conflict! + +See also \url{https://happygitwithr.com/git-branches.html#dealing-with-conflicts}. +} +\section{Git commands}{ + +\verb{git merge}. +} + +\examples{ +\dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +parent_path <- withr::local_tempdir() +path <- exo_conflict(parent_path = parent_path) +\dontshow{\}) # examplesIf} +} diff --git a/tests/testthat/_snaps/conflict.md b/tests/testthat/_snaps/conflict.md new file mode 100644 index 0000000..5050b44 --- /dev/null +++ b/tests/testthat/_snaps/conflict.md @@ -0,0 +1,9 @@ +# exo_conflict() works + + Code + gert::git_log(repo = path)[["commit"]] + Output + [1] "5d871367c8a247a5e63bd0701d7bce830d1dc614" + [2] "2a61d9da6865eb7f7272c9f901f13c1da377a01e" + [3] "e227ecc55e421f70b6e30602e6a2eee02aad42e0" + diff --git a/tests/testthat/_snaps/create-all.md b/tests/testthat/_snaps/create-all.md index f0f393e..251ef4d 100644 --- a/tests/testthat/_snaps/create-all.md +++ b/tests/testthat/_snaps/create-all.md @@ -22,6 +22,9 @@ | +-- R | +-- bla | \-- fix.txt + +-- conflict + | \-- R + | \-- script.R +-- latest-message | +-- R | \-- bla diff --git a/tests/testthat/test-conflict.R b/tests/testthat/test-conflict.R new file mode 100644 index 0000000..8f75afa --- /dev/null +++ b/tests/testthat/test-conflict.R @@ -0,0 +1,7 @@ +test_that("exo_conflict() works", { + rlang::local_options(cli.default_handler = function(msg) invisible(NULL)) + parent_path <- withr::local_tempdir() + path <- exo_conflict(parent_path = parent_path) + expect_equal(fs::path_file(path), "conflict") + expect_snapshot(gert::git_log(repo = path)[["commit"]]) +})