Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@
^docs$
^pkgdown$
^\.github$
^[.]?air[.]toml$
^\.vscode$
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ jobs:
build:
working_directory: ~/oysteR
docker:
- image: rocker/verse:3.6.1
- image: rocker/verse:4
steps:
- checkout
- run:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/check-standard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- uses: r-lib/actions/setup-r@v1
with:
Expand All @@ -41,7 +41,7 @@ jobs:

- name: Cache R packages
if: runner.os != 'Windows'
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: ${{ env.R_LIBS_USER }}
key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }}
Expand Down
16 changes: 10 additions & 6 deletions .lintr
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
linters: with_defaults(
assignment_linter = NULL,
object_name_linter = NULL,
trailing_whitespace_linter = NULL,
line_length_linter(100)
)
linters: linters_with_defaults(
assignment_linter = NULL,
indentation_linter = NULL,
commented_code_linter = NULL,
object_length_linter = NULL,
object_name_linter = NULL,
line_length_linter(100),
cyclocomp_linter(complexity_limit = 15),
undesirable_operator_linter = undesirable_operator_linter(
op = list("<-" = "Please use '=' for assignment")))
12 changes: 6 additions & 6 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: oysteR
Title: Scans R Projects for Vulnerable Third Party Dependencies
Version: 0.1.3.9001
Authors@R:
Version: 0.1.4
Authors@R:
c(person(given = "Jeffry",
family = "Hesse",
role = "aut",
Expand Down Expand Up @@ -33,10 +33,10 @@ Description: Collects a list of your third party R packages, and
use.
License: Apache License 2.0 | file LICENSE
URL: https://github.com/sonatype-nexus-community/oysteR
BugReports:
BugReports:
https://github.com/sonatype-nexus-community/oysteR/issues
Depends:
R (>= 3.5.0)
R (>= 4.0.0)
Imports:
cli,
dplyr,
Expand All @@ -57,9 +57,9 @@ Suggests:
knitr,
rmarkdown,
testthat (>= 2.1.0)
VignetteBuilder:
VignetteBuilder:
knitr
Encoding: UTF-8
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.1.1
RoxygenNote: 7.3.3
1 change: 0 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

export(audit)
export(audit_conda)
export(audit_deps)
export(audit_description)
export(audit_installed_r_pkgs)
export(audit_renv_lock)
Expand Down
15 changes: 9 additions & 6 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
# oysteR 0.1.3.9001 _2021-05-18_
* Bug: Incorrectly states how many packages were found in the database (see #62)
# oysteR 0.1.4 _2025-10-08_
* bug: Incorrectly states how many packages were found in the database (see #62)
* feat: Pass tokens as arguments
* chore: Formatting via air
* chore: linting

# oysteR 0.1.3 _2021-03-11-_
# oysteR 0.1.3 _2021-03-11-_
* Internal: Return missing values as `NA`'s (see #59)

# oysteR 0.1.2 _2021-02-26_
* Feature: Add `audit_conda()` functions
# oysteR 0.1.2 _2021-02-26_
* Feature: Add `audit_conda()` functions
* Feature: Add Josiah Parry as an author
* Feature: Handle missing versions in a nice way

# oysteR 0.1.1 _2021-01-08_
* Use `dontrun{}` in examples that may hit rate limits.

# oysteR 0.1.0 _2020-12-17_
# oysteR 0.1.0 _2020-12-17_
* Feature: Add API caching. Calls are now cached for 12 hours (on R4+ only)
* Feature: Extract packages from `requirements.txt`, `renv.lock`, and `environment.yml` files
* Feature: Handle more general vulnerabilities
Expand Down
31 changes: 20 additions & 11 deletions R/audit.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#' By default it will search all known versions. If not `*`, must be the same length as pkg.
#' @param type The package management environment. For R packages, set equal to "cran".
#' This defaults to \code{"cran"}. See https://ossindex.sonatype.org/ecosystems.
#' @param token If NULL, looks at OSSINDEX_USER & OSSINDEX_TOKEN, env variables. If those
#' aren't available, try `"~/.ossindex/.oss-index-config"`
#' @param verbose Default \code{TRUE}.
#'
#' @export
Expand All @@ -32,10 +34,13 @@
#' version = c("1.4-5", "1.4.1")
#' audit(pkg, version, type = "cran")
#' }
audit = function(pkg, version, type, verbose = TRUE) {

if (is.null(pkg)) pkg = character(0)
if (is.null(version)) version = character(0)
audit = function(pkg, version, type, verbose = TRUE, token = NULL) {
if (is.null(pkg)) {
pkg = character(0)
}
if (is.null(version)) {
version = character(0)
}
# Create the purls. Checks will be inherited
purls = generate_purls(pkg, version, type)
## Get cache & remove cached purls
Expand All @@ -51,16 +56,20 @@ audit = function(pkg, version, type, verbose = TRUE) {
pkgs = tibble::tibble(package = pkg, version = version, type = type)[!is_cached, ]

## Call OSS index on remaining
results = call_oss_index(purls, verbose = verbose)
results = call_oss_index(purls, verbose = verbose, token = token)
audit = dplyr::bind_cols(pkgs, results)

# Update cache and combine
update_cache(audit)
# Replace NA versions
audit = dplyr::bind_rows(audit, cache) %>%
mutate(description = dplyr::if_else(is.na(version), NA_character_, .data$description),
no_of_vulnerabilities = dplyr::if_else(is.na(version), NA_integer_,
.data$no_of_vulnerabilities),
mutate(
description = dplyr::if_else(is.na(version), NA_character_, .data$description),
no_of_vulnerabilities = dplyr::if_else(
is.na(version),
NA_integer_,
.data$no_of_vulnerabilities
),
)
if (isTRUE(verbose)) {
audit_verbose(audit)
Expand All @@ -72,7 +81,7 @@ audit = function(pkg, version, type, verbose = TRUE) {
#'
#' Audits all installed packages by calling \code{installed.packages()}
#' and checking them against the OSS Index.
#' @param verbose Default \code{TRUE}.
#' @inheritParams audit
#' @return A tibble/data.frame.
#' @importFrom utils installed.packages
#' @export
Expand All @@ -82,7 +91,7 @@ audit = function(pkg, version, type, verbose = TRUE) {
#' # This calls installed.packages()
#' pkgs = audit_installed_r_pkgs()
#' }
audit_installed_r_pkgs = function(verbose = TRUE) {
audit_installed_r_pkgs = function(verbose = TRUE, token = NULL) {
pkgs = get_r_pkgs(verbose = verbose)
audit(pkg = pkgs$package, version = pkgs$version, type = "cran", verbose = verbose)
audit(pkg = pkgs$package, version = pkgs$version, type = "cran", verbose = verbose, token = token)
}
24 changes: 16 additions & 8 deletions R/cache.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@ get_cache_dir = function() {
get_cache_file = function() {
dir = get_cache_dir()
path = file.path(dir, "cached-deps.rds")
return(path)
path
}

ensure_cache = function() {
path = get_cache_file()
if (file.exists(path)) return(path)
if (file.exists(path)) {
return(path)
}

dir.create(get_cache_dir(), recursive = TRUE, showWarnings = FALSE)
audits = no_purls_case()
audits$time = integer(0)
class(audits$time) = c("POSIXct", "POSIXt")
saveRDS(audits, file = path)
return(path)
path
}

## General cache idea
Expand All @@ -29,7 +31,9 @@ ensure_cache = function() {
#' @importFrom rlang .data
get_cache = function() {
## Only available for R4+
if (getRversion() < "4.0.0") return(no_purls_case())
if (getRversion() < "4.0.0") {
return(no_purls_case())
}
path = ensure_cache()
audits = readRDS(path) %>%
dplyr::filter(.data$time > Sys.time() - 60 * 60 * 12) %>%
Expand All @@ -38,7 +42,9 @@ get_cache = function() {
}

update_cache = function(audits) {
if (getRversion() < "4.0.0") return(audits)
if (getRversion() < "4.0.0") {
return(audits)
}
audits$time = Sys.time()
path = ensure_cache()

Expand All @@ -49,7 +55,7 @@ update_cache = function(audits) {
dplyr::bind_rows(audits)

saveRDS(audits, file = path)
return(audits)
audits
}

#' Remove cache
Expand All @@ -60,6 +66,8 @@ update_cache = function(audits) {
#' @export
remove_cache = function() {
path = get_cache_file()
if (file.exists(path)) file.remove(path)
return(NULL)
if (file.exists(path)) {
file.remove(path)
}
NULL
}
Loading
Loading