This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
pkgnet is an R package for analyzing R packages using graph theory. It builds network representations of packages to:
- Analyze function interdependencies within a package
- Map recursive package dependencies
- Trace class inheritance structures (S4, R5/Reference Classes, R6)
- Prioritize functions for unit testing based on centrality metrics
The core functionality is CreatePackageReport() which generates HTML reports analyzing package structure.
The package uses an object-oriented architecture built on R6 classes with a hierarchical reporter system:
Base Classes:
AbstractPackageReporter(R/AbstractPackageReporter.R): Base class for all reporters. Handles package setup viaset_package()method.AbstractGraphReporter(R/AbstractGraphReporter.R): Extends AbstractPackageReporter for network-based reporters. Providesnodes,edges,network_measures, andpkg_graphactive bindings.
Concrete Reporters:
DependencyReporter(R/DependencyReporter.R): Analyzes recursive package dependenciesFunctionReporter(R/FunctionReporter.R): Maps function call networks and test coverageInheritanceReporter(R/InheritanceReporter.R): Traces S4/R5/R6 class inheritance
Report Generation:
PackageReport(R/CreatePackageReport.R): Aggregates multiple reporters and renders HTML via rmarkdownCreatePackageReport(): Convenience function that instantiates PackageReport with default reporters
DirectedGraph class (R/GraphClasses.R) wraps igraph functionality and provides:
- Node and graph measure calculations
- Network visualization via visNetwork
- Integration with reporter system
- Reporter Lifecycle: Instantiate →
set_package()→ extract nodes/edges → calculate measures → render - Active Bindings: Reporters use R6 active bindings for lazy evaluation of
nodes,edges, andnetwork_measures - Namespacing: All non-base function calls must use
::namespace operator (e.g.,data.table::data.table()) - data.table convention: data.table objects named with
DTsuffix (e.g.,nodesDT)
Run full test suite (builds tarball and runs R CMD check):
./test.shThis script:
- Builds package tarball with
R CMD build - Runs
R CMD check --as-cranin isolated directory - Fails if any WARNINGs found
- Fails if NOTEs exceed allowed count (currently 0)
Run tests interactively in R:
# Set to run NOT_CRAN tests
Sys.setenv(NOT_CRAN = "true")
# Run all tests
devtools::test()
# Run specific test file
devtools::test(filter = "FunctionReporter")Tests use a temporary package library (PKGNET_TEST_LIB) with fake test packages (baseballstats, sartre, milne). Setup/teardown in:
tests/testthat/setup-setTestEnv.Rtests/testthat/teardown-setTestEnv.R
On CRAN, only test-cran-true.R runs due to complications with temporary package handling.
# Build tarball
R CMD build .
# Install locally
R CMD INSTALL pkgnet_*.tar.gz
# Build documentation
Rscript -e "devtools::document()"covr::package_coverage()- R6 classes: UpperCamelCase (e.g.,
FunctionReporter) - Exported functions: UpperCamelCase (e.g.,
CreatePackageReport) - Methods/fields: snake_case (e.g.,
set_package,pkg_name) - data.table objects: camelCase ending in
DT(e.g.,nodesDT)
- Always use
::namespacing for non-base calls - Add
#' @importFrom package functionin roxygen docs - Exceptions: operators like
%>%and:=don't need namespacing - New package dependencies must be added to DESCRIPTION
Imports
- Use 4 spaces (never tabs)
- Comma-first style for multi-line lists:
sample_list <- list(
norm_sample = rnorm(100)
, unif_sample = runif(100)
, t_sample = rt(100, df = 100)
)- All comments above code, never beside
- Avoid comments where code is self-evident
Functions require:
#' @title#' @name#' @description#' @param(for each parameter)#' @export(if public API)
R6 Classes require sections:
#' @section Class Constructor:#' @section Public Methods:#' @section Public Members:- Document all public methods and active bindings
FunctionReporter treats R6 methods as functions with naming convention:
- Format:
<classname>$<methodtype>$<methodname> - Example:
FunctionReporter$private$extract_nodes - Uses generator object name from namespace, not
classnameattribute
InheritanceReporter naming:
- Reference Classes: Uses
Classarg fromsetRefClass() - R6 Classes: Uses generator object name in namespace (not
classnamearg)
-
FunctionReporter:
- Non-standard evaluation can cause false positives when column names match function names
- Functions stored in lists (not namespace) are invisible
- Instantiated R6/reference object method calls not recognized
- Reference class methods not yet supported
-
InheritanceReporter:
- S3 classes not supported (no formal class definitions)
Follows semantic versioning (MAJOR.MINOR.PATCH):
- Development versions append
.9999(e.g.,0.5.0.9999) - Release versions remove
.9999for CRAN submission
GitHub Actions workflows:
.github/workflows/ci.yml: Tests on Ubuntu/macOS with R release.github/workflows/release.yml: Tests on R-devel for CRAN submission.github/workflows/smoke-tests.yaml: RunsCreatePackageReport()on many packages.github/workflows/website.yaml: Builds pkgdown site
Reports use rmarkdown templates from inst/package_report/:
- Work done in temp directory to avoid writing to package repo
- See
PackageReport$render_report()in R/CreatePackageReport.R:67-98