Encourage Imports not Depends

Open
#3,076 21 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
30/100
Issue type
Refactor
Clarity
Mostly clear
Activity status
Quiet
Tech stack
r

Research direction

Start by reading PR #3069 commit 51590bcfec6e9cccc9271800bcf01749a42c7e80 and the cedta() implementation, especially its final tryCatch line for packages using Depends. Review the CRAN and BioC package table and the linked issue or PR status for each package. Done means a maintainer-approved decision on disallowing Depends, with the required package migrations and any cedta() changes accounted for.

Written by the indexing model from the issue text.

Description

breaking-change

CRAN + BioC: Depends Imports


I've only recently realized how bad Depends: is, thanks to Jan's importing vignette. I just made its discouragement stronger : https://github.com/Rdatatable/data.table/pull/3069/commits/51590bcfec6e9cccc9271800bcf01749a42c7e80

We could disallow Depends. This would also be beneficial to cedta()'s awkward implementation on its last line where it needs to do the tryCatch just for packages which Depend; that line could be removed.

But before we disallow Depends, we'd need to ask 69 CRAN packages to change from Depends to Imports. (Most revdeps already Import.) The longer we leave it, the greater the potential for new packages using Depends to be added to CRAN and the harder it will be to change.

Package Host Last Upload Issue? PR/Patch? Fixed in dev
1 DiSCos CRAN 2026-07-12
2 KMD CRAN 2026-07-09 ✉️: 2026-08-19
3 unvs.med CRAN 2026-06-30 ✉️: 2026-08-19
4 OmicFlow CRAN 2026-05-19 2026-06-25
5 poissonsuperlearner CRAN 2026-05-18 2026-08-19
6 CoSMoS CRAN 2026-05-07
7 pep725 CRAN 2026-04-24 2026-07-25
8 RapidoPGS CRAN 2026-04-03 2026-08-20
9 circhelp CRAN 2026-04-02 2024-09-04
10 rMIDAS CRAN 2026-03-13
11 didimputation CRAN 2026-03-09 2026-08-18
12 partools CRAN 2026-02-06
13 rTLS CRAN 2026-01-19
14 normfluodbf CRAN 2025-10-10
15 tma CRAN 2025-09-19 ✉️: 2026-08-19
16 colocPropTest CRAN 2025-09-16
17 FORD CRAN 2025-05-30
18 damr CRAN 2025-04-21
19 behavr CRAN 2025-03-27
20 HospitalNetwork CRAN 2024-12-22 2025-07-08
21 ZIM4rv CRAN 2024-12-19
22 lori CRAN 2024-11-18
23 SOMnmR CRAN 2024-07-04
24 LKT CRAN 2024-07-01
25 SeaVal CRAN 2024-06-14
26 limexhub CRAN 2024-05-06
27 rblt CRAN 2024-02-19
28 nosoi CRAN 2024-02-09 2025-07-11
29 tablecompare CRAN 2023-11-14 ✉️: 2026-08-19
30 sqlHelpers CRAN 2023-10-14 ✉️: 2026-08-19
31 PreProcessRecordLinkage CRAN 2023-09-13 ✉️: 2026-08-19
32 fplyr CRAN 2023-08-23
33 IBRtools CRAN 2023-08-14 2026-08-19
34 TrumpetPlots CRAN 2023-06-13
35 DiDforBigData CRAN 2023-04-03
36 pgTools CRAN 2023-03-24
38 libbib CRAN 2022-11-05
39 mind CRAN 2022-10-27 ✉️: 2026-08-19
40 acdcR CRAN 2022-06-27
41 chicane CRAN 2021-11-06 ✉️: 2026-08-19
42 FeatureImpCluster CRAN 2021-10-20
43 edl CRAN 2021-09-20 ✉️: 2026-08-19
44 ZIprop CRAN 2021-06-09 ✉️: 2026-08-19
45 FOCI CRAN 2021-03-18 ✉️: 2026-08-19
46 shinyML CRAN 2021-02-24
47 textTools CRAN 2021-02-05 ✉️: 2026-08-19
48 dbWebForms CRAN 2021-01-28 ✉️: 2026-08-19
49 classifierplots CRAN 2020-10-13
50 intervalaverage CRAN 2020-07-23
51 LSPFP CRAN 2020-05-13 ✉️: 2026-08-19
52 eyeTrackR CRAN 2020-03-29 ✉️: 2026-08-19
53 birankr CRAN 2020-03-23
54 GenomicTools.fileHandler CRAN 2020-03-05
55 gdxdt CRAN 2019-11-30 ✉️: 2026-08-19
56 cdparcoord CRAN 2019-08-04
57 twl CRAN 2018-08-24 ✉️: 2026-08-19
58 RWildbook CRAN 2018-04-06 ✉️: 2026-08-19
59 miLineage CRAN 2018-03-23 ✉️: 2026-08-19
60 Ac3net CRAN 2018-02-26 ✉️: 2026-08-19
61 bea.R CRAN 2018-02-23
62 heims CRAN 2018-01-25
64 orgR CRAN 2014-12-20
65 Chicago Bioconductor 2026-04-28
66 GOTHiC Bioconductor 2026-04-28 ✉️: 2026-08-19
67 GladiaTOX Bioconductor 2026-04-28
68 HMMcopy Bioconductor 2026-04-28
69 ModCon Bioconductor 2026-04-28 2026-07-16
70 RCAS Bioconductor 2026-04-28
71 TIN Bioconductor 2026-04-28 ✉️: 2026-08-19
72 chimeraviz Bioconductor 2026-04-28 2026-08-18
73 deconvR Bioconductor 2026-04-28 2025-07-13
74 methrix Bioconductor 2026-04-28 2025-12-01
75 rBiopaxParser Bioconductor 2026-04-28
76 sangeranalyseR Bioconductor 2026-04-28 2026-05-05
77 SNPhood Bioconductor 2025-11-04 ✉️: 2026-08-19
Repro script to re-generate this table
library(tools)
library(data.table)

