forked from r-lib/devtools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpackage.R
108 lines (91 loc) · 2.61 KB
/
package.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#' Coerce input to a package.
#'
#' Possible specifications of package:
#' \itemize{
#' \item path
#' \item package object
#' }
#' @param x object to coerce to a package
#' @param create only relevant if a package structure does not exist yet: if
#' `TRUE`, create a package structure; if `NA`, ask the user
#' (in interactive mode only)
#' @export
#' @keywords internal
as.package <- function(x = NULL, create = NA) {
if (is.package(x)) return(x)
x <- package_file(path = x)
load_pkg_description(x, create = create)
}
#' Find file in a package.
#'
#' It always starts by walking up the path until it finds the root directory,
#' i.e. a directory containing `DESCRIPTION`. If it cannot find the root
#' directory, or it can't find the specified path, it will throw an error.
#'
#' @param ... Components of the path.
#' @param path Place to start search for package directory.
#' @export
#' @examples
#' \dontrun{
#' package_file("figures", "figure_1")
#' }
package_file <- function(..., path = ".") {
if (!is.character(path) || length(path) != 1) {
stop("`path` must be a string.", call. = FALSE)
}
path <- strip_slashes(normalizePath(path, mustWork = FALSE))
if (!file.exists(path)) {
stop("Can't find '", path, "'.", call. = FALSE)
}
if (!file.info(path)$isdir) {
stop("'", path, "' is not a directory.", call. = FALSE)
}
# Walk up to root directory
while (!has_description(path)) {
path <- dirname(path)
if (is_root(path)) {
stop("Could not find package root.", call. = FALSE)
}
}
file.path(path, ...)
}
has_description <- function(path) {
file.exists(file.path(path, "DESCRIPTION"))
}
is_root <- function(path) {
identical(path, dirname(path))
}
strip_slashes <- function(x) {
x <- sub("/*$", "", x)
x
}
# Load package DESCRIPTION into convenient form.
load_pkg_description <- function(path, create) {
path_desc <- file.path(path, "DESCRIPTION")
if (!file.exists(path_desc)) {
if (is.na(create)) {
if (interactive()) {
message("No package infrastructure found in ", path, ". Create it?")
create <- (menu(c("Yes", "No")) == 1)
} else {
create <- FALSE
}
}
if (create) {
setup(path = path)
} else {
stop("No description at ", path_desc, call. = FALSE)
}
}
desc <- as.list(read.dcf(path_desc)[1, ])
names(desc) <- tolower(names(desc))
desc$path <- path
structure(desc, class = "package")
}
#' Is the object a package?
#'
#' @keywords internal
#' @export
is.package <- function(x) inherits(x, "package")
# Mockable variant of interactive
interactive <- function() .Primitive("interactive")()