From ea54deb8091a35450ad2ac443938f061b2ef952d Mon Sep 17 00:00:00 2001 From: Jason French Date: Fri, 19 May 2017 08:23:58 -0500 Subject: [PATCH 1/5] Initial commit --- .Rbuildignore | 1 + docs/LICENSE | 20 ++ docs/articles/index.html | 101 ++++++ docs/articles/registry.html | 117 ++++++ docs/authors.html | 102 ++++++ docs/index.html | 173 +++++++++ docs/jquery.sticky-kit.min.js | 9 + docs/link.svg | 12 + docs/pkgdown.css | 154 ++++++++ docs/pkgdown.js | 8 + docs/reference/any_is_substring_of.html | 131 +++++++ docs/reference/apply_pattern.html | 120 +++++++ ...parser_and_preprocessor_are_identical.html | 128 +++++++ docs/reference/complete_extension.html | 145 ++++++++ docs/reference/dependency-tracking.html | 243 +++++++++++++ docs/reference/director.html | 152 ++++++++ docs/reference/director_exists.html | 149 ++++++++ docs/reference/director_filename.html | 146 ++++++++ docs/reference/director_find.html | 186 ++++++++++ docs/reference/drop_idempotence.html | 122 +++++++ docs/reference/duplicate.html | 116 ++++++ docs/reference/enforce_type.html | 148 ++++++++ docs/reference/extensionless_exists.html | 132 +++++++ docs/reference/get_helpers.html | 140 ++++++++ .../grapes-less-than-less-than-grapes.html | 132 +++++++ docs/reference/has_preprocessor.html | 123 +++++++ docs/reference/index.html | 332 ++++++++++++++++++ docs/reference/initialize.html | 138 ++++++++ docs/reference/is.director.html | 116 ++++++ docs/reference/is.idempotent_directory.html | 132 +++++++ docs/reference/modification-tracking.html | 229 ++++++++++++ docs/reference/parser.html | 140 ++++++++ docs/reference/preprocessor.html | 159 +++++++++ docs/reference/register_parser.html | 144 ++++++++ docs/reference/register_preprocessor.html | 135 +++++++ docs/reference/registry.html | 132 +++++++ docs/reference/resource-caching.html | 195 ++++++++++ docs/reference/resource.html | 179 ++++++++++ docs/reference/resource_name.html | 122 +++++++ docs/reference/search_pattern.html | 164 +++++++++ docs/reference/simple_cache.html | 113 ++++++ docs/reference/sized_queue.html | 133 +++++++ docs/reference/strip_r_extension.html | 122 +++++++ docs/reference/strip_root.html | 132 +++++++ docs/reference/tower.html | 171 +++++++++ docs/reference/virtual-resource.html | 203 +++++++++++ 46 files changed, 6201 insertions(+) create mode 100644 .Rbuildignore create mode 100644 docs/LICENSE create mode 100644 docs/articles/index.html create mode 100644 docs/articles/registry.html create mode 100644 docs/authors.html create mode 100644 docs/index.html create mode 100644 docs/jquery.sticky-kit.min.js create mode 100644 docs/link.svg create mode 100644 docs/pkgdown.css create mode 100644 docs/pkgdown.js create mode 100644 docs/reference/any_is_substring_of.html create mode 100644 docs/reference/apply_pattern.html create mode 100644 docs/reference/check_if_parser_and_preprocessor_are_identical.html create mode 100644 docs/reference/complete_extension.html create mode 100644 docs/reference/dependency-tracking.html create mode 100644 docs/reference/director.html create mode 100644 docs/reference/director_exists.html create mode 100644 docs/reference/director_filename.html create mode 100644 docs/reference/director_find.html create mode 100644 docs/reference/drop_idempotence.html create mode 100644 docs/reference/duplicate.html create mode 100644 docs/reference/enforce_type.html create mode 100644 docs/reference/extensionless_exists.html create mode 100644 docs/reference/get_helpers.html create mode 100644 docs/reference/grapes-less-than-less-than-grapes.html create mode 100644 docs/reference/has_preprocessor.html create mode 100644 docs/reference/index.html create mode 100644 docs/reference/initialize.html create mode 100644 docs/reference/is.director.html create mode 100644 docs/reference/is.idempotent_directory.html create mode 100644 docs/reference/modification-tracking.html create mode 100644 docs/reference/parser.html create mode 100644 docs/reference/preprocessor.html create mode 100644 docs/reference/register_parser.html create mode 100644 docs/reference/register_preprocessor.html create mode 100644 docs/reference/registry.html create mode 100644 docs/reference/resource-caching.html create mode 100644 docs/reference/resource.html create mode 100644 docs/reference/resource_name.html create mode 100644 docs/reference/search_pattern.html create mode 100644 docs/reference/simple_cache.html create mode 100644 docs/reference/sized_queue.html create mode 100644 docs/reference/strip_r_extension.html create mode 100644 docs/reference/strip_root.html create mode 100644 docs/reference/tower.html create mode 100644 docs/reference/virtual-resource.html diff --git a/.Rbuildignore b/.Rbuildignore new file mode 100644 index 0000000..2b2683d --- /dev/null +++ b/.Rbuildignore @@ -0,0 +1 @@ +^docs$ diff --git a/docs/LICENSE b/docs/LICENSE new file mode 100644 index 0000000..57cf4dc --- /dev/null +++ b/docs/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014-2017 Syberia, Avant, Robert Krzyzanowski + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/docs/articles/index.html b/docs/articles/index.html new file mode 100644 index 0000000..ae03cdc --- /dev/null +++ b/docs/articles/index.html @@ -0,0 +1,101 @@ + + + + + + + + +Articles • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ + + +
+
+
+

All vignettes

+

+ + +
+
+
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/articles/registry.html b/docs/articles/registry.html new file mode 100644 index 0000000..9a83557 --- /dev/null +++ b/docs/articles/registry.html @@ -0,0 +1,117 @@ + + + + + + + + • director + + + + + + +
+
+ + + +
+
+ + + + +
+ +
+

+Using registries to maintain state between R sessions

+

Frequently, there is a need to maintain state between consecutive R sessions without polluting the local project with temporary or configuration-related files.

+

director aims to solve this problem by providing a registry, a simple wrapper around reading and writing to a directory that takes cares of checking for non-existent paths.

+

A registry should be used only internally by a project to store data it needs to maintain across R sessions (or amongst different R sessions) and should not be exposed to the user. This is because the keys you choose to store values under are purely convention, and you do not want to give someone the ability to overwrite them.

+
r <- registry$new(file.path(dirname(tempfile()), '.registry'))
+# You don't have to use .registry, but making the directory hidden is preferable
+# as it is for internal use only.
+
+r$set('some/key', list('some', 5, 'value'))
+value <- r$get('some/key') # value is now the above list.
+print(value)
+
## [[1]]
+## [1] "some"
+## 
+## [[2]]
+## [1] 5
+## 
+## [[3]]
+## [1] "value"
+

You can perform complicated logic with this.

+
projects <- list(proj1 = list(config_key1 = 'config_value1', config_key2 = 'config_value2'),
+                 proj2 = list(config_key1 = 'settings_value1', config_key2 = 'settings_value2'))
+for (name in names(projects)) r$set(file.path(name, 'config'), projects[[name]])
+print(sapply(names(projects), function(name) r$get(file.path(name, 'config'))$config_key1))
+
##             proj1             proj2 
+##   "config_value1" "settings_value1"
+
+
+
+ + + +
+ + +
+ +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/authors.html b/docs/authors.html new file mode 100644 index 0000000..daa7c53 --- /dev/null +++ b/docs/authors.html @@ -0,0 +1,102 @@ + + + + + + + + +Authors • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
    +
  • +

    Robert Krzyzanowski. Author, maintainer. +

    +
  • +
+ +
+ +
+ + +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..3c4e88c --- /dev/null +++ b/docs/index.html @@ -0,0 +1,173 @@ + + + + + + + +Load, track, and manage dependencies in a file structure. • director + + + + + + +
+
+ + + +
+
+ +
+ + +

Director aims to partially solve the problem of project structure in R by re-defining R scripts as “resources” and allowing the developer to focus only on what is important: this makes code more modular and re-usable.

+
+
+

+Example

+

Suppose we wish to be able to read data in, perform some munging, and save it back to its source. One way to do this is as follows.

