[med-svn] [r-cran-globals] 01/01: New upstream version 0.7.0

Michael Crusoe misterc-guest at moszumanska.debian.org
Mon Sep 19 09:54:48 UTC 2016


This is an automated email from the git hooks/post-receive script.

misterc-guest pushed a commit to annotated tag upstream/0.7.0
in repository r-cran-globals.

commit 07c7275451aa192c68b533b366f92554f8090714
Author: Michael R. Crusoe <michael.crusoe at gmail.com>
Date:   Sun Sep 18 06:28:18 2016 -0700

    New upstream version 0.7.0
---
 .Rbuildignore          |  53 ++++++
 .Rinstignore           |   5 +
 .covr.R                |  26 +++
 .gitignore             |   9 +
 .make/Makefile         | 475 +++++++++++++++++++++++++++++++++++++++++++++++++
 .travis.yml            |  38 ++++
 DESCRIPTION            |  14 +-
 MD5                    |  19 --
 Makefile               |   1 +
 NAMESPACE              |   6 +
 NEWS                   |   8 +
 R/Globals-class.R      | 141 ++++++++++++++-
 R/cleanup.R            |   9 +-
 R/globalsOf.R          |  45 ++++-
 R/utils.R              |   4 +-
 R/walkAST.R            |  57 ++++++
 README.md              |  17 +-
 appveyor.yml           |  65 +++++++
 cran-comments.md       |  54 ++++++
 incl/globalsOf.R       |  10 ++
 man/Globals.Rd         |   1 +
 man/cleanup.Globals.Rd |   2 +-
 man/globalsByName.Rd   |  26 +++
 man/walkAST.Rd         |  31 ++++
 revdep/README.md       | 384 +++++++++++++++++++++++++++++++++++++++
 revdep/check.R         |  20 +++
 revdep/checks.rds      | Bin 0 -> 8337 bytes
 revdep/problems.md     |  24 +++
 tests/Globals.R        | 250 ++++++++++++++++++++++++++
 tests/globalsOf.R      |  73 ++++++--
 tests/utils.R          |  28 ++-
 tests/walkAST.R        |  88 +++++++++
 tests/zzz.R            |   1 +
 33 files changed, 1927 insertions(+), 57 deletions(-)

