Skip to content

Commit

Permalink
move checks of src dirs before installation.
Browse files Browse the repository at this point in the history
new option --check-subdirs for 'check'
more documentation


git-svn-id: https://svn.r-project.org/R/trunk@37232 00db46b3-68df-0310-9c12-caf00c1e9a41
  • Loading branch information
ripley committed Feb 1, 2006
1 parent 1dab76f commit 120e9c6
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 58 deletions.
6 changes: 4 additions & 2 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -477,12 +477,14 @@ UTILITIES
are now in exactly the same format.

o The base name of a help file needs to be valid as part of a file://
URL, do R CMD check now checks the names are ASCII and do not
URL, so R CMD check now checks the names are ASCII and do not
contain % .

o R CMD check now warns about unknown sections in Rd files, and
invalid names for help, demo and R files, as well as unlikely
file names in the 'src' directory.
file names in the 'src' directory. The latter is controlled
by option --check-subdirs and by default is done if checking a
tarball without a configure script.

R CMD build excludes invalid files in the 'man', 'R' and 'demo'
subdirectories.
Expand Down
84 changes: 53 additions & 31 deletions doc/manual/R-exts.texi
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,8 @@ facilities available as from @R{} 2.0.0 they should be removed if possible.
@subsection Package subdirectories
@cindex Package subdirectories

The @file{R} subdirectory contains @R{} code files. The code files to
be installed must start with a (lower or upper case) letter or
The @file{R} subdirectory contains @R{} code files, only. The code
files to be installed must start with a (lower or upper case) letter or
digit@footnote{This is enforced as from @R{} 2.3.0.} and have one of the
extensions @file{.R}, @file{.S}, @file{.q}, @file{.r}, or @file{.s}. We
recommend using @file{.R}, as this extension seems to be not used by any
Expand Down Expand Up @@ -486,40 +486,46 @@ packages and rare to have a @code{.Last.lib} function: one use is to
call @code{library.dynam.unload} to unload compiled code.


