├── .github
├── .gitignore
├── FUNDING.yml
└── workflows
│ ├── pkgdown.yaml
│ └── R-CMD-check.yaml
├── vignettes
├── .gitignore
└── personalr.Rmd
├── .gitignore
├── LICENSE
├── data-raw
├── icon.png
├── logo_seb.png
├── dependency-helper.R
├── build_logo.R
└── icon.svg
├── man
├── figures
│ └── logo.png
├── personalr-package.Rd
├── update_core.Rd
└── setup_package.Rd
├── pkgdown
├── favicon
│ ├── favicon.ico
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── apple-touch-icon.png
│ ├── apple-touch-icon-60x60.png
│ ├── apple-touch-icon-76x76.png
│ ├── apple-touch-icon-120x120.png
│ ├── apple-touch-icon-152x152.png
│ └── apple-touch-icon-180x180.png
├── extra.css
└── _pkgdown.yml
├── NAMESPACE
├── inst
└── templates
│ ├── packagename-package.R
│ ├── pipe.R
│ ├── zzz.R
│ ├── package-README
│ ├── utils.R
│ ├── attach.R
│ └── conflicts.R
├── NEWS.md
├── .Rbuildignore
├── R
├── personalr-package.R
├── update_core.R
├── setup_package.R
└── utils.R
├── cran-comments.md
├── personalr.Rproj
├── DESCRIPTION
├── LICENSE.md
├── README.md
└── README.Rmd
/.github/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 |
--------------------------------------------------------------------------------
/vignettes/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 | *.R
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | docs
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2020
2 | COPYRIGHT HOLDER: Sebastian Carl
3 |
--------------------------------------------------------------------------------
/data-raw/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/data-raw/icon.png
--------------------------------------------------------------------------------
/man/figures/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/man/figures/logo.png
--------------------------------------------------------------------------------
/data-raw/logo_seb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/data-raw/logo_seb.png
--------------------------------------------------------------------------------
/pkgdown/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/pkgdown/favicon/favicon.ico
--------------------------------------------------------------------------------
/pkgdown/favicon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/pkgdown/favicon/favicon-16x16.png
--------------------------------------------------------------------------------
/pkgdown/favicon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/pkgdown/favicon/favicon-32x32.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/pkgdown/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/pkgdown/favicon/apple-touch-icon-60x60.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/pkgdown/favicon/apple-touch-icon-76x76.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/pkgdown/favicon/apple-touch-icon-120x120.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/pkgdown/favicon/apple-touch-icon-152x152.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrcaseb/personalr/HEAD/pkgdown/favicon/apple-touch-icon-180x180.png
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 | export(setup_package)
4 | export(update_core)
5 | importFrom(magrittr,"%>%")
6 | importFrom(withr,with_tempdir)
7 |
--------------------------------------------------------------------------------
/inst/templates/packagename-package.R:
--------------------------------------------------------------------------------
1 | #' @keywords internal
2 | "_PACKAGE"
3 |
4 | # The following block is used by usethis to automatically manage
5 | # roxygen namespace tags. Modify with care!
6 | ## usethis namespace: start
7 | ## usethis namespace: end
8 | NULL
9 |
--------------------------------------------------------------------------------
/inst/templates/pipe.R:
--------------------------------------------------------------------------------
1 | #' Pipe operator
2 | #'
3 | #' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details.
4 | #'
5 | #' @name %>%
6 | #' @rdname pipe
7 | #' @keywords internal
8 | #' @export
9 | #' @importFrom magrittr %>%
10 | #' @usage lhs \%>\% rhs
11 | NULL
12 |
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 | # personalr 1.0.3
2 |
3 | * The installation of the personal package does not prompt the user with package upgrades.
4 | * Documentation update for R4.2
5 |
6 | # personalr 1.0.1
7 |
8 | * Preparation for CRAN
9 |
10 | # personalr 1.0.0
11 |
12 | * Initial release
13 |
--------------------------------------------------------------------------------
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^personalr\.Rproj$
2 | ^\.Rproj\.user$
3 | ^LICENSE\.md$
4 | ^README\.Rmd$
5 | ^cran-comments\.md$
6 | ^data-raw$
7 | ^vignettes/articles$
8 | ^_pkgdown\.yml$
9 | ^docs$
10 | ^pkgdown$
11 | ^\.github$
12 | ^vignettes$
13 | ^\.travis\.yml$
14 | ^CRAN-RELEASE$
15 | ^CRAN-SUBMISSION$
16 |
--------------------------------------------------------------------------------
/R/personalr-package.R:
--------------------------------------------------------------------------------
1 | #' @keywords internal
2 | "_PACKAGE"
3 |
4 | # The following block is used by usethis to automatically manage
5 | # roxygen namespace tags. Modify with care!
6 | ## usethis namespace: start
7 | #' @importFrom magrittr %>%
8 | #' @importFrom withr with_tempdir
9 | ## usethis namespace: end
10 | NULL
11 |
--------------------------------------------------------------------------------
/pkgdown/extra.css:
--------------------------------------------------------------------------------
1 | /*
2 | Check: https://www.w3schools.com/css/css_rwd_mediaqueries.asp
3 | for Responsive Web Design - Media Queries
4 | */
5 | .row > main {
6 | max-width: 100%;
7 | }
8 |
9 | @media only screen and (min-width: 640px) {
10 | main + .col-md-3 {
11 | margin-left: unset;
12 | padding-left: 5rem;
13 | max-width: 75%;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/data-raw/dependency-helper.R:
--------------------------------------------------------------------------------
1 | # Run this to update the DESCRIPTION
2 | imports <- c(
3 | "purrr",
4 | "usethis",
5 | "rstudioapi",
6 | "glue",
7 | "xfun",
8 | "devtools",
9 | "utils",
10 | "desc",
11 | "rprojroot",
12 | "magrittr",
13 | "fs",
14 | "withr"
15 | )
16 | purrr::walk(imports, usethis::use_package, "Imports")
17 | usethis::use_tidy_description()
18 | rm(imports)
19 |
--------------------------------------------------------------------------------
/cran-comments.md:
--------------------------------------------------------------------------------
1 | ## Submission
2 |
3 | This is a minor release that updates that fixes html 5 docs.
4 |
5 | ## R CMD check results
6 |
7 | 0 errors | 0 warnings | 0 notes
8 |
9 | ## revdepcheck results
10 |
11 | We checked 0 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package.
12 |
13 | * We saw 0 new problems
14 | * We failed to check 0 packages
15 |
--------------------------------------------------------------------------------
/personalr.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 | ProjectId: 6b174bb7-cce2-4f1f-a3d4-fff70038b18f
3 |
4 | RestoreWorkspace: No
5 | SaveWorkspace: No
6 | AlwaysSaveHistory: Default
7 |
8 | EnableCodeIndexing: Yes
9 | UseSpacesForTab: Yes
10 | NumSpacesForTab: 2
11 | Encoding: UTF-8
12 |
13 | RnwWeave: Sweave
14 | LaTeX: pdfLaTeX
15 |
16 | AutoAppendNewline: Yes
17 | StripTrailingWhitespace: Yes
18 |
19 | BuildType: Package
20 | PackageUseDevtools: Yes
21 | PackageInstallArgs: --no-multiarch --with-keep.source
22 | PackageRoxygenize: rd,collate,namespace
23 |
--------------------------------------------------------------------------------
/inst/templates/zzz.R:
--------------------------------------------------------------------------------
1 | .onAttach <- function(...) {
2 | needed <- core[!is_attached(core)]
3 | if (length(needed) == 0)
4 | return()
5 |
6 | crayon::num_colors(TRUE)
7 | personalr_to_replace_attach()
8 |
9 | # if (!"package:conflicted" %in% search()) {
10 | # x <- personalr_to_replace_conflicts()
11 | # msg(personalr_to_replace_conflict_message(x), startup = TRUE)
12 | # }
13 |
14 | msg(cli::rule(right = crayon::bold("Ready to go!")),startup = TRUE)
15 |
16 | }
17 |
18 | is_attached <- function(x) {
19 | paste0("package:", x) %in% search()
20 | }
21 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: #
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: mrcaseb # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/data-raw/build_logo.R:
--------------------------------------------------------------------------------
1 | library(hexSticker)
2 | library(showtext)
3 |
4 | ## Loading Google fonts (http://www.google.com/fonts)
5 | # font_add_google("Turret Road", "seb")
6 | # font_add_google("Comfortaa", "seb")
7 | font_add_google("Architects Daughter", "seb")
8 | # font_add_google("Russo One", "seb")
9 | ## Automatically use showtext to render text for future devices
10 | showtext_auto()
11 |
12 | sticker(
13 | "data-raw/icon.png", # icon is 2000x1600 Pixel
14 | package = "personalr",
15 | p_family = "seb",
16 | # asp = 2000 / 1600,
17 | # p_size = 20,
18 | s_x = 1.02,
19 | s_y = .75,
20 | s_width = 0.45,
21 | s_height = (0.45 * 1600 / 2000),
22 | spotlight = TRUE,
23 | l_y = 1.5,
24 | l_alpha = 0.2,
25 | h_fill = "#2c4f67",
26 | h_color = "#192D3B",
27 | h_size = 0.8,
28 | filename = "data-raw/logo_seb.png"
29 | )
30 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: personalr
2 | Title: Automated Personal Package Setup
3 | Version: 1.0.3
4 | Authors@R:
5 | person("Sebastian", "Carl", , "mrcaseb@gmail.com", role = c("aut", "cre"))
6 | Description: Functions to setup a personal R package that attaches given
7 | libraries and exports personal helper functions.
8 | License: MIT + file LICENSE
9 | URL: https://mrcaseb.github.io/personalr/index.html,
10 | https://github.com/mrcaseb/personalr
11 | BugReports: https://github.com/mrcaseb/personalr/issues
12 | Imports:
13 | desc,
14 | devtools,
15 | fs,
16 | glue,
17 | magrittr,
18 | purrr,
19 | rprojroot,
20 | rstudioapi,
21 | usethis,
22 | utils,
23 | withr,
24 | xfun
25 | Suggests:
26 | dplyr,
27 | tibble
28 | Encoding: UTF-8
29 | Roxygen: list(markdown = TRUE)
30 | RoxygenNote: 7.3.2
31 |
--------------------------------------------------------------------------------
/man/personalr-package.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/personalr-package.R
3 | \docType{package}
4 | \name{personalr-package}
5 | \alias{personalr}
6 | \alias{personalr-package}
7 | \title{personalr: Automated Personal Package Setup}
8 | \description{
9 | \if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}}
10 |
11 | Functions to setup a personal R package that attaches given libraries and exports personal helper functions.
12 | }
13 | \seealso{
14 | Useful links:
15 | \itemize{
16 | \item \url{https://mrcaseb.github.io/personalr/index.html}
17 | \item \url{https://github.com/mrcaseb/personalr}
18 | \item Report bugs at \url{https://github.com/mrcaseb/personalr/issues}
19 | }
20 |
21 | }
22 | \author{
23 | \strong{Maintainer}: Sebastian Carl \email{mrcaseb@gmail.com}
24 |
25 | }
26 | \keyword{internal}
27 |
--------------------------------------------------------------------------------
/pkgdown/_pkgdown.yml:
--------------------------------------------------------------------------------
1 | url: https://mrcaseb.github.io/personalr/
2 |
3 | template:
4 | bootstrap: 5
5 | bootswatch: flatly
6 | bslib:
7 | font_scale: 1.2
8 | base_font: {google: "IBM Plex Sans"}
9 | heading_font: {google: "Kanit"}
10 | code_font: {google: "Fira Code"}
11 | opengraph:
12 | twitter:
13 | creator: "@mrcaseb"
14 | site: "@mrcaseb"
15 | card: summary_large_image
16 |
17 | authors:
18 | Sebastian Carl:
19 | href: https://mrcaseb.com
20 |
21 | home:
22 | title: An R Package for Automated Personal Package Setup
23 |
24 | navbar:
25 | structure:
26 | left: [home, intro, reference, news, articles]
27 | right: [search, sponsor, twitter, github]
28 | components:
29 | twitter:
30 | icon: "fa-brands fa-bluesky fa-lg"
31 | href: https://mrcaseb.com
32 | alt: Bluesky
33 | reference:
34 | text: "Functions"
35 | href: reference/index.html
36 | sponsor:
37 | icon: "fas fa-heart fa-lg"
38 | href: https://patreon.com/mrcaseb
39 | alt: Patreon
40 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2020 Sebastian Carl
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/inst/templates/package-README:
--------------------------------------------------------------------------------
1 | {{#Rmd}}
2 | ---
3 | output: github_document
4 | ---
5 |
6 |
7 |
8 | ```{r, include = FALSE}
9 | knitr::opts_chunk$set(
10 | collapse = TRUE,
11 | comment = "#>",
12 | fig.path = "man/figures/README-",
13 | out.width = "100%"
14 | )
15 | ```
16 | {{/Rmd}}
17 |
18 | # {{{ Package }}}
19 |
20 |
21 |
22 |
23 | The goal of {{{ Package }}} is to attach a list of chosen 'core' packages when {{{ Package }}} is loaded. It can also be used to export some additional helper functions to make them available on other machines or scripts.
24 |
25 | More information about how to update the core list or add own functions can be found on the [personalr home page](https://mrcaseb.github.io/personalr/articles/personalr.html).
26 |
27 | ## Usage
28 |
29 | {{{ Package }}} is already installed on your machine and can be called with
30 |
31 | ``` r
32 | library({{{ Package }}})
33 | ```
34 | If you make changes and want to reinstall it, please open the corresponding project and run
35 |
36 | ``` r
37 | devtools::document()
38 | devtools::install()
39 | ```
40 |
--------------------------------------------------------------------------------
/inst/templates/utils.R:
--------------------------------------------------------------------------------
1 | msg <- function(..., startup = FALSE) {
2 | if (startup) {
3 | if (!isTRUE(getOption("personalr_to_replace.quiet"))) {
4 | packageStartupMessage(text_col(...))
5 | }
6 | } else {
7 | message(text_col(...))
8 | }
9 | }
10 |
11 | text_col <- function(x) {
12 | # If RStudio not available, messages already printed in black
13 | if (!rstudioapi::isAvailable()) {
14 | return(x)
15 | }
16 |
17 | if (!rstudioapi::hasFun("getThemeInfo")) {
18 | return(x)
19 | }
20 |
21 | theme <- rstudioapi::getThemeInfo()
22 |
23 | if (isTRUE(theme$dark)) crayon::white(x) else crayon::black(x)
24 |
25 | }
26 |
27 | personalr_to_replace_packages <- function(include_self = TRUE) {
28 | raw <- utils::packageDescription("personalr_to_replace")$Imports
29 | imports <- strsplit(raw, ",")[[1]]
30 | parsed <- gsub("^\\s+|\\s+$", "", imports)
31 | names <- vapply(strsplit(parsed, "\\s+"), "[[", 1, FUN.VALUE = character(1))
32 |
33 | if (include_self) {
34 | names <- c(names, "personalr_to_replace")
35 | }
36 |
37 | names
38 | }
39 |
40 | invert <- function(x) {
41 | if (length(x) == 0) return()
42 | stacked <- utils::stack(x)
43 | tapply(as.character(stacked$ind), stacked$values, list)
44 | }
45 |
--------------------------------------------------------------------------------
/man/update_core.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/update_core.R
3 | \name{update_core}
4 | \alias{update_core}
5 | \title{Update Core of Personal Package}
6 | \usage{
7 | update_core(path, packagename, core = NULL, append = TRUE)
8 | }
9 | \arguments{
10 | \item{path}{The path in which the package shall be created.
11 | If it exists, it is used. If it does not exist, it is created, provided
12 | that the parent path exists.}
13 |
14 | \item{packagename}{The name of the newly generated package. It will be
15 | checked to make sure it meets R package naming conventions.}
16 |
17 | \item{core}{A vector or list containing package names that shall be attached
18 | when the newly generated package is loaded. The packages must be installed
19 | on the current system, otherwise an error will be shown.}
20 |
21 | \item{append}{If \code{TRUE} the packages of the argument \code{core} will
22 | be appended to the current core and the package version will be increased
23 | on the "patch" level. Otherwise \code{core} will be overwritten and the
24 | package version will be increased on the "minor" level.}
25 | }
26 | \description{
27 | Updates the "core" of a personal package created with personalr. It can
28 | either append another package to the current core or overwrite it
29 | with a new core.
30 | }
31 |
--------------------------------------------------------------------------------
/man/setup_package.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/setup_package.R
3 | \name{setup_package}
4 | \alias{setup_package}
5 | \title{Setup Personal Package}
6 | \usage{
7 | setup_package(path, packagename, core = NULL)
8 | }
9 | \arguments{
10 | \item{path}{The path in which the package shall be created.
11 | If it exists, it is used. If it does not exist, it is created, provided
12 | that the parent path exists.}
13 |
14 | \item{packagename}{The name of the newly generated package. It will be
15 | checked to make sure it meets R package naming conventions.}
16 |
17 | \item{core}{A vector or list containing package names that shall be attached
18 | when the newly generated package is loaded. The packages must be installed
19 | on the current system, otherwise an error will be shown.}
20 | }
21 | \description{
22 | A function to setup a new personal package or update an existing package.
23 | }
24 | \examples{
25 | \donttest{
26 | # create package "mypackage" in temporary directory with
27 | # the core packages dplyr, glue and purrr
28 | withr::with_tempdir({
29 | install.packages(
30 | c("dplyr", "glue", "purrr"),
31 | repos = "http://cran.us.r-project.org"
32 | )
33 | setup_package(
34 | path = tempdir(),
35 | packagename = "mypackage",
36 | core = c("dplyr", "glue", "purrr")
37 | )
38 | })
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/.github/workflows/pkgdown.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | on:
4 | push:
5 | branches: [main, master]
6 | pull_request:
7 | release:
8 | types: [published]
9 | workflow_dispatch:
10 |
11 | name: pkgdown.yaml
12 |
13 | permissions: read-all
14 |
15 | jobs:
16 | pkgdown:
17 | runs-on: ubuntu-latest
18 | # Only restrict concurrency for non-PR jobs
19 | concurrency:
20 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
21 | env:
22 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
23 | permissions:
24 | contents: write
25 | steps:
26 | - uses: actions/checkout@v4
27 |
28 | - uses: r-lib/actions/setup-pandoc@v2
29 |
30 | - uses: r-lib/actions/setup-r@v2
31 | with:
32 | use-public-rspm: true
33 |
34 | - uses: r-lib/actions/setup-r-dependencies@v2
35 | with:
36 | extra-packages: any::pkgdown, local::.
37 | needs: website
38 |
39 | - name: Build site
40 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
41 | shell: Rscript {0}
42 |
43 | - name: Deploy to GitHub pages 🚀
44 | if: github.event_name != 'pull_request'
45 | uses: JamesIves/github-pages-deploy-action@v4.5.0
46 | with:
47 | clean: false
48 | branch: gh-pages
49 | folder: docs
50 |
--------------------------------------------------------------------------------
/.github/workflows/R-CMD-check.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | on:
4 | push:
5 | branches: [main, master]
6 | pull_request:
7 |
8 | name: R-CMD-check.yaml
9 |
10 | permissions: read-all
11 |
12 | jobs:
13 | R-CMD-check:
14 | runs-on: ${{ matrix.config.os }}
15 |
16 | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
17 |
18 | strategy:
19 | fail-fast: false
20 | matrix:
21 | config:
22 | - {os: macos-latest, r: 'release'}
23 | - {os: windows-latest, r: 'release'}
24 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
25 | - {os: ubuntu-latest, r: 'release'}
26 | - {os: ubuntu-latest, r: 'oldrel-1'}
27 |
28 | env:
29 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
30 | R_KEEP_PKG_SOURCE: yes
31 |
32 | steps:
33 | - uses: actions/checkout@v4
34 |
35 | - uses: r-lib/actions/setup-pandoc@v2
36 |
37 | - uses: r-lib/actions/setup-r@v2
38 | with:
39 | r-version: ${{ matrix.config.r }}
40 | http-user-agent: ${{ matrix.config.http-user-agent }}
41 | use-public-rspm: true
42 |
43 | - uses: r-lib/actions/setup-r-dependencies@v2
44 | with:
45 | extra-packages: any::rcmdcheck
46 | needs: check
47 |
48 | - uses: r-lib/actions/check-r-package@v2
49 | with:
50 | upload-snapshots: true
51 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'
52 |
--------------------------------------------------------------------------------
/inst/templates/attach.R:
--------------------------------------------------------------------------------
1 | core_unloaded <- function() {
2 | search <- paste0("package:", core)
3 | core[!search %in% search()]
4 | }
5 |
6 | # Attach the package from the same package library it was
7 | # loaded from before. https://github.com/tidyverse/tidyverse/issues/171
8 | same_library <- function(pkg) {
9 | loc <- if (pkg %in% loadedNamespaces()) dirname(getNamespaceInfo(pkg, "path"))
10 | do.call(
11 | "library",
12 | list(pkg, lib.loc = loc, character.only = TRUE, warn.conflicts = FALSE)
13 | )
14 | }
15 |
16 | personalr_to_replace_attach <- function() {
17 | to_load <- core_unloaded()
18 | if (length(to_load) == 0) {
19 | return(invisible())
20 | }
21 |
22 | msg(
23 | cli::rule(
24 | left = crayon::bold("Attaching packages"),
25 | right = crayon::cyan(crayon::bold(paste0(
26 | "personalr_to_replace ",
27 | package_version("personalr_to_replace")
28 | )))
29 | ),
30 | startup = TRUE
31 | )
32 |
33 | versions <- vapply(to_load, package_version, character(1))
34 | packages <- paste0(
35 | crayon::green(cli::symbol$tick), " ", crayon::cyan(format(to_load)), " ",
36 | crayon::col_align(versions, max(crayon::col_nchar(versions)))
37 | )
38 |
39 | if (length(packages) %% 2 == 1) {
40 | packages <- append(packages, "")
41 | }
42 | col1 <- seq_len(length(packages) / 2)
43 | info <- paste0(packages[col1], " ", packages[-col1])
44 |
45 | msg(paste(info, collapse = "\n"), startup = TRUE)
46 |
47 | suppressPackageStartupMessages(
48 | lapply(to_load, same_library)
49 | )
50 |
51 | invisible()
52 | }
53 |
54 | package_version <- function(x) {
55 | version <- as.character(unclass(utils::packageVersion(x))[[1]])
56 |
57 | if (length(version) > 3) {
58 | version[4:length(version)] <-
59 | crayon::yellow(as.character(version[4:length(version)]))
60 | }
61 | paste0(version, collapse = ".")
62 | }
63 |
--------------------------------------------------------------------------------
/inst/templates/conflicts.R:
--------------------------------------------------------------------------------
1 | personalr_to_replace_conflicts <- function() {
2 | envs <- grep("^package:", search(), value = TRUE)
3 | envs <- purrr::set_names(envs)
4 | objs <- invert(lapply(envs, ls_env))
5 |
6 | conflicts <- purrr::keep(objs, ~ length(.x) > 1)
7 |
8 | personalr_to_replace_names <-
9 | paste0("package:", personalr_to_replace_packages())
10 | conflicts <- purrr::keep(conflicts, ~ any(.x %in% personalr_to_replace_names))
11 |
12 | conflict_funs <- purrr::imap(conflicts, confirm_conflict)
13 | conflict_funs <- purrr::compact(conflict_funs)
14 |
15 | structure(conflict_funs, class = "personalr_to_replace_conflicts")
16 | }
17 |
18 | personalr_to_replace_conflict_message <- function(x) {
19 | if (length(x) == 0) {
20 | return("")
21 | }
22 |
23 | header <- cli::rule(
24 | left = crayon::bold("Conflicts"),
25 | right = "personalr_to_replace_conflicts()"
26 | )
27 |
28 | pkgs <- x %>% purrr::map(~ gsub("^package:", "", .))
29 | others <- pkgs %>% purrr::map(`[`, -1)
30 | other_calls <- purrr::map2_chr(
31 | others, names(others),
32 | ~ paste0(crayon::blue(.x), "::", .y, "()", collapse = ", ")
33 | )
34 |
35 | winner <- pkgs %>% purrr::map_chr(1)
36 | funs <- format(paste0(
37 | crayon::blue(winner),
38 | "::",
39 | crayon::green(paste0(names(x), "()"))
40 | ))
41 | bullets <- paste0(
42 | crayon::red(cli::symbol$cross), " ", funs,
43 | " masks ", other_calls,
44 | collapse = "\n"
45 | )
46 |
47 | paste0(header, "\n", bullets)
48 | }
49 |
50 |
51 | print.personalr_to_replace_conflicts <- function(x, ..., startup = FALSE) {
52 | cli::cat_line(personalr_to_replace_conflict_message(x))
53 | }
54 |
55 |
56 | confirm_conflict <- function(packages, name) {
57 | # Only look at functions
58 | objs <- packages %>%
59 | purrr::map(~ get(name, pos = .)) %>%
60 | purrr::keep(is.function)
61 |
62 | if (length(objs) <= 1) {
63 | return()
64 | }
65 |
66 | # Remove identical functions
67 | objs <- objs[!duplicated(objs)]
68 | packages <- packages[!duplicated(packages)]
69 | if (length(objs) == 1) {
70 | return()
71 | }
72 |
73 | packages
74 | }
75 |
76 | ls_env <- function(env) {
77 | x <- ls(pos = env)
78 | if (identical(env, "package:dplyr")) {
79 | x <- setdiff(x, c("intersect", "setdiff", "setequal", "union"))
80 | }
81 | x
82 | }
83 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # personalr
5 |
6 |
7 |
8 | [](https://CRAN.R-project.org/package=personalr)
10 | [](https://CRAN.R-project.org/package=personalr)
12 | [](https://lifecycle.r-lib.org/articles/stages.html#stable)
14 | [](https://github.com/mrcaseb/personalr/actions/workflows/R-CMD-check.yaml)
15 |
16 |
17 | ## Preface
18 |
19 | If you work with R or any other programming language for a while, you
20 | will come to the point where you want to use already written code when
21 | developing a script and often need the same packages to do your work.The
22 | easiest solution is to save the loading of the regularly used packages
23 | and maybe some helper functions in a separate script and then load this
24 | script with `source(...)` into the Global Environment.
25 |
26 | However, this approach has two disadvantages:
27 |
28 | 1. Over time, the Global Environment becomes littered, making it harder
29 | to find important objects and
30 | 2. The `source` script must either be available and up-to-date on the
31 | local machine or be made available on the Internet.
32 |
33 | ## Package Purpose
34 |
35 | The best solution for the above mentioned disadvantages is an own
36 | (personal) package, but for the setup it needs a basic understanding of
37 | how to develop packages.
38 |
39 | The goal of personalr is to do exactly that. A basic setup of a personal
40 | package, which loads a modifiable list of packages and some basic
41 | functions.
42 |
43 | ## Installation
44 |
45 | You can install the released version of personalr from
46 | [CRAN](https://cran.r-project.org/package=personalr) with:
47 |
48 | ``` r
49 | install.packages("personalr")
50 | ```
51 |
52 | You can install the development version from
53 | [GitHub](https://github.com/mrcaseb/personalr/) with:
54 |
55 | ``` r
56 | if (!require("pak")) install.packages("pak")
57 | pak::pak("mrcaseb/personalr")
58 | ```
59 |
--------------------------------------------------------------------------------
/R/update_core.R:
--------------------------------------------------------------------------------
1 | #' Update Core of Personal Package
2 | #'
3 | #' Updates the "core" of a personal package created with personalr. It can
4 | #' either append another package to the current core or overwrite it
5 | #' with a new core.
6 | #'
7 | #' @inheritParams setup_package
8 | #' @param append If \code{TRUE} the packages of the argument \code{core} will
9 | #' be appended to the current core and the package version will be increased
10 | #' on the "patch" level. Otherwise \code{core} will be overwritten and the
11 | #' package version will be increased on the "minor" level.
12 | #' @export
13 | update_core <- function(path, packagename, core = NULL, append = TRUE) {
14 | # check the core vector
15 | purrr::walk(core, check_for_package)
16 |
17 | # create the package and use the path for next steps
18 | if (!is_package(path)) {
19 | path <- fs::path_expand(glue::glue("{path}/{packagename}"))
20 | }
21 |
22 | # move to the correct working directory
23 | usethis::local_project(path)
24 |
25 | # Remove deps if append = FALSE
26 | if (!isTRUE(append)) {
27 | desc::desc_del_deps()
28 | }
29 |
30 | # write new deps and tidy up DESCRIPTION
31 | purrr::walk(c(core, "cli", "crayon", "rstudioapi"), use_dependency, "Imports")
32 | usethis::use_tidy_description()
33 |
34 | # get old core packages
35 | if (isTRUE(append)) {
36 | old_core <- utils::packageDescription(packagename)$Imports %>%
37 | strsplit(",\n") %>%
38 | unlist()
39 | } else {
40 | old_core <- NULL
41 | }
42 |
43 | # combine old and new core
44 | new_core <- c(
45 | core,
46 | old_core[which(!old_core %in% c("cli", "crayon", "rstudioapi"))]
47 | ) %>%
48 | sort()
49 |
50 | output_string <- glue::glue(
51 | "If you really want to update your core you'll have to",
52 | "confirm the following dialogue...!"
53 | )
54 |
55 | usethis::ui_info("{output_string}\n")
56 |
57 | # write new core file
58 | usethis::write_over(
59 | usethis::proj_path("R/core.R"),
60 | create_core_script(new_core)
61 | )
62 |
63 | if (isTRUE(append)) {
64 | usethis::use_version("patch")
65 | } else {
66 | usethis::use_version("minor")
67 | }
68 |
69 | # Now document and install the package
70 | usethis::ui_todo("Updating documentation and installing {packagename}...")
71 | devtools::document(pkg = path, quiet = TRUE)
72 | devtools::install(
73 | pkg = path,
74 | reload = FALSE,
75 | build = FALSE,
76 | force = TRUE,
77 | quiet = FALSE
78 | )
79 |
80 | return(invisible(TRUE))
81 | }
82 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 |
6 |
7 | ```{r, include = FALSE}
8 | knitr::opts_chunk$set(
9 | collapse = TRUE,
10 | comment = "#>",
11 | fig.path = "man/figures/README-",
12 | out.width = "100%"
13 | )
14 | ```
15 |
16 | # personalr
17 |
18 |
19 | [](https://CRAN.R-project.org/package=personalr)
20 | [](https://CRAN.R-project.org/package=personalr)
21 | [](https://lifecycle.r-lib.org/articles/stages.html#stable)
22 | [](https://github.com/mrcaseb/personalr/actions/workflows/R-CMD-check.yaml)
23 |
24 |
25 | ## Preface
26 |
27 | If you work with R or any other programming language for a while, you will come to the point where you want to use already written code when developing a script and often need the same packages to do your work.The easiest solution is to save the loading of the regularly used packages and maybe some helper functions in a separate script and then load this script with `source(...)` into the Global Environment.
28 |
29 | However, this approach has two disadvantages:
30 |
31 | 1. Over time, the Global Environment becomes littered, making it harder to find important objects and
32 | 1. The `source` script must either be available and up-to-date on the local machine or be made available on the Internet.
33 |
34 | ## Package Purpose
35 |
36 | The best solution for the above mentioned disadvantages is an own (personal) package, but for the setup it needs a basic understanding of how to develop packages.
37 |
38 | The goal of personalr is to do exactly that. A basic setup of a personal package, which loads a modifiable list of packages and some basic functions.
39 |
40 | ## Installation
41 |
42 | You can install the released version of personalr from [CRAN](https://cran.r-project.org/package=personalr) with:
43 |
44 | ``` {r eval = FALSE}
45 | install.packages("personalr")
46 | ```
47 |
48 | You can install the development version from [GitHub](https://github.com/mrcaseb/personalr/) with:
49 |
50 | ``` {r eval = FALSE}
51 | if (!require("pak")) install.packages("pak")
52 | pak::pak("mrcaseb/personalr")
53 | ```
54 |
55 | ## One more thing
56 |
57 | personalr is open source and it builds on top of other open source projects. However, maintaining this package will be a lot of work so I kindly ask you to consider donating at [patreon](https://www.patreon.com/mrcaseb).
58 |
--------------------------------------------------------------------------------
/R/setup_package.R:
--------------------------------------------------------------------------------
1 | #' Setup Personal Package
2 | #'
3 | #' A function to setup a new personal package or update an existing package.
4 | #'
5 | #' @param path The path in which the package shall be created.
6 | #' If it exists, it is used. If it does not exist, it is created, provided
7 | #' that the parent path exists.
8 | #' @param packagename The name of the newly generated package. It will be
9 | #' checked to make sure it meets R package naming conventions.
10 | #' @param core A vector or list containing package names that shall be attached
11 | #' when the newly generated package is loaded. The packages must be installed
12 | #' on the current system, otherwise an error will be shown.
13 | #' @export
14 | #' @examples
15 | #' \donttest{
16 | #' # create package "mypackage" in temporary directory with
17 | #' # the core packages dplyr, glue and purrr
18 | #' withr::with_tempdir({
19 | #' install.packages(
20 | #' c("dplyr", "glue", "purrr"),
21 | #' repos = "http://cran.us.r-project.org"
22 | #' )
23 | #' setup_package(
24 | #' path = tempdir(),
25 | #' packagename = "mypackage",
26 | #' core = c("dplyr", "glue", "purrr")
27 | #' )
28 | #' })
29 | #' }
30 | setup_package <- function(path, packagename, core = NULL) {
31 | # check the core vector
32 | purrr::walk(core, check_for_package)
33 |
34 | # create the package and use the path for next steps
35 | path <- usethis::create_package(
36 | glue::glue("{path}/{packagename}"),
37 | rstudio = rstudioapi::isAvailable(),
38 | open = FALSE,
39 | fields = list(
40 | Version = "1.0.0"
41 | )
42 | )
43 |
44 | # move to the correct working directory
45 | usethis::local_project(path)
46 |
47 | # Add package doc file
48 | usethis::use_template(
49 | "packagename-package.R",
50 | glue::glue("R/{packagename}-package.R")
51 | )
52 |
53 | # Add Readme as markdown file because we want to keep it easy
54 | usethis::use_template(
55 | "package-README",
56 | "README.md",
57 | data = package_data(),
58 | open = FALSE,
59 | package = "personalr"
60 | )
61 |
62 | # Add core packages to "Imports" and save core script
63 | purrr::walk(c(core, "cli", "crayon", "rstudioapi"), use_dependency, "Imports")
64 | usethis::use_tidy_description()
65 | usethis::write_over(usethis::proj_path("R/core.R"), create_core_script(core))
66 |
67 | # Add template files
68 | templates <- c("attach", "conflicts", "pipe", "utils", "zzz")
69 | purrr::walk(templates, add_template)
70 |
71 | # Use the package name in all templates
72 | xfun::gsub_dir(
73 | "personalr_to_replace",
74 | packagename,
75 | dir = usethis::proj_path("R"),
76 | ext = "R"
77 | )
78 |
79 | # Now document and install the package
80 | usethis::ui_todo("Updating documentation and installing {packagename}...")
81 | devtools::document(pkg = path, quiet = TRUE)
82 | devtools::install(
83 | pkg = path,
84 | reload = FALSE,
85 | build = FALSE,
86 | force = TRUE,
87 | quiet = FALSE,
88 | upgrade = FALSE
89 | )
90 |
91 | # Now activate project
92 | usethis::proj_activate(path)
93 | }
94 |
95 |
96 |
--------------------------------------------------------------------------------
/data-raw/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
64 |
--------------------------------------------------------------------------------
/R/utils.R:
--------------------------------------------------------------------------------
1 | # Taken from usethis ------------------------------------------------------
2 |
3 | use_dependency <- function(package, type, min_version = NULL) {
4 | stopifnot(is_string(package))
5 | stopifnot(is_string(type))
6 |
7 | if (package != "R" && !is_installed(package)) {
8 | usethis::ui_stop(c(
9 | "{usethis::ui_value(package)} must be installed before you can ",
10 | "take a dependency on it."
11 | ))
12 | }
13 |
14 | if (isTRUE(min_version)) {
15 | min_version <- utils::packageVersion(package)
16 | }
17 | version <- if (is.null(min_version)) "*" else paste0(">= ", min_version)
18 |
19 | types <- c("Depends", "Imports", "Suggests", "Enhances", "LinkingTo")
20 | names(types) <- tolower(types)
21 | type <- types[[match.arg(tolower(type), names(types))]]
22 |
23 | deps <- desc::desc_get_deps(usethis::proj_get())
24 |
25 | existing_dep <- deps$package == package
26 | existing_type <- deps$type[existing_dep]
27 | existing_ver <- deps$version[existing_dep]
28 | is_linking_to <- (existing_type != "LinkingTo" & type == "LinkingTo") |
29 | (existing_type == "LinkingTo" & type != "LinkingTo")
30 |
31 | # No existing dependency, so can simply add
32 | if (!any(existing_dep) || any(is_linking_to)) {
33 | usethis::ui_done("Adding {usethis::ui_value(package)} to {usethis::ui_field(type)} field in DESCRIPTION")
34 | desc::desc_set_dep(package, type, version = version, file = usethis::proj_get())
35 | return(invisible())
36 | }
37 |
38 | existing_type <- setdiff(existing_type, "LinkingTo")
39 | delta <- sign(match(existing_type, types) - match(type, types))
40 | if (delta < 0) {
41 | # don't downgrade
42 | usethis::ui_warn(
43 | "Package {usethis::ui_value(package)} is already listed in \\
44 | {usethis::ui_value(existing_type)} in DESCRIPTION, no change made."
45 | )
46 | } else if (delta == 0 && !is.null(min_version)) {
47 | # change version
48 | upgrade <- existing_ver == "*" || numeric_version(min_version) > version_spec(existing_ver)
49 | if (upgrade) {
50 | usethis::ui_done(
51 | "Increasing {usethis::ui_value(package)} version to {usethis::ui_value(version)} in DESCRIPTION"
52 | )
53 | desc::desc_set_dep(package, type, version = version, file = usethis::proj_get())
54 | }
55 | } else if (delta > 0) {
56 | # upgrade
57 | if (existing_type != "LinkingTo") {
58 | usethis::ui_done(
59 | "
60 | Moving {usethis::ui_value(package)} from {usethis::ui_field(existing_type)} to {usethis::ui_field(type)} \\
61 | field in DESCRIPTION
62 | "
63 | )
64 | desc::desc_del_dep(package, existing_type, file = usethis::proj_get())
65 | desc::desc_set_dep(package, type, version = version, file = usethis::proj_get())
66 | }
67 | }
68 |
69 | invisible()
70 | }
71 |
72 | is_installed <- function(pkg) {
73 | requireNamespace(pkg, quietly = TRUE)
74 | }
75 |
76 | check_for_package <- function(package){
77 | if (package != "R" && !is_installed(package)) {
78 | usethis::ui_stop(c(
79 | "Package {usethis::ui_value(package)} must be installed before you can ",
80 | "take a dependency on it."
81 | ))
82 | }
83 | }
84 |
85 | package_data <- function(base_path = usethis::proj_get()){
86 | desc <- desc::description$new(base_path)
87 | as.list(desc$get(desc$fields()))
88 | }
89 |
90 | version_spec <- function(x) {
91 | x <- gsub("(<=|<|>=|>|==)\\s*", "", x)
92 | numeric_version(x)
93 | }
94 |
95 | is_package <- function(base_path = usethis::proj_get()) {
96 | res <- tryCatch(
97 | rprojroot::find_package_root_file(path = base_path),
98 | error = function(e) NULL
99 | )
100 | !is.null(res)
101 | }
102 |
103 | # Taken from https://github.com/radiant-rstats/radiant.data/blob/m --------
104 |
105 | is_string <- function(x) {
106 | length(x) == 1 && is.character(x) && !is_empty(x)
107 | }
108 |
109 | is_empty <- function(x, empty = "\\s*") {
110 | is_not(x) || (length(x) == 1 && grepl(paste0("^", empty, "$"), x))
111 | }
112 |
113 | is_not <- function(x) {
114 | length(x) == 0 || (length(x) == 1 && is.na(x))
115 | }
116 |
117 |
118 | # Own stuff ---------------------------------------------------------------
119 |
120 | add_template <- function(template_name){
121 | usethis::use_template(
122 | glue::glue("{template_name}.R"),
123 | glue::glue("R/{template_name}.R"),
124 | package = "personalr")
125 | }
126 |
127 | create_core_script <- function(pkgs){
128 | paste(
129 | 'core <- c( \n"',
130 | paste0(pkgs, collapse = '",\n"'), '"\n)',
131 | collapse = "\n",
132 | sep = ""
133 | )
134 | }
135 |
--------------------------------------------------------------------------------
/vignettes/personalr.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Introduction to personalr"
3 | author: "Sebastian Carl"
4 | ---
5 |
6 | ```{r, include = FALSE}
7 | knitr::opts_chunk$set(
8 | collapse = TRUE,
9 | comment = "#>"
10 | )
11 | options(cli.num_colors = 1, crayon.enabled = FALSE)
12 | ```
13 |
14 | # Acknowledgement
15 |
16 | Setting up an R package isn't really intuitive as the developer needs a basic understanding of some package conventions and good practice methods. There are multiple packages in the R landscape that help doing exactly this. `personalr` makes heavy usage of the most important package development helper package: [`usethis`](https://usethis.r-lib.org/). It has a ton of useful functions but the developer has to know which of them is needed for the individual purpose.
17 |
18 | `personalr` is more or less a wrapper around several usethis functions and completes the whole thing with some helper functions. The package setup that personalr creates is also based on the [`tidyverse`](https://tidyverse.tidyverse.org/) package.
19 |
20 | Everything you need to know about R package development is perfectly summarized in [Hadley Wickham's book R Packages](https://r-pkgs.org/).
21 |
22 | # Usage
23 |
24 | ## First setup
25 |
26 | The main function of `personalr` is `setup_package()`. Handed a valid path, the desired package name and a vector or list of package names (the 'core' of the personal package that is about to be created) it does the following things:
27 |
28 | - create the project with the intended package name
29 | - create all basic package files like DESCRIPTION (including the Imports of the 'core' packages), NAMESPACE or the "R" directory
30 | - create a basic Readme
31 | - create all scripts and functions in the R directory that are required to attach the core packages
32 | - add the pipe operator `magrittr::%>%()` to your exported functions so it is usable as soon as the package is loaded
33 | - document and install the package
34 | - open the new package in a separate R session.
35 |
36 | The following example creates the new package `"mypackage"` with the `core` packages dplyr, glue and purrr in a temporary directory.
37 |
38 | ```{r, eval=FALSE}
39 | library(personalr)
40 | temp_directory <- tempdir()
41 | setup_package(path = temp_directory, packagename = "mypackage", core = c("dplyr", "glue", "purrr"))
42 | ```
43 |
44 | ```{r setup, eval=TRUE, echo=FALSE}
45 | library(personalr)
46 | temp_directory <- tempdir()
47 | setup_package(path = temp_directory, packagename = "mypackage", core = c("dplyr", "glue", "purrr"))
48 | ```
49 |
50 | Once the setup is finished and the new package installed, the new package should be opened in a separate R session. It will show the following files and directories
51 |
52 | ```{r, echo=FALSE}
53 | library(fs)
54 | fs::dir_tree(fs::path(temp_directory, "mypackage"))
55 | ```
56 |
57 | ## Update your package
58 |
59 | There are basically two reasons why you want to update your personal package:
60 |
61 | 1. You want to update the list of `core` packages
62 | 1. You want to add a helper function so you can call it when the package is loaded (i.e. 'export' a function)
63 |
64 | ### Update your 'core' packages
65 |
66 | There is a separate function in `personalr` to update your list of `core` packages: `update_core()`. It can either append new packages to the existing `core` or overwrite it completely (with the logical argument `append`).
67 |
68 | Assuming you have run the above code and have created the personal package `"mypackage"` with the `core` packages "dplyr", "glue" and "purrr" you can add another package, e.g. "tibble" by running the following code (please note that the example uses temporary directories and if you run this on your machine it's easier to open the project and set `path = "."`).
69 |
70 | ```{r, eval=FALSE}
71 | update_core(path = temp_directory, packagename = "mypackage", core = "tibble", append = TRUE)
72 | ```
73 |
74 | ```{r, eval=TRUE, echo=FALSE}
75 | update_core(path = temp_directory, packagename = "mypackage", core = "tibble", append = TRUE)
76 | ```
77 |
78 | Now `"mypackage"` attaches "dplyr", "glue", "purrr" and "tibble" when it is loaded. If you want to overwrite the core (i.e. only use "tibble" and drop the other packages) just set `append = FALSE` in the above code chunk.
79 |
80 | ### Add your own exported helper function
81 |
82 | One of the strengths of a package is that you are able to save your helper functions inside the package and make them available in your code without littering the Global Environment.
83 |
84 | Let's say you often use the negated version of `%in%` to select values that are *not* in a vector. The typical way to do it is `!value %in% vector`. This is somewhat annoying as it's hard to read the code and see the exclamation mark at the beginning of the expression. So now we want to write and export our own little helper for the negated version of `%in%`, and we call it `%nin%`.
85 |
86 | If you run this inside your project
87 |
88 | ```{r, eval=FALSE}
89 | usethis::use_r("nin")
90 | ```
91 |
92 | it will create a new script `"R/nin.R"` and open it directly. Add the code of your helper function and don't forget to export it with `#' @export` (this means the next time you document and install your package the new function will be exported and available for usage).
93 |
94 | ```{r, eval=FALSE}
95 | #' @export
96 | '%nin%' <- Negate(`%in%`)
97 | ```
98 |
99 | To update your package you should consider changing the package version to make more clear something changed by running
100 |
101 | ```{r, eval=FALSE}
102 | usethis::use_version()
103 | ```
104 |
105 | and afterwards documenting and installing the new version by running
106 |
107 | ```{r, eval=FALSE}
108 | devtools::document()
109 | devtools::install()
110 | ```
111 |
112 |
--------------------------------------------------------------------------------