{"id":14066210,"url":"https://github.com/robertdj/cranitor","last_synced_at":"2025-03-29T07:12:15.727Z","repository":{"id":53616937,"uuid":"235429115","full_name":"robertdj/cranitor","owner":"robertdj","description":"Janitor for a CRAN","archived":false,"fork":false,"pushed_at":"2021-03-20T15:22:35.000Z","size":127,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-03T20:12:51.476Z","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":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robertdj.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":"2020-01-21T19:53:27.000Z","updated_at":"2024-06-11T15:21:24.000Z","dependencies_parsed_at":"2022-08-25T18:41:34.064Z","dependency_job_id":null,"html_url":"https://github.com/robertdj/cranitor","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertdj%2Fcranitor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertdj%2Fcranitor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertdj%2Fcranitor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertdj%2Fcranitor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robertdj","download_url":"https://codeload.github.com/robertdj/cranitor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246150454,"owners_count":20731419,"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-08-13T07:04:59.411Z","updated_at":"2025-03-29T07:12:15.694Z","avatar_url":"https://github.com/robertdj.png","language":"R","funding_links":[],"categories":["R"],"sub_categories":[],"readme":"cranitor\n========\n\n\u003c!-- badges: start --\u003e\n[![R build status](https://github.com/robertdj/cranitor/workflows/R-CMD-check/badge.svg)](https://github.com/robertdj/cranitor/actions)\n\u003c!-- badges: end --\u003e\n\n\n# Overview\n\nA CRAN is nothing but compressed versions of package files (in `tar.gz` or `zip` format) in a certain folder structure and with a few metadata files.\n\nThe {cranitor} package helps to organize a CRAN from creating it in the first place to updating it with new packages.\nThe goal is to have a CRAN that works with the built-in `install.packages` and `install_version` from the [remotes package](https://github.com/r-lib/remotes).\n\nNote that in order to make CRAN accessible it should be served over HTTP. \nThe {cranitor} package does not provide hosting -- this should be done using other tools.\nIf you want to try out {cranitor}, the tests show how to use the [servr package](https://github.com/yihui/servr) to perform the hosting.\n\nMy usecase for {cranitor} is to maintain a CRAN for internally developed packages. \nAs part of our continuous integration pipelines new versions of a package are first compressed/compiled and then imported into our CRAN using {cranitor}.\n\n\n# Installation\n\n{cranitor} is currently only available on GitHub and can be installed using e.g. the remotes package:\n\n```\nremotes::install_github(\"robertdj/cranitor\")\n```\n\nI have no experience trying to publish a package to CRAN, but let me know if I should try :-)\n\n\n# Usage\n\nTo create/update a local CRAN with a new package file the `update_cran` function is available:\n\n```\ncranitor::update_cran(package_file, cran_root)\n```\n\nThe `package_file` can be `tar.gz` file (with the source of a package) or a `zip` file (a binary version of package suitable for Windows).\n{cranitor} figures out where the `package_file` should go in the CRAN and updates metadata.\n\nA demo CRAN can be made that create and import a few \"empty packages\":\n\n```\ncran_root \u003c- cranitor::make_demo_cran()\n```\n\nThe empty packages are created with `create_empty_package`.\n\nAlternatively, a vector of filenames with paths to package files can be supplied to `make_demo_cran`.\nPackage files can be made from a project with `devtools::build` or downloaded from another CRAN.\n\nIf a CRAN is a mess (I have typically seen unwanted files scattered in different folders), the function `clean_cran` can help out by deleting unexpected files.\n\n\n# Binary Linux packages\n\nAs of version 0.3.0 {cranitor} supports binary Linux packages -- that is, R packages that does not require compilation on the user's computer.\nThe approach is inspired by (the demo videos I have seen of) [RStudio's Package Manager](https://rstudio.com/products/package-manager), where each Linux distribution and version of R has a dedicated folder with binary packages.\n\nThe format of a binary Linux package is still `tar.gz` like for source packages.\nIt is *not* possible to infer which Linux distribution compiled the package, since all Linux distributions are collectively referred to as \"unix\" in the metadata.\nTherefore, the `update_cran` function needs a `distro` argument for binary Linux packages.\n\n\n# CRAN Content\n\nWith R 4.0.x on Windows the content of `cran_root` looks like this:\n\n```\n\u003e cran_root \u003c- cranitor::make_demo_cran(cran_root = fs::path_temp(\"cran\"), binary = TRUE)\n\u003e fs::dir_tree(cran_root)\n+-- bin\n|   \\-- windows\n|       \\-- contrib\n|           \\-- 4.0\n|               +-- bar_0.0.1.zip\n|               +-- foo_0.0.2.zip\n|               +-- PACKAGES\n|               +-- PACKAGES.gz\n|               \\-- PACKAGES.rds\n\\-- src\n    \\-- contrib\n        +-- Archive\n        |   \\-- foo\n        |       \\-- foo_0.0.1.tar.gz\n        +-- bar_0.0.1.tar.gz\n        +-- foo_0.0.2.tar.gz\n        +-- Meta\n        |   \\-- archive.rds\n        +-- PACKAGES\n        +-- PACKAGES.gz\n        \\-- PACKAGES.rds\n```\n\nWith R 4.0.2 on Ubuntu 20.04 the content of `cran_root` looks like this (the value of the `distro` argument is an example):\n\n```\n\u003e cran_root \u003c- cranitor::make_demo_cran(cran_root = fs::path_temp(\"cran\"), binary = TRUE, distro = \"ubuntu/focal\")\n\u003e fs::dir_tree(cran_root)\n├── __linux__\n│   └── ubuntu\n│       └── focal\n│           └── 4.0.2\n│               └── src\n│                   └── contrib\n│                       ├── PACKAGES\n│                       ├── PACKAGES.gz\n│                       ├── PACKAGES.rds\n│                       ├── bar_0.0.1.tar.gz\n│                       └── foo_0.0.2.tar.gz\n└── src\n    └── contrib\n        ├── Archive\n        │   └── foo\n        │       └── foo_0.0.1.tar.gz\n        ├── Meta\n        │   └── archive.rds\n        ├── PACKAGES\n        ├── PACKAGES.gz\n        ├── PACKAGES.rds\n        ├── bar_0.0.1.tar.gz\n        └── foo_0.0.2.tar.gz\n```\n\nIn this example the URL for the binary Linux packages should be `\u003cCRAN URL\u003e/__linux__/ubuntu/focal/4.0.2`.\nWhen packages are downloaded to **the same Linux distribution** R figures out that the packages are already compiled.\n\nWhen making a binary package on Linux the filename typically includes information about the architecture, such as `foo_0.0.1_R_x86_64-pc-linux-gnu.tar.gz`.\nHowever, R on Linux expects package names to be of the form `\u003cname\u003e_\u003cversion\u003e.tar.gz`, so everything else is stripped when importing the package.\n\n\n# macOS\n\nUnfortunately, I don't have access to a contemporary Mac, making it very difficult to debug on this platform.\nAs a consequence, there is no support for `tgz` files (a binary version suitable for macOS).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertdj%2Fcranitor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobertdj%2Fcranitor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertdj%2Fcranitor/lists"}