7 my $HAVE_PARSE_DEB_CONTROL;
10 eval { require Parse
::Deb
::Control
};
12 warn "WARNING: Failed to load Parse::Deb::Control, and it is needed to check R dependencies:\n$@\n"
14 $HAVE_PARSE_DEB_CONTROL = !$@
;
18 use base
'Module::Build';
22 eval { require Capture
::Tiny
};
26 # we should probably convert this to autodie at some point
28 # build action just runs make on programs
31 $self->SUPER::ACTION_build
(@_);
32 system "make -C programs";
35 die "make -C programs failed\!n";
39 or die "R dependency check failed, aborting.\n";
42 # override install to just copy the whole dir into the install_base
46 # installation is just copying the entire dist into
49 my $tgt_dir = File
::Spec
->catdir($self->install_base,'sgn');
50 system 'cp', '-rl', '.', $tgt_dir;
53 die "SGN site copy ( cp -rl . $tgt_dir ) failed!\n";
58 shift->SUPER::ACTION_clean
(@_);
59 system "make -C programs clean";
62 die "make -C programs clean failed!\n";
66 sub ACTION_installdeps
{
69 $self->_R_installdeps;
71 $self->SUPER::ACTION_installdeps
( @_ );
74 sub create_build_script
{
78 or warn $self->{R
}{check_output
};
80 return $self->SUPER::create_build_script
(@_);
84 my ( $self, @args ) = @_;
87 my $out = Capture
::Tiny
::capture_merged
{
88 $ret = $self->_run_R_check( @args );
91 $self->{R
}{check_output
} = $out;
92 if( !$ret and my ($missing) = $out =~ /required but not available:\s+(\S(?:[^\n]+\n)+)\n/si ) {
93 $self->{R
}{missing_packages
} = [ split /\s+/, $missing ];
98 return $self->_run_R_check( @args );
105 if( $self->check_R ) {
106 print "All R prerequisites satisfied\n";
110 my @missing_packages = @
{ $self->{R
}{missing_packages
} || [] };
111 unless( @missing_packages ) {
112 print "No missing R packages detected, cannot installdeps for R.\n";
116 my $package_vec = 'c('.join( ',', map qq|"$_"|, @missing_packages ).')';
117 my $cran_mirror = $ENV{CRAN_MIRROR
} || "http://lib.stat.cmu.edu/R/CRAN";
119 my $tf = File
::Temp
->new;
121 userdir <- unlist(strsplit(Sys.getenv("R_LIBS_USER"), .Platform\$path.sep))[1L]
122 if (!file.exists(userdir) && !dir.create(userdir, recursive = TRUE, showWarnings = TRUE))
123 stop("unable to create ", sQuote(userdir))
124 .libPaths(c(userdir, .libPaths()))
125 install.packages( $package_vec, contriburl = contrib.url("$cran_mirror") )
129 # use system so the user will be able to use the R graphical
130 # mirror chooser, and other things
131 system 'R', '--slave', -f
=> "$tf", '--no-save', '--no-restore';
134 warn "Failed to automatically install R dependencies\n";
135 } elsif( $self->check_R ) {
136 print "Successfully installed R dependencies.\n";
141 my ($exit_code) = @_;
142 if ($exit_code == -1) {
143 print "Error: failed to execute: $!\n";
144 } elsif ($exit_code & 127) {
145 warn sprintf("Error: child died with signal %d, %s coredump\n",
146 ($exit_code & 127), ($exit_code & 128) ?
'with' : 'without');
148 warn sprintf("Error: child exited with value %d\n",$exit_code >> 8);
155 print "\nChecking R prerequisites...\n";
157 # check the R version ourself, since R CMD check apparently does
159 $self->_check_R_version
162 my $no_manual = $self->_R_version_current ge version
->new('2.10.0') ?
'--no-manual' : '';
164 my $ret = system "R CMD check $no_manual --no-codoc --no-vignettes -o _build R_files";
167 warn "\nR PREREQUISITE CHECK FAILED.\n\n";
170 print "R prerequisites OK.\n\n";
175 sub _check_R_version
{
179 unless ($HAVE_PARSE_DEB_CONTROL) {
180 warn "Parse::Deb::Control not present, skipping R configuration";
183 my ( $cmp, $v ) = $self->_R_version_required;
185 if( eval '$self->_R_version_current'." $cmp version->parse('$v')" ) {
188 warn "R VERSION CHECK FAILED, we have ".$self->_R_version_current.", but we require $cmp $v.\n";
189 warn "To install R : sudo aptitude install r-base-core\n\n";
194 # parse and return the R DESCRIPTION file
196 return Parse
::Deb
::Control
->new([qw
[ R_files DESCRIPTION
]]);
199 # parse and return the version of R we require as string list like
201 sub _R_version_required
{
203 my @k = $self->_R_desc->get_keys('Depends')
204 or return ( '>=', 0 );
205 my ($version) = ${$k[0]->{value
}} =~ / \b R \s* \( ([^\)]+) /x
206 or return ( '>=', 0 );
208 my @v = split /\s+/, $version;
209 unshift @v, '==' unless @v > 1;
214 # parse and return the current R version as a version object
215 sub _R_version_current
{
216 my $r = `R --version`;
219 $r =~ /R version ([\d\.]+)/;
221 return version
->new($1);