# 1. Fetch CRAN metadata and reverse dependencies (Depends: data.table)
cran_db = as.data.table(CRAN_package_db())
cran_deps = package_dependencies("data.table", db = as.matrix(cran_db), reverse = TRUE, which = "Depends")$data.table
cran_sub = cran_db[Package %in% cran_deps]

# 2. Fetch Bioconductor metadata and reverse dependencies (Depends: data.table)
bioc_views_url = "https://bioconductor.org/packages/release/bioc/VIEWS"
tf = tempfile()
download.file(bioc_views_url, tf, quiet = TRUE)
bioc_views = as.data.table(read.dcf(tf))
bioc_deps = package_dependencies("data.table", db = as.matrix(bioc_views), reverse = TRUE, which = "Depends")$data.table
bioc_sub = bioc_views[Package %in% bioc_deps]

# 3. Harvest existing tracked links dynamically from GitHub issue #3076 body
issue_body = tryCatch({
  res = httr::GET("https://api.github.com/repos/Rdatatable/data.table/issues/3076", httr::user_agent("Rdatatable"))
  httr::content(res, "parsed")$body
}, error = function(e) "")

known_links = list()
fixed_links = list()
lines = strsplit(issue_body, "\r?\n")[[1]]

for (l in lines) {
  # Parse table rows: | # | [pkg](repo) | [Host](host_url) | Last Upload | [✅](issue) | [✅](pr) | [date](fix) |
  if (grepl(r"{^\|.*\|.*\|.*\|}", l)) {
    parts = strsplit(l, "\\|")[[1]]
    if (length(parts) > 0 && parts[1] == "") parts = parts[-1]
    parts = trimws(parts)
    if (length(parts) >= 4 && !any(grepl("Last Upload|:---", parts))) {
      pkg_col = if (grepl("^[0-9]+$", parts[1])) 2 else 1
      pkg = sub(r"{^\[([^]]+)\].*}", "\\1", parts[pkg_col])
      
      issue_col = pkg_col + 3
      pr_col    = pkg_col + 4
      fix_col   = pkg_col + 5
      
      if (length(parts) >= issue_col && grepl(r"{https?://}", parts[issue_col])) {
        m_iss = regmatches(parts[issue_col], regexec(r"{\((https?://[^)]+)\)}", parts[issue_col]))[[1]]
        if (length(m_iss) > 1) {
          known_links[[length(known_links) + 1]] = data.table(Package = pkg, Type = "Issue", URL = m_iss[2])
        }
      }
      if (length(parts) >= pr_col && grepl(r"{https?://}", parts[pr_col])) {
        m_pr = regmatches(parts[pr_col], regexec(r"{\((https?://[^)]+)\)}", parts[pr_col]))[[1]]
        if (length(m_pr) > 1) {
          known_links[[length(known_links) + 1]] = data.table(Package = pkg, Type = "PR", URL = m_pr[2])
        }
      }
      if (length(parts) >= fix_col && grepl(r"{https?://}", parts[fix_col])) {
        fixed_links[[length(fixed_links) + 1]] = data.table(Package = pkg, Fixed_In_Dev = parts[fix_col])
      }
    }
  }
}

