See mvbutils.packaging.tools
before reading or experimenting!
Set up task package(s) for editing and/or live-editing. Usually called in .First
or .First.task
. You need to be cd
ed into the parent task of your task-package. maintain.packages
must be called before loading the package via library
or require
. The converse, unmaintain.package
, is rarely needed; it's really only meant for when unpackage
doesn't work properly, and you want a "clean slate" task package.
# E.g. in your .First, after library( mvbutils), or in...
# ... a '.First.task' above yr task-package
maintain.packages(..., character.only = FALSE, autopatch=FALSE)
unmaintain.package( pkg, character.only = FALSE)
names of packages, unquoted unless character.only
is TRUE. Package names must correspond to subtasks of the current task.
see above
name of package, unquoted unless character.only
is TRUE.
whether to patch.install
out-of-date installed packages (default FALSE, but TRUE is common).
If you use mvbutils
to pre-build your package, then your package must exist as a task in the cd
hierarchy. Older versions of mvbutils
allowed you to cd
to a maintained package, but this is now forbidden because of the scope for confusion. Thanks to maintain.packages
, there is no compelling need to have the package/task at the top of the search path; fixr
, move
, etc work just fine without. If you really do want to cd
to a maintained package, you must call unmaintain.package
first.
One piece of cleanup that I recommend, is to move any subtasks of "mypack" one level up in the task hierarchy, and to remove the tasks
object from "Splendid" itself, e.g. via something like:
cd( task.above.splendid) tasks <- c( tasks, combined.file.paths( tasks[ "Splendid"], ..Splendid$tasks)) # ... combined.file.paths is an imaginary function. Watch out if you've used relative paths! rm.pkg( tasks, pkg="Splendid")
maintain.packages( mypack)
loads a copy of your task-package "mypack" (as stored in its ".RData" file) into a environment ..mypack
(an "in-memory-task-package"), which itself lives in the "mvb.session.info" environment on the search path. You don't normally need to know this, because normally you'd modify/create/delete objects in the package via fixr
or fixr(..., pkg="mypack")
or rm.pkg( ..., pkg="mypack")
. But to move objects between the package and other tasks, you do need to refer to the in-memory task package, e.g. via move( ..., from=..Splendid, to=subtask/of/current)
. In most cases, you will be prompted afterwards for whether to save the task package on disk, but you can always do yourself via Save.pos( ..Splendid)
. Note that only these updates and saves only update the task package and the loaded package. To update the source package using the task package, call pre.install
; to update the installed package on disk as well as the source package, call patch.install
.
.GlobalEnv
, then use move(newthing,.,..mypack)
. For a new function, you can shortcut this two-step process and create it directly in the in-memory maintained package, via fixr(..mypack$newfun)
; fixr
will take care of synchronization with the loaded package. This also ought to work for text objects created via fixtext
. Otherwise, use the two-step route, unless you have a good reason to do the following...Rarely, you may have a really good reason to directly modify the contents of ..mypack
, e.g. via
..mypack$newfun <<- function( x) whatever
You can do it, but there are two problems to be aware of. The first is that changes won't be directly propagated to the loaded package, possibly not even after patch.install
(though they will be honoured when you library()
the package again). That is definitely the case for general data objects, and I'm not sure about functions; however, successful propagation after patch.install
may happen for a special objects such as mypack.DESCRIPTION
and documentation objects. Hence my general advice is to use fixr
or move
.
The second, minor, problem is that you will probably forget to use <<-
and will use <-
instead, so that a local copy of ..mypack
will be created in the current task. This is no big deal, and you can just rm
the local copy; the local copy and the master copy in "mvb.session.info" both point to the same thing, and modifying one implies modifying the other, so that deleting the local copy won't lose your changes. Save
detects accidental local copies of task packages, and omits them from the disk image, so there shouldn't be any problems next time you start R even if you completely forget about local/master copies.
autopatch==TRUE
, then maintain.packages
will check whether the corresponding installed packages are older than the ".RData" files of the task packages. If they are, it will do a full patch.install
; if not, it will still call patch.install
but only to reverse-update any bundled DLLs (see pre.install
), not to re-install the R-source. I find autopatch
useful with packages containing C code, where a crash in the C code can cause R to die before the most recent R-code changes have been "committed" with patch.install
. When you next start R, a call to maintain.packages
with autopatch=TRUE
will "commit" the changes before the package is loaded, because you have to call maintain.packages
before library
; this seems to be more reliable than running patch.install
manually after library
after a restart.mvbutils.packaging.tools
, fixr
, pre.install
, patch.installed
, unpackage
# NOT RUN {
# In your .First:
library( mvbutils)
maintain.packages( myfirstpack, mysecondpack, mythirdpack)
# or...
live.edit.list <- c( 'myfirstpack', 'mysecondpack', 'mythirdpack')
maintain.packages( live.edit.list, character.only=TRUE)
library( myfirstpack) # etc
# }
Run the code above in your browser using DataLab