-
Notifications
You must be signed in to change notification settings - Fork 10
/
z-advanced-topic-handling-packages-with-remote-dependencies.Rmd
198 lines (163 loc) · 6.46 KB
/
z-advanced-topic-handling-packages-with-remote-dependencies.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
---
title: "z - Advanced topic: Handling packages with remote dependencies"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{z-advanced-topic-handling-packages-with-remote-dependencies}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
```{r, include=FALSE}
library(rix)
```
## Introduction
Packages published on CRAN must have their dependencies on either CRAN or
Bioconductor, but not on GitHub. However, there are many packages available on
GitHub that never get published on CRAN, and some of these packages may even
depend on other packages that are also only available on GitHub. `{rix}` makes
it possible to install packages from GitHub, but in case one of the package's
dependencies has also only been released on GitHub, building the Nix environment
will fail. This is because Nix will be looking for these packages on `nixpkgs`,
but only packages released on CRAN and Bioconductor are available through
`nixpkgs`. This vignette explains how to install such a packages that have
dependencies only available on GitHub.
## The {lookup} package
As an example we are going to use the
[{lookup}](https://github.com/jimhester/lookup) package which has only been
released on GitHub. [Here is the
repository](https://github.com/jimhester/lookup). This package comes with the
`lookup()` function which makes it possible to check the source code of any
function from a loaded package, even if the source of that function is in C or
Fortran. To create a reproducible development environment that makes
[{lookup}](https://github.com/jimhester/lookup) available to you, you could use
the following `rix::rix()` call:
```{r parsermd-chunk-1}
path_default_nix <- tempdir()
rix(r_ver = "latest",
r_pkgs = NULL,
system_pkgs = NULL,
git_pkgs = list(package_name = "lookup",
repo_url = "https://github.com/jimhester/lookup/",
branch_name = "master",
commit = "eba63db477dd2f20153b75e2949eb333a36cccfc"),
ide = "other",
project_path = path_default_nix,
overwrite = TRUE,
print = TRUE)
```
Trying to build this environment will fail with following error message:
```
error: attribute 'highlite' missing
```
## Building remote dependencies
`{highlite}` is a dependency of [{lookup}](https://github.com/jimhester/lookup)
that is only available on GitHub. This can be checked by looking at the
`DESCRIPTION` file of [{lookup}](https://github.com/jimhester/lookup):
```
Remotes:
jimhester/highlite,
gaborcsardi/gh,
hadley/memoise
```
We see that there are actually three packages that come from GitHub: but `{gh}`
and `{memoise}` have in the meantime been released on CRAN, which means that
they are also available through `nixpkgs`. We have to deal with `{highlite}`
however, because it never got released on CRAN. Doing so is fairly easy: first,
create a new expression using `{rix}` to install `{highlite}`:
```
rix(r_ver = "latest",
r_pkgs = NULL,
system_pkgs = NULL,
git_pkgs = list(package_name = "highlite",
repo_url = "https://github.com/jimhester/highlite/",
branch_name = "master",
commit = "767b122ef47a60a01e1707e4093cf3635a99c86b"),
ide = "other",
project_path = path_default_nix,
overwrite = FALSE,
print = TRUE)
```
(you don't need to overwrite the previous expression, simply printing this
one on screen will do). Copy the following lines:
```
git_archive_pkgs = [(pkgs.rPackages.buildRPackage {
name = "highlite";
src = pkgs.fetchgit {
url = "https://github.com/jimhester/highlite/";
branchName = "master";
rev = "767b122ef47a60a01e1707e4093cf3635a99c86b";
sha256 = "sha256-lkWMlAi75MYxiBUYnLwxLK9ApXkWanA4Mt7g4qtLpxM=";
};
propagatedBuildInputs = builtins.attrValues {
inherit (pkgs.rPackages) Rcpp BH;
};
}) ];
```
into the previous expression (and change `git_archive_pkgs` into `highlite`).
The file should look like this now:
```
let
pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/b200e0df08f80c32974a6108ce431d8a8a5e6547.tar.gz") {};
highlite = [(pkgs.rPackages.buildRPackage {
name = "highlite";
src = pkgs.fetchgit {
url = "https://github.com/jimhester/highlite/";
branchName = "master";
rev = "767b122ef47a60a01e1707e4093cf3635a99c86b";
sha256 = "sha256-lkWMlAi75MYxiBUYnLwxLK9ApXkWanA4Mt7g4qtLpxM=";
};
propagatedBuildInputs = builtins.attrValues {
inherit (pkgs.rPackages) Rcpp BH;
};
}) ];
git_archive_pkgs = [(pkgs.rPackages.buildRPackage {
name = "lookup";
src = pkgs.fetchgit {
url = "https://github.com/jimhester/lookup/";
branchName = "master";
rev = "eba63db477dd2f20153b75e2949eb333a36cccfc";
sha256 = "sha256-arl7LVxL8xGUW3LhuDCSUjcfswX0rdofL/7v8Klw8FM=";
};
propagatedBuildInputs = builtins.attrValues {
inherit (pkgs.rPackages) gh memoise Rcpp codetools crayon rex highlite jsonlite rstudioapi withr httr;
};
}) ];
system_packages = builtins.attrValues {
inherit (pkgs) R ;
};
in
pkgs.mkShell {
buildInputs = [ git_archive_pkgs system_packages ];
shellHook = ''
R --vanilla
'';
}
```
The only thing that we need to change is this line:
```
propagatedBuildInputs = builtins.attrValues {
inherit (pkgs.rPackages) gh memoise Rcpp codetools crayon rex highlite jsonlite rstudioapi withr httr;
};
```
into:
```
propagatedBuildInputs = builtins.attrValues {
inherit (pkgs.rPackages) gh memoise Rcpp codetools crayon rex jsonlite rstudioapi withr httr;
} ++ [highlite];
```
Building the expression now succeeds.
We know that this is quite tedious, but at the moment there are no plans to make
`{rix}` handle remote dependencies automatically. This is for mainly three
reasons:
- packages with remote dependencies are rare, and never on CRAN on Bioconductor;
- packages may have remote dependencies, but these dependencies may later be available on CRAN (such as with `{memoise}` and `{gh}` for [{lookup}](https://github.com/jimhester/lookup));
- `{rix}` cannot decide for the user which commit to use for a remote dependency (or whether to use the released version of that dependency from CRAN).
Because of these reasons, we believe that it is safer for users that really need
to use such packages to manually edit their Nix expressions. Don't hesitate to
[open an issue](https://github.com/b-rodrigues/rix/issues) if you require
assistance.