links_dt = if (length(known_links) > 0) {
  dcast(unique(rbindlist(known_links)), Package ~ Type, value.var = "URL", fun.aggregate = function(x) x[1])
} else {
  data.table(Package = character(), Issue = character(), PR = character())
}

fixed_dt = if (length(fixed_links) > 0) unique(rbindlist(fixed_links)) else data.table(Package = character(), Fixed_In_Dev = character())

# Helper: extract source forge repository (GitHub/GitLab) from package fields or links
extract_repo <- function(pkg, url_fields, issue_url, pr_url) {
  ref_url = na.omit(c(issue_url, pr_url))
  if (length(ref_url) > 0) {
    m = regmatches(ref_url[1], regexec(r"{(https?://[^/]+/[^/]+/[^/#?]+)}", ref_url[1]))[[1]]
    if (length(m) > 1) {
      repo = sub(r"{/(issues|pull|tree|blob|commit)/?.*$}", "", m[2])
      repo = sub(r"{/-/issues/?.*$}", "", repo)
      return(repo)
    }
  }
  urls = unlist(strsplit(url_fields[!is.na(url_fields)], "[,\n\t ]+"))
  urls = urls[urls != ""]
  repo_urls = grep("git(hub|lab)", urls, value = TRUE)
  repo_urls = repo_urls[!grepl("\\.github\\.io", repo_urls)]
  if (length(repo_urls) > 0) {
    m = regmatches(repo_urls[1], regexec(r"{(https?://[^/]+/[^/]+/[^/#?]+)}", repo_urls[1]))[[1]]
    if (length(m) > 1) {
      repo = sub(r"{\.git$}", "", m[2])
      repo = sub(r"{/(issues|pull)/?.*$}", "", repo)
      repo = sub(r"{/-/issues/?.*$}", "", repo)
      return(repo)
    }
  }
  NA_character_
}

# CRAN data
cran_dt = data.table(
  Package_Name = cran_sub$Package,
  Host_Name = "CRAN",
  Host_URL = sprintf("https://cran.r-project.org/package=%s", cran_sub$Package),
  Last_Upload = as.character(as.Date(as.POSIXct(cran_sub[["Date/Publication"]]))),
  URL_Fields = paste(cran_sub$URL, cran_sub$BugReports, sep = ", ")
)

# Bioconductor data
bioc_dt = data.table(
  Package_Name = bioc_sub$Package,
  Host_Name = "Bioconductor",
  Host_URL = sprintf("https://bioconductor.org/packages/%s", bioc_sub$Package),
  Last_Upload = bioc_sub[["Date/Publication"]],
  URL_Fields = paste(bioc_sub$URL, bioc_sub$BugReports, bioc_sub$git_url, sep = ", ")
)

all_pkgs = rbind(cran_dt, bioc_dt)
all_pkgs = merge(all_pkgs, links_dt, by.x = "Package_Name", by.y = "Package", all.x = TRUE)
all_pkgs = merge(all_pkgs, fixed_dt, by.x = "Package_Name", by.y = "Package", all.x = TRUE)

all_pkgs[, Repo := mapply(extract_repo, Package_Name, URL_Fields, Issue, PR)]
all_pkgs[, Package := ifelse(!is.na(Repo) & Repo != "", sprintf("[%s](%s)", Package_Name, Repo), Package_Name)]
all_pkgs[, Host := sprintf("[%s](%s)", Host_Name, Host_URL)]
all_pkgs[, `Issue?` := ifelse(!is.na(Issue) & Issue != "", sprintf("[✅](%s)", Issue), "")]
all_pkgs[, `PR?` := ifelse(!is.na(PR) & PR != "", sprintf("[✅](%s)", PR), "")]
all_pkgs[, `Fixed in dev` := ifelse(!is.na(Fixed_In_Dev), Fixed_In_Dev, "")]

# Sort by Host (CRAN then Bioconductor) and descending Last_Upload
all_pkgs[, Host_Order := factor(Host_Name, levels = c("CRAN", "Bioconductor"))]
setorder(all_pkgs, Host_Order, -Last_Upload)

# Leftmost column numbered 1...n with empty header
all_pkgs[, ` ` := .I]

out_dt = all_pkgs[, .(` `, Package, Host, `Last Upload` = Last_Upload, `Issue?`, `PR?`, `Fixed in dev`)]
writeLines(knitr::kable(out_dt, format = "markdown", align = c("r", "l", "l", "l", "c", "c", "l")))
Dominant language
R
Stars
3.9k
Forks
1.1k
Avg merge
14h 4m
Merged PRs (30d)
4

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Rdatatable/data.table

All issues in Rdatatable/data.table

Similar issues

More R issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.