Skip to content

Commit

Permalink
31 exclusion list (#40)
Browse files Browse the repository at this point in the history
* feat: added exclusion list to the available configuration

Closes #31
  • Loading branch information
kpagacz authored Feb 9, 2025
1 parent b182164 commit 753b2ad
Show file tree
Hide file tree
Showing 22 changed files with 301 additions and 136 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

The following directories contain the projects:

| Directory Name | Project description |
| --------------:|:------------------- |
| antidotum (latin antidote) | `anitodutm` contains the R bindings (ie. an **R package**) for the Rust formatting library |
| aqua (latin water) | `aqua` houses a Rust library that implements a basic R **tokenizer** |
| balnea (latin bath) | `balnea` contains a Rust library that acts as **an entrypoint** to general formatting workflows |
| scopa (latin broom) | `scopa` conains **a Visual Studio Code extension** that acts as a code formatter for R language |
| spongia (lating sponge) | `spongia` contains a Rust library that implements an imperfect **R parser** |
| tergo (latin to clean) | `tergo` contains **a command line interface (CLI)** that uses the `balnea` library to format R code |
| unguentum (latin perfume) | `unguentum` houses a Rust library that implements all the **formatting tools** |
| Directory Name | Project description |
| -------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| antidotum (latin antidote) | [`anitodutm`](./antidotum/tergo) contains the R bindings (ie. an **R package**) for the Rust formatting library |
| aqua (latin water) | [`aqua`](./aqua/) houses a Rust library that implements a basic R **tokenizer** |
| balnea (latin bath) | [`balnea`](./balnea/) contains a Rust library that acts as **an entrypoint** to general formatting workflows |
| scopa (latin broom) | [`scopa`](./scopa) contains [**a Visual Studio Code extension**](https://marketplace.visualstudio.com/items?itemName=konradpagacz.tergo) that acts as a code formatter for R language |
| spongia (lating sponge) | [`spongia`](./spongia) contains a Rust library that implements an imperfect **R parser** |
| tergo (latin to clean) | [`tergo`](./tergo) contains **a command line interface (CLI)** that uses the `balnea` library to format R code |
| unguentum (latin perfume) | [`unguentum`](./unguentum) houses a Rust library that implements all the **formatting tools** |

## Authors

Expand Down
1 change: 1 addition & 0 deletions antidotum/tergo/.Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
^src/rust/repo_vendor/
^data-raw/
^cran-comments\.md$
^tergo\.toml
85 changes: 76 additions & 9 deletions antidotum/tergo/R/styling.R
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,33 @@ style_pkg <- function(path = ".",
# Define ANSI Color Codes and Unicode Symbols
green_tick <- "\u001B[32m\u2714\u001B[0m"
red_cross <- "\u001B[31m\u274C\u001B[0m"
# Define ANSI Color Codes and Unicode Symbols for a yellow dot
yellow_dot <- "\u001B[33m\u2022\u001B[0m"

ignored_paths <- vapply(
config$exclusion_list,
function(ignored_path) {
if (startsWith(ignored_path, "./")) {
ignored_path <- substr(ignored_path, 3, nchar(ignored_path))
}
file.path(path, ignored_path)
},
FUN.VALUE = character(1),
USE.NAMES = FALSE
)
success_count <- 0

skipped_count <- 0
for (file in files) {
tryCatch(
{
style_file(file, config)
success_count <- success_count + 1
# Print File Path and Green Tick
if (verbose) cat(sprintf("%s %s\n", basename(file), green_tick))
succes <- style_file_internal(file, config, ignored_paths)
if (succes) {
success_count <- success_count + 1
if (verbose) cat(sprintf("%s %s\n", file, green_tick))
} else {
skipped_count <- skipped_count + 1
if (verbose) cat(sprintf("%s %s\n", file, yellow_dot))
}
},
error = function(err) {
# Print File Path, Red Cross, and Error Message
Expand All @@ -138,7 +155,8 @@ style_pkg <- function(path = ".",
cat("\nSummary:\n")
cat(sprintf(" %s Files processed : %d\n", summary_bullet, length(files)))
cat(sprintf(" %s Successful : %d\n", green_tick, success_count))
cat(sprintf(" %s Failed : %d\n", red_cross, length(files) - success_count))
cat(sprintf(" %s Skipped : %d\n", yellow_dot, skipped_count))
cat(sprintf(" %s Failed : %d\n", red_cross, length(files) - success_count - skipped_count))
}

invisible(NULL)
Expand All @@ -150,8 +168,9 @@ style_pkg <- function(path = ".",
#' To see possible configuration options, see [get_default_config()].
#'
#' @inheritParams style
#' @param file (`character`) the file to format
#' @return No return value, called for side effects.
#' @param file (`character`) path to the file to format.
#' @return (`logical`) whether the file was formatted successfully
#' or skipped. `TRUE` - formatted successfully, `FALSE` - skipped.
#'
#' @export
#' @examples
Expand All @@ -162,6 +181,12 @@ style_pkg <- function(path = ".",
#' style_file(file = tmp, configuration = list())
#' unlink(tmp)
style_file <- function(file, configuration = list()) {
ignored_paths <- configuration$exclusion_list
if (!is.null(ignored_paths)) {
if (any(Map(function(ignored_path) startsWith(file, ignored_path), ignored_paths))) {
return(FALSE)
}
}
if (!file.exists(file)) {
stop("File " + file + " does not exist")
}
Expand All @@ -174,7 +199,49 @@ style_file <- function(file, configuration = list()) {
stop("Failed to style the file. Error: ", truncate_error(formatted[[2]]))
}
write(x = formatted[[2]], file = file)
invisible(NULL)
TRUE
}

#' Check whether a path is in ignored paths
#' @return (`logical`) whether the path is in the ignored paths.
#' @keywords internal
is_in_ignored_paths <- function(path, ignored_paths) {
if (!is.null(ignored_paths)) {
if (
any(
vapply(
ignored_paths,
FUN = function(ignored_path) startsWith(path, ignored_path),
FUN.VALUE = logical(1),
USE.NAMES = FALSE
)
)
) {
return(TRUE)
}
}
FALSE
}

#' Style a file internal
#' @keywords internal
style_file_internal <- function(file, configuration, ignored_paths) {
if (is_in_ignored_paths(file, ignored_paths)) {
return(FALSE)
}
if (!file.exists(file)) {
stop("File " + file + " does not exist")
}
size <- file.info(file)$size
code <- readChar(con = file, nchars = size)
formatted <- format_code(code, configuration)
if (formatted[[1]] == "success") {
formatted[[2]]
} else {
stop("Failed to style the file.")
}
write(x = formatted[[2]], file = file)
TRUE
}

#' Style text
Expand Down
15 changes: 15 additions & 0 deletions antidotum/tergo/man/is_in_ignored_paths.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions antidotum/tergo/man/style_file.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions antidotum/tergo/man/style_file_internal.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion antidotum/tergo/src/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ crate-type = ["staticlib"]
name = "tergo"

[dependencies]
tergo-lib = "0.2.8"
tergo-lib = "0.2.9"
toml = "0.8.19"
extendr-api = "*"

Expand Down
71 changes: 33 additions & 38 deletions antidotum/tergo/src/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ fn format_code(source_code: &str, configuration: extendr_api::List) -> extendr_a
"Unknown function line breaks in the configuration value. Allowed: single, double, hanging."
)
}
},
}
None => default_config.function_line_breaks,
},
match config_to_bool(
Expand All @@ -126,6 +126,15 @@ fn format_code(source_code: &str, configuration: extendr_api::List) -> extendr_a
Ok(value) => value,
Err(error) => return error,
},
match configuration.get("exclusion_list") {
Some(list) => match list.as_string_vector() {
Some(arr) => arr,
None => {
return list!(ERROR, "exclusion_list must be an array of strings.");
}
},
None => default_config.exclusion_list.0,
}
);

match tergo_lib::tergo_format(source_code, Some(&config)) {
Expand All @@ -147,44 +156,29 @@ fn format_code(source_code: &str, configuration: extendr_api::List) -> extendr_a
/// @keywords internal
#[extendr]
fn get_config(path: &str) -> extendr_api::List {
match std::fs::read_to_string(path) {
let config = match std::fs::read_to_string(path) {
Ok(config_file) => {
let config: Config = toml::from_str(&config_file).unwrap_or_else(|_| Config::default());
list!(
indent = config.indent.0,
line_length = config.line_length.0,
embracing_op_no_nl = config.embracing_op_no_nl.0,
allow_nl_after_assignment = config.allow_nl_after_assignment.0,
space_before_complex_rhs_in_formula = config.space_before_complex_rhs_in_formula.0,
strip_suffix_whitespace_in_function_defs =
config.strip_suffix_whitespace_in_function_defs.0,
function_line_breaks = match config.function_line_breaks {
FunctionLineBreaks::Hanging => "hanging",
FunctionLineBreaks::Double => "double",
FunctionLineBreaks::Single => "single",
},
insert_newline_in_quote_call = config.insert_newline_in_quote_call.0
)
}
Err(_) => {
let config = Config::default();
list!(
indent = config.indent.0,
line_length = config.line_length.0,
embracing_op_no_nl = config.embracing_op_no_nl.0,
allow_nl_after_assignment = config.allow_nl_after_assignment.0,
space_before_complex_rhs_in_formula = config.space_before_complex_rhs_in_formula.0,
strip_suffix_whitespace_in_function_defs =
config.strip_suffix_whitespace_in_function_defs.0,
function_line_breaks = match config.function_line_breaks {
FunctionLineBreaks::Hanging => "hanging",
FunctionLineBreaks::Double => "double",
FunctionLineBreaks::Single => "single",
},
insert_newline_in_quote_call = config.insert_newline_in_quote_call.0
)
toml::from_str::<Config>(&config_file).unwrap_or_else(|_| Config::default())
}
}
Err(_) => Config::default(),
};

list!(
indent = config.indent.0,
line_length = config.line_length.0,
embracing_op_no_nl = config.embracing_op_no_nl.0,
allow_nl_after_assignment = config.allow_nl_after_assignment.0,
space_before_complex_rhs_in_formula = config.space_before_complex_rhs_in_formula.0,
strip_suffix_whitespace_in_function_defs =
config.strip_suffix_whitespace_in_function_defs.0,
function_line_breaks = match config.function_line_breaks {
FunctionLineBreaks::Hanging => "hanging",
FunctionLineBreaks::Double => "double",
FunctionLineBreaks::Single => "single",
},
insert_newline_in_quote_call = config.insert_newline_in_quote_call.0,
exclusion_list = config.exclusion_list.0
)
}

/// Get the default configuration
Expand Down Expand Up @@ -240,7 +234,8 @@ fn get_default_config() -> extendr_api::List {
FunctionLineBreaks::Double => "double",
FunctionLineBreaks::Single => "single",
},
insert_newline_in_quote_call = config.insert_newline_in_quote_call.0
insert_newline_in_quote_call = config.insert_newline_in_quote_call.0,
exclusion_list = config.exclusion_list.0
)
}

Expand Down
Binary file modified antidotum/tergo/src/rust/vendor.tar.xz
Binary file not shown.
1 change: 1 addition & 0 deletions antidotum/tergo/tergo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exclusion_list = ["./R/extendr-wrappers.R", "./src", "tergo.Rcheck"]
1 change: 0 additions & 1 deletion antidotum/tergo/tests/testthat/test-style_text.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ testthat::test_that("style_text validates the configuration", {
)
)
})