diff --git a/.Rbuildignore b/.Rbuildignore
new file mode 100644
index 0000000..0a8e4b4
--- /dev/null
+++ b/.Rbuildignore
@@ -0,0 +1,53 @@
+#----------------------------
+# Git and SVN related
+#----------------------------
+^.svn
+^.git
+^.make
+INSTALL[.]md
+OVERVIEW[.]md
+README[.]md
+CONDUCT[.]md
+
+#----------------------------
+# devtools
+#----------------------------
+^revdep
+
+#----------------------------
+# Travis-CI et al.
+#----------------------------
+^[.]travis[.]yml$
+^travis-tool[.]sh$
+^pkg-build[.]sh$
+^appveyor[.]yml$
+^covr-utils.R$
+^[.]covr[.]R$
+^[.]covr[.]rds$
+
+#----------------------------
+# R related
+#----------------------------
+Rplots.pdf$
+^cran-comments[.].*$
+^vignettes/.*[.](pdf|PDF)$
+^vignettes/.*[.](r|R)$
+^vignettes/[.]install_extras$
+^Makefile$
+^incl
+^NAMESPACE,.*[.]txt$
+^nohup.*$
+^[.]R
+^[.]benchmark
+^[.]devel
+^[.]test
+^[.]check
+^.*[.]tar[.]gz$
+
+#----------------------------
+# Package specific
+#----------------------------
+^[.]BatchJobs[.]R$
+[.]future
+
+
diff --git a/.Rinstignore b/.Rinstignore
new file mode 100644
index 0000000..da2aee9
--- /dev/null
+++ b/.Rinstignore
@@ -0,0 +1,5 @@
+# Certain LaTeX files (e.g. bib, bst, sty) must be part of the build 
+# such that they are available for R CMD check.  These are excluded
+# from the install using .Rinstignore in the top-level directory
+# such as this one.
+doc/.*[.](bib|bst|sty)$
diff --git a/.covr.R b/.covr.R
new file mode 100644
index 0000000..0025697
--- /dev/null
+++ b/.covr.R
@@ -0,0 +1,26 @@
+#################################################################
+# Test coverage
+#
+# * covr-utils: https://github.com/HenrikBengtsson/covr-utils
+# * covr: https://github.com/jimhester/covr
+# * Coveralls: https://coveralls.io/
+#
+# Henrik Bengtsson
+#################################################################
+if (!file_test("-f", "covr-utils.R")) {
+  source("http://callr.org/install#R.utils[u]")
+  R.utils::downloadFile("https://raw.githubusercontent.com/HenrikBengtsson/covr-utils/master/covr-utils.R")
+}
+
+source("covr-utils.R")
+
+# Exclusion rules
+excl <- exclusions(
+  filter(r_files(), covr_lines), # Apply 'covr:' rules in source code
+  filter(r_files(), stop_lines)  # Skip lines with stop().
+)
+str(excl)
+
+# Run through tests, record source code coverage, and
+# publish to Coveralls
+covr <- covr_package(exclusions=excl, quiet=FALSE)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7b94b5b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+.Rhistory
+*~
+**/*~
+.check
+.test
+.o
+.dll
+.async
+
diff --git a/.make/Makefile b/.make/Makefile
new file mode 100644
index 0000000..ce331ea
--- /dev/null
+++ b/.make/Makefile
@@ -0,0 +1,475 @@
+# Makefile for R packages
+
+# CORE MACROS
+ifeq ($(OS), Windows_NT)
+CD=cd
+CURDIR=$(subst \,/,$(shell cmd.exe /C cd))
+FSEP=;
+else
+CD=cd -P "$(CURDIR)"; cd   # This handles the case when CURDIR is a softlink
+FSEP=:
+endif
+CP=cp
+MAKE=make
+MV=mv
+RM=rm -f
+MKDIR=mkdir -p
+RMDIR=$(RM) -r
+GIT=git
+
+# PACKAGE MACROS
+PKG_VERSION := $(shell grep -i ^version DESCRIPTION | cut -d : -d \  -f 2)
+PKG_NAME    := $(shell grep -i ^package DESCRIPTION | cut -d : -d \  -f 2)
+PKG_DIR     := $(shell basename "$(CURDIR)")
+PKG_DIR     := $(CURDIR)
+PKG_TARBALL := $(PKG_NAME)_$(PKG_VERSION).tar.gz
+PKG_ZIP     := $(PKG_NAME)_$(PKG_VERSION).zip
+PKG_TGZ     := $(PKG_NAME)_$(PKG_VERSION).tgz
+
+# FILE MACROS
+FILES_R := $(wildcard R/*.R)
+FILES_DATA := $(wildcard data/*)
+FILES_MAN := $(wildcard man/*.Rd)
+FILES_INCL := $(wildcard incl/*)
+FILES_INST := $(wildcard inst/* inst/*/* inst/*/*/* inst/*/*/*/*)
+FILES_VIGNETTES := $(wildcard vignettes/* vignettes/.install_extras)
+FILES_SRC := $(wildcard src/* src/*/* src/*/*/* src/*/*/*/* src/*/*/*/*/* src/*/*/*/*/*/* src/*/*/*/*/*/*/* src/*/*/*/*/*/*/*/*)
+FILES_SRC_C := $(wildcard src/*.c)
+FILES_SRC_H := $(wildcard src/*.h)
+FILES_TESTS := $(wildcard tests/*.R)
+FILES_NEWS := $(wildcard NEWS inst/NEWS)
+FILES_MISC := $(wildcard README.md)
+FILES_ROOT := DESCRIPTION NAMESPACE $(wildcard .Rbuildignore .Rinstignore)
+PKG_FILES := $(FILES_ROOT) $(FILES_NEWS) $(FILES_R) $(FILES_DATA) $(FILES_MAN) $(FILES_INST) $(FILES_VIGNETTES) $(FILES_SRC) $(FILES_TESTS) $(FILES_MISC)
+FILES_MAKEFILE := $(wildcard ../../Makefile)
+
+# Has vignettes in 'vignettes/' or 'inst/doc/'?
+DIR_VIGNS := $(wildcard vignettes inst/doc)
+
+# R MACROS
+R = R
+R_SCRIPT = Rscript
+R_HOME := $(shell $(R_SCRIPT) -e "cat(R.home())")
+
+## R_USE_CRAN := $(shell $(R_SCRIPT) -e "cat(Sys.getenv('R_USE_CRAN', 'FALSE'))")
+R_NO_INIT := --no-init-file
+R_VERSION_STATUS := $(shell $(R_SCRIPT) -e "status <- tolower(R.version[['status']]); if (regexpr('unstable', status) != -1L) status <- 'devel'; cat(status)")
+R_VERSION_X_Y := $(shell $(R_SCRIPT) -e "cat(gsub('[.][0-9]+$$', '', getRversion()))")
+R_VERSION := $(shell $(R_SCRIPT) -e "cat(as.character(getRversion()))")
+R_VERSION_FULL := $(R_VERSION)$(R_VERSION_STATUS)
+R_LIBS_USER_X := $(shell $(R_SCRIPT) -e "cat(.libPaths()[1])")
+R_INCLUDE := $(shell $(R_SCRIPT) -e "cat(R.home('include'))")
+R_OUTDIR := ../_R-$(R_VERSION_FULL)
+## R_BUILD_OPTS :=
+## R_BUILD_OPTS := $(R_BUILD_OPTS) --no-build-vignettes
+R_CHECK_OUTDIR := $(R_OUTDIR)/$(PKG_NAME).Rcheck
+_R_CHECK_CRAN_INCOMING_ = $(shell $(R_SCRIPT) -e "cat(Sys.getenv('_R_CHECK_CRAN_INCOMING_', 'FALSE'))")
+_R_CHECK_XREFS_REPOSITORIES_ = $(shell if test "$(_R_CHECK_CRAN_INCOMING_)" = "TRUE"; then echo ""; else echo "invalidURL"; fi)
+_R_CHECK_FULL_ = $(shell $(R_SCRIPT) -e "cat(Sys.getenv('_R_CHECK_FULL_', ''))")
+R_CHECK_OPTS = --as-cran --timings $(shell if test "$(_R_CHECK_USE_VALGRIND_)" = "TRUE"; then echo "--use-valgrind"; fi)
+R_RD4PDF = $(shell $(R_SCRIPT) -e "if (getRversion() < 3) cat('times,hyper')")
+R_CRAN_OUTDIR := $(R_OUTDIR)/$(PKG_NAME)_$(PKG_VERSION).CRAN
+
+HAS_ASPELL := $(shell $(R_SCRIPT) -e "cat(Sys.getenv('HAS_ASPELL', !inherits(try(aspell('DESCRIPTION', control=c('--master=en_US', '--add-extra-dicts=en_GB'), dictionaries='en_stats', program='aspell'), silent=TRUE), 'try-error')))")
+
+## Git related
+GIT_BRANCH := $(shell $(GIT) symbolic-ref --short HEAD)
+GIT_BRANCH := $(subst /,-,$(GIT_BRANCH))
+GIT_COMMIT := $(shell $(GIT) log -1 --format="%h")
+R_LIBS_BRANCH := $(CURDIR)/.R/$(GIT_BRANCH)
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Main
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+all: build install check
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Displays macros
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+debug:
+	@echo CURDIR=\'$(CURDIR)\'
+	@echo R_HOME=\'$(R_HOME)\'
+	@echo
+	@echo PKG_DIR=\'$(PKG_DIR)\'
+	@echo PKG_NAME=\'$(PKG_NAME)\'
+	@echo PKG_VERSION=\'$(PKG_VERSION)\'
+	@echo PKG_TARBALL=\'$(PKG_TARBALL)\'
+	@echo
+	@echo HAS_ASPELL=\'$(HAS_ASPELL)\'
+	@echo
+	@echo R=\'$(R)\'
+##	@echo R_USE_CRAN=\'$(R_USE_CRAN)\'
+	@echo R_NO_INIT=\'$(R_NO_INIT)\'
+	@echo R_SCRIPT=\'$(R_SCRIPT)\'
+	@echo R_VERSION_X_Y=\'$(R_VERSION_X_Y)\'
+	@echo R_VERSION=\'$(R_VERSION)\'
+	@echo R_VERSION_STATUS=\'$(R_VERSION_STATUS)\'
+	@echo R_VERSION_FULL=\'$(R_VERSION_FULL)\'
+	@echo R_LIBS_USER_X=\'$(R_LIBS_USER_X)\'
+	@echo R_INCLUDE=\'$(R_INCLUDE)\'
+	@echo R_OUTDIR=\'$(R_OUTDIR)\'
+	@echo
+	@echo "Default packages:" $(shell $(R) --slave -e "cat(paste(getOption('defaultPackages'), collapse=', '))")
+	@echo
+	@echo R_BUILD_OPTS=\'$(R_BUILD_OPTS)\'
+	@echo
+	@echo R_CHECK_OUTDIR=\'$(R_CHECK_OUTDIR)\'
+	@echo _R_CHECK_CRAN_INCOMING_=\'$(_R_CHECK_CRAN_INCOMING_)\'
+	@echo _R_CHECK_XREFS_REPOSITORIES_=\'$(_R_CHECK_XREFS_REPOSITORIES_)\'
+	@echo _R_CHECK_FULL_=\'$(_R_CHECK_FULL_)\'
+	@echo R_CHECK_OPTS=\'$(R_CHECK_OPTS)\'
+	@echo R_RD4PDF=\'$(R_RD4PDF)\'
+	@echo
+	@echo R_CRAN_OUTDIR=\'$(R_CRAN_OUTDIR)\'
+	@echo
+
+
+debug_full: debug
+	@echo
+	@echo FILES_ROOT=\'$(FILES_ROOT)\'
+	@echo FILES_R=\'$(FILES_R)\'
+	@echo FILES_DATA=\'$(FILES_DATA)\'
+	@echo FILES_MAN=\'$(FILES_MAN)\'
+	@echo FILES_INST=\'$(FILES_INST)\'
+	@echo FILES_VIGNETTES=\'$(FILES_VIGNETTES)\'
+	@echo FILES_SRC=\'$(FILES_SRC)\'
+	@echo FILES_TESTS=\'$(FILES_TESTS)\'
+	@echo FILES_INCL=\'$(FILES_INCL)\'
+	@echo FILES_MISC=\'$(FILES_MISC)\'
+	@echo
+	@echo DIR_VIGNS=\'$(DIR_VIGNS)\'
+	@echo dirname\(DIR_VIGNS\)=\'$(shell dirname $(DIR_VIGNS))\'
+	@echo
+	@echo GIT_BRANCH=\'$(GIT_BRANCH)\'
+	@echo GIT_COMMIT=\'$(GIT_COMMIT)\'
+	@echo R_LIBS_BRANCH=\'$(R_LIBS_BRANCH)\'
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Update / install
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Update existing packages
+update:
+	$(R_SCRIPT) -e "try(update.packages(ask=FALSE)); source('http://bioconductor.org/biocLite.R'); biocLite(ask=FALSE);"
+
+# Install missing dependencies
+deps: DESCRIPTION
+	$(MAKE) update
+	$(R_SCRIPT) -e "x <- unlist(strsplit(read.dcf('DESCRIPTION',fields=c('Depends', 'Imports', 'Suggests')),',')); x <- gsub('([[:space:]]*|[(].*[)])', '', x); libs <- .libPaths()[file.access(.libPaths(), mode=2) == 0]; x <- unique(setdiff(x, c('R', rownames(installed.packages(lib.loc=libs))))); if (length(x) > 0) { try(install.packages(x)); x <- unique(setdiff(x, c('R', rownames(installed.packages(lib.loc=libs))))); source('http://bioconductor.org/biocLite.R'); biocLite(x); }"
+
+setup:	update deps
+	$(R_SCRIPT) -e "source('http://aroma-project.org/hbLite.R'); hbLite('R.oo')"
+
+ns:
+	$(R_SCRIPT) -e "library('$(PKG_NAME)'); source('X:/devtools/NAMESPACE.R'); writeNamespaceSection('$(PKG_NAME)'); writeNamespaceImports('$(PKG_NAME)');"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Build source tarball
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_OUTDIR)/$(PKG_TARBALL): $(PKG_FILES)
+	$(MKDIR) $(R_OUTDIR)
+	$(RM) $@
+	$(CD) $(R_OUTDIR);\
+	$(R) $(R_NO_INIT) CMD build $(R_BUILD_OPTS) $(PKG_DIR)
+
+build: $(R_OUTDIR)/$(PKG_TARBALL)
+
+build_force:
+	$(RM) $(R_OUTDIR)/$(PKG_TARBALL)
+	$(MAKE) install
+
+# Make sure the tarball is readable
+build_fix: $(R_OUTDIR)/$(PKG_TARBALL)
+ifeq ($(OS), Windows_NT)
+  ifeq ($(USERNAME), hb)
+	$(MKDIR) X:/tmp/$(R_VERSION_FULL)
+	$(CP) -f $< X:/tmp/$(R_VERSION_FULL)/
+	$(RM) $<
+	$(MV) X:/tmp/$(R_VERSION_FULL)/$(<F) $<
+  endif
+endif
+
+build_fast: $(PKG_FILES)
+	$(MKDIR) $(R_OUTDIR)
+	$(RM) $@
+	$(CD) $(R_OUTDIR);\
+	$(R) $(R_NO_INIT) CMD build --keep-empty-dirs --no-build-vignettes --no-manual --no-resave-data --compact-vignettes="no" $(R_BUILD_OPTS) $(PKG_DIR)
+
+build: $(R_OUTDIR)/$(PKG_TARBALL)
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Install on current system
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_LIBS_USER_X)/$(PKG_NAME)/DESCRIPTION: $(R_OUTDIR)/$(PKG_TARBALL) build_fix
+	$(CD) $(R_OUTDIR);\
+	$(R) --no-init-file CMD INSTALL $(PKG_TARBALL)
+
+install: $(R_LIBS_USER_X)/$(PKG_NAME)/DESCRIPTION
+
+install_force:
+	$(RM) $(R_LIBS_USER_X)/$(PKG_NAME)/DESCRIPTION
+	$(MAKE) install
+
+install_fast:
+	$(CD) $(R_OUTDIR);\
+	$(R) --no-init-file CMD INSTALL --no-docs --no-multiarch --no-byte-compile --no-test-load $(PKG_TARBALL)
+
+
+$(R_LIBS_BRANCH)/$(PKG_NAME)/DESCRIPTION: $(R_OUTDIR)/$(PKG_TARBALL) build_fix
+	$(CD) $(R_OUTDIR);\
+	$(MKDIR) $(R_LIBS_BRANCH);\
+	$(R) --no-init-file CMD INSTALL --library=$(R_LIBS_BRANCH) $(PKG_TARBALL)
+
+install_branch: $(R_LIBS_BRANCH)/$(PKG_NAME)/DESCRIPTION
+
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Check source tarball
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_CHECK_OUTDIR)/.check.complete: $(R_OUTDIR)/$(PKG_TARBALL) build_fix
+	$(CD) $(R_OUTDIR);\
+	$(RM) -r $(PKG_NAME).Rcheck;\
+	export _R_CHECK_CRAN_INCOMING_=$(_R_CHECK_CRAN_INCOMING_);\
+	export _R_CHECK_CRAN_INCOMING_USE_ASPELL_=$(HAS_ASPELL);\
+	export _R_CHECK_XREFS_REPOSITORIES_=$(_R_CHECK_XREFS_REPOSITORIES_);\
+	export _R_CHECK_DOT_INTERNAL_=1;\
+	export _R_CHECK_USE_CODETOOLS_=1;\
+	export _R_CHECK_FORCE_SUGGESTS_=0;\
+	export R_RD4PDF=$(R_RD4PDF);\
+	export _R_CHECK_FULL_=$(_R_CHECK_FULL_);\
+	$(R) --no-init-file CMD check $(R_CHECK_OPTS) $(PKG_TARBALL);\
+	echo done > $(PKG_NAME).Rcheck/.check.complete
+
+check: $(R_CHECK_OUTDIR)/.check.complete
+
+check_force:
+	$(RM) -r $(R_CHECK_OUTDIR)
+	$(MAKE) check
+
+clang:
+	clang -c -pedantic -Wall -I$(R_INCLUDE) src/*.c
+	$(RM) *.o
+
+clang-ubsan:
+	clang -fsanitize=undefined -I$(R_INCLUDE) -c src/*.c
+	$(RM) *.o
+
+valgrind_scan:
+	grep -E "^==.*==[ ]+(at|by) 0x" $(R_CHECK_OUTDIR)/tests*/*.Rout | cat
+	grep "^==.* ERROR SUMMARY:" $(R_CHECK_OUTDIR)/tests*/*.Rout | grep -v -F "ERROR SUMMARY: 0 errors" | cat
+
+valgrind:
+	export _R_CHECK_USE_VALGRIND_=TRUE;\
+	$(MAKE) check_force
+	$(MAKE) valgrind_scan
+
+# Check the line width of incl/*.(R|Rex) files [max 100 chars in R devel]
+check_Rex:
+	$(R_SCRIPT) -e "if (!file.exists('incl')) quit(status=0); setwd('incl/'); fs <- dir(pattern='[.](R|Rex)$$'); ns <- sapply(fs, function(f) max(nchar(readLines(f)))); ns <- ns[ns > 100]; print(ns); if (length(ns) > 0L) quit(status=1)"
+
+
+covr:
+	$(R_SCRIPT) -e "source('.covr.R'); covr::shine(covr)"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Install and build binaries
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_OUTDIR)/$(PKG_ZIP): $(R_OUTDIR)/$(PKG_TARBALL) build_fix
+	$(CD) $(R_OUTDIR);\
+	$(R) --no-init-file CMD INSTALL --build --merge-multiarch $(PKG_TARBALL)
+
+binary: $(R_OUTDIR)/$(PKG_ZIP)
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Build Rd help files from Rdoc comments
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+rox:
+	$(R_SCRIPT) -e "roxygen2::roxygenize()"
+
+Rd: check_Rex
+	$(R_SCRIPT) -e "setwd('..'); Sys.setlocale(locale='C'); R.oo::compileRdoc('$(PKG_NAME)', path='$(PKG_DIR)')"
+
+%.Rd:
+	$(R_SCRIPT) -e "setwd('..'); Sys.setlocale(locale='C'); R.oo::compileRdoc('$(PKG_NAME)', path='$(PKG_DIR)', '$*.R')"
+
+missing_Rd:
+	$(R_SCRIPT) -e "x <- readLines('$(R_CHECK_OUTDIR)/00check.log'); from <- grep('Undocumented code objects:', x)+1; if (length(from) > 0L) { to <- grep('All user-level objects', x)-1; x <- x[from:to]; x <- gsub('^[ ]*', '', x); x <- gsub('[\']', '', x); cat(x, sep='\n', file='999.missingdocs.txt'); }"
+
+spell_Rd:
+	$(R_SCRIPT) -e "f <- list.files('man', pattern='[.]Rd$$', full.names=TRUE); utils::aspell(f, filter='Rd')"
+
+
+spell_NEWS:
+	$(R_SCRIPT) -e "utils::aspell('$(FILES_NEWS)')"
+
+spell:
+	$(R_SCRIPT) -e "utils::aspell('DESCRIPTION', filter='dcf')"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Build package vignettes
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_OUTDIR)/vigns: install
+	$(MKDIR) $(R_OUTDIR)/vigns/$(shell dirname $(DIR_VIGNS))
+	$(CP) DESCRIPTION $(R_OUTDIR)/vigns/
+	$(CP) -r $(DIR_VIGNS) $(R_OUTDIR)/vigns/$(shell dirname $(DIR_VIGNS))
+	$(CD) $(R_OUTDIR)/vigns;\
+	$(R_SCRIPT) -e "v <- tools::buildVignettes(dir='.'); file.path(getwd(), v[['outputs']])"
+
+vignettes: $(R_OUTDIR)/vigns
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Run package tests
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_OUTDIR)/tests/%.R: $(FILES_TESTS)
+	$(RMDIR) $(R_OUTDIR)/tests
+	$(MKDIR) $(R_OUTDIR)/tests
+	$(CP) $? $(R_OUTDIR)/tests
+
+test_files: $(R_OUTDIR)/tests/*.R
+
+test: $(R_OUTDIR)/tests/%.R
+	$(CD) $(R_OUTDIR)/tests;\
+	$(R_SCRIPT) -e "for (f in list.files(pattern='[.]R$$')) { print(f); source(f, echo=TRUE) }"
+
+test_full: $(R_OUTDIR)/tests/%.R
+	$(CD) $(R_OUTDIR)/tests;\
+	export _R_CHECK_FULL_=TRUE;\
+	$(R_SCRIPT) -e "for (f in list.files(pattern='[.]R$$')) { print(f); source(f, echo=TRUE) }"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Benchmarking
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+R_branch:
+	R_LIBS="$(R_LIBS_USER_X)$(FSEP)$(R_LIBS)" R_LIBS_USER="$(R_LIBS_BRANCH)" $(R)
+
+benchmark:
+	$(MKDIR) .benchmark/$(PKG_VERSION);\
+	$(CD) .benchmark/$(PKG_VERSION);\
+	$(R_SCRIPT) -e "$(PKG_NAME):::benchmark('index')"
+
+benchmark_branch:
+	$(MKDIR) .benchmark/$(PKG_VERSION)_$(GIT_BRANCH)_$(GIT_COMMIT);\
+	$(CD) .benchmark/$(PKG_VERSION)_$(GIT_BRANCH)_$(GIT_COMMIT);\
+	R_LIBS="$(R_LIBS_USER_X)$(FSEP)$(R_LIBS)" R_LIBS_USER="$(R_LIBS_BRANCH)" $(R_SCRIPT) -e "$(PKG_NAME):::benchmark('index')"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Miscellaneous development tools
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+## Fully expanded src/*.c files
+.devel/src/%: src/% $(FILES_SRC)
+	$(MKDIR) .devel/src/;\
+	gcc -I$(R_INCLUDE) -E $< | sed -e '/./b' -e :n -e 'N;s/\n$$//;tn' > .devel/$<
+
+.devel/src/all: $(FILES_SRC)
+	for f in $(FILES_SRC_C); do\
+	  echo $$f;\
+	  $(MAKE) .devel/$$f;\
+	done
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Run extensive CRAN submission checks
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_CRAN_OUTDIR)/$(PKG_TARBALL): $(R_OUTDIR)/$(PKG_TARBALL) build_fix
+	$(MKDIR) $(R_CRAN_OUTDIR)
+	$(CP) $(R_OUTDIR)/$(PKG_TARBALL) $(R_CRAN_OUTDIR)
+
+$(R_CRAN_OUTDIR)/$(PKG_NAME),EmailToCRAN.txt: $(R_CRAN_OUTDIR)/$(PKG_TARBALL)
+	$(CD) $(R_CRAN_OUTDIR);\
+	$(R_SCRIPT) -e "RCmdCheckTools::testPkgsToSubmit(delta=2/3)"
+
+cran_setup: $(R_CRAN_OUTDIR)/$(PKG_TARBALL)
+	$(R_SCRIPT) -e "if (!nzchar(system.file(package='RCmdCheckTools'))) { source('http://aroma-project.org/hbLite.R'); hbLite('RCmdCheckTools', devel=TRUE); }"
+
+cran: cran_setup $(R_CRAN_OUTDIR)/$(PKG_NAME),EmailToCRAN.txt
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Send to win-builder server
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+WIN_BUILDER = win-builder.r-project.org
+win-builder-devel: $(R_OUTDIR)/$(PKG_TARBALL)
+	curl -v -T $? ftp://anonymous@$(WIN_BUILDER)/R-devel/
+
+win-builder-release: $(R_OUTDIR)/$(PKG_TARBALL)
+	curl -v -T $? ftp://anonymous@$(WIN_BUILDER)/R-release/
+
+win-builder: win-builder-devel win-builder-release
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Local repositories
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ifeq ($(OS), Windows_NT)
+REPOS_PATH = T:/My\ Repositories/braju.com/R
+else
+REPOS_PATH = /tmp/hb/repositories/braju.com/R
+endif
+REPOS_SRC := $(REPOS_PATH)/src/contrib
+
+$(REPOS_SRC):
+	$(MKDIR) "$@"
+
+$(REPOS_SRC)/$(PKG_TARBALL): $(R_OUTDIR)/$(PKG_TARBALL) $(REPOS_SRC)
+	$(CP) $(R_OUTDIR)/$(PKG_TARBALL) $(REPOS_SRC)
+
+repos: $(REPOS_SRC)/$(PKG_TARBALL)
+
+Makefile: $(FILES_MAKEFILE)
+	$(R_SCRIPT) -e "d <- 'Makefile'; s <- '../../Makefile'; if (file_test('-nt', s, d) && (regexpr('Makefile for R packages', readLines(s, n=1L)) != -1L)) file.copy(s, d, overwrite=TRUE)"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Refresh
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+.make/Makefile:
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/Makefile', path='.make/')"
+
+.make/.travis.yml.rsp:
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/.travis.yml.rsp', path='.make/')"
+
+.make/appveyor.yml.rsp:
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/appveyor.yml.rsp', path='.make/')"
+
+.make/README.md.rsp:
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/README.md.rsp', path='.make/')"
+
+.covr.R:
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/covr-utils/master/.covr.R')"
+
+clean:
+	$(RM) .make/.travis.yml.rsp .make/appveyor.yml.rsp .make/README.md.rsp .covr.R
+	$(RM) covr-utils.R
+
+refresh: clean
+	$(MAKE) --silent .make/.travis.yml.rsp
+	$(MAKE) --silent .make/appveyor.yml.rsp
+	$(MAKE) --silent .make/README.md.rsp
+	$(MAKE) --silent .covr.R
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/Makefile', path='.make/', skip=FALSE)"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# GitHub, Travis CI, ...
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+README.md: .make/README.md.rsp
+	$(R_SCRIPT) -e "R.rsp::rfile('$<', postprocess=FALSE)"
+
+.travis.yml: .make/.travis.yml.rsp
+	$(R_SCRIPT) -e "R.rsp::rfile('$<', postprocess=FALSE)"
+
+appveyor.yml: .make/appveyor.yml.rsp
+	$(R_SCRIPT) -e "R.rsp::rfile('$<', postprocess=FALSE)"
+
+config: .travis.yml appveyor.yml README.md
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..cefeaf3
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,38 @@
+#----------------------------------------------------------------
+# Travis-CI configuration for R packages
+#
+# REFERENCES:
+# * Travis CI: https://docs.travis-ci.com/user/languages/r
+# * covr: https://github.com/jimhester/covr
+#
+# Validate your .travis.yml file at http://lint.travis-ci.org/
+#----------------------------------------------------------------
+language: r
+sudo: false
+cache: packages
+warnings_are_errors: false
+r_check_args: --as-cran
+latex: false
+
+matrix:
+  include:
+    - os: linux
+      r: oldrel
+    - os: linux
+      r: release
+      r_github_packages:
+      - jimhester/covr
+      after_success:
+      - Rscript -e 'covr::codecov(quiet=FALSE)'
+      env: NB='w/ covr' ## Just a label
+    - os: linux
+      r: devel
+    - os: osx
+      r: oldrel
+    - os: osx
+      r: release
+    
+notifications:
+  email:
+    on_success: change
+    on_failure: change
diff --git a/DESCRIPTION b/DESCRIPTION
index 0f9a11e..9bc40f3 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,7 +1,9 @@
 Package: globals
-Version: 0.6.1
-Depends: R (>= 3.1.2)
-Imports: codetools
+Version: 0.7.0
+Depends:
+    R (>= 3.1.2)
+Imports:
+    codetools
 Title: Identify Global Objects in R Expressions
 Authors at R: c(
   person("Henrik", "Bengtsson", role=c("aut", "cre", "cph"),
@@ -16,9 +18,3 @@ ByteCompile: TRUE
 URL: https://github.com/HenrikBengtsson/globals
 BugReports: https://github.com/HenrikBengtsson/globals/issues
 RoxygenNote: 5.0.1
-NeedsCompilation: no
-Packaged: 2016-02-03 06:35:36 UTC; hb
-Author: Henrik Bengtsson [aut, cre, cph]
-Maintainer: Henrik Bengtsson <henrikb at braju.com>
-Repository: CRAN
-Date/Publication: 2016-02-03 12:26:20
diff --git a/MD5 b/MD5
deleted file mode 100644
index 58acd95..0000000
--- a/MD5
+++ /dev/null
@@ -1,19 +0,0 @@
-ff516fd4c49cfd3807baa82d4d0cd113 *DESCRIPTION
-fa86d5707883f776e460df2d0ab86403 *NAMESPACE
-63820c16cc7597cd5233728495f1e1eb *NEWS
-7556d0412a854a17730afcac56259e6f *R/Globals-class.R
-d0e7cb156704a70b97e50e3bd7c8c34e *R/cleanup.R
-8d3fe54f9457bec3553e7d32dd8da76c *R/findGlobals.R
-6c662e51ebb5f4e10bda6aaf595dd7bd *R/globalsOf.R
-872b7b7be000da61e173d5be37df37c1 *R/packagesOf.R
-f5298931e3d28825ed127ab1426fd2b9 *R/utils.R
-55017055e1f1b4d3b56e75cceaf29c16 *README.md
-7e270fef5b03b44d97fd1076681eca76 *man/Globals.Rd
-8ff7d3934be276a7df5b3b993d4b8ef2 *man/cleanup.Globals.Rd
-79e73476957d6fa97778691ab9b30516 *man/globalsOf.Rd
-937c4cb33fb344a0c74330cd162a285c *man/packagesOf.Globals.Rd
-0a4fd4c3594bcf15e685886e0475e528 *tests/conservative.R
-b840f7e78850bd3a4af136f8649bf05a *tests/dotdotdot.R
-a54c80af61326308c5d6625b712021d3 *tests/globalsOf.R
-04ee391b83ac7278c0040be00d32756b *tests/liberal.R
-c2774d49049724b5e147ddccc793e9e4 *tests/utils.R
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..c6e7a04
--- /dev/null
+++ b/Makefile
@@ -0,0 +1 @@
+include .make/Makefile
diff --git a/NAMESPACE b/NAMESPACE
index 9778d5f..336617e 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -1,16 +1,22 @@
 # Generated by roxygen2: do not edit by hand
 
+S3method("$<-",Globals)
 S3method("[",Globals)
+S3method("names<-",Globals)
 S3method(as.Globals,Globals)
 S3method(as.Globals,list)
+S3method(c,Globals)
 S3method(cleanup,Globals)
 S3method(packagesOf,Globals)
+S3method(unique,Globals)
 export(Globals)
 export(as.Globals)
 export(cleanup)
 export(findGlobals)
+export(globalsByName)
 export(globalsOf)
 export(packagesOf)
+export(walkAST)
 importFrom(codetools,findLocalsList)
 importFrom(codetools,makeUsageCollector)
 importFrom(codetools,walkCode)
diff --git a/NEWS b/NEWS
index 754bb06..97be795 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,14 @@
 Package: globals
 ================
 
+Version: 0.7.0 [2016-09-08]
+o Added walkAST(), which can be used to tweak expressions.
+o Added globalsByName() for locating and retrieving a set of
+  known global variables.
+o Added c(), $<-(), names(), unique() for Globals objects.
+  Improved as.Globals() for lists.
+
+
 Version: 0.6.1 [2016-01-31]
 o Now the error message of globalsOf(..., mustExist=TRUE) when
   it fails to locate a global also gives information on the
diff --git a/R/Globals-class.R b/R/Globals-class.R
index 1313f37..9bc8695 100644
--- a/R/Globals-class.R
+++ b/R/Globals-class.R
@@ -11,7 +11,7 @@
 #' The \code{\link{globalsOf}()} function identifies globals
 #' from an R expression and returns a Globals object.
 #'
-#' @aliases as.Globals as.Globals.Globals as.Globals.list [.Globals
+#' @aliases as.Globals as.Globals.Globals as.Globals.list [.Globals names
 #' @export
 Globals <- function(object, ...) {
   if (!is.list(object)) {
@@ -25,7 +25,17 @@ Globals <- function(object, ...) {
     stop("Argument 'object' specifies globals with empty names.")
   }
 
-  structure(object, class=c(class(object), "Globals"))
+  where <- attr(object, "where")
+  stopifnot(is.list(where))
+  
+  ## TODO: Add only when future (> 1.0.1) is on CRAN /HB 2016-09-05
+##  stopifnot(
+##    is.list(where),
+##    length(where) == length(object),
+##    all(names(where) == names)
+##  )
+
+  structure(object, class=c("Globals", class(object)))
 }
 
 #' @export
@@ -36,9 +46,30 @@ as.Globals.Globals <- function(x, ...) x
 
 #' @export
 as.Globals.list <- function(x, ...) {
+  ## Use the globals environments as the locals?
+  ## (with emptyenv() as the fallback)
+  where <- attr(x, "where")
+  if (is.null(where)) {
+    where <- lapply(x, FUN=function(obj) {
+        e <- environment(obj)
+	if (is.null(e)) e <- emptyenv()
+	e
+    })
+    names(where) <- names(x)
+    attr(x, "where") <- where
+  }
+  
   Globals(x, ...)
 }
 
+#' @export
+`names<-.Globals` <- function(x, value) {
+  x <- NextMethod("names")
+  where <- attr(x, "where")
+  names(where) <- names(x)
+  attr(x, "where") <- where
+  invisible(x)
+}
 
 #' @export
 `[.Globals` <- function(x, i) {
@@ -46,5 +77,111 @@ as.Globals.list <- function(x, ...) {
   res <- NextMethod("[")
   attr(res, "where") <- where[i]
   class(res) <- class(x)
+
+  ## TODO: Add only when future (> 1.0.1) is on CRAN /HB 2016-09-05
+##  where <- attr(res, "where")
+##  stopifnot(
+##    is.list(where),
+##    length(where) == length(res),
+##    all(names(where) == names(res))
+##  )
+
   res
 }
+
+
+#' @export
+`$<-.Globals` <- function(x, name, value) {
+  where <- attr(x, "where")
+  
+  ## Remove an element?
+  if (is.null(value)) {
+    x[[name]] <- NULL
+    where[[name]] <- NULL
+  } else {
+    ## Value must be Globals object of length one
+    if (inherits(value, "Globals")) {
+      if (length(value) != 1) {
+        stop("Cannot assign Globals object of length different than one: ", length(value))
+      }
+      x[[name]] <- value[[1]]
+      where[[name]] <- attr(value, "where")[[1]]
+    } else {
+      w <- environment(value)
+      if (is.null(w)) w <- emptyenv()
+      x[[name]] <- value
+      where[[name]] <- w
+    }
+  }
+  
+  attr(x, "where") <- where
+  invisible(x)
+}
+
+
+
+#' @export
+c.Globals <- function(x, ...) {
+  args <- list(...)
+
+  where <- attr(x, "where")
+  clazz <- class(x)
+  class(x) <- NULL
+
+  for (kk in seq_along(args)) {
+    g <- args[[kk]]
+    name <- names(args)[kk]
+    
+    if (inherits(g, "Globals")) {
+      w <- attr(g, "where")
+    } else if (is.list(g)) {
+      names <- names(g)
+      stopifnot(!is.null(names))
+      w <- lapply(g, FUN=function(obj) {
+        e <- environment(obj)
+	if (is.null(e)) e <- emptyenv()
+	e
+      })
+      names(w) <- names
+    } else {
+      if (is.null(name)) {
+        stop("Can only append named objects to Globals list: ", sQuote(mode(g)))
+      }
+      g <- structure(list(g), names=name)
+      e <- environment(g)
+      if (is.null(e)) e <- emptyenv()
+      w <- structure(list(e), names=name)
+    }
+    where <- c(where, w)
+    x <- c(x, g)
+  }
+  
+  class(x) <- clazz
+  attr(x, "where") <- where
+
+  stopifnot(
+    length(where) == length(x),
+    all(names(where) == names(x))
+  )
+
+  x
+}
+
+#' @export
+unique.Globals <- function(x, ...) {
+  names <- names(x)
+  dups <- duplicated(names)
+  if (any(dups)) {
+    where <- attr(x, "where")
+    where <- where[!dups]
+    x <- x[!dups]
+    attr(x, "where") <- where
+    
+    stopifnot(
+      length(where) == length(x),
+      all(names(where) == names(x))
+    )
+  }
+
+  x
+}
diff --git a/R/cleanup.R b/R/cleanup.R
index caba05f..e6fd3b6 100644
--- a/R/cleanup.R
+++ b/R/cleanup.R
@@ -9,13 +9,20 @@ cleanup <- function(...) UseMethod("cleanup")
 #'
 #' @aliases cleanup
 #' @export
-cleanup.Globals <- function(globals, drop=c("base-packages"), ...) {
+cleanup.Globals <- function(globals, drop=c("missing", "base-packages"), ...) {
   where <- attr(globals, "where")
 
   names <- names(globals)
   keep <- rep(TRUE, times=length(globals))
   names(keep) <- names
 
+  ## Drop non-found objects
+  if ("missing" %in% drop) {
+    for (name in names) {
+      if (is.null(where[[name]])) keep[name] <- FALSE
+    }
+  }
+
   ## Drop objects that are part of one of the "base" packages
   if ("base-packages" %in% drop) {
     for (name in names) {
diff --git a/R/globalsOf.R b/R/globalsOf.R
index a535b23..b5f7738 100644
--- a/R/globalsOf.R
+++ b/R/globalsOf.R
@@ -51,8 +51,42 @@ globalsOf <- function(expr, envir=parent.frame(), ..., method=c("ordered", "cons
 
   if (substitute) expr <- substitute(expr)
 
+  ## 1. Identify global variables (static code inspection)
   names <- findGlobals(expr, envir=envir, ..., method=method, tweak=tweak, substitute=FALSE, unlist=unlist)
 
+  ## 2. Locate them (run time)
+  globals <- tryCatch({
+    globalsByName(names, envir=envir, mustExist=mustExist)
+  }, error = function(ex) {
+    ## HACK: Tweak error message to also include the expression inspected.
+    msg <- conditionMessage(ex)
+    msg <- sprintf("Identified global objects via static code inspection (%s). %s", hexpr(expr), msg)
+    ex$message <- msg
+    stop(ex)
+  })
+
+  globals
+} ## globalsOf()
+
+
+
+
+#' Locates and retrieves a set of global variables by their names
+#'
+#' @param names A character vector of global variable names.
+#' @param envir The environment from where to search for globals.
+#' @param mustExist If TRUE, an error is thrown if the object of the
+#'        identified global cannot be located.  Otherwise, the global
+#'        is not returned.
+#' @param ... Not used.
+#'
+#' @return A \link{Globals} object.
+#'
+#' @export
+globalsByName <- function(names, envir=parent.frame(), mustExist=TRUE, ...) {
+  names <- as.character(names)
+
+  ## Locate and retrieve the specified globals
   n <- length(names)
   needsDotdotdot <- (identical(names[n], "..."))
   if (needsDotdotdot) names <- names[-n]
@@ -70,9 +104,10 @@ globalsOf <- function(expr, envir=parent.frame(), ..., method=c("ordered", "cons
         globals[[name]] <- value
       }
     } else {
+      globals[name] <- list(NULL)
       where[name] <- list(NULL)
       if (mustExist) {
-        stop(sprintf("Identified a global object via static code inspection (%s), but failed to locate the corresponding object in the relevant environments: %s", hexpr(expr), sQuote(name)))
+        stop(sprintf("Failed to locate global object in the relevant environments: %s", sQuote(name)))
       }
     }
   }
@@ -89,7 +124,13 @@ globalsOf <- function(expr, envir=parent.frame(), ..., method=c("ordered", "cons
     globals[["..."]] <- ddd
   }
 
+  stopifnot(
+    is.list(where),
+    length(where) == length(globals),
+    all(names(where) == names(globals))
+  )
+
   attr(globals, "where") <- where
 
   globals
-}
+} ## globalsByName()
diff --git a/R/utils.R b/R/utils.R
index 5590672..be1290b 100644
--- a/R/utils.R
+++ b/R/utils.R
@@ -67,8 +67,8 @@ hpaste <- function(..., sep="", collapse=", ", lastCollapse=NULL, maxHead=if (mi
 
   # Abbreviate?
   if (n > maxHead + maxTail + 1) {
-    head <- x[seq(length=maxHead)]
-    tail <- rev(rev(x)[seq(length=maxTail)])
+    head <- x[seq_len(maxHead)]
+    tail <- rev(rev(x)[seq_len(maxTail)])
     x <- c(head, abbreviate, tail)
     n <- length(x)
   }
diff --git a/R/walkAST.R b/R/walkAST.R
new file mode 100644
index 0000000..8e67dcf
--- /dev/null
+++ b/R/walkAST.R
@@ -0,0 +1,57 @@
+#' Walk the Abstract Syntax Tree (AST) of an R Expression
+#'
+#' @param expr R \link[base]{expression}.
+#' @param atomic,name,call,pairlist single-argument function that takes an atomic, name, call and pairlist expression, respectively. Have to return a valid R expression.
+#' @param name single-argument function that takes a name expression.
+#' @param call single-argument function that takes a call expression.
+#' @param pairlist single-argument function that takes a pairlist expression.
+#' @param substitute If TRUE, \code{expr} is \code{\link[base]{substitute}()}:ed.
+#'
+#' @return R \link[base]{expression}.
+#'
+#' @export
+#' @keywords programming internal
+walkAST <- function(expr, atomic=NULL, name=NULL, call=NULL, pairlist=NULL, substitute=FALSE) {
+  if (substitute) expr <- substitute(expr)
+
+  if (is.atomic(expr)) {
+    if (is.function(atomic)) expr <- atomic(expr)
+  } else if (is.name(expr)) {
+    if (is.function(name)) expr <- name(expr)
+  } else if (is.call(expr)) {
+##    message("call")
+    for (cc in seq_along(expr)) {
+      ## AD HOC: The following is needed to handle x[,1]. /HB 2016-09-06
+      if (is.name(expr[[cc]]) && expr[[cc]] == "") next
+      e <- walkAST(expr[[cc]], atomic=atomic, name=name, call=call, pairlist=pairlist, substitute=FALSE)
+      if (is.null(e)) {
+        expr[cc] <- list(NULL)
+      } else {
+        expr[[cc]] <- e
+      }
+    }
+    if (is.function(call)) expr <- call(expr)
+  } else if (is.pairlist(expr)) {
+##    message("pairlist")
+    for (pp in seq_along(expr)) {
+      ## AD HOC: The following is needed to handle '...'. /HB 2016-09-06
+      if (is.name(expr[[pp]]) && expr[[pp]] == "") next
+      e <- walkAST(expr[[pp]], atomic=atomic, name=name, call=call, pairlist=pairlist, substitute=FALSE)
+      if (is.null(e)) {
+        expr[pp] <- list(NULL)
+      } else {
+        expr[[pp]] <- e
+      }
+    }
+    if (is.function(pairlist)) expr <- pairlist(expr)
+  } else {
+    stop("Cannot walk expression. Unknown object type ", sQuote(typeof(expr)), call.=FALSE)
+  }
+
+  ## Assert that the tweak functions return a valid object
+  if (!missing(expr)) {
+    stopifnot(is.atomic(expr) || is.name(expr) || is.call(expr) || is.pairlist(expr))
+  }
+  
+  expr
+} ## walkAST()
diff --git a/README.md b/README.md
index 344cba7..9c4c4eb 100644
--- a/README.md
+++ b/README.md
@@ -7,13 +7,20 @@ R package globals is available on [CRAN](http://cran.r-project.org/package=globa
 install.packages('globals')
 ```
 
+### Pre-release version
+
+To install the pre-release version that is available in branch `develop`, use:
+```r
+source('http://callr.org/install#HenrikBengtsson/globals@develop')
+```
+This will install the package from source.  
 
 
 
 ## Software status
 
-| Resource:     | CRAN        | Travis CI     | Appveyor         |
-| ------------- | ------------------- | ------------- | ---------------- |
-| _Platforms:_  | _Multiple_          | _Linux_       | _Windows_        |
-| R CMD check   | <a href="http://cran.r-project.org/web/checks/check_results_globals.html"><img border="0" src="http://www.r-pkg.org/badges/version/globals" alt="CRAN version"></a> | <a href="https://travis-ci.org/HenrikBengtsson/globals"><img src="https://travis-ci.org/HenrikBengtsson/globals.svg" alt="Build status"></a> | <a href="https://ci.appveyor.com/project/HenrikBengtsson/globals"><img src="https://ci.appveyor.com/api/projects/status/github/HenrikBengtsson/globals?svg=true" alt= [...]
-| Test coverage |                     | <a href="https://coveralls.io/r/HenrikBengtsson/globals"><img src="https://coveralls.io/repos/HenrikBengtsson/globals/badge.svg?branch=develop" alt="Coverage Status"/></a>   |                  |
+| Resource:     | CRAN        | Travis CI      | Appveyor         |
+| ------------- | ------------------- | -------------- | ---------------- |
+| _Platforms:_  | _Multiple_          | _Linux & OS X_ | _Windows_        |
+| R CMD check   | <a href="http://cran.r-project.org/web/checks/check_results_globals.html"><img border="0" src="http://www.r-pkg.org/badges/version/globals" alt="CRAN version"></a> | <a href="https://travis-ci.org/HenrikBengtsson/globals"><img src="https://travis-ci.org/HenrikBengtsson/globals.svg" alt="Build status"></a>  | <a href="https://ci.appveyor.com/project/HenrikBengtsson/globals"><img src="https://ci.appveyor.com/api/projects/status/github/HenrikBengtsson/globals?svg=true" alt [...]
+| Test coverage |                     | <a href="https://codecov.io/gh/HenrikBengtsson/globals"><img src="https://codecov.io/gh/HenrikBengtsson/globals/branch/develop/graph/badge.svg" alt="Coverage Status"/></a>    |                  |
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..21351ed
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,65 @@
+#----------------------------------------------------------------
+# AppVeyor configuration for R packages
+#
+# REFERENCES:
+# * AppVeyor CI: https://ci.appveyor.com/
+# * r-travis: https://github.com/craigcitro/r-travis
+#
+# Validate your .appveyor.yml file at
+# https://ci.appveyor.com/tools/validate-yaml 
+#----------------------------------------------------------------
+environment:
+  _R_CHECK_FORCE_SUGGESTS_: false
+
+  matrix:
+  - R_VERSION: devel
+    R_ARCH: x64
+
+  - R_VERSION: devel
+    R_ARCH: i386
+
+#  - R_VERSION: release
+#    R_ARCH: x64
+
+# DO NOT CHANGE the "init" and "install" sections below
+
+# Download script file from GitHub
+init:
+  ps: |
+        $ErrorActionPreference = "Stop"
+        Invoke-WebRequest http://raw.github.com/HenrikBengtsson/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1"
+        Import-Module '..\appveyor-tool.ps1'
+install:
+  ps: Bootstrap
+
+# Adapt as necessary starting from here
+
+build_script:
+  - echo Current directory=%CD%
+  - travis-tool.sh install_r codetools
+
+test_script:
+  - travis-tool.sh run_tests
+
+after_test:
+  - 7z a all-Rout.zip *.Rcheck\**\*.Rout *.Rcheck\**\*.fail
+
+artifacts:
+  - path: '*.Rcheck\**\*.log'
+    name: Logs
+
+  - path: '*.Rcheck\**\*.out'
+    name: Logs
+
+  - path: all-Rout.zip
+    name: AllRout
+
+  - path: '\*_*.tar.gz'
+    name: Bits
+
+  - path: '\*_*.zip'
+    name: Bits
+
+on_failure:
+  - 7z a failure.zip *.Rcheck\*
+  - appveyor PushArtifact failure.zip
diff --git a/cran-comments.md b/cran-comments.md
new file mode 100644
index 0000000..b006a3e
--- /dev/null
+++ b/cran-comments.md
@@ -0,0 +1,54 @@
+# CRAN submission globals 0.7.0
+on 2016-09-08
+
+I've verified that this submission causes *no* issues for
+any of the 20 reverse (recursive) package dependencies
+available on CRAN and Bioconductor.
+
+Thanks in advance
+
+
+## Notes not sent to CRAN
+
+### R CMD check --as-cran validation
+
+The package has been verified using `R CMD check --as-cran` on:
+
+* Platform x86_64-apple-darwin13.4.0 (64-bit) [Travis CI]:
+  - R 3.2.4 Revised (2016-03-16 r70336)
+  - R version 3.3.1 (2016-06-21)
+  
+* Platform x86_64-unknown-linux-gnu (64-bit) [Travis CI]:
+  - R version 3.2.5 (2016-04-14)
+  - R version 3.3.1 (2016-06-21)
+  - R Under development (unstable) (2016-09-07 r71224)
+
+* Platform x86_64-pc-linux-gnu (64-bit):
+  - R version 3.2.5 (2016-04-14)
+  - R version 3.3.1 (2016-06-21)
+  - R version 3.3.1 Patched (2016-09-07 r71224)
+  - R Under development (unstable) (2016-09-07 r71224)
+
+* Platform i686-pc-linux-gnu (32-bit):
+  - R version 3.3.1 (2016-06-21)
+
+* Platform i386-w64-mingw32 (32-bit) [Appveyor CI]:
+  - R Under development (unstable) (2016-09-06 r71220)
+
+* Platform x86_64-w64-mingw32/x64 (64-bit) [Appveyor CI]:
+  - R Under development (unstable) (2016-09-06 r71220)
+
+* Platform x86_64-w64-mingw32/x64 (64-bit) [win-builder]:
+  - R version 3.3.1 (2016-06-21)
+  - R Under development (unstable) (2016-09-08 r71224)
+
+
+### Reverse package check validation
+
+All of the 20 reverse (recursive) package dependencies available
+on CRAN and Bioconductor have been checked against this version
+with `R CMD check --as-cran` (using `devtools::revdep_check()`).
+See `revdeps/` folder for full results.
+
+This version does _not_ introduce any known issues for any of
+those packages.
diff --git a/incl/globalsOf.R b/incl/globalsOf.R
new file mode 100644
index 0000000..f41140e
--- /dev/null
+++ b/incl/globalsOf.R
@@ -0,0 +1,10 @@
+b <- 2
+expr <- substitute({ a <- b; b <- 1 })
+
+## Will _not_ identify 'b' (because it's also a local)
+globalsC <- globalsOf(expr, method="conservative")
+print(globalsC)
+
+## Will identify 'b'
+globalsL <- globalsOf(expr, method="liberal")
+print(globalsL)
diff --git a/man/Globals.Rd b/man/Globals.Rd
index 333a25e..b559e02 100644
--- a/man/Globals.Rd
+++ b/man/Globals.Rd
@@ -6,6 +6,7 @@
 \alias{as.Globals}
 \alias{as.Globals.Globals}
 \alias{as.Globals.list}
+\alias{names}
 \title{A representation of a set of globals}
 \usage{
 Globals(object, ...)
diff --git a/man/cleanup.Globals.Rd b/man/cleanup.Globals.Rd
index 3810738..513406d 100644
--- a/man/cleanup.Globals.Rd
+++ b/man/cleanup.Globals.Rd
@@ -5,7 +5,7 @@
 \alias{cleanup.Globals}
 \title{Drop certain types of globals}
 \usage{
-\method{cleanup}{Globals}(globals, drop = c("base-packages"), ...)
+\method{cleanup}{Globals}(globals, drop = c("missing", "base-packages"), ...)
 }
 \arguments{
 \item{globals}{A Globals object.}
diff --git a/man/globalsByName.Rd b/man/globalsByName.Rd
new file mode 100644
index 0000000..019ec08
--- /dev/null
+++ b/man/globalsByName.Rd
@@ -0,0 +1,26 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/globalsOf.R
+\name{globalsByName}
+\alias{globalsByName}
+\title{Locates and retrieves a set of global variables by their names}
+\usage{
+globalsByName(names, envir = parent.frame(), mustExist = TRUE, ...)
+}
+\arguments{
+\item{names}{A character vector of global variable names.}
+
+\item{envir}{The environment from where to search for globals.}
+
+\item{mustExist}{If TRUE, an error is thrown if the object of the
+identified global cannot be located.  Otherwise, the global
+is not returned.}
+
+\item{...}{Not used.}
+}
+\value{
+A \link{Globals} object.
+}
+\description{
+Locates and retrieves a set of global variables by their names
+}
+
diff --git a/man/walkAST.Rd b/man/walkAST.Rd
new file mode 100644
index 0000000..c8ed28f
--- /dev/null
+++ b/man/walkAST.Rd
@@ -0,0 +1,31 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/walkAST.R
+\name{walkAST}
+\alias{walkAST}
+\title{Walk the Abstract Syntax Tree (AST) of an R Expression}
+\usage{
+walkAST(expr, atomic = NULL, name = NULL, call = NULL, pairlist = NULL,
+  substitute = FALSE)
+}
+\arguments{
+\item{expr}{R \link[base]{expression}.}
+
+\item{atomic, name, call, pairlist}{single-argument function that takes an atomic, name, call and pairlist expression, respectively. Have to return a valid R expression.}
+
+\item{name}{single-argument function that takes a name expression.}
+
+\item{call}{single-argument function that takes a call expression.}
+
+\item{pairlist}{single-argument function that takes a pairlist expression.}
+
+\item{substitute}{If TRUE, \code{expr} is \code{\link[base]{substitute}()}:ed.}
+}
+\value{
+R \link[base]{expression}.
+}
+\description{
+Walk the Abstract Syntax Tree (AST) of an R Expression
+}
+\keyword{internal}
+\keyword{programming}
+
diff --git a/revdep/README.md b/revdep/README.md
new file mode 100644
index 0000000..09f246d
--- /dev/null
+++ b/revdep/README.md
@@ -0,0 +1,384 @@
+# Setup
+
+## Platform
+
+|setting  |value                        |
+|:--------|:----------------------------|
+|version  |R version 3.3.1 (2016-06-21) |
+|system   |x86_64, linux-gnu            |
+|ui       |X11                          |
+|language |en                           |
+|collate  |en_US.UTF-8                  |
+|tz       |SystemV/PST8PDT              |
+|date     |2016-09-08                   |
+
+## Packages
+
+|package |*  |version    |date       |source                             |
+|:-------|:--|:----------|:----------|:----------------------------------|
+|globals |   |0.6.1-9000 |2016-09-08 |local (HenrikBengtsson/globals at NA) |
+
+# Check results
+20 packages
+
+## ACNE (0.8.1)
+Maintainer: Henrik Bengtsson <henrikb at braju.com>  
+Bug reports: https://github.com/HenrikBengtsson/ACNE/issues
+
+0 errors | 0 warnings | 0 notes
+
+## aroma.affymetrix (3.0.0)
+Maintainer: Henrik Bengtsson <henrikb at braju.com>  
+Bug reports: https://github.com/HenrikBengtsson/aroma.affymetrix/issues
+
+0 errors | 0 warnings | 0 notes
+
+## aroma.cn (1.6.1)
+Maintainer: Henrik Bengtsson <henrikb at braju.com>  
+Bug reports: https://github.com/HenrikBengtsson/aroma.cn/issues
+
+0 errors | 0 warnings | 0 notes
+
+## aroma.core (3.0.0)
+Maintainer: Henrik Bengtsson <henrikb at braju.com>  
+Bug reports: https://github.com/HenrikBengtsson/aroma.core/issues
+
+0 errors | 0 warnings | 1 note 
+
+```
+checking package dependencies ... NOTE
+Packages suggested but not available for checking:
+  ‘expectile’ ‘HaarSeg’ ‘mpcbs’
+```
+
+## calmate (0.12.1)
+Maintainer: Henrik Bengtsson <henrikb at braju.com>  
+Bug reports: https://github.com/HenrikBengtsson/calmate/issues
+
+0 errors | 0 warnings | 0 notes
+
+## doFuture (0.2.1)
+Maintainer: Henrik Bengtsson <henrikb at braju.com>  
+Bug reports: https://github.com/HenrikBengtsson/doFuture/issues
+
+0 errors | 0 warnings | 0 notes
+
+## fiery (0.2.1)
+Maintainer: Thomas Lin Pedersen <thomasp85 at gmail.com>  
+Bug reports: https://github.com/thomasp85/fiery/issues
+
+0 errors | 0 warnings | 0 notes
+
+## future.BatchJobs (0.13.0)
+Maintainer: Henrik Bengtsson <henrikb at braju.com>  
+Bug reports: https://github.com/HenrikBengtsson/future.BatchJobs/issues
+
+0 errors | 0 warnings | 0 notes
+
+## future (1.0.1)
+Maintainer: Henrik Bengtsson <henrikb at braju.com>  
+Bug reports: https://github.com/HenrikBengtsson/future/issues
+
+0 errors | 0 warnings | 0 notes
+
+## GeneBreak (1.2.0)
+Maintainer: Evert van den Broek <vandenbroek.evert at gmail.com>
+
+0 errors | 0 warnings | 1 note 
+
+```
+checking R code for possible problems ... NOTE
+.glmbreak: no visible global function definition for ‘glm’
+.glmbreak: no visible global function definition for ‘predict’
+addGeneAnnotation,CopyNumberBreakPoints: no visible global function
+  definition for ‘head’
+bpStats,CopyNumberBreakPoints: no visible global function definition
+  for ‘sd’
+bpStats,CopyNumberBreakPoints: no visible global function definition
+  for ‘p.adjust’
+Undefined global functions or variables:
+  glm head p.adjust predict sd
+Consider adding
+  importFrom("stats", "glm", "p.adjust", "predict", "sd")
+  importFrom("utils", "head")
+to your NAMESPACE file.
+```
+
+## MPAgenomics (1.1.2)
+Maintainer: Samuel Blanck <samuel.blanck at inria.fr>
+
+0 errors | 0 warnings | 2 notes
+
+```
+checking dependencies in R code ... NOTE
+'library' or 'require' calls in package code:
+  ‘R.devices’ ‘R.filesets’ ‘R.methodsS3’ ‘R.oo’ ‘aroma.affymetrix’
+  ‘aroma.cn’ ‘aroma.core’ ‘aroma.light’ ‘matrixStats’ ‘snowfall’
+  Please use :: or requireNamespace() instead.
+  See section 'Suggested packages' in the 'Writing R Extensions' manual.
+Unexported object imported by a ':::' call: ‘cghseg:::segmeanCO’
+  See the note in ?`:::` about the use of this operator.
+
+checking R code for possible problems ... NOTE
+.varregtimescount: no visible global function definition for ‘var’
+CGHSEGaroma: no visible global function definition for ‘read.csv’
+CGHSEGaroma : <anonymous>: no visible global function definition for
+  ‘points’
+CGHSEGaroma : <anonymous>: no visible global function definition for
+  ‘lines’
+CGHSEGaroma : <anonymous>: no visible global function definition for
+  ‘write.table’
+CGHcall: no visible global function definition for ‘mad’
+... 43 lines ...
+tumorboostPlot: no visible global function definition for ‘par’
+tumorboostPlot: no visible global function definition for ‘axis’
+tumorboostPlot: no visible global function definition for ‘points’
+Undefined global functions or variables:
+  axis head lines lm mad median optim par points read.csv sd var
+  write.table
+Consider adding
+  importFrom("graphics", "axis", "lines", "par", "points")
+  importFrom("stats", "lm", "mad", "median", "optim", "sd", "var")
+  importFrom("utils", "head", "read.csv", "write.table")
+to your NAMESPACE file.
+```
+
+## NSA (0.0.32)
+Maintainer: Maria Ortiz-Estevez <mortizest at gmail.com>
+
+0 errors | 0 warnings | 6 notes
+
+```
+checking package dependencies ... NOTE
+Depends: includes the non-default packages:
+  ‘R.methodsS3’ ‘MASS’ ‘matrixStats’ ‘R.oo’ ‘R.utils’ ‘aroma.core’
+  ‘aroma.affymetrix’ ‘DNAcopy’
+Adding so many packages to the search path is excessive and importing
+selectively is preferable.
+
+checking top-level files ... NOTE
+Non-standard file/directory found at top level:
+  ‘incl’
+
+checking dependencies in R code ... NOTE
+Packages in Depends field not imported from:
+  ‘DNAcopy’ ‘MASS’ ‘R.methodsS3’ ‘R.oo’ ‘aroma.affymetrix’ ‘aroma.core’
+  ‘matrixStats’
+  These packages need to be imported from (in the NAMESPACE file)
+  for when this namespace is loaded but not attached.
+
+checking S3 generic/method consistency ... NOTE
+Found the following apparent S3 methods exported but not registered:
+  NSAByTotalAndFracB.matrix allocateOutputDataSets.NSANormalization
+  allocateOutputDataSets.SNPsNormalization
+  allocateOutputDataSets.SampleNormalization
+  as.character.NSANormalization as.character.SNPsNormalization
+  as.character.SampleNormalization findArraysTodo.NSANormalization
+  findArraysTodo.SampleNormalization findUnitsTodo.SNPsNormalization
+  fitNSA.matrix fitNSAcnPs.matrix getDataSets.NSANormalization
+  getDataSets.SNPsNormalization getDataSets.SampleNormalization
+  getName.NSANormalization getName.SNPsNormalization
+  getName.SampleNormalization getOutputDataSets.NSANormalization
+  getOutputDataSets.SNPsNormalization
+  getOutputDataSets.SampleNormalization getPath.NSANormalization
+  getPath.SNPsNormalization getPath.SampleNormalization
+  getRootPath.NSANormalization getRootPath.SNPsNormalization
+  getRootPath.SampleNormalization process.NSANormalization
+  process.SNPsNormalization process.SampleNormalization
+  sampleNByTotalAndFracB.numeric snpsNByTotalAndFracB.matrix
+See section ‘Registering S3 methods’ in the ‘Writing R Extensions’
+manual.
+
+checking R code for possible problems ... NOTE
+NB: .First.lib is obsolete and will not be used in R >= 3.0.0
+
+.First.lib: no visible global function definition for
+  ‘packageDescription’
+NSAByTotalAndFracB.matrix: no visible global function definition for
+  ‘throw’
+NSAByTotalAndFracB.matrix: no visible global function definition for
+  ‘str’
+NSANormalization: no visible global function definition for ‘throw’
+... 279 lines ...
+  extractMatrix findUnitsTodo getAsteriskTags getChipType getFile
+  getFullName getFullNames getGenomeInformation getName getNames
+  getPath getPathname getPathnames getPositions getRam getRootPath
+  getTags getUnitsOnChromosome hist median nbrOfFiles newInstance
+  packageDescription rowAlls rowMedians segment setTags str throw trim
+  verbose
+Consider adding
+  importFrom("graphics", "hist")
+  importFrom("stats", "approxfun", "median")
+  importFrom("utils", "packageDescription", "str")
+to your NAMESPACE file.
+
+checking Rd line widths ... NOTE
+Rd file 'NSANormalization.Rd':
+  \examples lines wider than 100 characters:
+     by <- 50e3; # 50kb bins; you may want to try with other amounts of smoothing xOut <- seq(from=xRange[1], to=xRange[2], by=by);
+     plot(getSignals(cnCNPS), getSignals(cnSNPS), xlim=Clim, ylim=Clim); abline(a=0, b=1, col="red", lwd=2);
+
+These lines will be truncated in the PDF manual.
+```
+
+## pbmcapply (1.1.0)
+Maintainer: Kevin kuang <kvn.kuang at mail.utoronto.ca>  
+Bug reports: https://github.com/kvnkuang/pbmcapply/issues
+
+0 errors | 0 warnings | 0 notes
+
+## PECA (1.8.0)
+Maintainer: Tomi Suomi <tomi.suomi at utu.fi>
+
+0 errors | 0 warnings | 1 note 
+
+```
+checking Rd line widths ... NOTE
+Rd file 'PECA.Rd':
+  \usage lines wider than 90 characters:
+     PECA_AffyBatch(affy=NULL, normalize=FALSE, test="t", type="median", paired=FALSE, progress=FALSE)
+
+These lines will be truncated in the PDF manual.
+```
+
+## PSCBS (0.61.0)
+Maintainer: Henrik Bengtsson <henrikb at braju.com>  
+Bug reports: https://github.com/HenrikBengtsson/PSCBS/issues
+
+0 errors | 0 warnings | 0 notes
+
+## PureCN (1.0.4)
+Maintainer: Markus Riester <markus.riester at novartis.com>
+
+0 errors | 0 warnings | 1 note 
+
+```
+checking R code for possible problems ... NOTE
+Found the following calls to data() loading into the global environment:
+File ‘PureCN/R/createCurationFile.R’:
+  data(purecn.example.output)
+File ‘PureCN/R/findFocal.R’:
+  data(purecn.example.output)
+File ‘PureCN/R/plotAbs.R’:
+  data(purecn.example.output)
+File ‘PureCN/R/predictSomatic.R’:
+  data(purecn.example.output)
+File ‘PureCN/R/readCurationFile.R’:
+  data(purecn.example.output)
+File ‘PureCN/R/runAbsoluteCN.R’:
+  data(purecn.example.output)
+File ‘PureCN/R/segmentationCBS.R’:
+  data(purecn.example.output)
+See section ‘Good practice’ in ‘?data’.
+```
+
+## QDNAseq (1.8.0)
+Maintainer: Daoud Sie <d.sie at vumc.nl>  
+Bug reports: https://github.com/ccagc/QDNAseq/issues
+
+0 errors | 0 warnings | 1 note 
+
+```
+checking R code for possible problems ... NOTE
+estimateCorrection,QDNAseqReadCounts : calculateFits: no visible global
+  function definition for ‘formula’
+Undefined global functions or variables:
+  formula
+Consider adding
+  importFrom("stats", "formula")
+to your NAMESPACE file.
+```
+
+## Repitools (1.18.2)
+Maintainer: Mark Robinson <mark.robinson at imls.uzh.ch>
+
+0 errors | 0 warnings | 2 notes
+
+```
+checking R code for possible problems ... NOTE
+Found an obsolete/platform-specific call in the following function:
+  ‘maskOut’
+Found the platform-specific device:
+  ‘windows’
+dev.new() is the preferred way to open a new device, in the unlikely
+event one is needed.
+.cpgBoxplots: no visible global function definition for ‘pdf’
+.cpgBoxplots: no visible global function definition for ‘par’
+.cpgBoxplots: no visible global function definition for ‘dev.off’
+... 291 lines ...
+  rainbow read.table rect str t.test text title verbose
+Consider adding
+  importFrom("grDevices", "dev.off", "pdf", "rainbow")
+  importFrom("graphics", "abline", "axis", "barplot", "bxp", "grid",
+             "layout", "legend", "lines", "matlines", "matplot", "mtext",
+             "par", "persp", "plot", "plot.new", "plot.window", "points",
+             "polygon", "rect", "text", "title")
+  importFrom("stats", "dbeta", "embed", "filter", "kmeans", "lm",
+             "lowess", "p.adjust", "predict", "pt", "qnorm", "t.test")
+  importFrom("utils", "read.table", "str")
+to your NAMESPACE file.
+
+checking Rd line widths ... NOTE
+Rd file 'ChromaBlocks.Rd':
+  \usage lines wider than 90 characters:
+     ChromaBlocks(rs.ip, rs.input, organism, chrs, ipWidth=100, inputWidth=500, preset=NULL, blockWidth=NULL, minBlocks=NULL, extend=NULL, c ... [TRUNCATED]
+
+Rd file 'GCbiasPlots.Rd':
+  \usage lines wider than 90 characters:
+                 cex = 0.2, pch.col = "black", line.col = "red", lty = 1, lwd = 2, verbose = TRUE)
+
+Rd file 'absoluteCN.Rd':
+... 57 lines ...
+
+Rd file 'regionStats.Rd':
+  \usage lines wider than 90 characters:
+     regionStats(x, design = NULL, maxFDR=0.05, n.perm=5, window=600, mean.trim=.1, min.probes=10, max.gap=500, two.sides=TRUE, ndf, return. ... [TRUNCATED]
+     regionStats(x, design = NULL, maxFDR=0.05, n.perm=5, window=600, mean.trim=.1, min.probes=10, max.gap=500, two.sides=TRUE, ind=NULL, re ... [TRUNCATED]
+
+Rd file 'writeWig.Rd':
+  \usage lines wider than 90 characters:
+     writeWig(rs, seq.len = NULL, design=NULL, sample=20, drop.zero=TRUE, normalize=TRUE, verbose=TRUE)
+
+These lines will be truncated in the PDF manual.
+```
+
+## R.filesets (2.10.0)
+Maintainer: Henrik Bengtsson <henrikb at braju.com>  
+Bug reports: https://github.com/HenrikBengtsson/R.filesets/issues
+
+0 errors | 0 warnings | 0 notes
+
+## TIN (1.4.1)
+Maintainer: Bjarne Johannessen <bjajoh at rr-research.no>
+
+0 errors | 0 warnings | 2 notes
+
+```
+checking top-level files ... NOTE
+Non-standard file/directory found at top level:
+  ‘doc’
+
+checking R code for possible problems ... NOTE
+aberrantExonUsage: no visible global function definition for ‘quantile’
+aberrantExonUsage: no visible global function definition for ‘ave’
+clusterPlot: no visible global function definition for ‘dist’
+clusterPlot: no visible global function definition for ‘hclust’
+clusterPlot: no visible global function definition for
+  ‘colorRampPalette’
+clusterPlot: no visible global function definition for ‘par’
+clusterPlot: no visible global function definition for ‘png’
+clusterPlot: no visible global function definition for ‘jpeg’
+... 50 lines ...
+  importFrom("stats", "ave", "dist", "hclust", "median", "quantile")
+  importFrom("utils", "data", "read.table")
+to your NAMESPACE file.
+
+Found the following assignments to the global environment:
+File ‘TIN/R/aberrantExonUsage.R’:
+  assign("quantiles", quantiles, envir = .GlobalEnv)
+  assign("aberrantExons", aberrantExons, envir = .GlobalEnv)
+File ‘TIN/R/correlationPlot.R’:
+  assign("randomGeneSetsDist", B, envir = .GlobalEnv)
+  assign("traPermutationsDist", L, envir = .GlobalEnv)
+```
+
diff --git a/revdep/check.R b/revdep/check.R
new file mode 100644
index 0000000..1eefa00
--- /dev/null
+++ b/revdep/check.R
@@ -0,0 +1,20 @@
+library("devtools")
+
+availableCores <- function() {
+  getenv <- function(name) {
+    as.integer(Sys.getenv(name, NA_character_))
+  }
+  getopt <- function(name) {
+    as.integer(getOption(name, NA_integer_))
+  }
+  if (is.finite(n <- getopt("mc.cores") + 1L)) return(n)
+  if (is.finite(n <- getopt("Ncpus") + 1L)) return(n)
+  if (is.finite(n <- getenv("PBS_NUM_PPN"))) return(n)
+  if (is.finite(n <- getenv("SLURM_CPUS_PER_TASK"))) return(n)
+  if (is.finite(n <- getenv("NSLOTS"))) return(n)
+  1L
+}
+
+revdep_check(bioconductor = TRUE, recursive = TRUE, threads = availableCores())
+revdep_check_save_summary()
+revdep_check_print_problems()
diff --git a/revdep/checks.rds b/revdep/checks.rds
new file mode 100644
index 0000000..df04acf
Binary files /dev/null and b/revdep/checks.rds differ
diff --git a/revdep/problems.md b/revdep/problems.md
new file mode 100644
index 0000000..2dd5396
--- /dev/null
+++ b/revdep/problems.md
@@ -0,0 +1,24 @@
+# Setup
+
+## Platform
+
+|setting  |value                        |
+|:--------|:----------------------------|
+|version  |R version 3.3.1 (2016-06-21) |
+|system   |x86_64, linux-gnu            |
+|ui       |X11                          |
+|language |en                           |
+|collate  |en_US.UTF-8                  |
+|tz       |SystemV/PST8PDT              |
+|date     |2016-09-08                   |
+
+## Packages
+
+|package |*  |version    |date       |source                             |
+|:-------|:--|:----------|:----------|:----------------------------------|
+|globals |   |0.6.1-9000 |2016-09-08 |local (HenrikBengtsson/globals at NA) |
+
+# Check results
+0 packages with problems
+
+
diff --git a/tests/Globals.R b/tests/Globals.R
new file mode 100644
index 0000000..d6af4e0
--- /dev/null
+++ b/tests/Globals.R
@@ -0,0 +1,250 @@
+library("globals")
+
+a <- 1
+b <- 2
+
+message("*** Globals() ...")
+
+globals0 <- globalsByName(c("a", "rnorm"))
+
+globals <- globals0
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 2L,
+  length(where) == length(globals),
+  all(names(globals) == c("a", "rnorm")),
+  all(names(globals) == names(where))
+)
+
+message("*** Globals() - names ...")
+
+globals <- globals0
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 2L,
+  length(where) == length(globals),
+  all(names(globals) == c(names(globals0))),
+  all(names(globals) == names(where))
+)
+
+names(globals)[1] <- "A"
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 2L,
+  length(where) == length(globals),
+  all(names(globals) == c("A", names(globals0)[-1])),
+  all(names(globals) == names(where))
+)
+
+message("*** Globals() - names ... DONE")
+
+message("*** Globals() - subsetting ...")
+
+globals <- globals0[1]
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 1L,
+  length(where) == length(globals),
+  all(names(globals) == c("a")),
+  all(names(globals) == names(where))
+)
+
+globals <- globals0[2]
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 1L,
+  length(where) == length(globals),
+  all(names(globals) == c("rnorm")),
+  all(names(globals) == names(where))
+)
+
+globals <- globals0[2:1]
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 2L,
+  length(where) == length(globals),
+  all(names(globals) == c("rnorm", "a")),
+  all(names(globals) == names(where))
+)
+
+## rev() works automatically thanks to `[`() :)
+globals <- rev(globals0)
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 2L,
+  length(where) == length(globals),
+  all(names(globals) == rev(names(globals0))),
+  all(names(globals) == names(where)),
+  identical(rev(globals), globals0)
+)
+
+message("*** Globals() - subsetting ... DONE")
+
+
+message("*** Globals() - subsetted assignment ...")
+
+globals <- globals0
+globals$a <- globals0["a"]
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 2L,
+  length(where) == length(globals),
+  all(names(globals) == names(globals0)),
+  all(names(globals) == names(where)),
+  identical(globals, globals0)
+)
+
+globals <- globals0
+globals$b <- globals0["a"]
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 3L,
+  length(where) == length(globals),
+  all(names(globals) == c(names(globals0), "b")),
+  all(names(globals) == names(where)),
+  identical(globals$b, globals0$a)
+)
+
+globals <- globals0
+globals$a <- NULL
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 1L,
+  length(where) == length(globals),
+  all(names(globals) == names(globals0)[-1]),
+  all(names(globals) == names(where)),
+  is.null(globals$a)
+)
+
+globals <- globals0
+globals$a <- 1:2
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 2L,
+  length(where) == length(globals),
+  all(names(globals) == names(globals0)),
+  all(names(globals) == names(where)),
+  identical(globals$a, 1:2)
+)
+
+message("*** Globals() - subsetted assignment ... DONE")
+
+
+message("*** Globals() - combining ...")
+
+globalsA <- globals0[1:2]
+globalsB <- globals0[1:2]
+globals <- c(globalsA, globalsB)
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 4L,
+  length(where) == length(globals),
+  all(names(globals) == c(names(globalsA), names(globalsB))),
+  all(names(globals) == names(where))
+)
+
+globalsA <- globals0[1:2]
+globalsB <- list(b=1, c=letters)
+globals <- c(globalsA, globalsB)
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 4L,
+  length(where) == length(globals),
+  all(names(globals) == c(names(globalsA), names(globalsB))),
+  all(names(globals) == names(where))
+)
+
+globalsA <- globals0[1:2]
+globals <- c(globalsA, b=1, c=letters)
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 4L,
+  length(where) == length(globals),
+  all(names(globals) == c(names(globalsA), names(globalsB))),
+  all(names(globals) == names(where))
+)
+
+message("*** Globals() - combining ... DONE")
+
+
+message("*** Globals() - unique ...")
+
+globals <- globals0[c(1:2, 1:2, 1:2)]
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == 6L,
+  length(where) == length(globals),
+  all(names(globals) == rep(names(globals0), times=3L)),
+  all(names(globals) == names(where))
+)
+
+globals <- unique(globals)
+str(globals)
+where <- attr(globals, "where")
+stopifnot(
+  length(globals) == length(globals0),
+  length(where) == length(globals),
+  all(names(globals) == names(globals0)),
+  all(names(globals) == names(where))
+)
+
+message("*** Globals() - unique ... DONE")
+
+
+message("*** Globals() - coercion ...")
+
+globals <- as.Globals(globals0)
+stopifnot(identical(globals, globals0))
+
+globals <- as.Globals(unclass(globals0))
+stopifnot(identical(globals, globals0))
+
+globalsT <- unclass(globals0)
+attr(globalsT, "where") <- NULL
+globals <- as.Globals(globalsT)
+stopifnot(
+  length(globals) == length(globals0),
+  names(globals) == names(globals0)
+)
+
+message("*** Globals() - coercion ... DONE")
+
+
+message("*** Globals() - exceptions ...")
+
+res <- tryCatch({ Globals(NULL) }, error = identity)
+stopifnot(inherits(res, "simpleError"))
+
+res <- tryCatch({ Globals(list(1,2)) }, error = identity)
+stopifnot(inherits(res, "simpleError"))
+
+res <- tryCatch({ Globals(list(a=1,2)) }, error = identity)
+stopifnot(inherits(res, "simpleError"))
+
+## Assigning more than one element
+globals <- globals0
+res <- tryCatch({ globals$a <- globals0[2:1] }, error = identity)
+stopifnot(inherits(res, "simpleError"))
+
+## Appending unnamed objects
+res <- tryCatch({ c(globals0, 2) }, error = identity)
+stopifnot(inherits(res, "simpleError"))
+
+message("*** Globals() - exceptions ... DONE")
+
+message("*** Globals() ... DONE")
diff --git a/tests/globalsOf.R b/tests/globalsOf.R
index 25cb708..c5949b2 100644
--- a/tests/globalsOf.R
+++ b/tests/globalsOf.R
@@ -32,6 +32,44 @@ stopifnot(all(globalsI %in% c("{", "<-", "b", "c", "d")))
 message("*** findGlobals() ... DONE")
 
 
+message("*** globalsByName() ...")
+
+globalsC <- globalsByName(c("{", "<-", "c", "d"))
+str(globalsC)
+stopifnot(all(names(globalsC) %in% c("{", "<-", "c", "d")))
+globalsC <- cleanup(globalsC)
+str(globalsC)
+stopifnot(all(names(globalsC) %in% c("c", "d")))
+where <- attr(globalsC, "where")
+stopifnot(
+  length(where) == length(globalsC),
+  identical(where$c, globalenv()),
+  identical(where$d, globalenv())
+)
+
+foo <- globals::Globals
+globals <- globalsByName(c("{", "foo", "list"))
+str(globals)
+stopifnot(all(names(globals) %in% c("{", "foo", "list")))
+where <- attr(globals, "where")
+stopifnot(length(where) == length(globals))
+if (!covr) stopifnot(
+  identical(where$`{`, baseenv()),
+  identical(where$foo, globalenv()),
+  identical(where$list, baseenv())
+)
+
+globals <- cleanup(globals)
+str(globals)
+stopifnot(all(names(globals) %in% c("foo")))
+globals <- cleanup(globals, drop="internals")
+str(globals)
+stopifnot(all(names(globals) %in% c("foo")))
+pkgs <- packagesOf(globals)
+stopifnot(pkgs == "globals")
+
+message("*** globalsByName() ... DONE")
+
 
 message("*** globalsOf() ...")
 
@@ -126,10 +164,10 @@ globals <- globalsOf(expr)
 str(globals)
 stopifnot(all(names(globals) %in% c("{", "foo", "list")))
 where <- attr(globals, "where")
-stopifnot(
-  length(where) == length(globals),
+stopifnot(length(where) == length(globals))
+if (!covr) stopifnot(
   identical(where$`{`, baseenv()),
-  covr || identical(where$foo, globalenv()),
+  identical(where$foo, globalenv()),
   identical(where$list, baseenv())
 )
 
@@ -148,21 +186,21 @@ globals <- globalsOf(expr)
 str(globals)
 stopifnot(all(names(globals) %in% c("{", "<-", "sample", "sample2", "sessionInfo", "sum", "sum2")))
 where <- attr(globals, "where")
-stopifnot(
-  length(where) == length(globals),
+stopifnot(length(where) == length(globals))
+if (!covr) stopifnot(
   identical(where$`<-`, baseenv()),
   identical(where$sample, baseenv()),
-  covr || identical(where$sample2, globalenv())
+  identical(where$sample2, globalenv())
 )
 
+
 globals <- cleanup(globals)
 str(globals)
 stopifnot(all(names(globals) %in% c("sample2", "sum2")))
 where <- attr(globals, "where")
-stopifnot(
-  length(where) == length(globals),
-  covr || identical(where$sample2, globalenv())
-)
+stopifnot(length(where) == length(globals))
+if (!covr) stopifnot(identical(where$sample2, globalenv()))
+
 
 globals <- cleanup(globals, drop="primitives")
 str(globals)
@@ -178,3 +216,18 @@ res <- try({
 stopifnot(inherits(res, "try-error"))
 
 message("*** globalsOf() - exceptions ... DONE")
+
+
+message("*** Globals() - exceptions ...")
+
+res <- tryCatch({ Globals(NULL) }, error = identity)
+stopifnot(inherits(res, "simpleError"))
+
+res <- tryCatch({ Globals(list(1,2)) }, error = identity)
+stopifnot(inherits(res, "simpleError"))
+
+res <- tryCatch({ Globals(list(a=1,2)) }, error = identity)
+stopifnot(inherits(res, "simpleError"))
+
+message("*** Globals() - exceptions ... DONE")
+
diff --git a/tests/utils.R b/tests/utils.R
index c7ac25c..7ff0091 100644
--- a/tests/utils.R
+++ b/tests/utils.R
@@ -53,15 +53,17 @@ printf("y = %s.\n", hpaste(y, maxHead=Inf))
 printf("y = %s.\n", paste(y, collapse=", "))
 ## y = 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
 
-
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-# Adding a special separator before the last element
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 # Change last separator
 printf("x = %s.\n", hpaste(x, lastCollapse=" and "))
 ## x = 1, 2, 3, 4, 5 and 6.
 
-message("* hpaste() ...")
+# No collapse
+stopifnot(all(hpaste(x, collapse=NULL) == x))
+
+# Empty input
+stopifnot(identical(hpaste(character(0)), character(0)))
+
+message("* hpaste() ... DONE")
 
 
 message("* asFunction() ...")
@@ -83,18 +85,28 @@ stopifnot(!isBasePkgs("globals"))
 message("* is.base() & is.internal() ...")
 stopifnot(is.base(base::library))
 stopifnot(!is.base(globals::globalsOf))
+stopifnot(!is.base(NULL))
 stopifnot(is.internal(print.default))
 stopifnot(!is.internal(globals::globalsOf))
+stopifnot(!is.internal(NULL))
 
 
 
 
 message("* where() ...")
 
+env <- where("sample", where=1L)
+str(env)
+
+env <- where("sample", frame=1L)
+str(env)
+
 message("- where('sample') ...")
 env <- where("sample", mode="function")
 print(env)
-stopifnot(identical(env, baseenv()))
+if (!"covr" %in% loadedNamespaces()) {
+  stopifnot(identical(env, baseenv()))
+}
 obj <- get("sample", mode="function", envir=env, inherits=FALSE)
 stopifnot(identical(obj, base::sample))
 
@@ -128,6 +140,10 @@ stopifnot(identical(envs$aa, globalenv()))
 stopifnot(identical(envs$bb, envs$envir))
 stopifnot(is.null(envs$cc))
 
+message("- where() - missing ...")
+env <- where("non-existing-object", inherits=FALSE)
+stopifnot(is.null(env))
+
 rm(list=c("aa", "envs", "foo", "env", "obj", "where"))
 
 message("* where() ... DONE")
diff --git a/tests/walkAST.R b/tests/walkAST.R
new file mode 100644
index 0000000..86f1f9e
--- /dev/null
+++ b/tests/walkAST.R
@@ -0,0 +1,88 @@
+library("globals")
+
+message("*** walkAST() ...")
+
+exprs <- list(
+  null     = substitute(NULL),
+  atomic   = substitute(1),
+  atomic   = substitute("a"),
+  atomic   = substitute(TRUE),
+  assign   = substitute(a <- 1),
+  assign   = substitute(1 -> a),
+  assign   = substitute(a <- b + 1),
+  assign   = substitute(x <- rnorm(20, mu=0)),
+  index    = substitute(x[1,1]),
+  index    = substitute(x[1:2,1:2]),
+  index    = substitute(x[,1:2]),
+  index    = substitute(x[,1]),
+  fcn      = substitute(function(a=1, b=2) sum(c(a, b))),
+  fcn      = substitute(function(a=1, b) sum(c(a, b))),
+  fcn      = substitute(function(a=1, b=2, ...) sum(c(a, b, ...))),
+  ok       = substitute(function(...) sum(x, ...)),
+  warn     = substitute(sum(x, ...)),
+  null     = substitute(NULL)
+)
+
+nullify <- function(e) NULL
+
+disp <- function(expr) {
+  cat("Expression:\n")
+  print(expr)
+  cat("str():\n")
+  str(expr)
+  cat(sprintf("typeof: %s\n", typeof(expr)))
+  cat("as.list():\n")
+  str(as.list(expr))
+  expr
+} ## disp()
+
+for (kk in seq_along(exprs)) {
+  name <- names(exprs)[kk]
+  message(sprintf("- walkAST(<expression #%d (%s)>) ...", kk, sQuote(name)))
+  expr <- exprs[[kk]]
+  print(expr)
+  str(as.list(expr))
+
+  ## Assert identity (default behavior)
+  exprI <- walkAST(expr)
+  str(as.list(exprI))
+  res <- all.equal(exprI, expr)
+  print(res)
+  if (!identical(exprI, expr)) saveRDS(list(expr=expr, exprI=exprI), file="/tmp/foo.rds")
+  stopifnot(length(exprI) == length(expr), identical(exprI, expr))
+
+  ## Display the AST tree
+  walkAST(expr, atomic=disp, name=disp, call=disp, pairlist=disp)
+
+  ## Nullify
+  exprN <- walkAST(expr, atomic=nullify, name=nullify, call=nullify, pairlist=nullify)
+  print(exprN)
+  str(as.list(exprN))
+  
+
+message("*** walkAST() - nullify ... DONE")
+
+  message(sprintf("- walkAST(<expression #%d (%s)>) ... DONE", kk, sQuote(name)))
+} ## for (name ...)
+
+
+
+message("*** walkAST() - substitute=TRUE ...")
+
+expr <- walkAST(a <- 1, substitute=TRUE)
+print(expr)
+
+message("*** walkAST() - substitute=TRUE ... DONE")
+
+
+message("*** walkAST() - exceptions ...")
+
+res <- tryCatch({
+  expr <- walkAST(list())
+}, error = identity)
+print(res)
+stopifnot(inherits(res, "simpleError"))
+
+message("*** walkAST() - exceptions ... DONE")
+
+message("*** walkAST() ... DONE")
diff --git a/tests/zzz.R b/tests/zzz.R
new file mode 100644
index 0000000..13a347a
--- /dev/null
+++ b/tests/zzz.R
@@ -0,0 +1 @@
+## Just a dummy place holder

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-cran-globals.git



More information about the debian-med-commit mailing list