---
title: "About the `abusethis` package"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{About the `abusethis` package}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  prompt=TRUE,
  collapse = TRUE,
  comment = "#>"
)
```

# History

In the old days people doing casual work tended to not write packages,
and instead developed their own ways of working - often using `source` to read
a file of function definitions into their working environment. To structure 
this a bit more, maybe they put functions into separate files and then wrote a
"master" file that called `source` on everything else they needed. Make one tiny
edit, then `source` everything.

The alternative, putting your code into packages, meant you could have
a well-structured folder of code and documentation, including
dependency specification, compiled languages, vignettes and all that
goodness. But the downside was you had to build and install the package after
every change. Users eventually developed ways to create things more like
Python modules that could be attached and detached. 

# Devtools

The `devtools` package gave us an easier way to work with the package structure
without needing to build and reinstall on every change. A simple `load_all` call
would detach the old package, recompile any compiled code that needed going, and
attach the new code. It took care of all the details and worked pretty well.

I started using it and developed a discipline of putting all my code into a 
package structure. This meant sometimes I was working on multiple packages at
once - for example I might be implementing a new statistical method and have a
dataset for it. That method would have its own package, and the dataset would
have another package for functions for loading and cleaning the data. That meant
I would end up with a general package for a statistical method that could be 
shared, and a package for the specific project for manipulating the data and
producing the project outputs.

The `devtools` package also supplied a stack of `use_` functions which added
functionality to your package. At first you could specify the package folder,
so I could do `use_package("AA", "sp")` and `use_package("BB", "gam")` to add
specific requirements to packages AA and BB respectively.

# Splitters

Then `devtools` split out the `use_` functions into the `usethis` package. And
at some point the ability to specify a package folder went. I think at some point
it was just a matter of changing the working directory with `setwd` before
running them, so the above operations would have been:

```{r old1, eval=FALSE}
setwd("A")
use_package("sp")
setwd("../B")
use_package("gam")
setwd("..")
```

That's quite clunky, and its easy to forget to go back to your original working 
directory. Luckily the `withr` package has some functions that do things within
setups that are guaranteed to be reset after the code completes, and `with_dir`
will help with the above, making it:

```{r old2, eval=FALSE}
with_dir("./A", use_package("sp"))
with_dir("./B", use_package("gam"))
```

But if this used to work, it doesn't now. Currently, `usethis` keeps a global idea
of the current "project" in an environment. Use of the word "project" here, which is
not an R concept, appears to relate to tighter integration with particular IDEs
that support it. 

Again, there's a `withr` function that lets you apply code within the context of a
new "project", resetting the current project back afterwards. For package development
this is sufficient. So we now have:

```{r old3, eval=FALSE}
with_project("./A", use_package("sp"))
with_project("./B", use_package("gam"))
```

# Easier with A-B-Usage

Can we make this any easier? That's what the `abusethis` package is all about. It
lets you use the `use_` functions on any number of packages.


First we need the `devtools` package and this package:

```{r setup}
library(devtools)
library(abusethis)
```

Next we'll make a couple of skeletal packages called A and B in R's temporary
directory location. They could be anywhere in your filesystem, with any names. The extra options
to `create_package` stop R setting the new package as the current project,
and also to allow a single-character package name (which is valid in R, but CRAN
doesn't like it):

```{r makeAB}
A = file.path(tempdir(), "A")
message("Package A is at ",A)
B = file.path(tempdir(), "B")
message("Package B is at ",B)
create_package(A, open=FALSE, check=FALSE)
create_package(B, open=FALSE, check=FALSE)
```

Now we have two packages that we'd like to use `usethis` on. We can use
`attach_use` to create a set of wrapped `use_` functions from the `usethis` 
package and attach them to the search path. We do this once for package A and
once for package B. See how they are added to the search path:

```{r Ause}
print(search())
attach_use(A)
attach_use(B)
print(search())
```

Looking at the first four functions in these environments you can see how they
are prefixed versions of the corresponding `usethis` functions:

```{r ABusefuncs}
ls("A_use")[1:4]
ls("B_use")[1:4]
```

Then if I want to set package A to have the MIT license, and package B to have
the GPL3 licence, I do:

```{r setlicense}
A_use_mit_license()
B_use_gpl3_license()
```

Arguments are the same as the corresponding `usethis` functions. So if package A 
uses the `grid` package, and package B uses the `stats` package, we do this:

```{r setpacks}
A_use_package("grid")
B_use_package("stats")
```


# More Details

By default `abusethis` uses the basename of the package folder
to create the environment and the functions. But what if I have two
packages with the same name? In that case you can use the prefix
argument to create wrapped functions with different names. 

For example, suppose you have two versions of a package, one for
development and one for production? Let's set that up.

```{r twonames}
devdir = file.path(tempdir(), "dev")
prodir = file.path(tempdir(), "pro")
dir.create(devdir)
dir.create(prodir)
create_package(file.path(devdir,"codez"), open=FALSE)
create_package(file.path(prodir,"codez"), open=FALSE)
```

Now I can attach all the `usethis` functions with a development
or production prefix:

```{r attachprefix}
attach_use(file.path(devdir,"codez"), prefix="dev_")
attach_use(file.path(prodir,"codez"), prefix="pro_")
```

and do stuff like this:

```{r devprostuff}
dev_use_mit_license()
pro_use_gpl3_license()
```

# Summary

I wrote this because its useful. If you find it useful, use it. If you don't, then don't.
If you've got an easier way to do this, use that. If you tell me about it and I like it
I'll use it too.
