From bc285dda446fe58b7afce84ee0f07cef0954236b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Apr 2026 15:49:11 +0000 Subject: [PATCH 1/6] Initial plan From 88159f51e7e54a2192e2d5a1defa166c7973559d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Apr 2026 15:50:59 +0000 Subject: [PATCH 2/6] fix: ignore css :: selectors in dependency detection Agent-Logs-Url: https://github.com/ThinkR-open/attachment/sessions/319ceb68-c3d2-4c15-95b8-0bd45ca20959 Co-authored-by: VincentGuyader <10470699+VincentGuyader@users.noreply.github.com> --- R/att_from_rscripts.R | 5 ++++- tests/testthat/test-rscript.R | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/R/att_from_rscripts.R b/R/att_from_rscripts.R index ce36c4c..59f8adb 100644 --- a/R/att_from_rscripts.R +++ b/R/att_from_rscripts.R @@ -22,7 +22,10 @@ att_from_rscript <- function(path) { # Replace newlines `\n` by space file <- gsub("\\\\n", " ", file) - pkg_points <- file %>% + # Ignore `::` patterns found in string literals (e.g. CSS selectors) + file_without_strings <- gsub("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'", "", file) + + pkg_points <- file_without_strings %>% .[grep("^#", ., invert = TRUE)] %>% str_extract_all("[[:alnum:]\\.]+(?=::)") %>% unlist() diff --git a/tests/testthat/test-rscript.R b/tests/testthat/test-rscript.R index d8a279f..18baacd 100644 --- a/tests/testthat/test-rscript.R +++ b/tests/testthat/test-rscript.R @@ -92,3 +92,20 @@ test_that("folder_to_exclude works in att_from_rscripts", { }) + +test_that("att_from_rscript ignores :: found in CSS strings", { + css_script <- tempfile(fileext = ".R") + on.exit(unlink(css_script), add = TRUE) + writeLines( + c( + "x <- '.pretty .state label::after { color: red; }'", + "glue::glue('ok')" + ), + con = css_script + ) + + res <- att_from_rscript(path = css_script) + + expect_true("glue" %in% res) + expect_false("label" %in% res) +}) From e888bdcd56c49719edcb17bd8845d6573d043778 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Apr 2026 15:51:29 +0000 Subject: [PATCH 3/6] chore: clarify variable name in string-literal filtering Agent-Logs-Url: https://github.com/ThinkR-open/attachment/sessions/319ceb68-c3d2-4c15-95b8-0bd45ca20959 Co-authored-by: VincentGuyader <10470699+VincentGuyader@users.noreply.github.com> --- R/att_from_rscripts.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/att_from_rscripts.R b/R/att_from_rscripts.R index 59f8adb..140568a 100644 --- a/R/att_from_rscripts.R +++ b/R/att_from_rscripts.R @@ -23,9 +23,9 @@ att_from_rscript <- function(path) { file <- gsub("\\\\n", " ", file) # Ignore `::` patterns found in string literals (e.g. CSS selectors) - file_without_strings <- gsub("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'", "", file) + file_without_string_literals <- gsub("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'", "", file) - pkg_points <- file_without_strings %>% + pkg_points <- file_without_string_literals %>% .[grep("^#", ., invert = TRUE)] %>% str_extract_all("[[:alnum:]\\.]+(?=::)") %>% unlist() From a392de997489d8339a931c66c15131072757092a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Apr 2026 15:51:54 +0000 Subject: [PATCH 4/6] chore: shorten temporary variable name in parser Agent-Logs-Url: https://github.com/ThinkR-open/attachment/sessions/319ceb68-c3d2-4c15-95b8-0bd45ca20959 Co-authored-by: VincentGuyader <10470699+VincentGuyader@users.noreply.github.com> --- R/att_from_rscripts.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/att_from_rscripts.R b/R/att_from_rscripts.R index 140568a..601afd1 100644 --- a/R/att_from_rscripts.R +++ b/R/att_from_rscripts.R @@ -23,9 +23,9 @@ att_from_rscript <- function(path) { file <- gsub("\\\\n", " ", file) # Ignore `::` patterns found in string literals (e.g. CSS selectors) - file_without_string_literals <- gsub("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'", "", file) + file_no_strings <- gsub("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'", "", file) - pkg_points <- file_without_string_literals %>% + pkg_points <- file_no_strings %>% .[grep("^#", ., invert = TRUE)] %>% str_extract_all("[[:alnum:]\\.]+(?=::)") %>% unlist() From 16eeb4f0991eeeafafe37d74fbdcfc8dd1a31d75 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Apr 2026 15:52:19 +0000 Subject: [PATCH 5/6] docs: clarify string-literal stripping regex intent Agent-Logs-Url: https://github.com/ThinkR-open/attachment/sessions/319ceb68-c3d2-4c15-95b8-0bd45ca20959 Co-authored-by: VincentGuyader <10470699+VincentGuyader@users.noreply.github.com> --- R/att_from_rscripts.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/att_from_rscripts.R b/R/att_from_rscripts.R index 601afd1..c494419 100644 --- a/R/att_from_rscripts.R +++ b/R/att_from_rscripts.R @@ -23,6 +23,7 @@ att_from_rscript <- function(path) { file <- gsub("\\\\n", " ", file) # Ignore `::` patterns found in string literals (e.g. CSS selectors) + # Match both double-quoted and single-quoted strings, including escaped quotes file_no_strings <- gsub("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'", "", file) pkg_points <- file_no_strings %>% From 24d501f8170773441752430812d105f037c0cae8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Apr 2026 18:44:34 +0000 Subject: [PATCH 6/6] fix: ignore css files when scanning script dependencies Agent-Logs-Url: https://github.com/ThinkR-open/attachment/sessions/16289198-c761-4f4f-b380-39925762c303 Co-authored-by: VincentGuyader <10470699+VincentGuyader@users.noreply.github.com> --- R/att_from_rscripts.R | 2 ++ tests/testthat/test-rscript.R | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/R/att_from_rscripts.R b/R/att_from_rscripts.R index c494419..c94ec69 100644 --- a/R/att_from_rscripts.R +++ b/R/att_from_rscripts.R @@ -81,6 +81,8 @@ att_from_rscripts <- function(path = "R", pattern = "*.[.](r|R)$", recursive = T all_f <- setdiff(all_f, exclude_files) } + # `att_from_rscript()` parses R code, so keep only R scripts + all_f <- all_f[grepl("\\.[rR]$", all_f)] lapply(all_f, att_from_rscript) %>% unlist() %>% diff --git a/tests/testthat/test-rscript.R b/tests/testthat/test-rscript.R index 18baacd..395245d 100644 --- a/tests/testthat/test-rscript.R +++ b/tests/testthat/test-rscript.R @@ -109,3 +109,27 @@ test_that("att_from_rscript ignores :: found in CSS strings", { expect_true("glue" %in% res) expect_false("label" %in% res) }) + +test_that("att_from_rscripts ignores css files in scanned directories", { + dir_with_files <- tempfile(pattern = "rscripts_css") + dir.create(dir_with_files) + on.exit(unlink(dir_with_files, recursive = TRUE), add = TRUE) + + writeLines( + c( + ".pretty .state label::before {", + " color: red;", + "}" + ), + con = file.path(dir_with_files, "global.css") + ) + writeLines( + "glue::glue('ok')", + con = file.path(dir_with_files, "ok.R") + ) + + res <- att_from_rscripts(path = dir_with_files) + + expect_true("glue" %in% res) + expect_false("label" %in% res) +})