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";
38 unless( $ENV{SGN_SHIPWRIGHT_BUILDING
} ) {
40 or die "R dependency check failed, aborting.\n";
44 # override install to just copy the whole dir into the install_base
48 # installation is just copying the entire dist into
51 my $tgt_dir = File
::Spec
->catdir($self->install_base,'sgn');
52 system 'cp', '-rl', '.', $tgt_dir;
55 die "SGN site copy ( cp -rl . $tgt_dir ) failed!\n";
60 shift->SUPER::ACTION_clean
(@_);
61 system "make -C programs clean";
64 die "make -C programs clean failed!\n";
68 sub ACTION_installdeps
{
71 $self->_R_installdeps;
73 $self->SUPER::ACTION_installdeps
( @_ );
76 sub create_build_script
{
80 or warn $self->{R
}{check_output
};
82 return $self->SUPER::create_build_script
(@_);
86 my ( $self, @args ) = @_;
89 my $out = Capture
::Tiny
::capture_merged
{
90 $ret = $self->_run_R_check( @args );
93 $self->{R
}{check_output
} = $out;
94 if( !$ret and my ($missing) = $out =~ /required but not available:\s+(\S(?:[^\n]+\n)+)\n/si ) {
95 $self->{R
}{missing_packages
} = [ split /\s+/, $missing ];
100 return $self->_run_R_check( @args );
107 if( $self->check_R ) {
108 print "All R prerequisites satisfied\n";
112 my @missing_packages = @
{ $self->{R
}{missing_packages
} || [] };
113 unless( @missing_packages ) {
114 print "No missing R packages detected, cannot installdeps for R.\n";
118 my $package_vec = 'c('.join( ',', map qq|"$_"|, @missing_packages ).')';
119 my $cran_mirror = $ENV{CRAN_MIRROR
} || "http://lib.stat.cmu.edu/R/CRAN";
121 my $tf = File
::Temp
->new;
123 userdir <- unlist(strsplit(Sys.getenv("R_LIBS_USER"), .Platform\$path.sep))[1L]
124 if (!file.exists(userdir) && !dir.create(userdir, recursive = TRUE, showWarnings = TRUE))
125 stop("unable to create ", sQuote(userdir))
126 .libPaths(c(userdir, .libPaths()))
127 install.packages( $package_vec, contriburl = contrib.url("$cran_mirror") )
131 # use system so the user will be able to use the R graphical
132 # mirror chooser, and other things
133 system 'R', '--slave', -f
=> "$tf", '--no-save', '--no-restore';
136 warn "Failed to automatically install R dependencies\n";
137 } elsif( $self->check_R ) {
138 print "Successfully installed R dependencies.\n";
143 my ($exit_code) = @_;
144 if ($exit_code == -1) {
145 print "Error: failed to execute: $!\n";
146 } elsif ($exit_code & 127) {
147 warn sprintf("Error: child died with signal %d, %s coredump\n",
148 ($exit_code & 127), ($exit_code & 128) ?
'with' : 'without');
150 warn sprintf("Error: child exited with value %d\n",$exit_code >> 8);
157 print "\nChecking R prerequisites...\n";
159 # check the R version ourself, since R CMD check apparently does
161 $self->_check_R_version
164 my $no_manual = $self->_R_version_current ge version
->new('2.10.0') ?
'--no-manual' : '';
166 my $ret = system "R CMD check $no_manual --no-codoc --no-vignettes -o _build R_files";
169 warn "\nR PREREQUISITE CHECK FAILED.\n\n";
172 print "R prerequisites OK.\n\n";
177 sub _check_R_version
{
181 unless ($HAVE_PARSE_DEB_CONTROL) {
182 warn "Parse::Deb::Control not present, skipping R configuration";
185 my ( $cmp, $v ) = $self->_R_version_required;
187 if( eval '$self->_R_version_current'." $cmp version->parse('$v')" ) {
190 warn "R VERSION CHECK FAILED, we have ".$self->_R_version_current.", but we require $cmp $v.\n";
191 warn "To install R : sudo aptitude install r-base-core\n\n";
196 # parse and return the R DESCRIPTION file
198 return Parse
::Deb
::Control
->new([qw
[ R_files DESCRIPTION
]]);
201 # parse and return the version of R we require as string list like
203 sub _R_version_required
{
205 my @k = $self->_R_desc->get_keys('Depends')
206 or return ( '>=', 0 );
207 my ($version) = ${$k[0]->{value
}} =~ / \b R \s* \( ([^\)]+) /x
208 or return ( '>=', 0 );
210 my @v = split /\s+/, $version;
211 unshift @v, '==' unless @v > 1;
216 # parse and return the current R version as a version object
217 sub _R_version_current
{
218 my $r = `R --version`;
221 $r =~ /R version ([\d\.]+)/;
223 return version
->new($1);