+
data <- read.csv('/some/file')
+# Do some munging
+write.csv(data, '/some/file')
+

This works, but there are some problems with it. We have tied the data-set to a specific source: a CSV file. What if we had hundreds of such scripts and wanted to migrate them to read and write from a database or an S3 location? We would have to update read.csv in every file. The same applies if we want to add stringsAsFactors = FALSE to each read.csv call.

+

An alternative approach is to create a directory adapters that takes the following convention: any file in that directory must be of the following form.

+
read <- function(key) {
+  # Implement this.
+}
+
+write <- function(value, key) {
+  # Implement this.
+}
+

For example, we could implement CSV reading and writing as:

+
# ./adapters/csv.R
+read <- function(key) {
+  read.csv(file.path("/some/path", paste0(key, ".csv")))
+}
+
+write <- function(value, key) {
+  write.csv(value, file.path("/some/path", paste0(key, ".csv")))
+}
+

Our original file could now become

+
# ./our_script.R
+function(adapter) {
+  data <- adapter$read("file1")
+  # Munge the data.
+  adapter$write(data, "file1")
+}
+

But what is adapter? We now use director to create a special adapter object that will know how to read and write in the same format given a key.

+
# ./run.R
+
+# Initialize a "director" object. It is responsible for determining
+# what to do with files in the adapters directory (and eventually more).
+library(director)
+d <- director(".")
+
+# We'll explain this later.
+d$register_parser("/adapters", function(input) {
+  structure(list(read = input$read, write = input$write), class = 'adapter')
+})
+
+adapter  <- d$resource("adapters/file")$value() # we will explain $value() later
+resource <- d$resource("our_script.R")$value()
+resource(adapter) # This will run our script and save the data.
+

Our scripts no longer depend on CSV reading. If we moved all our CSV files to RDS files, we would only have to modify what adapter gets passed to each script.

+

Now imagine we have hundreds of such scripts. We can put them in scripts and use director to find all scripts.

+
scripts <- d$find(base = "scripts") # Find all .R files in the scripts directory
+# [1] "scripts/script1" "scripts/script2" ...
+
+lapply(scripts, function(script) {
+  script <- d$resource(script)$value()
+  script(adapter)
+})
+

The above executes all scripts in the scripts directory using an adapter of our choice.

+
+
+

+Installation

+

Director is in active development and not yet available on CRAN (as of May 18, 2017). To install the latest development build directly from Github, run the following in the R console.

+
if (!require(devtools)) install.packages('devtools')
+devtools::install_github('syberia/director'); library(director)
+
+
+

+Creating a director

+
d <- director('~/your/R/projects/directory')
+

You can now look for all files in your project using d$find().

+
+

+License

+

This project is licensed under the MIT License:

+

Copyright (c) 2014-2017 Syberia, Avant, Robert Krzyzanowski

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

+

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
+
+

+Authors

+

This package was created by Robert Krzyzanowski, rob@syberia.io in late 2014.