1 change: 1 addition & 0 deletions antidotum/tergo/vignettes/styling_with_tergo.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ tergo::style(config = list(
| `strip_suffix_whitespace_in_function_defs` | boolean | TRUE | Trim trailing whitespace in functions |
| `function_line_breaks` | string | "hanging" | `"single"`/`"double"`/`"hanging"` function argument formatting ([ref](https://style.tidyverse.org/functions.html#multi-line-function-definitions)) |
| `insert_newline_in_quote_call` | boolean | TRUE | Add newlines in long `quote()` calls |
| `exclusion_list` | array of strings | [] | Files/directories to exclude from formatting |

## Why Choose `tergo`?
- **Blazing Fast**: Formats large codebases 100-1000x faster than alternatives
Expand Down
4 changes: 2 additions & 2 deletions balnea/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tergo-lib"
version = "0.2.8"
version = "0.2.9"
edition = "2021"
description = "A tool to format R code"
license = "MIT"
Expand All @@ -14,7 +14,7 @@ path = "src/lib.rs"
[dependencies]
tokenizer = { package = "tergo-tokenizer", path = "../aqua", version = "0.2.2" }
parser = { package = "tergo-parser", path = "../spongia", version = "0.2.3" }
formatter = { package = "tergo-formatter", path = "../unguentum", version = "0.2.6" }
formatter = { package = "tergo-formatter", path = "../unguentum", version = "0.2.8" }
log = "0.4.21"
env_logger = "0.11.3"
serde = { version = "1.0.210", features = ["derive"] }
Loading

0 comments on commit 753b2ad

Please sign in to comment.