How to create a UUID for a Julia Package? - julia

I have a local package which I created from a template. The template repo already had a UUID in the project.toml file. I now need to generate a new UUID for the package but don't necessarily need to create a whole package from scratch, just the UUID. Do I still need to use PackageTemplates.jl and then copy and paste the UUID or is there a function for this? I tried the suggestion here: https://discourse.julialang.org/t/how-to-give-a-valid-uuid-to-an-existing-package-and-how-to-desactivate-an-environment/19236 but that is out of date now.

Julia code for generating packages (Method Pkg.generate) at generate.jl reads:
uuid = UUIDs.uuid4()
So the correct method seems to be:
julia> using UUIDs
julia> UUIDs.uuid4()
UUID("268e34f8-cc7d-4112-bf3a-0d45b12e3d15")
Reference:
https://github.com/JuliaLang/Pkg.jl/blob/b963d05a89cfacaa0fe57752de5f3fb439ccfa43/src/generate.jl#L49

Related

Read a package NAMESPACE file

I am looking for a fast R solution to read a package NAMESPACE file. The solution should contain already preprocessed (and aggregated) records and separated imports and exports.
Unfortunately I can’t use getNamespaceExports("dplyr")/getNamespaceImports("dplyr") as they need the package to be loaded to the R session, which is too slow.
I need a solution which simply process a text from the NAMESPACE file. Any solutions using external packages as well as partial solutions would still be welcome.
The raw data we could grabbed with a call like readLines("https://raw.githubusercontent.com/cran/dplyr/master/NAMESPACE"). roxygen2 generated files are formatted properly, but this will be not true for all manually generated files.
EDIT:
Thanks to Konrad R. answer I could develop such functionality in my new CRAN package - pacs. I recommended to check pacs::pac_namespace function. There is even one function which goes one step further, comparing NAMESPACE files between different package versions pacs::pac_comapre_namespace.
The function is included in R as base::parseNamespaceFile. Unfortunately the function does not directly take a path as an argument. Instead it constructs the path from a package name and the library location. However, armed with this knowledge you should be able to call it; e.g.:
parseNamespaceFile('dplyr', .libPaths()[1L])
EDIT
Somebody has to remember that the whole packages imports (like import(rlang)) have to be still invoked with the same function and the exports for them extracted. Two core elements are using parse on NAMESPACE code and then using the recursive extract function parseDirective.

Restore a previous version of a file using the aws.s3 package in R

I am trying to write a function in R with the package aws.s3 that allows previous versions of a file (object) to be restored (from AWS S3's versioning feature). I haven't found a solution yet - but if anyone has one, or has done this before any help would be much appreciated!
I think a good start would be the ability to be able to retrieve the versions of individual bucket objects, using get_versions - I've tried get_verions(bucket="bucket/path_to_object") and get_verions(bucket="bucket", path = "path_to_object) but I don't think either of these work?
It doesn't technically answer the question, but you can do it easily with the paws package. You can just do
s3$list_object_versions("bucket",Prefix = prefix)
s3$get_object("bucket",Key=key,VersionId = vid)

How to call R script from another R script, both in same package?

I'm building a package that uses two main functions. One of the functions model.R requires a special type of simulation sim.R and a way to set up the results in a table table.R
In a sharable package, how do I call both the sim.R and table.R files from within model.R? I've tried source("sim.R") and source("R/sim.R") but that call doesn't work from within the package. Any ideas?
Should I just copy and paste the codes from sim.R and table.R into the model.R script instead?
Edit:
I have all the scripts in the R directory, the DESCRIPTION and NAMESPACE files are all set. I just have multiple scripts in the R directory. ~R/ has premodel.R model.R sim.R and table.R. I need the model.R script to use both sim.R and table.R functions... located in the same directory in the package (e.g. ~R/).
To elaborate on joran's point, when you build a package you don't need to source functions.
For example, imagine I want to make a package named TEST. I will begin by generating a directory (i.e. folder) named TEST. Within TEST I will create another folder name R, in that folder I will include all R script(s) containing the different functions in the package.
At a minimum you need to also include a DESCRIPTION and NAMESPACE file. A man (for help files) and tests (for unit tests) are also nice to include.
Making a package is pretty easy. Here is a blog with a straightforward introduction: http://hilaryparker.com/2014/04/29/writing-an-r-package-from-scratch/
As others have pointed out you don't have to source R files in a package. The package loading mechanism will take care of losing the namespace and making all exported functions available. So usually you don't have to worry about any of this.
There are exceptions however. If you have multiple files with R code situations can arise where the order in which these files are processed matters. Often it doesn't matter or the default order used by R happens to be fine. If you find that there are some dependencies within your package that aren't resolved properly you may be faced with a situation where a custom processing order for the R files is required. The DESCRIPTION file offers the optional Collate field for this purpose. Simply list all your R files in the order they should be processed to satisfy the dependencies.
If all your files are in R directory, any function will be in memory after you do a package build or Load_All.
You may have issues if you have code in files that is not in a function tho.
R loads files in alphabetical order.
Usually, this is not a problem, because functions are evaluated when they are called for execution, not at loading time (id. a function can refer another function not yet defined, even in the same file).
But, if you have code outside a function in model.R, this code will be executed immediately at time of file loading, and your package build will fail usually with a
ERROR: lazy loading failed for package 'yourPackageName'
If this is the case, wrap the sparse code of model.R into a function so you can call it later, when the package has fully loaded, external library too.
If this piece of code is there for initialize some value, consider to use_data() to have R take care of load data into the environment for you.
If this piece of code is just interactive code written to test and implement the package itself, you should consider to put it elsewhere or wrap it to a function anyway.
if you really need that code to be executed at loading time or really have dependency to solve, then you must add the collate line into DESCRIPTION file, as already stated by Peter Humburg, to force R to load files order.
Roxygen2 can help you, put before your code
#' #include sim.R table.R
call roxygenize(), and collate line will be generate for you into the DESCRIPTION file.
But even doing that, external library you may depend are not yet loaded by the package, leading to failure again at build time.
In conclusion, you'd better don't leave code outside functions in a .R file if it's located inside a package.
Since you're building a package, the reason why you're having trouble accessing the other functions in your /R directory is because you need to first:
library(devtools)
document()
from within the working directory of your package. Now each function in your package should be accessible to any other function. Then, to finish up, do:
build()
install()
although it should be noted that a simple document() call will already be sufficient to solve your problem.
Make your functions global by defining them with <<- instead of <- and they will become available to any other script running in that environment.

I'm writing a package. How can make it such that when library(my_package) is called, other packages are loaded as well?

Title should be pretty clear I hope. I'm writing a package called forecasting, with imports for dplyr among other packages. With the imports written in to the DESCRIPTION file, I am able to force these other packages to be installed along with forecasting - is there an equivalent way to do this for the loading of the package? In other words, is there a way that when I load my package with library(forecasting), it automatically also loads dplyr and the other packages?
Thanks
Yes.
Re-read "Writing R Extensions". The Depends: forces both the initial installation as well as the loading of the depended-upon packages.
But these days you want Imports: along with importFrom() in the NAMESPACE file which is more fine-grained.
But first things first: get it working with Depends.
Edit:
Opps you're correct, the documentation I referenced is not a primary source. Perhaps this is better:
From the R documentation:
The ‘Depends’ field gives a comma-separated list of package names which this package depends on. Those packages will be attached before the current package when library or require is called.
and
The ‘Imports’ field lists packages whose namespaces are imported from (as specified in the NAMESPACE file) but which do not need to be attached. Namespaces accessed by the ‘::’ and ‘:::’ operators must be listed here, or in ‘Suggests’ or ‘Enhances’
Original:
From the R packages documentation:
Adding a package dependency here [the DESCRIPTION file] ensures that it’ll be installed. However, it does not mean that it will be attached along with your package (i.e., library(x)). The best practice is to explicitly refer to external functions using the syntax package::function(). This makes it very easy to identify which functions live outside of your package. This is especially useful when you read your code in the future.

Split an R package into two packages without disrupting users

Suppose I'm currently developing a package called mypackage. As time goes by, many different functions have landed in there, and I want to reorganize it. So I'd like to create a new package called newpackage in which I would move some of the functions of mypackage (and include new ones later).
The problem is that I don't want original users of mypackage to get object not found errors when they want to use one of the moved functions.
So, I thought about doing the following :
create newpackage and move the functions
add into mypackage DESCRIPTION file : Depends: newpackage
As such, when people would install, upgrade or load mypackage, newpackage would be installed or loaded too, and all the functions would be available.
Do you think it would work, or would there be some problems I don't think about ?
Thanks !
Isn't it so that it is not recommended to remove functions from a package without labeling them first to be depreciated?! So, maybe you proceed as you planned but before removing them from the mypackage, you could first mark them there as depreciated and then remove them from it finally in the next version of the package. And during the migrating phase you could use the namespace of the packages to refer already to the function in newpackage as you planned.

Resources