The @file{man} subdirectory should contain documentation files for the
objects in the package in @dfn{R documentation} (Rd) format. The
documentation files to be installed must also start with a (lower or
upper case ASCII) letter or digit@footnote{This is enforced as from
@R{} 2.3.0.} and have the extension @file{.Rd} (the default) or
@file{.rd}. @xref{Writing R documentation files}, for more information.
Note that all user-level objects in a package should be documented; if a
package @var{pkg} contains user-level objects which are for ``internal''
use only, it should provide a file @file{@var{pkg}-internal.Rd} which
documents all such objects, and clearly states that these are not meant
to be called by the user. See e.g.@: the sources for package @pkg{grid}
in the @R{} distribution for an example.
The @file{man} subdirectory should contain (only) documentation files
for the objects in the package in @dfn{R documentation} (Rd) format.
The documentation files to be installed must start with a (lower or
upper case ASCII) letter or digit@footnote{This is enforced as from @R{}
2.3.0.} and have the extension @file{.Rd} (the default) or @file{.rd}.
Further, the names must be valid in @samp{file://} URLs, which
means@footnote{More precisely, they can contain the English alphanumeric
characters and the symbols @samp{$ - _ . + ! ' ( ) , ; @ = &}.}
they must be entirely ASCII and not contain @samp{%}. @xref{Writing R
documentation files}, for more information. Note that all user-level
objects in a package should be documented; if a package @var{pkg}
contains user-level objects which are for ``internal'' use only, it
should provide a file @file{@var{pkg}-internal.Rd} which documents all
such objects, and clearly states that these are not meant to be called
by the user. See e.g.@: the sources for package @pkg{grid} in the @R{}
distribution for an example.

The @file{R} and @file{man} subdirectories may contain OS-specific
subdirectories named @file{unix} or @file{windows}.

The C, C++, or FORTRAN@footnote{Note that Ratfor is not supported. If
you have Ratfor source code, you need to convert it to FORTRAN. Only
FORTRAN-77 is supported on all platforms, but some also support
FORTRAN-95.} source files for the compiled code are in @file{src}, plus
optionally file @file{Makevars} or @file{Makefile}. When a package is
installed using @code{R CMD INSTALL}, Make is used to control
compilation and linking into a shared object for loading into @R{}.
There are default variables and rules for this (determined when @R{} is
configured and recorded in @file{@var{R_HOME}/etc/Makeconf}). These
rules can be tweaked by setting macros in a file @file{src/Makevars}
(@pxref{Using Makevars}). Note that this mechanism should be general
enough to eliminate the need for a package-specific @file{Makefile}. If
such a file is to be distributed, considerable care is needed to make it
general enough to work on all @R{} platforms. In addition, it should
have a target @samp{clean} which removes all files generated by Make.
If necessary, platform-specific files can be used, for example
@file{Makevars.win} or @file{Makefile.win} on Windows take precedence
over @file{Makevars} or @file{Makefile}.
FORTRAN-95. If you want to ship Ratfor source files, please do so in a
subdirectory of @file{src} and not in the main subdirectory.} source
files for the compiled code are in @file{src}, plus optionally file
@file{Makevars} or @file{Makefile}. When a package is installed using
@code{R CMD INSTALL}, Make is used to control compilation and linking
into a shared object for loading into @R{}. There are default variables
and rules for this (determined when @R{} is configured and recorded in
@file{@var{R_HOME}/etc/Makeconf}). These rules can be tweaked by
setting macros in a file @file{src/Makevars} (@pxref{Using Makevars}).
Note that this mechanism should be general enough to eliminate the need
for a package-specific @file{Makefile}. If such a file is to be
distributed, considerable care is needed to make it general enough to
work on all @R{} platforms. In addition, it should have a target
@samp{clean} which removes all files generated by Make. If necessary,
platform-specific files can be used, for example @file{Makevars.win} or
@file{Makefile.win} on Windows take precedence over @file{Makevars} or
@file{Makefile}.

The @file{data} subdirectory is for additional data files the package
makes available for loading using @code{data()}. Currently, data files
Expand Down Expand Up @@ -1072,7 +1078,17 @@ checked for completeness.

@item
The package subdirectories are checked for suitable file names and for
not being empty.
not being empty. The checks on file names are controlled by the option
@option{--check-subdirs=@var{value}}. This defaults to @samp{default},
which runs the checks only if checking a tarball and the package/bundle
does not contain a @file{configure} script: the default can be
overridden by specifying the value as @samp{yes} or
@samp{no}.@footnote{Another value which can be useful in test suites is
@samp{yes-maybe}, which runs the tests unless there is a
@file{configure} script, that is as if the sources were a tarball.}

To allow for a @file{configure} script to generate suitable files, files
ending in @samp{.in} will be allowed in the @file{R} directory.

@item
The R files are checked for syntax errors.
Expand Down Expand Up @@ -1167,7 +1183,10 @@ matched against the file names relative to the top-level source
directory. In addition, directories called @file{CVS} or @file{.svn} or
@file{.arch-ids} and files @file{GNUMakefile} or with base names
starting with @samp{.#}, or starting and ending with @samp{#}, or ending
in @samp{~}, @samp{.bak} or @samp{.swp}, are excluded by default.
in @samp{~}, @samp{.bak} or @samp{.swp}, are excluded by default. In
addition, those files in the @file{R} and @file{man} directories which
are flagged by @code{R CMD check} as having invalid names will be
excluded.

@c <FIXME>
@c From 1.8.0 on, the build code removes exclude files itself, rather
Expand All @@ -1191,6 +1210,9 @@ One of the checks that @code{R CMD build} runs is for empty source
directories. These are in most cases unintentional, in which case they
should be removed and the build re-run.

It can be useful to run @code{R CMD check --check-subdirs=yes} on the
built tarball as a final check on the contents.

@code{R CMD build} can also build pre-compiled version of packages for
binary distributions, but @code{R CMD INSTALL --build} is preferred (and
is considerably more flexible). In particular, Windows users are
Expand Down
78 changes: 53 additions & 25 deletions src/scripts/check.in
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,19 @@ my $opt_use_valgrind = 0;
my $opt_rcfile = ""; # Only set this if $ENV{"HOME"} is set.
$opt_rcfile = &file_path($ENV{"HOME"}, ".R", "check.conf")
if defined($ENV{"HOME"});
my $opt_subdirs;

my $WINDOWS = ($R::Vars::OSTYPE eq "windows");

R::Vars::error("R_HOME", "R_EXE");

my @known_options = ("help|h", "version|v", "outdir|o:s", "library|l:s",
"no-clean", "no-examples", "no-tests", "no-latex",
"use-gct" => \$opt_use_gct, "no-codoc",
"install=s" => \$opt_install, "no-install",
"no-clean", "no-examples", "no-tests", "no-latex",
"use-gct" => \$opt_use_gct, "no-codoc",
"install=s" => \$opt_install, "no-install",
"no-vignettes", "use-valgrind" => \$opt_use_valgrind,
"rcfile=s" => \$opt_rcfile);
"rcfile=s" => \$opt_rcfile,
"check-subdirs=s" => \$opt_subdirs);
GetOptions(@known_options) or usage();

R_version("R add-on package checker", $version) if $opt_version;
Expand All @@ -80,6 +82,7 @@ $opt_latex = 0 if $opt_no_latex;
$opt_codoc = 0 if $opt_no_codoc;
$opt_install = 0 if $opt_no_install;
$opt_vignettes = 0 if $opt_no_vignettes;
$opt_subdirs = "default" if $opt_subdirs eq "";

if($opt_install eq "fake") {
## If we fake installation, then we cannot *run* any code.
Expand Down Expand Up @@ -198,13 +201,17 @@ foreach my $pkg (@ARGV) {
$pkg =~ s+/$++; # strip any trailing '/'
my $pkgname = basename($pkg);

my $thispkg_subdirs = $opt_subdirs;
## is this a tar archive?
my $istar = 0;
if($pkgname =~ /\.tar\.gz$/ || $pkgname =~ /\.tgz$/) {
$pkgname =~ s/\.tar\.gz$//;
$pkgname =~ s/\.tgz$//;
$pkgname =~ s/_[0-9\.-]*$//;
$istar = 1;
$thispkg_subdirs = "yes-maybe" if $thispkg_subdirs eq "default";
} else {
$thispkg_subdirs = "no" if $thispkg_subdirs eq "default";
}

my $pkgoutdir = &file_path($outdir, "$pkgname.Rcheck");
Expand Down Expand Up @@ -234,6 +241,10 @@ foreach my $pkg (@ARGV) {
or die "Error: cannot change to directory '$pkg'\n";
my $pkgdir = R_cwd();
## my $pkgname = basename($pkgdir);
if($thispkg_subdirs eq "yes-maybe") {
## now see if there is a 'configure' file
$thispkg_subdirs = "no" if (-f "configure");
}
chdir($startdir);

$log = new R::Logfile(&file_path($pkgoutdir, "00check.log"));
Expand Down Expand Up @@ -322,9 +333,9 @@ foreach my $pkg (@ARGV) {
my $any;
my $pat = "(a|o|[ls][ao]|sl|obj)"; # Object file extensions.
my @dirs;
if($in_bundle) {
if($is_bundle) {
foreach my $ppkg (split(/\s+/,
description->{"Contains"})) {
$description->{"Contains"})) {
push(@dirs, &file_path($ppkg, "src"));
}
}
Expand All @@ -342,6 +353,33 @@ foreach my $pkg (@ARGV) {
"contains object files.\n");
}
}

if($thispkg_subdirs ne "no") {
foreach my $dir (@dirs) {
if((-d &file_path($pkgdir, $dir))) {
chdir(&file_path($pkgdir, $dir));
if(!(-f "Makefile") && !(-f "Makefile.win")) {
opendir(DIR, ".") or die "cannot opendir $dir: $!";
@srcfiles = grep {
!(/\.([Ccfh]|cc|cpp|f90|f95)$/
|| /^Makevars/ || /-win\.def$/ )
&& -f "$_" } readdir(DIR);
closedir(DIR);
if(@srcfiles) {
$log->warning() unless $any;
$any++;
$log->print("Subdirectory '$dir' contains:\n");
$log->print(wrap(" ", " ",
join(" ", sort @srcfiles) . "\n"));
$log->print(wrap("", "",
("These are unlikely file names",
"for src files.\n")));
}
}
chdir($startdir);
}
}
}
$log->result("OK") unless $any;
}
else {
Expand Down Expand Up @@ -539,7 +577,8 @@ foreach my $pkg (@ARGV) {
else {
chdir($startdir);
check_pkg($pkgdir, $pkgoutdir, $startdir, $library,
$is_bundle, $description, $log, $is_base_pkg);
$is_bundle, $description, $log, $is_base_pkg,
$thispkg_subdirs);
}

if($log->{"warnings"}) {
Expand All @@ -554,7 +593,7 @@ foreach my $pkg (@ARGV) {
sub check_pkg {

my ($pkg, $pkgoutdir, $startdir, $library,
$in_bundle, $description, $log, $is_base_pkg) = @_;
$in_bundle, $description, $log, $is_base_pkg, $subdirs) = @_;
my ($pkgdir, $pkgname);

## $pkg is the argument we received from the main loop.
Expand Down Expand Up @@ -887,6 +926,8 @@ sub check_pkg {
$log->print(wrap("", "",
("These files are deprecated.",
"See manual 'Writing R Extensions'.\n")));
} else {
$log->result("OK");
}

## Check index information.
Expand Down Expand Up @@ -982,7 +1023,7 @@ sub check_pkg {
"in manual 'Writing R Extensions'.\n")));
}
}
&check_subdirs(".");
&check_subdirs(".") unless ($subdirs eq "no");
if((-d "data") || (-d "demo") || (-d "src") || (-d "inst")) {
## Subdirectory 'data' without data sets?
if((-d "data") && !&list_files_with_type("data", "data")) {
Expand All @@ -1008,22 +1049,6 @@ sub check_pkg {
$any++;
$log->print("Subdirectory 'src' contains no source files.\n");
}
## We might have installed from this src directory,
## so it may be dirty. Hence the long list of allowed things.
## Shipping .def files is an error unless it is a -win.def file
opendir(DIR, "src") or die "cannot opendir src: $!";
@srcfiles = grep { !(/\.([Ccfh]|cc|cpp|f90|f95|in|d|o|so|a|sl|dylib|dll|rc)(~|\.~[0-9]+~)?$/ || /^Make/ || /-win\.def$/ )
&& -f "src/$_" } readdir(DIR);
closedir(DIR);
if(@srcfiles) {
$log->warning() unless $any;
$any++;
$log->print("Subdirectory 'src' contains suspect file names:\n");
$log->print(" " . join("\n ", @srcfiles) . "\n");
$log->print(wrap("", "",
("These are unlikely file names",
"for src files.\n")));
}
}
## Do subdirectories of 'inst' interfere with R package system
## subdirectories?
Expand Down Expand Up @@ -1977,6 +2002,9 @@ Options:
--no-latex do not run LaTeX on help files
--use-gct use 'gctorture(TRUE)' when running examples/tests
--use-valgrind use 'valgrind' when running examples/tests/vignettes
--check-subdirs=default|yes|no
run checks on the package subdirectories
(default is yes for a tarball, no otherwise)
--rcfile=FILE read configuration values from FILE
By default, all test sections are turned on.
Expand Down

0 comments on commit 120e9c6

Please sign in to comment.