From 030feec3cc81b07405a3c3522f510a05f873a70e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABlle=20Salmon?= Date: Thu, 18 Jan 2024 13:48:25 +0100 Subject: [PATCH] feat: add example for bisect --- NAMESPACE | 1 + R/debug.R | 73 +++++++++++++++++++ _pkgdown.yml | 1 + inst/exo_bisect-Rprofile.R | 25 +++++++ man/exo_bisect.Rd | 32 +++++++++ tests/testthat/_snaps/create-all.md | 3 + tests/testthat/_snaps/debug.md | 106 ++++++++++++++++++++++++++++ tests/testthat/test-debug.R | 7 ++ 8 files changed, 248 insertions(+) create mode 100644 R/debug.R create mode 100644 inst/exo_bisect-Rprofile.R create mode 100644 man/exo_bisect.Rd create mode 100644 tests/testthat/_snaps/debug.md create mode 100644 tests/testthat/test-debug.R diff --git a/NAMESPACE b/NAMESPACE index 10df3b5..b9269d5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,7 @@ # Generated by roxygen2: do not edit by hand export(create_all_exercises) +export(exo_bisect) export(exo_clean_dir) export(exo_committed_to_main) export(exo_committed_to_wrong) diff --git a/R/debug.R b/R/debug.R new file mode 100644 index 0000000..bf7d5a9 --- /dev/null +++ b/R/debug.R @@ -0,0 +1,73 @@ +#' "Hey I'd like to find which commit introduced a bug!" +#' +#' @description +#' I notice a bug in my codebase. +#' I can see the bug was not there a bunch of commits ago. +#' Beside doing regular debugging, I can find out +#' which commit introduced the bug by using `git bisect`. +#' See . +#' +#' +#' @inheritParams exo_one_small_change +#' +#' @section Git commands: +#' `git bisect`. +#' @return The path to the new project +#' @export +#' +#' @examplesIf interactive() +#' parent_path <- withr::local_tempdir() +#' path <- exo_bisect(parent_path = parent_path) +exo_bisect <- function(parent_path) { + + path <- file.path(parent_path, "bisect") + + withr::local_options(usethis.quiet = TRUE) + + dir_create(path) + original_dir <- getwd() + + withr::local_dir(path) + gert::git_init() + + file.copy( + system.file("exo_bisect-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") + + create_commit <- function(i, new_script) { + script_lines <- brio::read_lines(new_script) + if (i == 13) { + new_line <- "aaaaaaaaah" + } else { + new_line <- sprintf("1+%s", i) + } + brio::write_lines(text = c(script_lines, new_line), path = new_script) + gert::git_add(new_script) + git_commit("feat: edit script") + } + + purrr::walk(1:100, create_commit, new_script = new_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 981560a..8620eaa 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -17,6 +17,7 @@ reference: - exo_split_changes - exo_clean_dir - exo_rebase_i + - exo_bisect - title: All exercises at once contents: - create_all_exercises diff --git a/inst/exo_bisect-Rprofile.R b/inst/exo_bisect-Rprofile.R new file mode 100644 index 0000000..6cde041 --- /dev/null +++ b/inst/exo_bisect-Rprofile.R @@ -0,0 +1,25 @@ +if (file.exists("~/.Rprofile")) { + base::sys.source("~/.Rprofile", envir = environment()) +} + +cli::cli_alert_danger('"Hey, since when has my script {.path R/script.R} stopped to work?"') +cli::cli_alert_danger("I need to use git bisect.") +cli::cli_alert_info("For more help use {.run tip()}") + +tip <- function() { + cli::cli_li( + items = c( + "Examine Git history.", + "Source R/script.R and see it errors.", + "{.code git bisect start}", + "{.code git bisect bad} (the current version is broken).", + "{.code git bisect good 7d4d919e18bdedcebcd6a2783c8d73760f69d3dc} (the first was not).", + "At each step source R/script.R and type {.code git bisect bad} if it errors, {.code git bisect good} if not.", + "Continue until git bisect tells you about the culprit.", + "{.code git bisect reset} to exit.", + "Examine Git diff at that commit.", + "Advanced: instead of 'at each step' steps, run {.code git bisect run Rscript R/script.R}." + ) + ) + +} diff --git a/man/exo_bisect.Rd b/man/exo_bisect.Rd new file mode 100644 index 0000000..3c27c06 --- /dev/null +++ b/man/exo_bisect.Rd @@ -0,0 +1,32 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/debug.R +\name{exo_bisect} +\alias{exo_bisect} +\title{"Hey I'd like to find which commit introduced a bug!"} +\usage{ +exo_bisect(parent_path) +} +\arguments{ +\item{parent_path}{Path where to create the exercise repo} +} +\value{ +The path to the new project +} +\description{ +I notice a bug in my codebase. +I can see the bug was not there a bunch of commits ago. +Beside doing regular debugging, I can find out +which commit introduced the bug by using \verb{git bisect}. +See \url{https://git-scm.com/docs/git-bisect}. +} +\section{Git commands}{ + +\verb{git bisect}. +} + +\examples{ +\dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +parent_path <- withr::local_tempdir() +path <- exo_bisect(parent_path = parent_path) +\dontshow{\}) # examplesIf} +} diff --git a/tests/testthat/_snaps/create-all.md b/tests/testthat/_snaps/create-all.md index 9c3278d..f0f393e 100644 --- a/tests/testthat/_snaps/create-all.md +++ b/tests/testthat/_snaps/create-all.md @@ -4,6 +4,9 @@ create_all_exercises(parent_path) Output + +-- bisect + | \-- R + | \-- script.R +-- clean-dir | +-- R | | \-- script.R diff --git a/tests/testthat/_snaps/debug.md b/tests/testthat/_snaps/debug.md new file mode 100644 index 0000000..2b4fe5f --- /dev/null +++ b/tests/testthat/_snaps/debug.md @@ -0,0 +1,106 @@ +# exo_bisect() works + + Code + gert::git_log(repo = path)[["commit"]] + Output + [1] "d1e99031240ba2b6a78117f09df1c3b7b089f41a" + [2] "f26c132d3ab725336f321b6f0c403022e0ad7372" + [3] "85cebcf1f5c19397a19a009747353d7246979c52" + [4] "978a4d7a52ce0c4e5a3f82f53fff6d804f4efeeb" + [5] "2add1f6723f3d88c68999d97b3ffebe1fe119642" + [6] "beb2fa1f91f2cc320c2c8da9ba295e72cf0b1021" + [7] "4113e395ef532fd197de37528c914af919a6d90a" + [8] "a353215168eedc7cdeb8a16d638ad8d211c764bb" + [9] "e60758bcc20df042a217110a697e13de970a295d" + [10] "c74d07bc18a100e1b969b9ee803d4c6bc7660a49" + [11] "fc262ee71062d495b66c32f94ba6238797ecfb5e" + [12] "de1d69acb518fda55437c690304e650d2a081ee3" + [13] "843db009fdbe085b2a081379d22804ec3fc7abce" + [14] "c4d19abe6a81c459b49057c1cd7d8f836307e99f" + [15] "e4b56a8cb1f2b86d4015e35377ac8f05d710eca2" + [16] "9883805e2bcb053e621adfcfbae501ae70d9e3b9" + [17] "7e92a31809657e4ead7184e8411a9534a9702d28" + [18] "38c8d2c23cf77877bbe51f28f9d69cb9e9cf0b8a" + [19] "581894065e7e5e12e885b67caaf77684b8a77ef7" + [20] "e8519a9913ba9890efe75ba941c867d03528476e" + [21] "fb55c1c641709143fea89b6895c856d0acba6bd6" + [22] "f445fd3cbb253fc3b02d2bb9bbf43b43bf853d3a" + [23] "4f9e58a90ec9b851bce78093aec5ce015f977cc9" + [24] "8516bff3c7d23594835b54823b98acd60574920e" + [25] "1a2ac48fd6a50f616393fa8700f666567d27934e" + [26] "3591526ace41dc66086583ec8ba7d288f91dd553" + [27] "a0d6e545749bd382bdaa3ad43f963fec4d2f55d0" + [28] "f17ff3fc7467a5654dadc7d24309a402d670aac4" + [29] "5db97758e4eb3cd692d6333e06bd5c71d37fc80f" + [30] "6ace84269e8936f5245e3fc4226e88fb9212f00f" + [31] "67aab62cd4fe54bff1601af2adef1e183f9f6c8f" + [32] "1582b39ea86e0be37c87f50d57183dba9e939188" + [33] "6b032596e717f1705e3b88f100d36854fa86f3ea" + [34] "cdb9fd43823fafd215a8775a90b7891623723469" + [35] "e20687770882d803c89c3a3f10ced0784ff196ed" + [36] "a1c461e69f06189db0378346d2db8738f09a3945" + [37] "7113cec4933c9d4cf02f1d4a2adb94eeb28385f7" + [38] "69469fbd578cde159e4212ee1a35a4e8e69b5706" + [39] "aaf2948790eec15e3263442fed027974fabb47e3" + [40] "f873416354b3bde49e36b83ceb08f9811015a978" + [41] "ff7d357cc370ebfc06bfdef5cf525575ba09d8cd" + [42] "7b933aaa3152581effe2d6a6d84d155fa503ca6f" + [43] "f3824328266f1b2da9a33f9dd66a1235b473e6a0" + [44] "803209099f74a8fa9c1291dcb62f0ec53e2b289a" + [45] "0a912a1ddadda22a57d592c48da10e3f3d3ace69" + [46] "e1ff5bb7d572c9f96466e9b2dabf563e9b077c25" + [47] "a5070363a81c884c06757e7779464d0963a9da97" + [48] "e249ca8b8e2695329fd3332492bd19f354e80ba3" + [49] "91d748955338f63d4821611b18424d7538844a1f" + [50] "adc4979084cb06a2fa9fedc8fb4f21ca523c1c2d" + [51] "2486499ca45b1ff9d5cfc6cee63f246ebf70aa80" + [52] "c817f0c11bade833ade7fd8c16e62fcf96dcca3f" + [53] "8acdcb8f245563dbd2a6a8a1c0d30f560ea0fcc2" + [54] "d5504c3c7be7d1ba5d65ad6aff7857bb67b64495" + [55] "c25c06f6c6bbd7cd6b23fe93d4790a74f5a12023" + [56] "4f8a39b020db2d64951d7172d91ff01ea393601f" + [57] "c908af5f661bf47c4e6dd1a1970c6a29c2879d47" + [58] "8e0102f7ce52588bcc48a5948fc4503e8f45b2d4" + [59] "edecb3310988201341eeedc2bfac7e2f91ec0d70" + [60] "bf437c06343333a0943b985009e62ee318f70b5c" + [61] "085bee7609f8b98f3ac9629e4628a2d715bb8e15" + [62] "47c21eeebf122a7c687134b1d669ba6f9950f4f3" + [63] "ce1aa271bc990c89aa4e04232f9f7ce15391953d" + [64] "4e0e984827b9e4a5f6a80fc0f24db14615ff0988" + [65] "ba2b81702970ab0110ee31b9e8313934f24db0a7" + [66] "b3803b33e3903f187746b1254406d6a6a496aa5f" + [67] "4aac725a56d849c9cf3acaf82af165d96a0731ee" + [68] "dd033c2c1eed76f1ca6992100642e3624adf5dfc" + [69] "a6ab4fe86960d875abc7cc6eadf943e562fa8ae6" + [70] "25e4741e1a0fabd78c498ef9a0c87045a23937ef" + [71] "89abac6331aaab3cfdc1c1a097b6bdeabf61caa3" + [72] "897340c25932913f6fd12f1684e62238450d1af5" + [73] "81325b2c43fd355d44f8b4ff87101fdf2df3f399" + [74] "41b766c2204c441f7e6926a5552126f944c7d0ba" + [75] "3b5895fbb58e8a66a3e598736656c10c49bdb460" + [76] "ec2dcb6955dfb5e986e980604ad72c02d9e63eb3" + [77] "d700bda4942a64c865856390ddf2f0bbc7fff686" + [78] "9f787a48f57ef0c9d06bda9a335c1fd3e1a40027" + [79] "0f3358471a884bbf51c5581236fab97b302291b5" + [80] "6b60ee5812e7b334a5389f2903b29f906ef8b6da" + [81] "6bfed0a7e5882d5ab01f3970a0d8e57244e1fa10" + [82] "e2d0e6669f11d42a0adb5ba368e83ed76c912b06" + [83] "1a01f630b51b66d1877a8ac95503bff6c0c8f211" + [84] "0fff05b8297443779805f32878f3bd2bddb76e70" + [85] "0a96b1ee0ebc2c7bd10d3c4b7a8959112b16bd95" + [86] "295da1b747afd58d258ebff74aff541c391cff31" + [87] "28d269322932278a42310fe90176e501a90dc045" + [88] "011d8cb02cd49e8633a6c11374f2241209f5da9e" + [89] "fccd0905b276be6500166b2daa8f3113a0d35357" + [90] "1f395f6fa64d42a9baf7621c4a70a108735c5b05" + [91] "ae94af9223d2e0c0d40e0bc3e2f4e8856ef93490" + [92] "8cd8496b7750b125a791f52f0f16743e0a64e060" + [93] "71082d7c3e486d0c83263caaec5cff08a9d9c403" + [94] "31d65ac4b63d5c7b808524f961a34f98fd4a1db4" + [95] "f6769a326e28041bbe35238657b8a186860c221b" + [96] "704a5278d077af2b5426bf47930f9b8906286761" + [97] "5c69ee918e2f2d699171c8d5acd9f7721b1579e0" + [98] "37e062efff1535f758f4e45659618c9e0d479b30" + [99] "1e49dc2e775eda5bd7c81d67bf1b0256c4b4960a" + [100] "ff9753505d9840f8f536b06a5f81e1ba0c5cc406" + diff --git a/tests/testthat/test-debug.R b/tests/testthat/test-debug.R new file mode 100644 index 0000000..9b476c6 --- /dev/null +++ b/tests/testthat/test-debug.R @@ -0,0 +1,7 @@ +test_that("exo_bisect() works", { + rlang::local_options(cli.default_handler = function(msg) invisible(NULL)) + parent_path <- withr::local_tempdir() + path <- exo_bisect(parent_path = parent_path) + expect_equal(fs::path_file(path), "bisect") + expect_snapshot(gert::git_log(repo = path)[["commit"]]) +})