+
+
+ +
+ + +
+ + +
+ +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/jquery.sticky-kit.min.js b/docs/jquery.sticky-kit.min.js new file mode 100644 index 0000000..e2a3c6d --- /dev/null +++ b/docs/jquery.sticky-kit.min.js @@ -0,0 +1,9 @@ +/* + Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net +*/ +(function(){var b,f;b=this.jQuery||window.jQuery;f=b(window);b.fn.stick_in_parent=function(d){var A,w,J,n,B,K,p,q,k,E,t;null==d&&(d={});t=d.sticky_class;B=d.inner_scrolling;E=d.recalc_every;k=d.parent;q=d.offset_top;p=d.spacer;w=d.bottoming;null==q&&(q=0);null==k&&(k=void 0);null==B&&(B=!0);null==t&&(t="is_stuck");A=b(document);null==w&&(w=!0);J=function(a,d,n,C,F,u,r,G){var v,H,m,D,I,c,g,x,y,z,h,l;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);I=A.height();g=a.parent();null!=k&&(g=g.closest(k)); +if(!g.length)throw"failed to find stick parent";v=m=!1;(h=null!=p?p&&a.closest(p):b("
"))&&h.css("position",a.css("position"));x=function(){var c,f,e;if(!G&&(I=A.height(),c=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),d=parseInt(g.css("padding-bottom"),10),n=g.offset().top+c+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q, +u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:a.outerWidth(!0),height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,c=q,z=E,l=function(){var b,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+c>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),eb&&!v&&(c-=l,c=Math.max(b-u,c),c=Math.min(q,c),m&&a.css({top:c+"px"})))):e>F&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+c>C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}), +a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);b(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize", +y),b(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l,0)}};n=0;for(K=this.length;n + + + + + diff --git a/docs/pkgdown.css b/docs/pkgdown.css new file mode 100644 index 0000000..9c437c7 --- /dev/null +++ b/docs/pkgdown.css @@ -0,0 +1,154 @@ +/* Sticker footer */ +body > .container { + display: flex; + padding-top: 60px; + min-height: calc(100vh); + flex-direction: column; +} + +body > .container .row { + flex: 1; +} + +footer { + margin-top: 45px; + padding: 35px 0 36px; + border-top: 1px solid #e5e5e5; + color: #666; + display: flex; +} +footer p { + margin-bottom: 0; +} +footer div { + flex: 1; +} +footer .pkgdown { + text-align: right; +} +footer p { + margin-bottom: 0; +} + +img.icon { + float: right; +} + +/* Section anchors ---------------------------------*/ + +a.anchor { + margin-left: -30px; + display:inline-block; + width: 30px; + height: 30px; + visibility: hidden; + + background-image: url(./link.svg); + background-repeat: no-repeat; + background-size: 20px 20px; + background-position: center center; +} + +.hasAnchor:hover a.anchor { + visibility: visible; +} + +@media (max-width: 767px) { + .hasAnchor:hover a.anchor { + visibility: hidden; + } +} + + +/* Fixes for fixed navbar --------------------------*/ + +.contents h1, .contents h2, .contents h3, .contents h4 { + padding-top: 60px; + margin-top: -60px; +} + +/* Static header placement on mobile devices */ +@media (max-width: 767px) { + .navbar-fixed-top { + position: absolute; + } + .navbar { + padding: 0; + } +} + + +/* Sidebar --------------------------*/ + +#sidebar { + margin-top: 30px; +} +#sidebar h2 { + font-size: 1.5em; + margin-top: 1em; +} + +#sidebar h2:first-child { + margin-top: 0; +} + +#sidebar .list-unstyled li { + margin-bottom: 0.5em; +} + +/* Reference index & topics ----------------------------------------------- */ + +.ref-index th {font-weight: normal;} +.ref-index h2 {font-size: 20px;} + +.ref-index td {vertical-align: top;} +.ref-index .alias {width: 40%;} +.ref-index .title {width: 60%;} + +.ref-index .alias {width: 40%;} +.ref-index .title {width: 60%;} + +.ref-arguments th {text-align: right; padding-right: 10px;} +.ref-arguments th, .ref-arguments td {vertical-align: top;} +.ref-arguments .name {width: 20%;} +.ref-arguments .desc {width: 80%;} + +/* Nice scrolling for wide elements --------------------------------------- */ + +table { + display: block; + overflow: auto; +} + +/* Syntax highlighting ---------------------------------------------------- */ + +pre { + word-wrap: normal; + word-break: normal; + border: 1px solid #eee; +} + +pre, code { + background-color: #f8f8f8; + color: #333; +} + +pre img { + background-color: #fff; + display: block; +} + +code a, pre a { + color: #375f84; +} + +.fl {color: #1514b5;} +.fu {color: #000000;} /* function */ +.ch,.st {color: #036a07;} /* string */ +.kw {color: #264D66;} /* keyword */ +.co {color: #888888;} /* comment */ + +.message { color: black; font-weight: bolder;} +.error { color: orange; font-weight: bolder;} +.warning { color: #6A0366; font-weight: bolder;} + diff --git a/docs/pkgdown.js b/docs/pkgdown.js new file mode 100644 index 0000000..c8b38c4 --- /dev/null +++ b/docs/pkgdown.js @@ -0,0 +1,8 @@ +$(function() { + $("#sidebar").stick_in_parent({offset_top: 40}); + $('body').scrollspy({ + target: '#sidebar', + offset: 60 + }); + +}); diff --git a/docs/reference/any_is_substring_of.html b/docs/reference/any_is_substring_of.html new file mode 100644 index 0000000..f9d7765 --- /dev/null +++ b/docs/reference/any_is_substring_of.html @@ -0,0 +1,131 @@ + + + + + + + + +Whether or not any substring of a string is any of a set of strings. — any_is_substring_of • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Whether or not any substring of a string is any of a set of strings.

+ + +
any_is_substring_of(string, set_of_strings)
+ +

Arguments

+ + + + + + + + + + +
string

character.

set_of_strings

character.

+ +

Value

+ +

logical

+ + +

Examples

+
stopifnot(director:::any_is_substring_of('test', c('blah', 'te', 'woo'))) # TRUE +stopifnot(!director:::any_is_substring_of('test', c('blah', 'woo'))) # FALSE
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/apply_pattern.html b/docs/reference/apply_pattern.html new file mode 100644 index 0000000..a8d7f9f --- /dev/null +++ b/docs/reference/apply_pattern.html @@ -0,0 +1,120 @@ + + + + + + + + +Apply a pattern filter to a character vector. — apply_pattern • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Apply a pattern filter to a character vector.

+ + +
apply_pattern(pattern, strings)
+ +

Arguments

+ + + + + + + + + + +
pattern

search_pattern.

strings

character. The strings to filter down.

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/check_if_parser_and_preprocessor_are_identical.html b/docs/reference/check_if_parser_and_preprocessor_are_identical.html new file mode 100644 index 0000000..cb02869 --- /dev/null +++ b/docs/reference/check_if_parser_and_preprocessor_are_identical.html @@ -0,0 +1,128 @@ + + + + + + + + +If the parser and preprocessor for a path is the same, the user has probably made a mistake. — check_if_parser_and_preprocessor_are_identical • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

If the parser and preprocessor for a path is the same, the user has probably made a mistake.

+ + +
check_if_parser_and_preprocessor_are_identical(director, path)
+ +

Arguments

+ + + + + + + + + + +
director

director. The director object.

path

character. The path to check for whether the preprocessor and +parser are identical.

+ +

Value

+ +

Nothing, but issue a warning in red crayon if they are identical, + since it likely means the user forgot to specify a parser.

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/complete_extension.html b/docs/reference/complete_extension.html new file mode 100644 index 0000000..e0b6424 --- /dev/null +++ b/docs/reference/complete_extension.html @@ -0,0 +1,145 @@ + + + + + + + + +Complete the extension of a file (.r or .R). — complete_extension • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Complete the extension of a file (.r or .R).

+ + +
complete_extension(name, base = NULL)
+ +

Arguments

+ + + + + + + + + + +
name

character. The filename sans extension.

base

character. A base path to be prefixed to name when +checking if the suffixed versions exist. The final returned string will +not include this base.

+ +

Value

+ +

name suffixed by ".r" or ".R" according to which exists. + (Many Unix-based systems are extension case-sensitive).

+ +

Note

+ +

This function assumes at least one file ending in .r or .R exists.

+ + +

Examples

+
not_run({ + # Assume we have a file \code{"foo.R"}. + stopifnot(complete_extension("foo") == "foo.R") + + # Assume we have a file \code{"bar.r"}. + stopifnot(complete_extension("bar") == "bar.R") +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/dependency-tracking.html b/docs/reference/dependency-tracking.html new file mode 100644 index 0000000..2f1add1 --- /dev/null +++ b/docs/reference/dependency-tracking.html @@ -0,0 +1,243 @@ + + + + + + + + +Track the dependencies of a resource. — dependency tracking • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

More complex resources are often built from simpler resources. It is +the responsibility of the dependency_tracker to determine +whether any dependencies have been modified.

+ + +
dependency_tracker(object, ..., dependency_tracker.return = "object")
+ +

Arguments

+ + + + + + + + + + + + + + +
object

active_resource. See active_resource.

...

additional parameters to pass to the next layer in the resource +parsing tower.

dependency_tracker.return.

What to return in this layer + of the parsing tower. The options are "dependencies", + "any_dependencies_modified", and "object". + + The former returns the list of recursive dependencies of the resource, + as of last time the resource was executed. + + Choosing "any_dependencies_modified" will answer whether any + of the files associated with the dependencies, or the resource + itself, have been modified.

+

The last (default) choice, "object", will return the parsed + resource's value as usual by proceeding with the resource parsing + tower.

+ +

Value

+ +

The parsed resource.

+ +

Details

+ +

The dependency_tracker is very good at its job and can track +arbitrarily nested dependencies (for example, if resource "foo" +needs resource "bar" who needs resource "baz", etc.). +But beware! The dependency_tracker won't tolerate circular +dependencies with anything except tears of anguish.

+

The local any_dependencies_modified is injected by the +dependency_tracker for use in the preprocessor or parser +of a resource. Note this is based off the dependencies last time +the resource was executed, since it is impossible to know a priori +what the dependencies will be prior to sourcing the resource's file.

+

The local dependencies, a character vector of (recursive) +dependencies is also injected.

+ +

Note

+ +

The local any_dependencies_modified rarely needs to be + used by a preprocessor or parser. You should usually use + resource caching instead.

+

The parameters must be named object and ... due to + this method's inclusion in a tower.

+ +

See also

+ +

active_resource, resource_caching, + tower

+ + +

Examples

+
not_run({ + # Imagine we are constructing a stagerunner from a sequence of functions. + # However, some of those functions have been built by other resources. + # Imagine the following structure. + # (See github.com/robertzk/stagerunner for an explanation of stagerunners.) + + #=== /dir/runners/project1.R === + list( + "import data" = resource("importers/db"), # These are some functions + "munge data" = resource("mungers/impute"), # built by the user + "create model" = resource("models/lm"), # that live in other + "export model" = resource("exporters/file") # files. + ) + + #=== /dir/importers/db.R === + conn <- resource("connections/dev") # A list representing a connection + # setting to a development database. + DBI::dbReadTable(conn, "some_table") + + #=== /dir/connections/dev.R + + #=== R console === + d <- director("/dir") # Create a director object. + d$register_preprocessor("runners/", + function(director, source, any_dependencies_modified) { + # `any_dependencies_modified` has been set by the dependency_tracker to + # TRUE or FALSE according as /dir/runners/project1.R *or any of its + # dependencies* has been modified. + if (any_dependencies_modified || + is.null(runner <- director$cache_get("last_runner"))) { + # Construct a new stageRunner, since a dependency has been modified. + source() + } else { runner } + }) + + d$register_parser("runners/", function(output) { + # If it is a stageRunner, it must have been retrieved from the cache. + if (stagerunner::is.stageRunner(output)) { return(output) } + runner <- stagerunner::stageRunner$new(new.env(), output) + + # Cache the runner so it is available in the preprocessor next time. + # As long as the /dir/runners/project1.R file remains untouched, we will + # not have to bother re-sourcing the file and hence reconstructing the + # stageRunner. + director$cache_set("last_runner", runner) + runner + }) + + sr <- d$resource("runners/project1") # A fresh new stageRunner! + sr2 <- d$resource("runners/project1") # Same one, since it used the cache. + stopifnot(identical(sr, sr2)) + + # We can use base::Sys.setFileTime to pretend like we updated the + # modified time of the /dir/connections/dev.R file, triggering + # `any_dependencies_modified = TRUE`. + Sys.setFileTime(file.path(d$root(), "connections", "dev.R"), + Sys.time() - as.difftime(1, units = "mins")) + + sr3 <- d$resource("runners/project1") # Now it re-builds the runner. + stopifnot(!identical(sr, sr3)) # A new runner! +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/director.html b/docs/reference/director.html new file mode 100644 index 0000000..e8abe66 --- /dev/null +++ b/docs/reference/director.html @@ -0,0 +1,152 @@ + + + + + + + + +Management and Tracking of Files in R Projects. — director • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

The director package is responsible for managing and loading resources in +some fixed directory structure. It has support for tracking changes between +consecutive loads of resources (so that we can tell if a script was modified +since we last ran it) and defining parsers that allow us to generalize from +the pernicious simple linear execution that is common to R.

+

A director is an R6 class responsible for +a collection of file-traversal related responsibilities.

+ + +
director_
+ +

Details

+ +

Throughout, a "resource" refers to an R script + with possible helper functions. A resource with helpers is identified + by the following heuristic: if a filename sans extension is identical + to its directory name, it is considered the primary accessible "resource" + with any accompanying helpers (files in the same directory) natively + invisible to the directory. For example, a file called "foo.R" + residing in directory "foo" will be accessible from the director + object using director_object$resource('foo'), but any other R scripts + in the "foo" directory will not be visible to the director object.

+

With this definition of resource, a director manages all of the following + relative to a root directory.

+
"Loading"

Grabbing resources relative to the root directory + using the resource method. This also provides information + about the last time the resource was grabbed (modification time, + previous body).

+
"Tracking"

Besides tracking information about the loaded resource + (and any previous versions of the loaded resource), the director also + maintains a stack of resources that have been loaded so far. This allows + one to, for example, force clear the stack, execute some code, and have + a list of resources that were relevant to the computation. The current + stack is available with director_object$stack(all = TRUE), which + will also clear it.

+
"Parsers"

Some resources are not intended to be merely executed, + but also parsed. For example, if we define several functions in an + R script, we have access to those functions if we had sourced it + with base::source(script, local = some_environment) as they + are now present in some_environment. A parser is a wrapper + around loading of resources that allows one to do some further + computation with this information. For example, we may define + a read and write function, but parse this information + into some IO object when fetching the resource. Thus, a resource + can function as inputs to some parser that produces some final + resource object. Parsers can be defined for full directories or + specific files.

+
+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/director_exists.html b/docs/reference/director_exists.html new file mode 100644 index 0000000..622ed43 --- /dev/null +++ b/docs/reference/director_exists.html @@ -0,0 +1,149 @@ + + + + + + + + +Determine whether a resource exists relative to a director object. — director_exists • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Determine whether a resource exists relative to a director object.

+ + +
director_exists(resource, helper = FALSE)
+ +

Arguments

+ + + + + + + + + + +
resource

character. The name of the resource.

helper

logical. Whether or not to check helper existence +in an idempotent resource. The default is FALSE.

+ +

Value

+ +

TRUE or FALSE according as it does or does not + exist.

+ + +

Examples

+
not_run({ + # Imagine we have a file structure: + # - foo + # - one + # - one.R + # - helper.R + # - two.R + # + # Then the bellow will return \code{TRUE}, \code{FALSE}, and \code{TRUE}, + # respectively. Note that the \code{"helper.R"} file is not considered a + # resource by the director as \code{"one.R"} shares its name with its + # parent directory and is considered the accessible resource. + + d <- director('foo') + d$exists('one') + d$exists('one/helper') + d$exists('two') +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/director_filename.html b/docs/reference/director_filename.html new file mode 100644 index 0000000..218b36c --- /dev/null +++ b/docs/reference/director_filename.html @@ -0,0 +1,146 @@ + + + + + + + + +Convert a resource to a filename. — director_filename • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Convert a resource to a filename.

+ + +
director_filename(name, absolute = FALSE, check.exists = TRUE,
+  helper = FALSE, enclosing = FALSE)
+ +

Arguments

+ + + + + + + + + + + + + + + + + + + + + + +
name

character. The resource name to convert to a full path.

absolute

character. Whether or not to return the absolute path +(i.e., prepended by the director root). The default is FALSE.

check.exists

logical. Whether or not to check if the file exists. +The default is TRUE. This argument should be set to false if the +we are certain the file exists and can skip the check.

helper

logical. Whether or not to handle helper files instead of +resources. The default is FALSE.

enclosing

logical. If TRUE and name refers to an +idempotent resource the directory name will be returned instead of the +.R file.

+ +

Value

+ +

the absolute path, relative to the director root if + absolute = FALSE and an absolute path if absolute = TRUE.

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/director_find.html b/docs/reference/director_find.html new file mode 100644 index 0000000..fdfc269 --- /dev/null +++ b/docs/reference/director_find.html @@ -0,0 +1,186 @@ + + + + + + + + +Find resources within a director project. — director_find • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Find resources within a director project.

+ + +
director_find(pattern = "", method = "wildcard", base = "",
+  by_mtime = TRUE)
+ +

Arguments

+ + + + + + + + + + + + + + + + + + +
pattern

character. The resources to search for. The default is +"", which will list all resources within the base.

method

character. The search method. The available options +are "wildcard", code"substring", or "exact". See the function +description for the full explanation of these methods. The default is +"wildcard".

base

character. A prefix under which to look for. For example, +if base = "subdir", then only resources under the "subdir" +directory (relative to the director root) will be returned. The default is +"", which will list all resources within the director root.

by_mtime

logical. Whether or not to sort results by modification time +in descending order. The default is TRUE, so that the first result +is the most recently modified resource.

+ +

Value

+ +

a character vector of matched resources.

+ +

Note

+ +

The available search methods are:

+
wildcard

Similar to Sublime or vim's ctrl + P, this method + of search will look for consecutive appearances of characters. + For example, if we have a resource "some_resource", then + looking for "so", "sre" or even "smsrc" will + return a match, since those characters occur consecutively in the + original resource name.

+
partial

This method will try to find a substring that + matches the resource name. For example, if we have + "dir/some_resource", then looking for "dir/some" will + return a match.

+
exact

The exact name of the resource. In this mode, either a + single string (the resource name itself) or character(0) will + be returned.

+
+ + +

Examples

+
not_run({ + # Imagine we have a file structure: + # - foo + # - one + # - one.R + # - helper.R + # - two.R + # + # Then the bellow will return \code{"foo/one"}, \code{"two"}, and \code{""}, + # respectively. Note that the \code{"helper.R"} file is not considered a + # resource by the director as \code{"one.R"} shares its name with its + # parent directory and is considered the accessible resource. + + d <- director('foo') + d$find('fone', method = 'wildcard') # "foo/one" + # Under the hood, this looks for the regex .*f.*o.*n.*e.* + d$find('wo', method = 'partial') # "two" + d$find('none', method = 'exact') # "" +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/drop_idempotence.html b/docs/reference/drop_idempotence.html new file mode 100644 index 0000000..c22d346 --- /dev/null +++ b/docs/reference/drop_idempotence.html @@ -0,0 +1,122 @@ + + + + + + + + +Convert an idempotent resource name to a non-idempotent resource name. — drop_idempotence • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Convert an idempotent resource name to a non-idempotent resource name.

+ + +
drop_idempotence(filename)
+ +

Arguments

+ + + + + + +
filename

character. The filename to convert.

+ +

Value

+ +

the non-idempotent filename.

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/duplicate.html b/docs/reference/duplicate.html new file mode 100644 index 0000000..930069f --- /dev/null +++ b/docs/reference/duplicate.html @@ -0,0 +1,116 @@ + + + + + + + + +Duplicate a function object. — duplicate • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Duplicate a function object.

+ + +
duplicate(original)
+ +

Arguments

+ + + + + + +
original

function.

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/enforce_type.html b/docs/reference/enforce_type.html new file mode 100644 index 0000000..f853b09 --- /dev/null +++ b/docs/reference/enforce_type.html @@ -0,0 +1,148 @@ + + + + + + + + +Enforce parameter types (logical, character, etc.). — enforce_type • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Enforce parameter types (logical, character, etc.).

+ + +
enforce_type(object, admissible_types, function_name,
+  name = deparse(substitute(object)))
+ +

Arguments

+ + + + + + + + + + + + + + + + + + +
object

ANY. An R object to enforce types on.

admissible_types

character. A character vector of allowed types.

function_name

character. The function this enforcement is occurring +in, for error messages.

name

character. The name of the parameter whose type is being +enforced. By default, the string expression passed in to the first +argument, object.

+ +

Value

+ +

Nothing, but error if the type does not match.

+ + +

Examples

+
not_run({ + x <- 1 + enforce_type(x, "logical", "myfunction") + # Will call stop() with the following error: + # "In 'myfunction', the 'x' parameter must be a character; instead, I got + # a logical. +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/extensionless_exists.html b/docs/reference/extensionless_exists.html new file mode 100644 index 0000000..64329b4 --- /dev/null +++ b/docs/reference/extensionless_exists.html @@ -0,0 +1,132 @@ + + + + + + + + +Determine whether an R file exists regardless of case of extension. — extensionless_exists • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Determine whether an R file exists regardless of case of extension.

+ + +
extensionless_exists(filename)
+ +

Arguments

+ + + + + + +
filename

character. The filename to test (possibly without extension).

+ +

Value

+ +

TRUE or FALSE if the filename exists regardless of + R extension.

+ + +

Examples

+
not_run({ + # Assume we have a file \code{"foo.R"}. The following all return \code{TRUE}. + extensionless_exists('foo.R') + extensionless_exists('foo.r') + extensionless_exists('foo') +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/get_helpers.html b/docs/reference/get_helpers.html new file mode 100644 index 0000000..6ffad4a --- /dev/null +++ b/docs/reference/get_helpers.html @@ -0,0 +1,140 @@ + + + + + + + + +Get all helper files associated with an idempotent resource directory. — get_helpers • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Get all helper files associated with an idempotent resource directory.

+ + +
get_helpers(path, ..., leave_idempotent = FALSE)
+ +

Arguments

+ + + + + + + + + + + + + + +
path

character. The *absolute* path of the idempotent resource.

...

additional parameters to pass to list.files.

leave_idempotent

logical. Whether or not to leave the +idempotent file (non-helper). By default FALSE.

+ +

Value

+ +

a character list of relative helper paths.

+ + +

Examples

+
not_run({ + # If we have a directory structure given by \code{"model/model.R"}, + # \code{"model/constants.R"}, \code{"model/functions.R"}, then the + # below will return \code{c("constants.R", "functions.R")}. + get_helpers("model") +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/grapes-less-than-less-than-grapes.html b/docs/reference/grapes-less-than-less-than-grapes.html new file mode 100644 index 0000000..102a586 --- /dev/null +++ b/docs/reference/grapes-less-than-less-than-grapes.html @@ -0,0 +1,132 @@ + + + + + + + + +Append to a list or environment, overwriting if necessary. — %<<% • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Append to a list or environment, overwriting if necessary.

+ + +
obj1 %<<% obj2
+ +

Arguments

+ + + + + + + + + + +
obj1.

The object to be appended to.

obj2.

The object to append.

+ + +

Examples

+
not_run({ + x <- list(a = 1) + x %<<% list(b = 2) # list(a = 1, b = 2) + x %<<% list(a = 2) # list(a = 2) + y <- list2env(x) + y %<<% list(b = 2) # environment with a = 1 and b = 2 + y %<<% list2env(list(b = 2)) # same as above + y %<<% list(a = 2) # environment with a = 2 +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/has_preprocessor.html b/docs/reference/has_preprocessor.html new file mode 100644 index 0000000..ae3ec4e --- /dev/null +++ b/docs/reference/has_preprocessor.html @@ -0,0 +1,123 @@ + + + + + + + + +Whether there exists a preprocessor for a resource. — has_preprocessor • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Whether there exists a preprocessor for a resource.

+ + +
has_preprocessor(resource_path)
+ +

Arguments

+ + + + + + +
resource_path

character. The resource name.

+ +

Value

+ +

TRUE or FALSE depending on whether there + is a preprocessor for this resource.

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/index.html b/docs/reference/index.html new file mode 100644 index 0000000..27583f4 --- /dev/null +++ b/docs/reference/index.html @@ -0,0 +1,332 @@ + + + + + + + + +Function reference • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

All functions

+

+
+

any_is_substring_of

+

Whether or not any substring of a string is any of a set of strings.

+

apply_pattern

+

Apply a pattern filter to a character vector.

+

check_if_parser_and_preprocessor_are_identical

+

If the parser and preprocessor for a path is the same, the user has probably made a mistake.

+

complete_extension

+

Complete the extension of a file (.r or .R).

+

dependency_tracker

+

Track the dependencies of a resource.

+

director_exists

+

Determine whether a resource exists relative to a director object.

+

director_filename

+

Convert a resource to a filename.

+

director_find

+

Find resources within a director project.

+

director

+

Management and Tracking of Files in R Projects.

+

drop_idempotence

+

Convert an idempotent resource name to a non-idempotent resource name.

+

duplicate

+

Duplicate a function object.

+

enforce_type

+

Enforce parameter types (logical, character, etc.).

+

extensionless_exists

+

Determine whether an R file exists regardless of case of extension.

+

get_helpers

+

Get all helper files associated with an idempotent resource directory.

+

%&lt;&lt;%

+

Append to a list or environment, overwriting if necessary.

+

has_preprocessor

+

Whether there exists a preprocessor for a resource.

+

initialize

+

Initialize a director object.

+

is.director

+

Whether or not an object is a director.

+

is.idempotent_directory

+

Whether or not a directory is an idempotent resource.

+

modification_tracker

+

Detect modifications to a resource.

+

parser

+

Apply the parser to a resource.

+

preprocessor

+

Apply the preprocessor to a resource.

+

register_parser

+

Register a resource parser.

+

register_preprocessor

+

Register a resource preprocessor

+

registry

+

A persistent on-disk cache of R objects associated with a directory.

+

resource_name

+

Convert a filename to a resource name.

+

caching_layer

+

Cache a resource's parsed value.

+

resource

+

Fetch a resource relative to a director object.

+

search_pattern

+

Define a search pattern for use with the find method on a director.

+

simple_cache

+

A simple caching structure.

+

sized_queue

+

Queue with size limit.

+

strip_r_extension

+

Strip R extension.

+

strip_root

+

Strip a root file path from an absolute filename.

+

tower

+

Create a tower of functions.

+

virtual_check

+

Mark a resource as virtual.

+
+
+ + +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/initialize.html b/docs/reference/initialize.html new file mode 100644 index 0000000..bf5491a --- /dev/null +++ b/docs/reference/initialize.html @@ -0,0 +1,138 @@ + + + + + + + + +Initialize a director object. — initialize • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Initialize a director object.

+ + +
initialize(root, project_name = "")
+ +

Arguments

+ + + + + + + + + + +
root

character. The root directory for the director.

project_name

character. The name of the director project. Useful for +error messages. For example, if a resource is not found, an error message +to the effect of "no resource foo found in your project_name +project" will be displayed.

+ +

Value

+ +

a director reference class object.

+ + +

Examples

+
not_run({ + director(tempdir()) + director(tempdir(), "my project") # Error messages on using the director's + # methods will now usually result in + # the ending "in project 'my project'". +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/is.director.html b/docs/reference/is.director.html new file mode 100644 index 0000000..860d7d2 --- /dev/null +++ b/docs/reference/is.director.html @@ -0,0 +1,116 @@ + + + + + + + + +Whether or not an object is a director. — is.director • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Whether or not an object is a director.

+ + +
is.director(x)
+ +

Arguments

+ + + + + + +
x

ANY.

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/is.idempotent_directory.html b/docs/reference/is.idempotent_directory.html new file mode 100644 index 0000000..ae8fb41 --- /dev/null +++ b/docs/reference/is.idempotent_directory.html @@ -0,0 +1,132 @@ + + + + + + + + +Whether or not a directory is an idempotent resource. — is.idempotent_directory • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

By definition, this means the directory contains a file with the same name +(ignoring extension) as the directory.

+ + +
is.idempotent_directory(dir)
+ +

Arguments

+ + + + + + +
dir

character. The directory to check.

+ +

Value

+ +

TRUE or FALSE according as the directory is idempotent. + There is no checking to ensure the directory exists.

+ + +

Examples

+
not_run({ + # If we have a directory foo containing foo.R, then + is.idempotent_directory('foo') + # is TRUE, otherwise it's FALSE. +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/modification-tracking.html b/docs/reference/modification-tracking.html new file mode 100644 index 0000000..512b989 --- /dev/null +++ b/docs/reference/modification-tracking.html @@ -0,0 +1,229 @@ + + + + + + + + +Detect modifications to a resource. — modification tracking • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

The modification_tracker is responsible for determining whether +any changes have been made to the file(s) associated to the given +resource.

+ + +
modification_tracker(object, ..., modification_tracker.return = "object",
+  modification_tracker.touch = TRUE)
+ +

Arguments

+ + + + + + + + + + + + + + + + + + +
object

active_resource. See active_resource.

...

additional parameters to pass to the next layer in the resource +parsing tower.

modification_tracker.return

character. What to return in this layer + of the parsing tower. The options are c("modified", "object").

+

The former returns whether or not the file associated with the resource + has been modified (or in the case of idempotent resources, the file and + its helpers). The resource itself will not be parsed.

+

The latter, "object", will parse the resource as usual. This is + the default.

modification_tracker.touch

logical. Whether or not to update an +internal cache that keeps track of last time the resource is modified. +This is an internal parameter that is set to FALSE by recursive +calls to director$resource to avoid polluting the modification +cache while investigating dependency changes. The default is TRUE.

+ +

Value

+ +

The parsed resource.

+ +

Details

+ +

If a modification has been detected, the local modified +will be injected for use in the preprocessor or parser for the resource.

+

Note that we can use the modification_tracker to determine +whether the resource has been modified: + director_object$resource(resource_name, + modification_tracker.touch = FALSE, + modification_tracker.return = "modified")

+

The use of modification_tracker.touch = FALSE is necessary to avoid +polluting the internal cache that determines whether or not the resource +has been modified.

+ +

Note

+ +

The parameters must be named object and ... due to + this method's inclusion in a tower.

+ +

See also

+ +

active_resource, tower

+ + +

Examples

+
not_run({ + # Imagine we are constructing a stagerunner from a sequence of functions. + # However, some of those functions have been built by other resources. + # Imagine the following structure. + # (See github.com/robertzk/stagerunner for an explanation of stagerunners.) + + #=== /dir/runners/project1.R === + list( + "import data" = resource("importers/db"), # These are some functions + "munge data" = resource("mungers/impute"), # built by the user + "create model" = resource("models/lm"), # that live in other + "export model" = resource("exporters/file") # files. + ) + + #=== R console === + d <- director("/dir") # Create a director object. + d$register_preprocessor("runners/", function(director, source, modified) { + # `modified` has been set by the modification_tracker to + # TRUE or FALSE according as /dir/runners/project1.R has been modified. + if (modified || is.null(runner <- director$cache_get("last_runner"))) { + # Construct a new stageRunner, since the file has been modified. + source() + } else { runner } + }) + + d$register_parser("runners/", function(output) { + # If it is a stageRunner, it must have been retrieved from the cache. + if (stagerunner::is.stageRunner(output)) { return(output) } + runner <- stagerunner::stageRunner$new(new.env(), output) + + # Cache the runner so it is available in the preprocessor next time. + # As long as the /dir/runners/project1.R file remains untouched, we will + # not have to bother re-sourcing the file and hence reconstructing the + # stageRunner. + director$cache_set("last_runner", runner) + runner + }) + + sr <- d$resource("runners/project1") # A fresh new stageRunner! + sr2 <- d$resource("runners/project1") # Same one, since it used the cache. + stopifnot(identical(sr, sr2)) + + # We can use base::Sys.setFileTime to pretend like we updated the + # modified time of the project1.R file, triggering `modified = TRUE`. + Sys.setFileTime(file.path(d$root(), "runners", "project1.R"), + Sys.time() - as.difftime(1, units = "mins")) + + sr3 <- d$resource("runners/project1") # Now it re-builds the runner. + stopifnot(!identical(sr, sr3)) # A new runner! +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/parser.html b/docs/reference/parser.html new file mode 100644 index 0000000..354c607 --- /dev/null +++ b/docs/reference/parser.html @@ -0,0 +1,140 @@ + + + + + + + + +Apply the parser to a resource. — parser • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Apply the parser to a resource.

+ + +
parser(object, ...)
+ +

Arguments

+ + + + + + + + + + + + + + +
object

active_resource. See active_resource.

...

additional parameters to pass to the next layer in the resource +parsing tower.

parse.

logical. Whether or not to apply the parser to the +resource. If FALSE, this is equivalent to sourcing the resource's +file without running its parser. By default, TRUE.

+ +

Value

+ +

The parsed resource, usually some useful R object.

+ +

Note

+ +

The parameters must be named object and ... due to + this method's inclusion in a tower.

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/preprocessor.html b/docs/reference/preprocessor.html new file mode 100644 index 0000000..2112cdd --- /dev/null +++ b/docs/reference/preprocessor.html @@ -0,0 +1,159 @@ + + + + + + + + +Apply the preprocessor to a resource. — preprocessor • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Hand in hand with parsers, preprocessors are the heart of director. The idea +is to allow the developer to do any additional stuff prior to sourcing an R +file. For example, if some helper functions are desired or some operators +should be overloaded for a DSL (domain-specific language), the preprocessor +can perform this prior to sourcing the R file.

+ + +
preprocessor(object, ..., parse. = TRUE)
+ +

Arguments

+ + + + + + + + + + + + + + +
object

active_resource. See active_resource.

...

additional parameters to pass to the next layer in the resource +parsing tower.

parse.

logical. Whether or not to apply the parser to the +resource. If FALSE, this is equivalent to sourcing the resource's +file without running its parser. By default, TRUE.

+ +

Value

+ +

The parsed resource if parse. = TRUE, and the preprocessed + resource otherwise.

+ +

Details

+ +

To define a preprocessor for routes in a given path, you can use the +register_preprocessor method on the director object.

+ +

Note

+ +

The parameters must be named object and ... due to + this method's inclusion in a tower.

+ +

See also

+ +

register_preprocessor, active_resource, + tower

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/register_parser.html b/docs/reference/register_parser.html new file mode 100644 index 0000000..33c8e02 --- /dev/null +++ b/docs/reference/register_parser.html @@ -0,0 +1,144 @@ + + + + + + + + +Register a resource parser. — register_parser • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Register a resource parser.

+ + +
register_parser(path, parser = function() { }, overwrite = FALSE,
+  cache = FALSE)
+ +

Arguments

+ + + + + + + + + + + + + + + + + + +
path

character. The prefix to look for in the director.

parser

function.

overwrite

logical. If TRUE, register_parser will overwrite +the route instead of erroring if the path already has a registered +parser. The default is FALSE.

cache

logical. Whether or not to cache resources processed with this +parser. Cached resources will not be re-parsed if their dependencies have +not been modified. This distinction is important, as most resources are +factory resources (the object they generate should not be shared across +the entire project; instead, a copy should be made). The default is FALSE.

+ + +

Examples

+
not_run({ + d <- director('some/project') + d$register_parser('models', function() { print("I am a ", resource, ", a model!") }) + r <- d$resource('models/some_model.R') + r$value() # Will print: I am a models/some_model, a model! +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/register_preprocessor.html b/docs/reference/register_preprocessor.html new file mode 100644 index 0000000..928ff07 --- /dev/null +++ b/docs/reference/register_preprocessor.html @@ -0,0 +1,135 @@ + + + + + + + + +Register a resource preprocessor — register_preprocessor • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Register a resource preprocessor

+ + +
register_preprocessor(path, preprocessor, overwrite = FALSE)
+ +

Arguments

+ + + + + + + + + + + + + + +
path

character. The prefix to look for in the director.

preprocessor

function.

overwrite

logical. If TRUE, register_preprocessor will overwrite +the route instead of erroring if the path already has a registered +preprocessor. The default is FALSE.

+ + +

Examples

+
not_run({ + d <- director("some/project") + d$register_preprocessor('models', function() { print("I am a ", resource, ", a model!") }) + r <- d$resource("models/some_model.R") + r$value() # Will print: I am a models/some_model, a model! +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/registry.html b/docs/reference/registry.html new file mode 100644 index 0000000..df14bef --- /dev/null +++ b/docs/reference/registry.html @@ -0,0 +1,132 @@ + + + + + + + + +A persistent on-disk cache of R objects associated with a directory. — registry • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Having a registry attached to a project is very helpful for maintaining +state across R sessions without encoding everything in the unreliable +.RData file.

+ + + +

Details

+ +

To create a registry, simply write r <- registry("some/directory"). +You can then use r$set('some/key', some_value) and +r$get('some/key') to set and retrieve values (arbitrary R objects).

+ +

Methods

+ + +
+
initialize(root = NULL)

Initialize a registry.

+
+ + +

Examples

+
not_run({ + r <- registry('some/dir') # Create "some/dir" and make a registry there. + r$set('some/key', value <- list(1,2,3)) + stopifnot(r$get('some/key'), value) +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/resource-caching.html b/docs/reference/resource-caching.html new file mode 100644 index 0000000..7b9b25c --- /dev/null +++ b/docs/reference/resource-caching.html @@ -0,0 +1,195 @@ + + + + + + + + +Cache a resource's parsed value. — resource caching • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

More complex resources are typically time-consuming to compile, or +are unnecessary to compile more than once per R session.

+ + +
caching_layer(object, ..., recompile. = FALSE)
+ +

Arguments

+ + + + + + + + + + + + + + +
object

active_resource. See active_resource.

...

additional parameters to pass to the next layer in the resource +parsing tower.

recompile.

logical. Whether or not to force the resource to +be recompiled (instead of retrieved from cache), regardless of +whether the resource or any of its dependencies have been modified.

+ +

Value

+ +

The parsed resource, retrieved from cache since the last time + the resource was executed if and only if the resource's file(s) and + none of its (recursive) dependencies have been modified.

+ +

Details

+ +

The caching_layer provides an internal caching mechanism that +will remember the value of the parsed resource and re-use it +unless the resource or any of its dependencies have been +modified (see dependency_tracking for an explanation of +how this is accomplished).

+ +

Note

+ +

The parameters must be named object and ... due to + this method's inclusion in a tower.

+ +

See also

+ +

active_resource, tower

+ + +

Examples

+
not_run({ + # Imagine we are constructing a stagerunner from a sequence of functions. + # However, some of those functions have been built by other resources. + # Imagine the following structure. + # (See github.com/robertzk/stagerunner for an explanation of stagerunners.) + + #=== /dir/runners/project1.R === + list( + "import data" = resource("importers/db"), # These are some functions + "munge data" = resource("mungers/impute"), # built by the user + "create model" = resource("models/lm"), # that live in other + "export model" = resource("exporters/file") # files. + ) + + #=== R console === + d <- director("/dir") # Create a director object. + d$register_parser("runners/", function(output) { + stagerunner::stageRunner$new(new.env(), output) + }, cache = TRUE) # Note the cache = TRUE argument. + + sr <- d$resource("runners/project1") # A fresh new stageRunner! + sr2 <- d$resource("runners/project1") # Same one, since it used the cache. + stopifnot(identical(sr, sr2)) + + # We can use base::Sys.setFileTime to pretend like we updated the + # modified time of the /dir/connections/dev.R file, triggering + # the caching layer to re-compile the resource. + Sys.setFileTime(file.path(d$root(), "runners", "project1.R"), + Sys.time() - as.difftime(1, units = "mins")) + + sr3 <- d$resource("runners/project1") # Now it re-builds the runner. + stopifnot(!identical(sr, sr3)) # A new runner, with hardly any work! +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/resource.html b/docs/reference/resource.html new file mode 100644 index 0000000..92818e7 --- /dev/null +++ b/docs/reference/resource.html @@ -0,0 +1,179 @@ + + + + + + + + +Fetch a resource relative to a director object. — resource • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Resources are R scripts that optionally have a "parser" attached +which takes the result of executing the file, including all of its local +variables, and does some additional computation. This is useful if, +for example, you are trying to define a standard format for creating a +reference class object by specifying some inputs, but want to make it +easy to provide those inputs by users.

+ + +
resource(name, ..., defining_environment. = parent.frame())
+ +

Arguments

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
name

character. The name of the resource (i.e. R script) relative +to the root of the director object.

provides

list or environment. A list or environment of values to provide +to the resource. The default is nothing, i.e., list(). Note that +provides will be coerced to an environment, and its parent +environment will be set to parent.env(topenv()) to prevent +access to global variables (and encourage modularity and lack of side +effects. There should always be a way to write your code without them).

body

logical. Whether or not to fetch the body of the resource.

soft

logical. Whether or not to modify the cache to reflect +the resource modification time and other details.

tracking

logical. Whether or not to perform modification tracking +by pushing accessed resources to the director's stack.

helper

logical. If TRUE, allow processing of helper files. + If a file shares its name with the parent directory (e.g., "foo" + and "foo/foo.R"), it is called an idempotent resource. Any other files + in the same directory as the idempotence resource, besides the file + itself, are called helper files, and are usually invisible to the + director object (e.g., "foo/other.R" if "foo/foo.R" exists).

+

If helper = TRUE, these will temporarily be treated as a + resource so that we can track whether they were modified and re-use + other directorResource features. By default, helper = FALSE.

+ +

Value

+ +

A directorResource object.

+ +

Details

+ +

This method will return a directorResource object that represents +that particular R script. A resource can have a preprocessor +and a link[=register_parser]{parser} attached to it.

+

The former determines how to source the R file. For example, if you need +to inject additional variables prior to sourcing it, you can do so +from the preprocessor.

+

The parser determines what to do with the R file after sourcing it. +It can tell what the dependencies of the file are (i.e., what other +resources were used when sourcing it), and whether or not it was modified +(i.e., whether the R file or any of its dependencies were modified).

+

Together, a preprocessor, parser, and source file compose a resource.

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/resource_name.html b/docs/reference/resource_name.html new file mode 100644 index 0000000..2ed0b64 --- /dev/null +++ b/docs/reference/resource_name.html @@ -0,0 +1,122 @@ + + + + + + + + +Convert a filename to a resource name. — resource_name • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Convert a filename to a resource name.

+ + +
resource_name(filename)
+ +

Arguments

+ + + + + + +
filename

character. The filename.

+ +

Value

+ +

the resource name (i.e., stripped of idempotence and extension).

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/search_pattern.html b/docs/reference/search_pattern.html new file mode 100644 index 0000000..75dfd62 --- /dev/null +++ b/docs/reference/search_pattern.html @@ -0,0 +1,164 @@ + + + + + + + + +Define a search pattern for use with the find method on a director. — search_pattern • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

A search pattern is one of the following:

+ + +
search_pattern(pattern, method)
+ +

Arguments

+ + + + + + + + + + +
pattern

character. The pattern to search for.

method

character. The search pattern method, one of "exact", +"partial", "wildcard", or "regex".

+ +

Details

+ +
+
exact

match. The strings must match exactly this value.

+
partial

match. The strings which contain this string as + a substring will be matched.

+
wildcard

match. Fuzzy matching like in the ctrl+p plugin + for vim. If the pattern is "abc", it will be translated to the + regular expression ".*a.*b.*c.*", that is, any characters followed + by an 'a' followed by any characters followed by a 'b' followed by + any characters followed by a 'c' followed by any characters (e.g., + "fabulous cake"). Note that wildcard match is case insensitive.

+
regex

match. Apply a regular expression filter to the + set of strings.

+
+ +

Note

+ +

Patterns can be combined using the | and & operators.

+ + +

Examples

+
not_run({ + d$find(search_pattern("this/file", "exact")) + # If d is a director object, the above will find exactly the resource + # "this/file". + + d$find(search_pattern("this", "partial")) + # The above will find any resource containing "this" as a substring. + + d$find(search_pattern("this", "wildcard")) + # The above will find any resource containing the consecutive letters + # "this" separated by arbitrary strings. + + d$find(search_pattern("foobar", "partial") | search_pattern("root", "exact")) + # The above will find any resource with the substring "foobar" or having + # exactly the name "root". +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/simple_cache.html b/docs/reference/simple_cache.html new file mode 100644 index 0000000..2741b31 --- /dev/null +++ b/docs/reference/simple_cache.html @@ -0,0 +1,113 @@ + + + + + + + + +A simple caching structure. — simple_cache • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

A simple caching structure.

+ + +
simple_cache()
+ +

Value

+ +

A list of four methods get, set, exists + and unset that modify another list under the hood.

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/sized_queue.html b/docs/reference/sized_queue.html new file mode 100644 index 0000000..26dddf4 --- /dev/null +++ b/docs/reference/sized_queue.html @@ -0,0 +1,133 @@ + + + + + + + + +Queue with size limit. — sized_queue • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

If you push more elements onto the queue than it has room for, they will +fall off screaming and wailing.

+ + +
sized_queue(size)
+ +

Arguments

+ + + + + + +
size

integer. Maximum number of elements in the queue.

+ + +

Examples

+
not_run({ + q <- sized_queue(size = 2) + q$push(1) + q$get(1) # 1 + q$get(2) # NULL + q$push(2) + q$get(1) # 2 + q$get(2) # 1 + q$push(3) + q$get(1) # 3 + q$get(2) # 2 + q$get(3) # NULL +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/strip_r_extension.html b/docs/reference/strip_r_extension.html new file mode 100644 index 0000000..9597e95 --- /dev/null +++ b/docs/reference/strip_r_extension.html @@ -0,0 +1,122 @@ + + + + + + + + +Strip R extension. — strip_r_extension • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Strip R extension.

+ + +
strip_r_extension(filename)
+ +

Arguments

+ + + + + + +
filename

character. The filename to strip.

+ +

Value

+ +

the filename without the '.r' or '.R' at the end.

+ + +
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/strip_root.html b/docs/reference/strip_root.html new file mode 100644 index 0000000..d869b0c --- /dev/null +++ b/docs/reference/strip_root.html @@ -0,0 +1,132 @@ + + + + + + + + +Strip a root file path from an absolute filename. — strip_root • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Strip a root file path from an absolute filename.

+ + +
strip_root(root, filename)
+ +

Arguments

+ + + + + + + + + + +
root

character. The root path.

filename

character. The full file name.

+ +

Value

+ +

the stripped file path.

+ + +

Examples

+
not_run({ + stopifnot("test" == strip_root("foo/bar/test", "test")) +})
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/tower.html b/docs/reference/tower.html new file mode 100644 index 0000000..5cdc58c --- /dev/null +++ b/docs/reference/tower.html @@ -0,0 +1,171 @@ + + + + + + + + +Create a tower of functions. — tower • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

A tower is equivalent to the Ruby gem Rack's notion of middleware.

+ + +
tower(functions = list())
+ +

Arguments

+ + + + + + +
functions

list. A list of functions in the tower. The +first argument of each function must be named "object" and +each function must take a ... parameter. By default +list(), which creates an identity tower that performs +no operation.

+ +

Value

+ +

An S3 "tower" object, which is a callable function + and must be passed the object as the first argument. + Additional arguments will be passed to the first function + in the tower.

+ +

Details

+ +

Imagine a function f1 that, in the middle of its processing, +calls another function, f2, which in the middle of its +processing, calls another function, f3, and so on.

+

To construct such a structure from the list of functions +list(f1, f2, ...) we need to be able to call the +next "inner" function from the previous outer function.

+

This is accomplished by providing a yield keyword +which simply calls the next function in the tower.

+

The purpose of a tower is to modify some primary object +throughout its operation. To this end, an object keyword +will be provided to each tower function. If object is +modified prior to a yield call, the next function in +the tower will receive the modified object.

+

For composability, every function in a tower should have a +yield keyword. The last function in the tower will +yield to an identity function that simply returns the object.

+ + +

Examples

+
functions <- list( + function(object, ...) { + object <- object + 1 + object <- yield() + object + 1 + }, + + function(object, ...) { + object <- object * 2 + yield() + } +) + +t <- tower(functions) +v <- t(1) # This is now 5, since in the tower, we increment object, + # Multiply it by 2 in the next function, then increment it + # again after receiving the previous function. +stopifnot(v == 5)
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + diff --git a/docs/reference/virtual-resource.html b/docs/reference/virtual-resource.html new file mode 100644 index 0000000..87c07d4 --- /dev/null +++ b/docs/reference/virtual-resource.html @@ -0,0 +1,203 @@ + + + + + + + + +Mark a resource as virtual. — virtual resource • director + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +

Virtual resources are those that are not recorded as a .R file. Instead, +the resource's value must be computed using a preprocessor.

+ + +
virtual_check(object, ..., virtual_check.skip = FALSE)
+ +

Arguments

+ + + + + + + + + + + + + + +
object

active_resource. See active_resource.

...

additional parameters to pass to the next layer in the resource +parsing tower.

virtual_check.skip

logical. Whether or not to skip the virtual +check entirely. Generally only used by internal calls.

+ +

Value

+ +

The parsed resource.

+ +

Details

+ +

For example, imagine we have a directory of resources where some of the +resources have been re-factored into a package. We would still like to be +able to turn objects from that package into proper resources, but they +may no longer be encoded as files in the Syberia project.

+

Instead, we could define a preprocessor that looks for those special values +and uses the package objects instead.

+

When parsing a resource, the local virtual is injected for use in +the preprocessor which corresponds to whether the resource seems +non-existent to the director (i.e., has no supporting .R file).

+ +

Note

+ +

The parameters must be named object and ... due to + this method's inclusion in a tower.

+ +

See also

+ +

active_resource, tower

+ + +

Examples

+
not_run({ + # We will use the example of a syberia project. + # See github.com/robertzk/syberia. + + # lib/mungebits has imputer.R and no other files, but the package + # syberiaMungebits has more mungebits. We can define the following + # preprocessor. + + #=== config/routes.R === + list( + "lib/mungebits" = "mungebits" + ) + + #=== lib/controllers/mungebits.R === + preprocessor <- function(resource, virtual) { + mungebit <- basename(resource) # lib/mungebits/discretizer becomes discretizer + if (virtual) { + if (exists(mungebit, envir = getNamespace("syberiaMungebits"), inherits = FALSE)) { + # The function exists in the syberiaMungebits package. + get(mungebit, envir = getNamespace("syberiaMungebits"))))) + } else { + stop("No mungebit called ", sQuote(resource)) + } + } else { + source() # Source the mungebit file as usual + } + } + + # Construct the mungebit parser as usual. + function(output) { mungebits::mungebit(output$train, output$predict) } + + #=== R console === + d <- syberia_project("/some/dir") + d$resource("lib/mungebits/imputer") # Will use lib/mungebits/imputer.R + d$resource("lib/mungebits/discretizer") # Will use syberiaMungebits::discretizer +}) +
#> Error: <text>:20:67: unexpected ')' +#> 19: # The function exists in the syberiaMungebits package. +#> 20: get(mungebit, envir = getNamespace("syberiaMungebits"))) +#> ^
+
+ +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + From 2cb8c50af0ddbf09b993ea8af4eddb7df12fe0af Mon Sep 17 00:00:00 2001 From: Jason French Date: Fri, 19 May 2017 13:40:40 -0500 Subject: [PATCH 2/5] Update pkgdown with latest --- .Rbuildignore | 1 + docs/index.html | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index 2b2683d..77437c6 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1 +1,2 @@ ^docs$ +^\.\./syberia\.github\.io/docs/packages/director$ diff --git a/docs/index.html b/docs/index.html index 3c4e88c..4fd6749 100644 --- a/docs/index.html +++ b/docs/index.html @@ -47,9 +47,9 @@
-
+

Director aims to partially solve the problem of project structure in R by re-defining R scripts as “resources” and allowing the developer to focus only on what is important: this makes code more modular and re-usable.

From bbdc15740beda15ce3471463caa6039b053c51d9 Mon Sep 17 00:00:00 2001 From: Jason French Date: Fri, 23 Jun 2017 16:13:14 -0500 Subject: [PATCH 3/5] Update roxygen2 --- .travis.yml | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index e09855f..129f9f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,16 @@ -language: c +language: r +sudo: required +cache: packages dist: trusty -before_install: -- curl -OL http://raw.github.com/craigcitro/r-travis/master/scripts/travis-tool.sh -- chmod 755 ./travis-tool.sh -- "./travis-tool.sh bootstrap" -install: -- "./travis-tool.sh install_deps" -- "./travis-tool.sh install_r testthat microbenchmark crayon" -- "./travis-tool.sh install_github robertzk/testthatsomemore" -- "./travis-tool.sh github_package jimhester/covr" -script: "./travis-tool.sh run_tests" -after_failure: -- "./travis-tool.sh dump_logs" +r_github_packages: + - robertzk/testthatsomemore + - kirillseva/covr +r_binary_packages: + - testthat + - microbenchmark + - crayon + - roxygen2 + after_success: - "Rscript -e 'library(covr);coveralls()'" notifications: From 645148b6187bab94d9f4a7afe649d0234c504dc8 Mon Sep 17 00:00:00 2001 From: Jason French Date: Fri, 23 Jun 2017 17:04:28 -0500 Subject: [PATCH 4/5] Enable matrix builds --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 129f9f6..08e1f58 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,11 @@ language: r sudo: required cache: packages dist: trusty +r: + - oldrel + - release + - devel + r_github_packages: - robertzk/testthatsomemore - kirillseva/covr From a2594f2a157bf9c95eba89f78c953e0c143473b0 Mon Sep 17 00:00:00 2001 From: Jason French Date: Fri, 23 Jun 2017 17:10:35 -0500 Subject: [PATCH 5/5] Enable matrix builds --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 08e1f58..f701e83 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,3 +33,7 @@ notifications: template: - "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message} | Details: %{build_url} | Changes: %{compare_url}" + +env: + - global: + - WARNINGS_ARE_ERRORS=1