Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #12

Open
wants to merge 73 commits into
base: master
Choose a base branch
from
Open

Dev #12

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
5c26f4e
No need for createDirectory(), unify url defs.
hsonne Jul 15, 2023
638efe9
Improve readability of DESCRIPTION file
hsonne Jul 15, 2023
9bf6126
Rename placeholder (was duplicated)
hsonne Jul 15, 2023
e86d363
Generalise download of scripts from GitHub
hsonne Jul 15, 2023
6a62d44
Use pipe operator (call usetthis::use_pipe())
hsonne Jul 26, 2023
8630a96
Improve comment
hsonne Jul 26, 2023
24332e3
Use the pipe operator
hsonne Jul 26, 2023
e913c4b
Use the pipe operator
Jul 26, 2023
4354196
Simplify the argument lists
hsonne Jul 26, 2023
afc2ee4
Use the pipe operator
hsonne Jul 26, 2023
b289efc
Add get_function_assignments(),
hsonne Jul 26, 2023
13a08d8
Improve duplicatesToFiles()
hsonne Aug 6, 2023
c98c135
Extract get_info_on_duplicated_function_names()
hsonne Aug 6, 2023
34c5e88
Add comments, simplify, use stopFormatted()
hsonne Aug 6, 2023
f3cdc4b
Loop through unique contents instead of while()
hsonne Aug 6, 2023
d421056
Extract found_in_scripts_header()
hsonne Aug 6, 2023
4d9d987
Improve naming, use lapply() instead of for()
hsonne Aug 6, 2023
9c6e1a9
Simplify/unify writeContentsTo(Less)Files()
hsonne Aug 6, 2023
7086243
Add utility function cat_formatted()
hsonne Aug 6, 2023
1cc0801
Add package specifiers, return file paths
hsonne Aug 6, 2023
fbd1386
Suppress warnings, error outputs in type_info()
hsonne Aug 6, 2023
7743c1d
Extract cat_error(), use startsWith()
hsonne Aug 6, 2023
10e0109
Return vector of file paths, improve file names
hsonne Aug 6, 2023
3038c4e
Fix tests
hsonne Aug 6, 2023
12a49ae
Use helper function collapse()
hsonne Aug 9, 2023
eb5fd52
Remove empty documentation of return value
hsonne Aug 11, 2023
ae555bf
Refactor get_elements_by_type(), use pipe
hsonne Aug 11, 2023
42c1ea6
Move functions from main.R to scripts per function
hsonne Aug 11, 2023
4689c2d
Fix error in info_to_text(), do not use sprintf()
hsonne Aug 11, 2023
8ab6eaf
Check for list-like structure, not for list
hsonne Aug 11, 2023
c6f677c
Allow path to be empty
hsonne Aug 11, 2023
4a401e5
Move functions to where they are used
hsonne Aug 12, 2023
da560a1
Rename argument, simplify
hsonne Aug 12, 2023
311e791
Implement basic tests for type_info()
hsonne Aug 12, 2023
fa1dbb5
Extract get_function_names_matching()
hsonne Aug 12, 2023
3a7b420
Fix test
hsonne Aug 12, 2023
3b4d44c
is_what(): suppress error messages and warnings
hsonne Aug 12, 2023
27f01e5
Clean/simplify code in analyse()
hsonne Aug 12, 2023
407a0bb
Fix typo
hsonne Aug 12, 2023
5df569e
Improve readability
hsonne Aug 12, 2023
e835c3b
Call is_what() also for objects with length > 1
hsonne Aug 12, 2023
0993215
Add normalise_expression()
hsonne Apr 4, 2024
08bc0ea
Use the pipe operator
hsonne Apr 4, 2024
562d1b2
Improve readability, use variable "keep_row"
hsonne Apr 4, 2024
6d269a2
Fix error in example. Add "keep.source = TRUE"
hsonne Apr 4, 2024
054c860
Use deparse() to make ensure that "text" is chr
hsonne Apr 4, 2024
8478c64
Add stop_formatted(), warn_formatted()
hsonne Apr 5, 2024
ff8718d
Add message_formatted()
hsonne Apr 5, 2024
06772d0
Use cat_formatted()
hsonne Apr 5, 2024
90444b7
Add shortcut to kwb.utils::shorten()
hsonne Apr 5, 2024
ae79444
Add shortcuts to select(Column|Element)s()
hsonne Apr 5, 2024
afd7458
Add shortcuts to kwb.utils::catAndRun()
hsonne Apr 5, 2024
6102965
Add shortcuts to kwb.utils::catIf()
hsonne Apr 5, 2024
e0f8809
Add shortcuts for all used kwb.utils functions
hsonne Apr 5, 2024
3ca5f51
Get rid of calls to kwb.utils::hsQuoteChr()
hsonne Apr 5, 2024
02e099e
Merge pull request #13 from KWB-R/clean
hsonne Apr 5, 2024
ed3264a
Make code more compact
hsonne Apr 5, 2024
bf6c350
Use the pipe operator, simplify
hsonne Apr 5, 2024
d980dae
Reuse stop_formatted()
hsonne Apr 5, 2024
1e4e8c6
Return early, use pipe operator
hsonne Apr 5, 2024
8cef64d
Simplify variable name, use pipe operator
hsonne Apr 5, 2024
6533695
Use pipe operator
hsonne Apr 5, 2024
aee3673
Use helper variable "nchars"
hsonne Apr 5, 2024
09f0795
Move functions between files
hsonne Apr 5, 2024
77be24e
Update Rd file
hsonne Apr 5, 2024
6fe61e1
Allow to pass arguments through to parse()
hsonne Apr 16, 2024
51fb253
Document interesting base function in vignette
hsonne Apr 16, 2024
144b4d6
Add find_function_name_duplicates()
hsonne Apr 30, 2024
e3b0241
Merge branch 'dev' into clean
hsonne Apr 30, 2024
a281bc9
Add tests with kwb.test::cretate_test_files()
hsonne Apr 30, 2024
488b5cb
Add tests and "fill" empty tests
hsonne Apr 30, 2024
f077d66
Fix documentation of ... args
hsonne Apr 30, 2024
0972a65
Merge pull request #14 from KWB-R/clean
hsonne Apr 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,28 @@ Package: kwb.code
Title: Analyse Your R Code!
Version: 0.3.0
Authors@R: c(
person("Hauke", "Sonnenberg", , "hauke.sonnenberg@kompetenz-wasser.de", role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-9134-2871")),
person("Michael", "Rustler", , "michael.rustler@kompetenz-wasser.de", role = "ctb",
comment = "0000-0003-0647-7726"),
person("FAKIN", role = "fnd"),
person("Kompetenzzentrum Wasser Berlin gGmbH (KWB)", role = "cph")
person(
given = "Hauke",
family = "Sonnenberg",
email = "hauke.sonnenberg@kompetenz-wasser.de",
role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-9134-2871")
),
person(
given = "Michael",
family = "Rustler",
email = "michael.rustler@kompetenz-wasser.de",
role = "ctb",
comment = "0000-0003-0647-7726"
),
person(
given = "FAKIN",
role = "fnd"
),
person(
given = "Kompetenzzentrum Wasser Berlin gGmbH (KWB)",
role = "cph"
)
)
Description: This package allows you to parse your R scripts and to
calculate some staticstics on your code.
Expand All @@ -18,6 +34,7 @@ Imports:
dplyr,
kwb.file,
kwb.utils,
magrittr,
stringr
Suggests:
covr,
Expand All @@ -33,4 +50,4 @@ ByteCompile: true
Config/testthat/edition: 3
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.2.3
RoxygenNote: 7.3.1
22 changes: 19 additions & 3 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,38 +1,54 @@
# Generated by roxygen2: do not edit by hand

export("%>%")
export(analyse)
export(arg_names)
export(find_function_name_duplicates)
export(find_string_constants)
export(find_weaknesses_in_scripts)
export(get_elements_by_type)
export(get_full_function_info)
export(get_function_assignments)
export(get_names_of_used_packages)
export(get_package_function_usage)
export(get_package_usage_per_script)
export(get_string_constants_in_scripts)
export(normalise_expression)
export(parse_scripts)
export(to_full_script_info)
export(walk_tree)
importFrom(dplyr,bind_rows)
importFrom(kwb.utils,backspace)
importFrom(kwb.utils,catAndRun)
importFrom(kwb.utils,catIf)
importFrom(kwb.utils,checkForMissingColumns)
importFrom(kwb.utils,collapsed)
importFrom(kwb.utils,commaCollapsed)
importFrom(kwb.utils,createDirectory)
importFrom(kwb.utils,defaultIfNULL)
importFrom(kwb.utils,excludeNULL)
importFrom(kwb.utils,extractSubstring)
importFrom(kwb.utils,hsQuoteChr)
importFrom(kwb.utils,getAttribute)
importFrom(kwb.utils,hsOpenWindowsExplorer)
importFrom(kwb.utils,isTryError)
importFrom(kwb.utils,left)
importFrom(kwb.utils,matchesCriteria)
importFrom(kwb.utils,moveColumnsToFront)
importFrom(kwb.utils,multiSubstitute)
importFrom(kwb.utils,noFactorDataFrame)
importFrom(kwb.utils,pairwise)
importFrom(kwb.utils,printIf)
importFrom(kwb.utils,rbindAll)
importFrom(kwb.utils,removeAttributes)
importFrom(kwb.utils,removeColumns)
importFrom(kwb.utils,removeEmptyColumns)
importFrom(kwb.utils,renameColumns)
importFrom(kwb.utils,resetRowNames)
importFrom(kwb.utils,safeRowBindAll)
importFrom(kwb.utils,selectColumns)
importFrom(kwb.utils,selectElements)
importFrom(kwb.utils,shorten)
importFrom(kwb.utils,stopFormatted)
importFrom(kwb.utils,stringList)
importFrom(magrittr,"%>%")
importFrom(stats,aggregate)
importFrom(stats,setNames)
importFrom(stringr,str_extract_all)
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Latest Changes

* Add normalise_expression()

# [kwb.code 0.3.0](https://github.com/KWB-R/kwb.code/releases/tag/v0.3.0) <small>2023-07-15</small>

* repair GitHub Actions
Expand Down
63 changes: 53 additions & 10 deletions R/analyse.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,65 @@
#' str(result, 3)
analyse <- function(x, path = "")
{
info <- type_info(x)

# result <- list(
# self = info_to_text(info)
# )

result <- info
result <- type_info(x)
result[["fulltype"]] <- info_to_text(result)
result[["path"]] <- path
result[["fulltype"]] <- info_to_text(info)

if (is.recursive(x)) {

result[["children"]] <- lapply(seq_along(x), function(i) {
analyse(x[[i]], path = paste(path, i, sep = "/"))
analyse(x[[i]], path = paste0(path, "/", i))
})
}

result
}

# type_info --------------------------------------------------------------------
type_info <- function(x, as_character = FALSE)
{
shorten <- function(x) paste(substr(x, 1, 30), "...")

text <- as.character(x)
mode_x <- mode(x)
class_x <- class(x)

info <- list(
type = typeof(x),
mode = mode_x,
class = class_x,
length = length(x),
text = shorten(paste0("[", seq_along(text), "]", text, collapse = "")),
is = is_what(x),
n_modes = length(mode_x),
n_classes = length(class_x)
)

if (as_character) {
info_to_text(info)
} else {
info
}
}

# info_to_text -----------------------------------------------------------------
info_to_text <- function(info)
{
collapse <- function(element) {
select_elements(info, element) %>%
comma_collapsed()
}

#prefix <- "type|mode|class|length|is: "
prefix <- NULL

paste0(
prefix,
paste(collapse = "|", c(
collapse("type"),
collapse("mode"),
collapse("class"),
collapse("length"),
collapse("is")
))
)
}
102 changes: 72 additions & 30 deletions R/duplicatesToFiles.R
Original file line number Diff line number Diff line change
@@ -1,27 +1,59 @@
# duplicatesToFiles ------------------------------------------------------------
#' @importFrom kwb.utils catIf
#' @importFrom kwb.utils createDirectory
#' @importFrom kwb.utils selectColumns
#' @importFrom kwb.utils selectElements
duplicatesToFiles <- function
(
trees, fun_duplicates, function_name, target_root = tempdir(), dbg = TRUE,
trees,
fun_duplicates = NULL,
function_name = NULL,
target_root = tempdir(),
dbg = TRUE,
write.all = FALSE
) {

selected <- selectColumns(fun_duplicates, "functionName") == function_name
)
{
if (is.null(fun_duplicates)) {
fun_duplicates <- get_info_on_duplicated_function_names(trees)
}

if (nrow(fun_duplicates) == 0L) {
message("No duplications given or no duplications found.")
return()
}

function_names <- select_columns(fun_duplicates, "functionName")

# Call this function for each function name if no function name is given
if (is.null(function_name)) {

message("No function name given.")

lapply(unique(function_names), function(function_name) {
#function_name <- unique(function_names)[1L]
cat_and_run(
sprintf(
"Calling duplicatesToFiles(..., function_name = \"%s\")",
function_name
),
duplicatesToFiles(trees, fun_duplicates, function_name),
newLine = 3L
)
})
}

scripts <- as.character(selectColumns(fun_duplicates[selected, ], "script"))
# Script files that contain a function <function_name>
scripts <- fun_duplicates[function_names == function_name, ] %>%
selectColumns("script") %>%
as.character()

function_defs <- lapply(scripts, function(script) {
extract_function_definition(selectElements(trees, script), function_name)
# From each script, extract the definition of function <function_name>
function_defs <- lapply(stats::setNames(nm = scripts), function(script) {
trees %>%
select_elements(script) %>%
extract_function_definition(function_name)
})

names(function_defs) <- scripts

target_dir <- file.path(target_root, "clean", function_name)
target_dir <- createDirectory(target_dir, dbg = FALSE)


target_dir <- target_root %>%
file.path("clean", function_name) %>%
create_directory(dbg = FALSE)

contents <- lapply(function_defs, function(x) deparse(x[[3L]]))

# Write one file per function definition
Expand All @@ -30,36 +62,46 @@ duplicatesToFiles <- function
}

# Write one file per unique function definition
n_files <- writeContentsToLessFiles(
files <- writeContentsToLessFiles(
contents, target_dir, function_name, dbg = dbg
)

if (n_files != length(contents)) {
if (length(files) != length(contents)) {
message("There are identical definitions for ", function_name)
}

target_dir
files
}

# extract_function_definition --------------------------------------------------
extract_function_definition <- function(tree, function_name) {

tree <- tree[sapply(tree, is_function_assignment)]
# get_info_on_duplicated_function_names ----------------------------------------
get_info_on_duplicated_function_names <- function(trees)
{
result <- get_full_function_info(trees)
result[selectColumns(result, "n.def") > 1L, ]
}

fnames <- sapply(tree, function(x) split_function_assignment(x)$functionName)
# extract_function_definition --------------------------------------------------
extract_function_definition <- function(tree, function_name)
{
fnames <- tree[sapply(tree, is_function_assignment)] %>%
sapply(function(x) split_function_assignment(x)$functionName)

index <- which(fnames == function_name)

n_defs <- length(index)

if (n_defs == 0L) {
stop("No such function: '", function_name, "' defined in the given tree")
stop_formatted(
"No such function: '%s' defined in the given tree",
function_name
)
}

if (n_defs > 1L) {
warning(
"The function '", function_name, "' is defined multiple times in ",
"the given tree. I return the first definition!"
warn_formatted(
"The function '%s' is defined multiple times in ",
"the given tree. I return the first definition!",
function_name
)
}

Expand Down
Loading
Loading