{"id":18046633,"url":"https://github.com/ltla/fuyuko","last_synced_at":"2025-04-05T04:24:55.301Z","repository":{"id":58192017,"uuid":"527381206","full_name":"LTLA/fuyuko","owner":"LTLA","description":"Inspect CMake dependencies from parsing FetchContent calls","archived":false,"fork":false,"pushed_at":"2022-09-02T06:44:36.000Z","size":44,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-10T12:29:25.729Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LTLA.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-08-22T02:13:44.000Z","updated_at":"2022-08-24T05:43:54.000Z","dependencies_parsed_at":"2023-01-17T21:32:02.902Z","dependency_job_id":null,"html_url":"https://github.com/LTLA/fuyuko","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LTLA%2Ffuyuko","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LTLA%2Ffuyuko/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LTLA%2Ffuyuko/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LTLA%2Ffuyuko/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LTLA","download_url":"https://codeload.github.com/LTLA/fuyuko/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247288134,"owners_count":20914310,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-30T19:08:16.754Z","updated_at":"2025-04-05T04:24:55.286Z","avatar_url":"https://github.com/LTLA.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Trace `FetchContent` dependency conflicts\n\n## Overview\n\nThis package scans `CMakeLists.txt` files for `FetchContent` dependencies to build a inter-repository dependency graph.\nIts main purpose is to identify dependency conflicts, most typically differences in the pinned SHAs from `FetchContent_Declare`.\nSuch differences may represent incompatibilities in the versions of the transitive dependencies.\n\nThis package was motivated by my own use of `FetchContent` within CMake to manage C++ library dependencies, e.g., in [**libscran**](https://github.com/LTLA/libscran).\n`FetchContent` will fetch all transitive dependencies automatically; however, if the same dependency is declared repeatedly, only the first declaration is fulfilled.\nThis can cause problems if the declarations involve different versions of the upstream project that are not compatible. \nWith **fuyuko**, we can identify such conflicts for manual resolution.\n\n## Quick start\n\nTo install, you can use the usual **devtools** process:\n\n```r\n# install.packages(\"devtools\") # if not installed\ninstall.packages(\"LTLA/fuyuko\")\n```\n\nUsage is fairly simple:\n\n```r\n# Clone a repository of interest.\npath \u003c- \"test\"\ngit2r::clone(\"https://github.com/LTLA/libscran\", path)\n\n# Query its dependencies:\nlibrary(fuyuko)\ndeps \u003c- queryAllDependencies(path)\ndeps$dependencies[,1:2]\n##              name                            git.repository\n## 1          aarand            https://github.com/LTLA/aarand\n## 2          aarand            https://github.com/LTLA/aarand\n## 3           Annoy          https://github.com/spotify/Annoy\n## 4          byteme            https://github.com/LTLA/byteme\n## 5           eigen         https://gitlab.com/libeigen/eigen\n## 6      googletest                                      \u003cNA\u003e\n## 7         hnswlib           https://github.com/LTLA/hnswlib\n## 8          igraph                                      \u003cNA\u003e\n## 9           irlba          https://github.com/LTLA/CppIrlba\n## 10         kmeans         https://github.com/LTLA/CppKmeans\n## 11         kmeans         https://github.com/LTLA/CppKmeans\n## 12       knncolle          https://github.com/LTLA/knncolle\n## 13        powerit           https://github.com/LTLA/powerit\n## 14         tatami            https://github.com/LTLA/tatami\n## 15 WeightedLowess https://github.com/LTLA/CppWeightedLowess\n\n# Find conflicts:\nsummarizeConflicts(deps)\n## $name\n## $name$aarand\n##                   git.repository                                  git.tag  url\n## 1 https://github.com/LTLA/aarand 2a8509c499f668bf424306f1aa986da429902c71 \u003cNA\u003e\n## 2 https://github.com/LTLA/aarand afb49e269e02000373c55ccc982a4817be2b9d9d \u003cNA\u003e\n##   url.hash\n## 1     \u003cNA\u003e\n## 2     \u003cNA\u003e\n## \n## $name$kmeans\n##                       git.repository                                  git.tag\n## 10 https://github.com/LTLA/CppKmeans 4397a8d576cf0b657fd9012c049e05727c45796d\n## 11 https://github.com/LTLA/CppKmeans aed1b7ad1c4eddaf80d851fc24fb81333337bf57\n##     url url.hash\n## 10 \u003cNA\u003e     \u003cNA\u003e\n## 11 \u003cNA\u003e     \u003cNA\u003e\n## \n## \n## $git.repository\n## $git.repository$`https://github.com/LTLA/aarand`\n##     name                                  git.tag  url url.hash\n## 1 aarand 2a8509c499f668bf424306f1aa986da429902c71 \u003cNA\u003e     \u003cNA\u003e\n## 2 aarand afb49e269e02000373c55ccc982a4817be2b9d9d \u003cNA\u003e     \u003cNA\u003e\n## \n## $git.repository$`https://github.com/LTLA/CppKmeans`\n##      name                                  git.tag  url url.hash\n## 10 kmeans 4397a8d576cf0b657fd9012c049e05727c45796d \u003cNA\u003e     \u003cNA\u003e\n## 11 kmeans aed1b7ad1c4eddaf80d851fc24fb81333337bf57 \u003cNA\u003e     \u003cNA\u003e\n## \n## \n## $url\n## list()\n```\n\nThis returns a list of the dependency conflicts, defined as dependencies with the same name, Git repository URI or URLs but differences in other properties.\n\n## Inspecting relationships\n\nTo trace the origin of these conflicts, we can inspect the relationships between dependencies.\nFor example, we can see that our `kmeans` conflict is driven by:\n\n```r\ndeps$relationships[deps$relationships$index %in% c(10, 11),]\n##    index parent                  path\n## 22    10     12 extern/CMakeLists.txt\n## 23    11      0 extern/CMakeLists.txt\n```\n\nSo, one is required by the top-level project (i.e., **libscran** itself) while the other is required by `knncolle` (see row 12 in `deps$dependencies`).\nIn both cases, the `FetchContent` call lives inside the `extern/CMakeLists.txt`, which is where I put all my non-test dependencies.\n\nAdvanced users can summarize these relationships in an **igraph** graph via `graphDependencies`.\nThis will also create a pretty color-coded plot that highlights the dependency conflicts.\n\n```r\n(g \u003c- graphDependencies(deps))\n## IGRAPH 54e3d62 DN-- 16 28 --\n## + attr: name (v/c)\n## + edges from 54e3d62 (vertex names):\n##  [1] powerit       -\u003eaarand-1   irlba         -\u003eaarand-2\n##  [3] kmeans-10     -\u003eaarand-2   kmeans-11     -\u003eaarand-2\n##  [5] knncolle      -\u003eAnnoy      tatami        -\u003ebyteme\n##  [7] irlba         -\u003eeigen      aarand-1      -\u003egoogletest\n##  [9] aarand-2      -\u003egoogletest byteme        -\u003egoogletest\n## [11] irlba         -\u003egoogletest kmeans-10     -\u003egoogletest\n## [13] kmeans-11     -\u003egoogletest knncolle      -\u003egoogletest\n## [15] powerit       -\u003egoogletest SOURCE        -\u003egoogletest\n## + ... omitted several edges\n```\n\nWe can then traverse this graph in topological order to determine which projects need to update their pinned versions.\nFor example, if we want to remove the conflicting `aarand-2` and `kmeans-11` from the dependency graph \n(presumably by switching all their `FetchContent` references to `aarand-1` and `kmeans-10`, respectively), \nwe could obtain an update order by examining the subgraph of affected projects:\n\n```r\naffected \u003c- igraph::subcomponent(g, c(\"aarand-2\", \"kmeans-11\"), mode=\"in\")\nsubg \u003c- igraph::subgraph(g, affected)\nigraph::topo_sort(subg, mode=\"in\")\n## + 6/6 vertices, named, from e9f3ab4:\n## [1] aarand-2  irlba     kmeans-10 kmeans-11 knncolle  SOURCE   \n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fltla%2Ffuyuko","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fltla%2Ffuyuko","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fltla%2Ffuyuko/lists"}