Closed klmr closed 3 years ago
The question is: why is box::use
searching the path C:/Users/greg/OneDrive - My Company/Documents
instead of C:\Users\greg\OneDrive - My Company\Desktop\Projects\Automations\Templates\Template (01)
?
Correct, that is indeed the question!
To be clear, this not the global module search path, since box.path
will only ever be set to a universally accessible location on a shared drive or server. Rather, it is the relative search path for project-specific modules, which fall within the \Resources\Modules
subdirectory of that project; here
C:\Users\greg\OneDrive - My Company\Desktop\Projects\Automations\Templates\Template (01)\Resources\Modules
.
I can say with confidence that the working directory was C:/Users/greg/OneDrive - My Company/Documents
, when I ran getwd()
from the console before source()
ing Script.R
in RStudio; and also that setwd(this.path::this.dir())
worked as intended at the beginning of Script.R
.
While I haven't had a chance to fire up my work computer, I suspect that RStudio defaults to my Documents
folder. That's why I am generally careful to "recalibrate" the working directory to this.path::this.dir()
at the start of each script.
Have you considered incorporating the this.path
package into box
as a one of its imports, and then availing yourself of the this.path::this.path()
function?
This could be used in default behavior for box::set_script_path()
, such that the path
parameter defaults to either
this.path::this.path()
whenever there is an R document in play
orNULL
whenever there is no R document in play, in which case this.path::this.path()
will throw an error like
Error in this.path::this.path() :
'this.path' used in an inappropriate fashion
Alternatively, you could automatically attempt this call to this.path::this.path()
, whenever the user makes a local call to project-specific modules:
box::use(./relative/path/to/local/module)
Then again, I fully understand if you want to limit dependency on external packages that (unlike base
and tools
) do not come with R.
Have you considered incorporating the this.path package into box as a one of its imports, and then availing yourself of the
this.path::this.path()
function?
That isn’t a bad idea by any means. But ‘box’ already implements (some of) the same functionality, so it shouldn’t need ‘this.path’ (it implements it differently, but for reasons that shouldn’t matter here). Anyway, I’ve just now found out why ‘box’ fails here so I should have a fix soon. I also found another (unrelated) bug in the functionality, so this was worthwhile!
Apart from the above: as you’ve guessed, keeping ‘box’ free of dependencies is an important goal, since it’s an “infrastructure package”, so its installation should both be as easy as possible, and not depend on other things that might break.
Great to know! Thank you for your transparency and attentiveness, Konrad!
I do have one further question: is there a way to permanently set the box.path
option? Much like some options
that do not come already baked into one's .Rprofile
, the box.path
does not persist from session to session. While some options
might fail to persist in value, and thus "reset" their values with every new session, it appears that box.path
will not even exist after terminating R, when getOption("box.path")
returns NULL
.
Ideally, one might wish to set box.path
once and for all, as with .libPaths()
. Do you think this is possible? If so, is this a topic for a whole new thread?
Thanks again! — Greg
I’m not sure I understand … (why) can’t you persist the option inside your .Rprofile
? After all, that’s where you’d normally customise other options and potentially .libPaths
as well.
Alternatively, and just like the package library path, you can use an environment variable to set the path, R_BOX_PATH
. This variable can be set either for your whole terminal session (e.g. in ~/.bashrc
or ~/.profile
) or for R only, inside your .REnviron
file.
For more information, see the documentation, box::use
: Search paths and more generally the R documentation about R startup.
Thanks, I'll check out those links!
I was merely hoping there might be functionality within box
to achieve the same effect. If I recall, when I used the bigrquery
package, it cached some of the oath configuration permanently, so I didn't have to reconfigure everything after starting a new session. Then again, this might be significantly more complicated than I imagine, and I can always do it by hand.
Hmm I think we might be talking past each other. The way I mentioned definitely allows to persist this configuration “permanently”, effortlessly, and I’m fairly sure that this is the intended way as far as R is concerned. Of course ‘box’ could maintain its own configuration file and variables instead of using R’s provide options but to what end?
(If I understand the ‘bigrquery’ use-case correctly then it’s different because it stores credentials, which are potentially sensitive user secrets, so they shouldn’t necessarily reside in the regular .Rprofile
, which might be under version control or otherwise shared.)
Or are you looking for a function inside ‘box’ which merely writes the configuration to the user’s .Rprofile
? I.e. something along these lines (omitting any error checking and sanitisation):
save_module_path = function (path) {
init_code = sprintf('options(box.path = %s)', deparse(path))
writeLines(init_code, Sys.getenv('R_PROFILE_USER'))
}
… to be honest I don’t see the value of such a function because it automates a process that’s already trivial (= open the .Rprofile
file in an editor, add the desired code), and implementing it correctly is actually quite complex (e.g. users might prefer writing to .REnviron
, and they might want to choose between global and user-specific configuration) and brittle (at minimum the code above should check whether the file in question actually exists, and needs to guard against including the configuration repeatedly if the user calls the function more than once). Lastly, CRAN does not like packages which write to user configuration files: such submission are automatically flagged and always need to be manually checked and green-lit. This causes submission delays and work for the CRAN maintainers.
Thank you for this detailed explanation! I certainly appreciate your reasoning, and I'm very inclined to agree.
Regarding your statement
To be honest I don’t see the value of such a function because it automates a process that’s already trivial (= open the
.Rprofile
file in an editor, add the desired code)
the only reason I wanted such a function is that these scripts, which employ box
to access my modules, are ultimately executed by a VM. So I would love for everything to be handled once and for all, in as portable and "hands-off" a manner as possible (ie. by a single call to save_module_path()
within a script).
However, given the complications, I should probably just do it manually.
Thanks again! — Greg
Via Stack Overflow: