1

I'm working on a fork of a package that depends upon the ReporteRs library.

However, this library has been deprecated by its owner for a few years, in favour of the officer and flextable libraries.

On of the main reasons for this depreciation is not to depend on rJava, which may cause installation problems and bugs.

In my package, how should I manage this case?

So far, my package was processing data to return a ReporteRs object. If I change my functions to return an officer object I would break backward compatibilty.

But if I don't, and keep old, ReporteRs returning function as legacy backward compatibilty functions, I have to keep ReporteRs in my dependencies and my package would be rJava-dependant.

Is there a win-win solution?

Dan Chaltiel
  • 7,811
  • 5
  • 47
  • 92
  • I think that the answer is in the question: why would you break the backward compatibility? I can think of several ways of at least controlling the damage, if not completely ensuring b. compatibility without using rJava, but that depends on how exactly this compatibility is broken. Also, I think that removing dependence on rJava is a goal worth fighting for. – January Jul 22 '19 at 07:52
  • @January I've tried to clarify my question, is that better? – Dan Chaltiel Jul 22 '19 at 07:58
  • Is your package public? How many users do you have? Do they use those functions? Since ReporteRs is archived in CRAN it will be more difficult to install it, so I guess it makes sense to break backwards compatibility and drop it. If your user base is large enough and you can afford the effort, you could consider exploring why ReporteRs was archived, fix the issues and step up as a maintainer for a while until all your users have adopted the new functions. – zeehio Jul 22 '19 at 08:16
  • Slightly better; I still lack an example of *why* you cannot implement your function keeping it's parameters / definition but using officer / flextable behind the curtains. – January Jul 22 '19 at 08:20
  • Ah. In that case, it is possible to make the package conditionally dependent on another package (as in 'please install `ReportR` if you want to run this legacy function` and have the package in `Suggests` rather than `Depends`). – January Jul 22 '19 at 09:08
  • You can use `if(require(ReportR))` or `if(requireNamespace(ReportR))` for that AFAIR. See example [here](https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Suggested-packages). – January Jul 22 '19 at 09:16

1 Answers1

1

Here is what I would do:

  1. Make your best attempt to re-implement your functions with the officer library, but keeping your old API. Make sure that you warn the users that these functions are deprecated. At the same time make new functions fully compliant with officer/flextable syntax. Note that you might change the behavior of the functions slightly (as in, not ensuring all parameters are properly evaluated), as long as they take the same parameters and return the same type of objects.
  2. If that is really not possible, just add a compatibility warning to your old functions.
  3. Create a transitional package version that you would keep around for a few weeks or months with both versions of these functions. If the package still needs to depend on rJava, tough luck.
  4. Keep track of the packages that depend on your package. If there are not too many, you can contact their developers directly. Maybe the issue is not as serious as you think it is?

EDIT: As discussed above, you can make your dependency on ReportR conditional on the availability of ReportR. Then, you can put ReportR into the Suggests field of the DESCRIPTION file rather than Depends, and in the package you can use code like this:

if(requireNamespace("ReportR")) {
   warning("This function is deprecated, better use MyNewFunction instead")
   ReportR::whatever() ...
} else {
   warning("To run this (deprecated) function, please install the ReportR package")
}
January
  • 16,320
  • 6
  • 52
  • 74