SmartCane/r_app/experiments/legacy_package_management/extract_current_versions.R
Timon d5fd4bb463 Add KPI reporting system and deployment documentation
Major Changes:
- NEW: Scripts 09 & 10 for KPI calculation and enhanced reporting
- NEW: Shell script wrappers (01-10) for easier execution
- NEW: R packages flextable and officer for enhanced Word reports
- NEW: DEPLOYMENT_README.md with complete deployment guide
- RENAMED: Numbered R scripts (02, 03, 04) for clarity
- REMOVED: Old package management scripts (using renv only)
- UPDATED: Workflow now uses scripts 09->10 instead of 05

Files Changed: 90+ files
New Packages: flextable, officer
New Scripts: 09_run_calculate_kpis.sh, 10_run_kpi_report.sh
Documentation: DEPLOYMENT_README.md, EMAIL_TO_ADMIN.txt

See DEPLOYMENT_README.md for full deployment instructions.
2025-10-14 11:49:30 +02:00

201 lines
6.8 KiB
R
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#' Version Extractor for SmartCane Project
#'
#' This script scans your R scripts to find all used packages and extracts
#' the currently installed versions. Use this to populate the package_manager.R
#' with your actual working versions.
#'
#' Usage:
#' source("extract_current_versions.R")
#'
#' Author: SmartCane Team
#' Date: 2025-06-24
# =============================================================================
# PACKAGE DISCOVERY
# =============================================================================
#' Extract packages from R scripts
extract_packages_from_scripts <- function(script_dir = ".") {
# Find all R files
r_files <- list.files(script_dir, pattern = "\\.(R|Rmd)$", recursive = TRUE, full.names = TRUE)
packages <- c()
for (file in r_files) {
cat("Scanning:", file, "\n")
tryCatch({
content <- readLines(file, warn = FALSE)
# Find library() calls
library_matches <- regmatches(content, regexpr('library\\(["\']?([^"\'\\)]+)["\']?\\)', content))
library_packages <- gsub('library\\(["\']?([^"\'\\)]+)["\']?\\)', '\\1', library_matches)
library_packages <- library_packages[library_packages != ""]
# Find require() calls
require_matches <- regmatches(content, regexpr('require\\(["\']?([^"\'\\)]+)["\']?\\)', content))
require_packages <- gsub('require\\(["\']?([^"\'\\)]+)["\']?\\)', '\\1', require_matches)
require_packages <- require_packages[require_packages != ""]
# Find package::function calls
namespace_matches <- regmatches(content, gregexpr('[a-zA-Z][a-zA-Z0-9.]*::', content))
namespace_packages <- unique(unlist(lapply(namespace_matches, function(x) gsub('::', '', x))))
namespace_packages <- namespace_packages[namespace_packages != ""]
packages <- c(packages, library_packages, require_packages, namespace_packages)
}, error = function(e) {
cat("Error reading", file, ":", e$message, "\n")
})
}
# Clean and deduplicate
packages <- unique(packages)
packages <- packages[!packages %in% c("", "base", "stats", "utils", "graphics", "grDevices")]
return(sort(packages))
}
#' Get current version of installed packages
get_current_versions <- function(packages) {
versions <- list()
cat("\nChecking installed versions...\n")
cat("===============================\n")
for (pkg in packages) {
if (pkg %in% rownames(installed.packages())) {
version <- as.character(packageVersion(pkg))
versions[[pkg]] <- version
cat(sprintf("✓ %-20s %s\n", pkg, version))
} else {
cat(sprintf("✗ %-20s NOT INSTALLED\n", pkg))
}
}
return(versions)
}
#' Generate package manager configuration
generate_package_config <- function(versions) {
cat("\n\nGenerating REQUIRED_PACKAGES configuration...\n")
cat("=============================================\n\n")
config_lines <- c(
"# Package requirements with your current working versions",
"REQUIRED_PACKAGES <- list("
)
# Group packages by category
categories <- list(
"Core data manipulation" = c("here", "dplyr", "tidyr", "readr", "readxl", "magrittr", "lubridate", "stringr"),
"Spatial data" = c("sf", "terra", "exactextractr", "raster", "sp", "sf", "rgdal", "rgeos"),
"Visualization" = c("tmap", "ggplot2", "RColorBrewer", "viridis", "scales"),
"Statistical analysis" = c("lme4", "nlme", "mgcv", "survival", "cluster"),
"Reporting" = c("knitr", "rmarkdown", "officedown", "officer", "flextable"),
"Tidyverse" = c("tidyverse", "purrr", "forcats", "tibble"),
"Other packages" = c()
)
# Categorize packages
categorized <- list()
uncategorized <- names(versions)
for (category in names(categories)) {
cat_packages <- intersect(names(versions), categories[[category]])
if (length(cat_packages) > 0) {
categorized[[category]] <- cat_packages
uncategorized <- setdiff(uncategorized, cat_packages)
}
}
# Add uncategorized packages
if (length(uncategorized) > 0) {
categorized[["Other packages"]] <- uncategorized
}
# Generate config
for (category in names(categorized)) {
config_lines <- c(config_lines, paste0(" # ", category))
packages_in_cat <- categorized[[category]]
for (i in seq_along(packages_in_cat)) {
pkg <- packages_in_cat[i]
version <- versions[[pkg]]
comma <- if (i == length(packages_in_cat) && category == names(categorized)[length(categorized)]) "" else ","
# Add special comment for critical packages
comment <- ""
if (pkg == "tmap") comment <- " # CRITICAL: for tm_scale_continuous() syntax"
if (pkg == "terra") comment <- " # CRITICAL: for raster processing"
config_lines <- c(config_lines, sprintf(' "%s" = "%s"%s%s', pkg, version, comma, comment))
}
if (category != names(categorized)[length(categorized)]) {
config_lines <- c(config_lines, "")
}
}
config_lines <- c(config_lines, ")")
# Print to console
cat(paste(config_lines, collapse = "\n"))
# Save to file
writeLines(config_lines, "generated_package_config.R")
cat("\n\n📁 Configuration saved to: generated_package_config.R\n")
return(config_lines)
}
# =============================================================================
# MAIN EXECUTION
# =============================================================================
main <- function() {
cat("🔍 SmartCane Package Version Extractor\n")
cat("======================================\n\n")
# Step 1: Find all packages used in scripts
cat("Step 1: Scanning R scripts for package usage...\n")
packages <- extract_packages_from_scripts()
cat("\nFound packages:\n")
cat(paste(packages, collapse = ", "), "\n")
cat("\nTotal packages found:", length(packages), "\n")
# Step 2: Get current versions
cat("\nStep 2: Checking installed versions...\n")
versions <- get_current_versions(packages)
installed_count <- length(versions)
missing_count <- length(packages) - installed_count
cat(sprintf("\n📊 Summary: %d installed, %d missing\n", installed_count, missing_count))
if (missing_count > 0) {
missing_packages <- setdiff(packages, names(versions))
cat("\n⚠ Missing packages:\n")
cat(paste(missing_packages, collapse = ", "), "\n")
cat("\nYou may want to install these first, then re-run this script.\n")
}
# Step 3: Generate configuration
if (length(versions) > 0) {
cat("\nStep 3: Generating package manager configuration...\n")
config <- generate_package_config(versions)
cat("\n✅ Next steps:\n")
cat("1. Review generated_package_config.R\n")
cat("2. Copy the REQUIRED_PACKAGES list to package_manager.R\n")
cat("3. Adjust any versions as needed\n")
cat("4. Run package_manager.R\n")
} else {
cat("\n❌ No installed packages found. Install packages first.\n")
}
}
# Run the extraction
main()